mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2026-02-09 01:07:27 +08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
123554e24d | ||
|
|
bb7ba249e9 | ||
|
|
3ecefcb802 | ||
|
|
798a838ca4 |
59
README.md
59
README.md
@@ -7,13 +7,46 @@ This is a small local Arcaea server based on Python and Flask, which can simulat
|
||||
> 虽然看起来很蠢,但是可以用!
|
||||
> It looks stupid, but it works!
|
||||
|
||||
## 特性 Features
|
||||
有 We have:
|
||||
- 登录、注册 Login and registration
|
||||
- 成绩上传 Score upload
|
||||
- PTT
|
||||
- 排名 Rank
|
||||
- 好友系统 Friends
|
||||
- 数据同步 Data synchronization
|
||||
- 爬梯 Climbing steps
|
||||
- 自定义世界模式 Customizable World Mode
|
||||
- 全角色立绘 All character drawings
|
||||
- 全剧情解锁 Unlock all the storys
|
||||
- 后台查分 Background search scores
|
||||
- 后台自定义歌曲定数 Customize chart consts in the background
|
||||
|
||||
没有以下 We don't have:
|
||||
- 角色特性 Character characteristics
|
||||
- 购买 Purchase
|
||||
- 歌曲解锁、曲包解锁 Songs unlocking and music packs unlocking
|
||||
- 反作弊系统 Anti cheating system
|
||||
- 服务器安全性保证 Server security assurance
|
||||
|
||||
可能有问题 There may be problems:
|
||||
- Recent 30
|
||||
|
||||
## 说明 Statement
|
||||
只是很有趣,用处探索中。
|
||||
It is just so interesting. What it can do is under exploration.
|
||||
|
||||
进行了一下项目改进,可能目录有所变化
|
||||
Some project improvements have been made and the catalog may have changed.
|
||||
|
||||
## 下载 Download
|
||||
[这里 Here](https://github.com/Lost-MSth/Arcaea-server/releases)
|
||||
|
||||
## 更新日志 Update log
|
||||
只保留最新版本 Only keep the latest version.
|
||||
### Version 1.3
|
||||
- 适用于Arcaea 3.2.1版本 For Arcaea 3.2.1
|
||||
- 更新了歌曲数据库 Update the song database.
|
||||
- 新增了可自定义的世界模式 Add customizable World Mode.
|
||||
- 对于官方版本,解锁几乎所有歌曲 For the official version, unlock almost all songs.
|
||||
|
||||
@@ -21,32 +54,6 @@ It is just so interesting. What it can do is under exploration.
|
||||
|
||||
> Update note: In this update you cannot synchronize data from an older version. Please use the data synchronization function in game to upload best_score data.
|
||||
|
||||
### Version 1.2
|
||||
- 仍然适用于Arcaea 3.2.0版本 Still for Arcaea 3.2.0
|
||||
- 新增了网页管理页面,可以通过 http:// HOST IP : PORT /web 进行访问 Add a new management webpage, you can visit http:// HOST IP : PORT /web to use it.
|
||||
- 修改了character表结构,这将方便以后的角色更新 The character table structure has been modified, which will facilitate the character update in the future.
|
||||
- 修复了best_score表的时间记录,应该是精确到秒的Unix时间戳 Fix the time record of best_score table. It should be a UNIX timestamp accurate to seconds.
|
||||
- 修复了一个bug,recent30现在会考虑同一首歌的不同难度 Fix a bug. Now recent30 will consider different difficulties of one song.
|
||||
> 更新说明:现在你可以使用web管理页面来迁移旧数据了,后台固定账号admin,密码admin
|
||||
> 如果使用数据迁移,那么请先清空recent30表数据,或者在迁移后打30首歌手动清除recent30,这次更新后web页面读取原来的recent30表将会报错
|
||||
|
||||
> Update note: Now you can use the web management page to migrate old data. Background account is fixed. Username is admin, and password is admin.
|
||||
> If you use data migration, please clear the data in the recent30 table first, or manually clear recent30 by playing 30 songs after the migration. After this update, an error will be reported when the web page reads the past recent30 table.
|
||||
|
||||
### Version 1.1
|
||||
- 适用于Arcaea 3.2.0版本 For Arcaea 3.2.0
|
||||
- 更新了歌曲数据库 Update the song database.
|
||||
- 角色**梦**可以看到觉醒立绘了 The drawing of uncapped character **Yume** can be seen.
|
||||
- 修复了一个Bug,现在剧情可以全部解锁了 Fix a bug. Now the plot can be unlocked.
|
||||
> 更新说明:您若需要做数据迁移,请使用原来的数据库文件**arcaea_database.db**,并使用数据库操作软件打开数据库修改角色数据,SQL命令为
|
||||
> `Update user_char set is_uncapped=1, is_uncapped_override=1 where character_id=21;`
|
||||
|
||||
> Update note: If you need to do data migration, please use the original database file **arcaea_ database.db**, and use the database operation software to open the database to modify the character data. The SQL command is
|
||||
> `Update user_char set is_uncapped=1, is_uncapped_override=1 where character_id=21;`
|
||||
|
||||
### Version 1.0
|
||||
- 适用于Arcaea 3.1.2版本 For Arcaea 3.1.2
|
||||
|
||||
## 运行环境与依赖 Running environment and requirements
|
||||
- Windows操作系统 Windows operating system
|
||||
- Python 3
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,251 +1,251 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists user(user_id int primary key,
|
||||
name text unique,
|
||||
password text not null,
|
||||
join_date char(20),
|
||||
user_code char(10),
|
||||
rating_ptt int,
|
||||
character_id int,
|
||||
is_skill_sealed int,
|
||||
is_char_uncapped int,
|
||||
is_char_uncapped_override int,
|
||||
is_hide_rating int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
favorite_character int,
|
||||
max_stamina_notification_enabled int,
|
||||
current_map text
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
last_login_time int,
|
||||
last_login_ip text,
|
||||
last_login_device text
|
||||
);''')
|
||||
c.execute('''create table if not exists friend(user_id_me int,
|
||||
user_id_other int,
|
||||
primary key (user_id_me, user_id_other)
|
||||
);''')
|
||||
c.execute('''create table if not exists best_score(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
best_clear_type int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_char(user_id int,
|
||||
character_id int,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag 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)
|
||||
);''')
|
||||
|
||||
char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)'
|
||||
,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna'
|
||||
,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)'
|
||||
,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin'
|
||||
,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C'
|
||||
,'Tairitsu(Tempest)','Brillante','Ilith(Summer)']
|
||||
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
|
||||
## def insert_user_char(c, user_id):
|
||||
## for i in range(0, 38):
|
||||
## if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
## c.execute(sql)
|
||||
## else:
|
||||
## if i != 5:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
## c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0, '')
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200,3,3,10.8)''')
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists user(user_id int primary key,
|
||||
name text unique,
|
||||
password text not null,
|
||||
join_date char(20),
|
||||
user_code char(10),
|
||||
rating_ptt int,
|
||||
character_id int,
|
||||
is_skill_sealed int,
|
||||
is_char_uncapped int,
|
||||
is_char_uncapped_override int,
|
||||
is_hide_rating int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
favorite_character int,
|
||||
max_stamina_notification_enabled int,
|
||||
current_map text
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
last_login_time int,
|
||||
last_login_ip text,
|
||||
last_login_device text
|
||||
);''')
|
||||
c.execute('''create table if not exists friend(user_id_me int,
|
||||
user_id_other int,
|
||||
primary key (user_id_me, user_id_other)
|
||||
);''')
|
||||
c.execute('''create table if not exists best_score(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
best_clear_type int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_char(user_id int,
|
||||
character_id int,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag 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)
|
||||
);''')
|
||||
|
||||
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']
|
||||
|
||||
for i in range(0, 39):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
|
||||
## def insert_user_char(c, user_id):
|
||||
## for i in range(0, 38):
|
||||
## if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
## c.execute(sql)
|
||||
## else:
|
||||
## if i != 5:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
## c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0, '')
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200,3,3,10.8)''')
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
@@ -1,51 +1,51 @@
|
||||
{
|
||||
"map_id": "byd_dement",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "dement2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "-400,-650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 250,
|
||||
"character_affinity": [13, 1],
|
||||
"affinity_multiplier": [2.6, 1.6],
|
||||
"step_count": 4,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_dement",
|
||||
"position": 0,
|
||||
"capture": 100.2865329512894
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 1,
|
||||
"capture": 110.31518624641834,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 2,
|
||||
"capture": 39.39828080229226,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1200
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 3,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "dement3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_dement",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "dement2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "-400,-650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 250,
|
||||
"character_affinity": [13, 1],
|
||||
"affinity_multiplier": [2.6, 1.6],
|
||||
"step_count": 4,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_dement",
|
||||
"position": 0,
|
||||
"capture": 100.2865329512894
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 1,
|
||||
"capture": 110.31518624641834,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 2,
|
||||
"capture": 39.39828080229226,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1200
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_dement",
|
||||
"position": 3,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "dement3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,45 +1,45 @@
|
||||
{
|
||||
"map_id": "byd_fairytale",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "fairytale2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "400,650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 3,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 0,
|
||||
"capture": 100,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 65
|
||||
}, {
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 1,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 4
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 2,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "fairytale3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_fairytale",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "fairytale2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "400,650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 3,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 0,
|
||||
"capture": 100,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 65
|
||||
}, {
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 1,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 4
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_fairytale",
|
||||
"position": 2,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "fairytale3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,68 +1,68 @@
|
||||
{
|
||||
"map_id": "byd_goodtek",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "goodtek2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "900,650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 250,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 6,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 0,
|
||||
"capture": 50
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 1,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 2,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 250
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 3,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 4,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 275
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 5,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "goodtek3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_goodtek",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "goodtek2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "900,650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 250,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 6,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 0,
|
||||
"capture": 50
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 1,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 2,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 250
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 3,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 4,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 275
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_goodtek",
|
||||
"position": 5,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "goodtek3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,91 +1,91 @@
|
||||
{
|
||||
"map_id": "byd_infinityheaven",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "infinityheaven2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "650,900",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 9,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 0,
|
||||
"capture": 25
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 1,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 2,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 3,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 4,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 2
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 5,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 6,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 7,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 8,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "infinityheaven3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_infinityheaven",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "infinityheaven2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "650,900",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 9,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 0,
|
||||
"capture": 25
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 1,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 2,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 3,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 4,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 2
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 5,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 6,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 7,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_infinityheaven",
|
||||
"position": 8,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "infinityheaven3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,61 +1,61 @@
|
||||
{
|
||||
"map_id": "byd_purgatorium",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "purgatorium2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "-900,-650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [13, 1],
|
||||
"affinity_multiplier": [2.6, 1.6],
|
||||
"step_count": 5,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 0,
|
||||
"capture": 75
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 1,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 2,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 3,
|
||||
"capture": 75,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 4,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "purgatorium3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_purgatorium",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "purgatorium2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "-900,-650",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [13, 1],
|
||||
"affinity_multiplier": [2.6, 1.6],
|
||||
"step_count": 5,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 0,
|
||||
"capture": 75
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 1,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 2,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 3,
|
||||
"capture": 75,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_purgatorium",
|
||||
"position": 4,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "purgatorium3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,42 +1,42 @@
|
||||
{
|
||||
"map_id": "byd_vexaria",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "vexaria2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "650,400",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 150,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 3,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 0,
|
||||
"capture": 140
|
||||
}, {
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 616
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 2,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "vexaria3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "byd_vexaria",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "vexaria2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "650,400",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 150,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [2.5, 1.5],
|
||||
"step_count": 3,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 0,
|
||||
"capture": 140
|
||||
}, {
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 616
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_vexaria",
|
||||
"position": 2,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "vexaria3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,428 +1,428 @@
|
||||
{
|
||||
"map_id": "chapter3_conflict",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 3,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-360,0",
|
||||
"step_count": 85,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 1,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 1
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 1,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 1,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 1
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 20,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 10
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 2,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 2
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 2,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 2,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 2,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 30,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 15
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 30,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 3,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 3,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 3,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 40,
|
||||
"items": [{
|
||||
"id": "bookmaker",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 40,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 200
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 4,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 4,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 2
|
||||
}]
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 50,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 250
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 5,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 5,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"id": "darakunosono",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 60,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 30
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 60,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 300
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 6,
|
||||
"restrict_id": "darakunosono",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 6,
|
||||
"restrict_id": "darakunosono",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 3
|
||||
}]
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 70,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 40
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 70
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 70,
|
||||
"items": [{
|
||||
"id": "espebranch",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 70
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 70,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 80,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 80,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "chapter3_conflict",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 3,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-360,0",
|
||||
"step_count": 85,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 1,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 1
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 1,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 1,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 1
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 20,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 10
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 2,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 100
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 2
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 2,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 2,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 2,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 30,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 15
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 30
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 30,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 3,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 3,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 3,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 40,
|
||||
"items": [{
|
||||
"id": "bookmaker",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 40
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 40,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 200
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 4,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 4,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 2
|
||||
}]
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 50
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 50,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 250
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 5,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 5,
|
||||
"restrict_id": "bookmaker",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"id": "darakunosono",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 60,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 30
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 60
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 60,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 300
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 6,
|
||||
"restrict_id": "darakunosono",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 6,
|
||||
"restrict_id": "darakunosono",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 3
|
||||
}]
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 70,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 40
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 70
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 70,
|
||||
"items": [{
|
||||
"id": "espebranch",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 70
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 70,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 8,
|
||||
"restrict_id": "suomi",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 80,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 80
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 80,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 9,
|
||||
"restrict_id": "rugie",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 90
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,268 +1,268 @@
|
||||
{
|
||||
"map_id": "chapter3_conflict_2",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 3,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-240,-180",
|
||||
"step_count": 51,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"id": "nhelv",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 100,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_ambivalent",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 100,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 20,
|
||||
"restrict_id": "nhelv",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_ambivalent",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "chapter3_conflict_2",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 3,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-240,-180",
|
||||
"step_count": 51,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"id": "nhelv",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 100,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_ambivalent",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 100,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 20,
|
||||
"restrict_id": "nhelv",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_ambivalent",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,236 +1,236 @@
|
||||
{
|
||||
"map_id": "chapter4_ripples",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 4,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-280,-200",
|
||||
"step_count": 51,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 170
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 15,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 14,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 170
|
||||
}]
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 15,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 14,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"id": "grimheart",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 190
|
||||
}]
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 18,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 17,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 16,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 19,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 190
|
||||
}]
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 18,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 17,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 16,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 15,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "vector",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "chapter4_ripples",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 4,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-280,-200",
|
||||
"step_count": 51,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 170
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 15,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 14,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 170
|
||||
}]
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 15,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 14,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"id": "grimheart",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 190
|
||||
}]
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 18,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 17,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 16,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 19,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 190
|
||||
}]
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 18,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 17,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 16,
|
||||
"restrict_id": "grimheart",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 15,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "vector",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,199 +1,199 @@
|
||||
{
|
||||
"map_id": "chapter4_waves",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 4,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-480,-200",
|
||||
"step_count": 41,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"id": "revixy",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 28
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 31
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 35
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 40,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 400
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 35,
|
||||
"restrict_id": "revixy",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 31,
|
||||
"restrict_id": "revixy",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 28,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 25,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 28
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 31
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 35
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "supernova",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "chapter4_waves",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 4,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "fragment",
|
||||
"require_value": 200,
|
||||
"coordinate": "-480,-200",
|
||||
"step_count": 41,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 150
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 20,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 16,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 13,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 20
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 25,
|
||||
"items": [{
|
||||
"id": "revixy",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 28
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 31
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 35
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 40,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 400
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 35,
|
||||
"restrict_id": "revixy",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 31,
|
||||
"restrict_id": "revixy",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 28,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 25,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 26
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 28
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 31
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 35
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "supernova",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,477 +1,477 @@
|
||||
{
|
||||
"map_id": "extra_originals",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 2,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"coordinate": "0,-200",
|
||||
"step_count": 101,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 2
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 6,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 11,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 12,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 16,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 16,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 12,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 11,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 3,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"id": "syro",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 8,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 13,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 14,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 18,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 18,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 14,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 13,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 8,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "blaster",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 10,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 11,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 15,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 16,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 19
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 20,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 21,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 90
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 22
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 23
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 23
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 22
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 21,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 90
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 20,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 19
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 16,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 15,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 11,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 91,
|
||||
"capture": 10,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 92,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 93,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 94,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 95,
|
||||
"capture": 8,
|
||||
"items": [{
|
||||
"id": "cyberneciacatharsis",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 96,
|
||||
"capture": 400
|
||||
}, {
|
||||
"position": 97,
|
||||
"capture": 2,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 6
|
||||
}, {
|
||||
"position": 98,
|
||||
"capture": 450,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 99,
|
||||
"capture": 1,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 6
|
||||
}, {
|
||||
"position": 100,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "extra_originals",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 2,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"coordinate": "0,-200",
|
||||
"step_count": 101,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 2
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 3
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 6,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 11,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 12,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 16,
|
||||
"restrict_id": "infinityheaven",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 17,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 16,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 12,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 11,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6,
|
||||
"restrict_id": "reinvent",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 4
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 3,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 4,
|
||||
"items": [{
|
||||
"id": "syro",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 8,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 13,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 14,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 18,
|
||||
"restrict_id": "dement",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 19,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 18,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 16
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 15
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 14,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 13,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 11
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 9,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 60
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 8,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "blaster",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 10,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 11,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 15,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 16,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 19
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 20,
|
||||
"restrict_id": "syro",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 21,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 90
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 22
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 23
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 23
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 22
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 21,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 90
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 20,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 19
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 18
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 17
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 16,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 80
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 15,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 14
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 13
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 12
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 11,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 70
|
||||
}]
|
||||
}, {
|
||||
"position": 91,
|
||||
"capture": 10,
|
||||
"restrict_id": "blaster",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 92,
|
||||
"capture": 9
|
||||
}, {
|
||||
"position": 93,
|
||||
"capture": 8
|
||||
}, {
|
||||
"position": 94,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 95,
|
||||
"capture": 8,
|
||||
"items": [{
|
||||
"id": "cyberneciacatharsis",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 96,
|
||||
"capture": 400
|
||||
}, {
|
||||
"position": 97,
|
||||
"capture": 2,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 6
|
||||
}, {
|
||||
"position": 98,
|
||||
"capture": 450,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 99,
|
||||
"capture": 1,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 6
|
||||
}, {
|
||||
"position": 100,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,407 +1,407 @@
|
||||
{
|
||||
"map_id": "hikari_art",
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 1,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"is_legacy": true,
|
||||
"stamina_cost": 1,
|
||||
"coordinate": "-270,150",
|
||||
"step_count": 91,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "babaroque",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"id": "shadesoflight",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 7,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 7,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"id": "kanagawa",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 100,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 150,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 150,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 200,
|
||||
"restrict_id": "ignotus",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "hikari_art",
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 1,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"is_legacy": true,
|
||||
"stamina_cost": 1,
|
||||
"coordinate": "-270,150",
|
||||
"step_count": 91,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "babaroque",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 6,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"id": "shadesoflight",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 7,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 7,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 7,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"id": "kanagawa",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 100,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 150,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 150,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 200,
|
||||
"restrict_id": "ignotus",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_hollow",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,407 +1,407 @@
|
||||
{
|
||||
"map_id": "tairitsu_tech",
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 1,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"is_legacy": true,
|
||||
"stamina_cost": 1,
|
||||
"coordinate": "270,-150",
|
||||
"step_count": 91,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "lucifer",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"id": "anokumene",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 7,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 7,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"id": "ignotus",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 100,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 150,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 150,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 200,
|
||||
"restrict_id": "kanagawa",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "tairitsu_tech",
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 1,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": false,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 1,
|
||||
"is_legacy": true,
|
||||
"stamina_cost": 1,
|
||||
"coordinate": "270,-150",
|
||||
"step_count": 91,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 5
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"id": "lucifer",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 12,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 13,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 14,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 15,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 16,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 17,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 18,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 19,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 20,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 21,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 22,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 23,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 24,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 25,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 26,
|
||||
"capture": 6
|
||||
}, {
|
||||
"position": 27,
|
||||
"capture": 6,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 28,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 29,
|
||||
"capture": 6,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 30,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"id": "anokumene",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 31,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 32,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 33,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 34,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 35,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 36,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 37,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 38,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 39,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 40,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 41,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 42,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 43,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 44,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 45,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 46,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 47,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 48,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 49,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 50,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 51,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 52,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 53,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 54,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 55,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 56,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 57,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 58,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 59,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 60,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 50
|
||||
}]
|
||||
}, {
|
||||
"position": 61,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 62,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 63,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 64,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 65,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 25
|
||||
}]
|
||||
}, {
|
||||
"position": 66,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 67,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 68,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 69,
|
||||
"capture": 7
|
||||
}, {
|
||||
"position": 70,
|
||||
"capture": 7,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 71,
|
||||
"capture": 7,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 72,
|
||||
"capture": 7,
|
||||
"restrict_id": "lucifer",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 73,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 74,
|
||||
"capture": 7,
|
||||
"restrict_id": "anokumene",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 75,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"id": "ignotus",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}, {
|
||||
"position": 76,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 77,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 78,
|
||||
"capture": 100
|
||||
}, {
|
||||
"position": 79,
|
||||
"capture": 100,
|
||||
"restrict_id": "babaroque",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 80,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 81,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 82,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 83,
|
||||
"capture": 150
|
||||
}, {
|
||||
"position": 84,
|
||||
"capture": 150,
|
||||
"restrict_id": "shadesoflight",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 85,
|
||||
"capture": 150,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}, {
|
||||
"position": 86,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 87,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 88,
|
||||
"capture": 200
|
||||
}, {
|
||||
"position": 89,
|
||||
"capture": 200,
|
||||
"restrict_id": "kanagawa",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 90,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_desolate",
|
||||
"amount": 5
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,94 +1,94 @@
|
||||
{
|
||||
"map_id": "test",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 0,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": true,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 0,
|
||||
"coordinate": "0,0",
|
||||
"step_count": 12,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 20,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1000
|
||||
}]
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10000,
|
||||
"step_type": ["plusstamina","speedlimit"],
|
||||
"plus_stamina_value": 2,
|
||||
"speed_limit_value": 5,
|
||||
"restrict_id": "fractureray",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 500
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "test",
|
||||
"is_legacy": false,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 200,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 0,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": true,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 0,
|
||||
"coordinate": "0,0",
|
||||
"step_count": 12,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 2,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 20,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1000
|
||||
}]
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id"
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 20
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10000,
|
||||
"step_type": ["plusstamina","speedlimit"],
|
||||
"plus_stamina_value": 2,
|
||||
"speed_limit_value": 5,
|
||||
"restrict_id": "fractureray",
|
||||
"restrict_type": "song_id"
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 500
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -1,120 +1,120 @@
|
||||
{
|
||||
"map_id": "test2",
|
||||
"is_legacy": true,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 0,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": true,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 0,
|
||||
"coordinate": "200,200",
|
||||
"step_count": 12,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 1,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1000
|
||||
}]
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"],
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 60,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 50
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}]
|
||||
{
|
||||
"map_id": "test2",
|
||||
"is_legacy": true,
|
||||
"is_beyond": false,
|
||||
"beyond_health": 100,
|
||||
"character_affinity": [],
|
||||
"affinity_multiplier": [],
|
||||
"chapter": 0,
|
||||
"available_from": -1,
|
||||
"available_to": 2106124800000,
|
||||
"is_repeatable": true,
|
||||
"require_id": "",
|
||||
"require_type": "",
|
||||
"require_value": 0,
|
||||
"coordinate": "200,200",
|
||||
"step_count": 12,
|
||||
"custom_bg": "",
|
||||
"stamina_cost": 1,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"position": 0,
|
||||
"capture": 10
|
||||
}, {
|
||||
"position": 1,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 1000
|
||||
}]
|
||||
}, {
|
||||
"position": 2,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 3,
|
||||
"capture": 10,
|
||||
"restrict_id": "base",
|
||||
"restrict_type": "pack_id",
|
||||
"step_type": ["randomsong"],
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 4,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 5,
|
||||
"capture": 10,
|
||||
"step_type": ["speedlimit"],
|
||||
"speed_limit_value": 60,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 6,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 7,
|
||||
"capture": 10,
|
||||
"step_type": ["plusstamina"],
|
||||
"plus_stamina_value": 2,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 8,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 9,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 10,
|
||||
"capture": 10,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}, {
|
||||
"position": 11,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_crimson",
|
||||
"amount": 50
|
||||
}, {
|
||||
"type": "fragment",
|
||||
"amount": 125
|
||||
}]
|
||||
}]
|
||||
}
|
||||
21
latest version/database/songs/dement/3.aff
Normal file
21
latest version/database/songs/dement/3.aff
Normal file
@@ -0,0 +1,21 @@
|
||||
AudioOffset:408
|
||||
-
|
||||
timing(0,210.00,4.00);
|
||||
(1142,4);
|
||||
(1571,2);
|
||||
(2857,1);
|
||||
(3142,2);
|
||||
(3428,3);
|
||||
(3857,4);
|
||||
(4142,3);
|
||||
(4571,2);
|
||||
(5000,1);
|
||||
(5428,3);
|
||||
arc(5714,6857,0.00,0.50,s,1.00,1.00,0,none,false);
|
||||
arc(6857,8000,0.50,0.00,s,1.00,1.00,0,none,false);
|
||||
arc(8000,9142,0.00,0.50,s,1.00,1.00,0,none,false);
|
||||
arc(9142,10285,0.50,0.00,s,1.00,1.00,0,none,false);
|
||||
arc(10285,11428,1.00,0.50,s,1.00,1.00,1,none,false);
|
||||
arc(11428,12571,0.50,1.00,s,1.00,1.00,1,none,false);
|
||||
arc(12571,13714,1.00,0.50,s,1.00,1.00,1,none,false);
|
||||
arc(13714,14571,0.50,1.00,s,1.00,1.00,1,none,false);
|
||||
File diff suppressed because it is too large
Load Diff
48
latest version/server/arcdownload.py
Normal file
48
latest version/server/arcdownload.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import os
|
||||
import hashlib
|
||||
from flask import url_for
|
||||
|
||||
|
||||
def get_file_md5(file_path):
|
||||
# 计算文件MD5
|
||||
if not os.path.isfile(file_path):
|
||||
return None
|
||||
myhash = hashlib.md5()
|
||||
f = open(file_path, 'rb')
|
||||
while True:
|
||||
b = f.read(8096)
|
||||
if not b:
|
||||
break
|
||||
myhash.update(b)
|
||||
f.close()
|
||||
return myhash.hexdigest()
|
||||
|
||||
|
||||
def get_one_song(song_id, file_dir='./database/songs'):
|
||||
# 获取一首歌的下载链接,返回字典
|
||||
dir_list = os.listdir(os.path.join(file_dir, song_id))
|
||||
re = {}
|
||||
for i in dir_list:
|
||||
if os.path.isfile(os.path.join(file_dir, song_id, i)) and i in ['0.aff', '1.aff', '2.aff', '3.aff', 'base.ogg']:
|
||||
if i == 'base.ogg':
|
||||
re['audio'] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, 'base.ogg')),
|
||||
"url": url_for('download', file_path=song_id+'/base.ogg', _external=True)}
|
||||
else:
|
||||
if 'chart' not in re:
|
||||
re['chart'] = {}
|
||||
|
||||
re['chart'][i[0]] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, i)),
|
||||
"url": url_for('download', file_path=song_id+'/'+i, _external=True)}
|
||||
|
||||
return {song_id: re}
|
||||
|
||||
|
||||
def get_all_songs(file_dir='./database/songs'):
|
||||
# 获取所有歌的下载链接,返回字典
|
||||
dir_list = os.listdir(file_dir)
|
||||
re = {}
|
||||
for i in dir_list:
|
||||
if os.path.isdir(os.path.join(file_dir, i)):
|
||||
re.update(get_one_song(i))
|
||||
|
||||
return re
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,259 +1,259 @@
|
||||
import json
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_world_name(file_dir='./database/map'):
|
||||
# 获取所有地图名称,返回列表
|
||||
L = []
|
||||
for root, dirs, files in os.walk(file_dir):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1] == '.json':
|
||||
L.append(os.path.splitext(file)[0])
|
||||
return L
|
||||
|
||||
|
||||
def get_world_info(map_id):
|
||||
# 读取json文件内容,返回字典
|
||||
f = open('./database/map/'+map_id+'.json', 'r')
|
||||
world_info = json.load(f)
|
||||
f.close()
|
||||
return world_info
|
||||
|
||||
|
||||
def get_user_world_info(user_id, map_id):
|
||||
# 读取json文件内容,加上用户信息,返回字典
|
||||
info = get_world_info(map_id)
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
if x:
|
||||
info['curr_position'] = x[2]
|
||||
info['curr_capture'] = x[3]
|
||||
info['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return info
|
||||
|
||||
|
||||
def get_current_map(user_id):
|
||||
# 得到user的当前图,返回字符串
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select current_map from user where user_id = :a''',
|
||||
{'a': user_id})
|
||||
x = c.fetchone()
|
||||
re = ''
|
||||
if x:
|
||||
re = x[0]
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def get_world_all(user_id):
|
||||
# 读取所有地图信息并处理,返回字典列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
worlds = get_world_name()
|
||||
re = []
|
||||
for map_id in worlds:
|
||||
info = get_world_info(map_id)
|
||||
steps = info['steps']
|
||||
del info['steps']
|
||||
rewards = []
|
||||
for step in steps:
|
||||
if 'items' in step:
|
||||
rewards.append(
|
||||
{'items': step['items'], 'position': step['position']})
|
||||
info['rewards'] = rewards
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
if x:
|
||||
info['curr_position'] = x[2]
|
||||
info['curr_capture'] = x[3]
|
||||
info['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
|
||||
re.append(info)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def get_user_world(user_id, map_id):
|
||||
# 获取用户图信息,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
re = {
|
||||
"user_id": user_id,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": False,
|
||||
"map_id": map_id
|
||||
}
|
||||
if x:
|
||||
re['curr_position'] = x[2]
|
||||
re['curr_capture'] = x[3]
|
||||
re['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def change_user_current_map(user_id, map_id):
|
||||
# 改变用户当前图
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''update user set current_map = :a where user_id=:b''', {
|
||||
'a': map_id, 'b': user_id})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def play_world_song(user_id, args):
|
||||
# 声明是世界模式的打歌,并且记录加成信息
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
|
||||
stamina_multiply = 1
|
||||
fragment_multiply = 100
|
||||
prog_boost_multiply = 0
|
||||
if 'stamina_multiply' in args:
|
||||
stamina_multiply = int(args['stamina_multiply'])
|
||||
if 'fragment_multiply' in args:
|
||||
fragment_multiply = int(args['fragment_multiply'])
|
||||
if 'prog_boost_multiply' in args:
|
||||
prog_boost_multiply = int(args['prog_boost_multiply'])
|
||||
|
||||
c.execute('''delete from world_songplay where user_id=:a and song_id=:b and difficulty=:c''', {
|
||||
'a': user_id, 'b': args['song_id'], 'c': args['difficulty']})
|
||||
c.execute('''insert into world_songplay values(:a,:b,:c,:d,:e,:f)''', {
|
||||
'a': user_id, 'b': args['song_id'], 'c': args['difficulty'], 'd': stamina_multiply, 'e': fragment_multiply, 'f': prog_boost_multiply})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def climb_step(user_id, map_id, step, prev_capture, prev_position):
|
||||
# 爬梯子,返回奖励列表,台阶列表,当前的位置和坐标,图信息
|
||||
info = get_world_info(map_id)
|
||||
step_count = int(info['step_count'])
|
||||
|
||||
restrict_ids = [[]] * step_count
|
||||
capture = [0] * step_count
|
||||
reward_bundle = [""] * step_count # 暂且不用
|
||||
restrict_id = [""] * step_count
|
||||
restrict_type = [""] * step_count
|
||||
items = [[]] * step_count
|
||||
step_type = [[]] * step_count
|
||||
speed_limit_value = [0] * step_count
|
||||
plus_stamina_value = [0] * step_count
|
||||
|
||||
for i in info['steps']:
|
||||
capture[i['position']] = i['capture']
|
||||
if 'items' in i:
|
||||
items[i['position']] = i['items']
|
||||
if 'restrict_id' in i:
|
||||
restrict_id[i['position']] = i['restrict_id']
|
||||
if 'restrict_ids' in i:
|
||||
restrict_ids[i['position']] = i['restrict_ids']
|
||||
if 'restrict_type' in i:
|
||||
restrict_type[i['position']] = i['restrict_type']
|
||||
if 'step_type' in i:
|
||||
step_type[i['position']] = i['step_type']
|
||||
if "speedlimit" in i['step_type']:
|
||||
speed_limit_value[i['position']] = i['speed_limit_value']
|
||||
if "plusstamina" in i['step_type']:
|
||||
plus_stamina_value[i['position']] = i['plus_stamina_value']
|
||||
|
||||
if info['is_beyond']: # beyond判断
|
||||
dt = info['beyond_health'] - prev_capture
|
||||
if dt >= step:
|
||||
curr_capture = prev_capture + step
|
||||
else:
|
||||
curr_capture = info['beyond_health']
|
||||
i = 0
|
||||
t = prev_capture + step
|
||||
while i < step_count and t > 0:
|
||||
dt = capture[i]
|
||||
if dt > t:
|
||||
t = 0
|
||||
else:
|
||||
t -= dt
|
||||
i += 1
|
||||
if i >= step_count:
|
||||
curr_position = step_count - 1
|
||||
else:
|
||||
curr_position = i
|
||||
|
||||
else:
|
||||
i = prev_position
|
||||
j = prev_capture
|
||||
t = step
|
||||
while t > 0 and i < step_count:
|
||||
dt = capture[i] - j
|
||||
if dt > t:
|
||||
j += t
|
||||
t = 0
|
||||
else:
|
||||
t -= dt
|
||||
j = 0
|
||||
i += 1
|
||||
if i >= step_count:
|
||||
curr_position = step_count - 1
|
||||
curr_capture = 0
|
||||
else:
|
||||
curr_position = i
|
||||
curr_capture = j
|
||||
|
||||
rewards = []
|
||||
steps = []
|
||||
for i in range(prev_position, curr_position+1):
|
||||
if items[i]:
|
||||
rewards.append({'position': i, 'items': items[i]})
|
||||
x = {
|
||||
"map_id": map_id,
|
||||
"position": i,
|
||||
"restrict_ids": restrict_ids[i],
|
||||
"capture": capture[i],
|
||||
"reward_bundle": reward_bundle[i],
|
||||
"restrict_id": restrict_id[i],
|
||||
"restrict_type": restrict_type[i]
|
||||
}
|
||||
if step_type[i]:
|
||||
x['step_type'] = step_type[i]
|
||||
if speed_limit_value[i]:
|
||||
x['speed_limit_value'] = speed_limit_value[i]
|
||||
if plus_stamina_value[i]:
|
||||
x['plus_stamina_value'] = plus_stamina_value[i]
|
||||
steps.append(x)
|
||||
|
||||
return rewards, steps, curr_position, curr_capture, info
|
||||
import json
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_world_name(file_dir='./database/map'):
|
||||
# 获取所有地图名称,返回列表
|
||||
L = []
|
||||
for root, dirs, files in os.walk(file_dir):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1] == '.json':
|
||||
L.append(os.path.splitext(file)[0])
|
||||
return L
|
||||
|
||||
|
||||
def get_world_info(map_id):
|
||||
# 读取json文件内容,返回字典
|
||||
f = open('./database/map/'+map_id+'.json', 'r')
|
||||
world_info = json.load(f)
|
||||
f.close()
|
||||
return world_info
|
||||
|
||||
|
||||
def get_user_world_info(user_id, map_id):
|
||||
# 读取json文件内容,加上用户信息,返回字典
|
||||
info = get_world_info(map_id)
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
if x:
|
||||
info['curr_position'] = x[2]
|
||||
info['curr_capture'] = x[3]
|
||||
info['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return info
|
||||
|
||||
|
||||
def get_current_map(user_id):
|
||||
# 得到user的当前图,返回字符串
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select current_map from user where user_id = :a''',
|
||||
{'a': user_id})
|
||||
x = c.fetchone()
|
||||
re = ''
|
||||
if x:
|
||||
re = x[0]
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def get_world_all(user_id):
|
||||
# 读取所有地图信息并处理,返回字典列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
worlds = get_world_name()
|
||||
re = []
|
||||
for map_id in worlds:
|
||||
info = get_world_info(map_id)
|
||||
steps = info['steps']
|
||||
del info['steps']
|
||||
rewards = []
|
||||
for step in steps:
|
||||
if 'items' in step:
|
||||
rewards.append(
|
||||
{'items': step['items'], 'position': step['position']})
|
||||
info['rewards'] = rewards
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
if x:
|
||||
info['curr_position'] = x[2]
|
||||
info['curr_capture'] = x[3]
|
||||
info['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
|
||||
re.append(info)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def get_user_world(user_id, map_id):
|
||||
# 获取用户图信息,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user_world where map_id = :a and user_id = :b''',
|
||||
{'a': map_id, 'b': user_id})
|
||||
x = c.fetchone()
|
||||
re = {
|
||||
"user_id": user_id,
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": False,
|
||||
"map_id": map_id
|
||||
}
|
||||
if x:
|
||||
re['curr_position'] = x[2]
|
||||
re['curr_capture'] = x[3]
|
||||
re['is_locked'] = int2b(x[4])
|
||||
else:
|
||||
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
|
||||
'a': user_id, 'b': map_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def change_user_current_map(user_id, map_id):
|
||||
# 改变用户当前图
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''update user set current_map = :a where user_id=:b''', {
|
||||
'a': map_id, 'b': user_id})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def play_world_song(user_id, args):
|
||||
# 声明是世界模式的打歌,并且记录加成信息
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
|
||||
stamina_multiply = 1
|
||||
fragment_multiply = 100
|
||||
prog_boost_multiply = 0
|
||||
if 'stamina_multiply' in args:
|
||||
stamina_multiply = int(args['stamina_multiply'])
|
||||
if 'fragment_multiply' in args:
|
||||
fragment_multiply = int(args['fragment_multiply'])
|
||||
if 'prog_boost_multiply' in args:
|
||||
prog_boost_multiply = int(args['prog_boost_multiply'])
|
||||
|
||||
c.execute('''delete from world_songplay where user_id=:a and song_id=:b and difficulty=:c''', {
|
||||
'a': user_id, 'b': args['song_id'], 'c': args['difficulty']})
|
||||
c.execute('''insert into world_songplay values(:a,:b,:c,:d,:e,:f)''', {
|
||||
'a': user_id, 'b': args['song_id'], 'c': args['difficulty'], 'd': stamina_multiply, 'e': fragment_multiply, 'f': prog_boost_multiply})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def climb_step(user_id, map_id, step, prev_capture, prev_position):
|
||||
# 爬梯子,返回奖励列表,台阶列表,当前的位置和坐标,图信息
|
||||
info = get_world_info(map_id)
|
||||
step_count = int(info['step_count'])
|
||||
|
||||
restrict_ids = [[]] * step_count
|
||||
capture = [0] * step_count
|
||||
reward_bundle = [""] * step_count # 暂且不用
|
||||
restrict_id = [""] * step_count
|
||||
restrict_type = [""] * step_count
|
||||
items = [[]] * step_count
|
||||
step_type = [[]] * step_count
|
||||
speed_limit_value = [0] * step_count
|
||||
plus_stamina_value = [0] * step_count
|
||||
|
||||
for i in info['steps']:
|
||||
capture[i['position']] = i['capture']
|
||||
if 'items' in i:
|
||||
items[i['position']] = i['items']
|
||||
if 'restrict_id' in i:
|
||||
restrict_id[i['position']] = i['restrict_id']
|
||||
if 'restrict_ids' in i:
|
||||
restrict_ids[i['position']] = i['restrict_ids']
|
||||
if 'restrict_type' in i:
|
||||
restrict_type[i['position']] = i['restrict_type']
|
||||
if 'step_type' in i:
|
||||
step_type[i['position']] = i['step_type']
|
||||
if "speedlimit" in i['step_type']:
|
||||
speed_limit_value[i['position']] = i['speed_limit_value']
|
||||
if "plusstamina" in i['step_type']:
|
||||
plus_stamina_value[i['position']] = i['plus_stamina_value']
|
||||
|
||||
if info['is_beyond']: # beyond判断
|
||||
dt = info['beyond_health'] - prev_capture
|
||||
if dt >= step:
|
||||
curr_capture = prev_capture + step
|
||||
else:
|
||||
curr_capture = info['beyond_health']
|
||||
i = 0
|
||||
t = prev_capture + step
|
||||
while i < step_count and t > 0:
|
||||
dt = capture[i]
|
||||
if dt > t:
|
||||
t = 0
|
||||
else:
|
||||
t -= dt
|
||||
i += 1
|
||||
if i >= step_count:
|
||||
curr_position = step_count - 1
|
||||
else:
|
||||
curr_position = i
|
||||
|
||||
else:
|
||||
i = prev_position
|
||||
j = prev_capture
|
||||
t = step
|
||||
while t > 0 and i < step_count:
|
||||
dt = capture[i] - j
|
||||
if dt > t:
|
||||
j += t
|
||||
t = 0
|
||||
else:
|
||||
t -= dt
|
||||
j = 0
|
||||
i += 1
|
||||
if i >= step_count:
|
||||
curr_position = step_count - 1
|
||||
curr_capture = 0
|
||||
else:
|
||||
curr_position = i
|
||||
curr_capture = j
|
||||
|
||||
rewards = []
|
||||
steps = []
|
||||
for i in range(prev_position, curr_position+1):
|
||||
if items[i]:
|
||||
rewards.append({'position': i, 'items': items[i]})
|
||||
x = {
|
||||
"map_id": map_id,
|
||||
"position": i,
|
||||
"restrict_ids": restrict_ids[i],
|
||||
"capture": capture[i],
|
||||
"reward_bundle": reward_bundle[i],
|
||||
"restrict_id": restrict_id[i],
|
||||
"restrict_type": restrict_type[i]
|
||||
}
|
||||
if step_type[i]:
|
||||
x['step_type'] = step_type[i]
|
||||
if speed_limit_value[i]:
|
||||
x['speed_limit_value'] = speed_limit_value[i]
|
||||
if plus_stamina_value[i]:
|
||||
x['plus_stamina_value'] = plus_stamina_value[i]
|
||||
steps.append(x)
|
||||
|
||||
return rewards, steps, curr_position, curr_capture, info
|
||||
@@ -1,150 +1,150 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
import server.arcworld
|
||||
|
||||
|
||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
||||
'name': name, 'password': hash_pwd})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = str(x[0])
|
||||
now = int(time.time() * 1000)
|
||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||
|
||||
if c.fetchone() == (1,): # 删掉多余token
|
||||
c.execute('''delete from login where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_register(name: str, password: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
# 生成9位的user_code,用的自然是随机
|
||||
import random
|
||||
flag = True
|
||||
while flag:
|
||||
user_code = ''.join([str(random.randint(0, 9)) for i in range(9)])
|
||||
c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if c.fetchone() == (0,):
|
||||
flag = False
|
||||
return user_code
|
||||
|
||||
def build_user_id(c):
|
||||
# 生成user_id,往后加1
|
||||
c.execute('''select max(user_id) from user''')
|
||||
x = c.fetchone()
|
||||
if x[0] is not None:
|
||||
return x[0] + 1
|
||||
else:
|
||||
return 2000001
|
||||
|
||||
# def insert_user_char(c, user_id):
|
||||
# # 为用户添加所有可用角色
|
||||
# for i in range(0, 38):
|
||||
# if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
# c.execute(sql)
|
||||
# else:
|
||||
# if i != 5:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
# c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '')
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return user_id, token, 0
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None, None, 101
|
||||
|
||||
|
||||
def token_get_id(token: str):
|
||||
# 用token获取id,没有考虑不同用户token相同情况,说不定会有bug
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from login where access_token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def code_get_id(user_code):
|
||||
# 用user_code获取id
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from user where user_code = :a''',
|
||||
{'a': user_code})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
import server.arcworld
|
||||
|
||||
|
||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
||||
'name': name, 'password': hash_pwd})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = str(x[0])
|
||||
now = int(time.time() * 1000)
|
||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||
|
||||
if c.fetchone() == (1,): # 删掉多余token
|
||||
c.execute('''delete from login where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_register(name: str, password: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
# 生成9位的user_code,用的自然是随机
|
||||
import random
|
||||
flag = True
|
||||
while flag:
|
||||
user_code = ''.join([str(random.randint(0, 9)) for i in range(9)])
|
||||
c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if c.fetchone() == (0,):
|
||||
flag = False
|
||||
return user_code
|
||||
|
||||
def build_user_id(c):
|
||||
# 生成user_id,往后加1
|
||||
c.execute('''select max(user_id) from user''')
|
||||
x = c.fetchone()
|
||||
if x[0] is not None:
|
||||
return x[0] + 1
|
||||
else:
|
||||
return 2000001
|
||||
|
||||
# def insert_user_char(c, user_id):
|
||||
# # 为用户添加所有可用角色
|
||||
# for i in range(0, 38):
|
||||
# if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
# c.execute(sql)
|
||||
# else:
|
||||
# if i != 5:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
# c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '')
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return user_id, token, 0
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None, None, 101
|
||||
|
||||
|
||||
def token_get_id(token: str):
|
||||
# 用token获取id,没有考虑不同用户token相同情况,说不定会有bug
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from login where access_token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def code_get_id(user_code):
|
||||
# 用user_code获取id
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from user where user_code = :a''',
|
||||
{'a': user_code})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
@@ -1,491 +1,491 @@
|
||||
import sqlite3
|
||||
import server.arcworld
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_recent_score(c, user_id):
|
||||
# 得到用户最近一次的成绩,返回列表
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if x[11] is not None:
|
||||
c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', {
|
||||
'u': user_id, 's': x[11], 'd': x[12]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
best_clear_type = y[0]
|
||||
else:
|
||||
best_clear_type = x[21]
|
||||
|
||||
return [{
|
||||
"rating": x[22],
|
||||
"modifier": x[19],
|
||||
"time_played": x[20],
|
||||
"health": x[18],
|
||||
"best_clear_type": best_clear_type,
|
||||
"clear_type": x[21],
|
||||
"miss_count": x[17],
|
||||
"near_count": x[16],
|
||||
"perfect_count": x[15],
|
||||
"shiny_perfect_count": x[14],
|
||||
"score": x[13],
|
||||
"difficulty": x[12],
|
||||
"song_id": x[11]
|
||||
}]
|
||||
return []
|
||||
|
||||
|
||||
def get_user_character(c, user_id):
|
||||
# 得到用户拥有的角色列表,返回列表
|
||||
c.execute('''select * from user_char where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
s = []
|
||||
for i in x:
|
||||
char_name = ''
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': i[1]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
char_name = y[0]
|
||||
s.append({
|
||||
"is_uncapped_override": int2b(i[14]),
|
||||
"is_uncapped": int2b(i[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": i[12],
|
||||
"skill_id_uncap": i[11],
|
||||
"skill_requires_uncap": int2b(i[10]),
|
||||
"skill_unlock_level": i[9],
|
||||
"skill_id": i[8],
|
||||
"overdrive": i[7],
|
||||
"prog": i[6],
|
||||
"frag": i[5],
|
||||
"level_exp": i[4],
|
||||
"exp": i[3],
|
||||
"level": i[2],
|
||||
"name": char_name,
|
||||
"character_id": i[1]
|
||||
})
|
||||
|
||||
return s
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_user_friend(c, user_id):
|
||||
# 得到用户的朋友列表,返回列表
|
||||
c.execute('''select user_id_other from friend where user_id_me = :user_id''', {
|
||||
'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
s = []
|
||||
if x != [] and x[0][0] is not None:
|
||||
|
||||
for i in x:
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': i[0], 'y': user_id})
|
||||
if c.fetchone() == (1,):
|
||||
is_mutual = True
|
||||
else:
|
||||
is_mutual = False
|
||||
|
||||
c.execute('''select * from user where user_id = :x''', {'x': i[0]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
s.append({
|
||||
"is_mutual": is_mutual,
|
||||
"is_char_uncapped_override": int2b(y[9]),
|
||||
"is_char_uncapped": int2b(y[8]),
|
||||
"is_skill_sealed": int2b(y[7]),
|
||||
"rating": y[5],
|
||||
"join_date": int(y[3]),
|
||||
"character": y[6],
|
||||
"recent_score": get_recent_score(c, i[0]),
|
||||
"name": y[1],
|
||||
"user_id": i[0]
|
||||
})
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def get_value_0(c, user_id):
|
||||
# 构造value id=0的数据,返回字典
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
x = c.fetchone()
|
||||
r = {}
|
||||
if x is not None:
|
||||
user_character = get_user_character(c, user_id)
|
||||
characters = []
|
||||
for i in user_character:
|
||||
characters.append(i['character_id'])
|
||||
|
||||
r = {"is_aprilfools": False,
|
||||
"curr_available_maps": [],
|
||||
"character_stats": user_character,
|
||||
"friends": get_user_friend(c, user_id),
|
||||
"settings": {
|
||||
"favorite_character": x[23],
|
||||
"is_hide_rating": int2b(x[10]),
|
||||
"max_stamina_notification_enabled": int2b(x[24])
|
||||
},
|
||||
"user_id": user_id,
|
||||
"name": x[1],
|
||||
"user_code": x[4],
|
||||
"display_name": x[1],
|
||||
"ticket": 114514,
|
||||
"character": x[6],
|
||||
"is_locked_name_duplicate": False,
|
||||
"is_skill_sealed": int2b(x[7]),
|
||||
"current_map": x[25],
|
||||
"prog_boost": 0,
|
||||
"next_fragstam_ts": -1,
|
||||
"max_stamina_ts": 1586274871917,
|
||||
"stamina": 12,
|
||||
"world_unlocks": [],
|
||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight"],
|
||||
"singles": ["dataerror", "yourvoiceso", "crosssoul", "impurebird", "auxesia", "modelista", "yozakurafubuki", "surrender", "metallicpunisher", "carminescythe", "bethere", "callmyname", "fallensquare", "dropdead", "alexandrite", "astraltale", "phantasia", "empireofwinter", "libertas", "dottodot", "dreadnought", "mirzam", "heavenlycaress", "filament", "avantraze", "battlenoone", "saikyostronger", "izana", "einherjar", "laqryma", "amygdata", "altale", "feelssoright", "scarletcage", "teriqma", "mahoroba", "badtek", "maliciousmischance", "buchigireberserker", "galaxyfriends", "buchigireberserker2"],
|
||||
"packs": ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"],
|
||||
"characters": characters,
|
||||
"cores": [],
|
||||
"recent_score": get_recent_score(c, user_id),
|
||||
"max_friend": 50,
|
||||
"rating": x[5],
|
||||
"join_date": int(x[3])
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def arc_aggregate_small(user_id):
|
||||
# 返回用户数据
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
}]}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_aggregate_big(user_id):
|
||||
# 返回用户数据和地图歌曲信息
|
||||
# 因为没有整理地图和曲包数据(不需要世界模式),所以直接复制了
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
}, {
|
||||
"id": 1,
|
||||
"value": [{
|
||||
"name": "core",
|
||||
"items": [{
|
||||
"id": "core",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "shiawase",
|
||||
"items": [{
|
||||
"id": "shiawase",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "kou",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "dynamix",
|
||||
"items": [{
|
||||
"id": "dynamix",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "sapphire",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "mirai",
|
||||
"items": [{
|
||||
"id": "mirai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "lethe",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "yugamu",
|
||||
"items": [{
|
||||
"id": "yugamu",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "lanota",
|
||||
"items": [{
|
||||
"id": "lanota",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "nijuusei",
|
||||
"items": [{
|
||||
"id": "nijuusei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "rei",
|
||||
"items": [{
|
||||
"id": "rei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "tonesphere",
|
||||
"items": [{
|
||||
"id": "tonesphere",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "groovecoaster",
|
||||
"items": [{
|
||||
"id": "groovecoaster",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "zettai",
|
||||
"items": [{
|
||||
"id": "zettai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "chunithm",
|
||||
"items": [{
|
||||
"id": "chunithm",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 300,
|
||||
"orig_price": 300
|
||||
}, {
|
||||
"name": "prelude",
|
||||
"items": [{
|
||||
"id": "prelude",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 400,
|
||||
"orig_price": 400
|
||||
}, {
|
||||
"name": "omatsuri",
|
||||
"items": [{
|
||||
"id": "omatsuri",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "vs",
|
||||
"items": [{
|
||||
"id": "vs",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "extend",
|
||||
"items": [{
|
||||
"id": "extend",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 700,
|
||||
"orig_price": 700
|
||||
}]
|
||||
}, {
|
||||
"id": 2,
|
||||
"value": {}
|
||||
}, {
|
||||
"id": 3,
|
||||
"value": {
|
||||
"max_stamina": 12,
|
||||
"stamina_recover_tick": 1800000,
|
||||
"core_exp": 250,
|
||||
"curr_ts": 1599547606825,
|
||||
"level_steps": [{
|
||||
"level": 1,
|
||||
"level_exp": 0
|
||||
}, {
|
||||
"level": 2,
|
||||
"level_exp": 50
|
||||
}, {
|
||||
"level": 3,
|
||||
"level_exp": 100
|
||||
}, {
|
||||
"level": 4,
|
||||
"level_exp": 150
|
||||
}, {
|
||||
"level": 5,
|
||||
"level_exp": 200
|
||||
}, {
|
||||
"level": 6,
|
||||
"level_exp": 300
|
||||
}, {
|
||||
"level": 7,
|
||||
"level_exp": 450
|
||||
}, {
|
||||
"level": 8,
|
||||
"level_exp": 650
|
||||
}, {
|
||||
"level": 9,
|
||||
"level_exp": 900
|
||||
}, {
|
||||
"level": 10,
|
||||
"level_exp": 1200
|
||||
}, {
|
||||
"level": 11,
|
||||
"level_exp": 1600
|
||||
}, {
|
||||
"level": 12,
|
||||
"level_exp": 2100
|
||||
}, {
|
||||
"level": 13,
|
||||
"level_exp": 2700
|
||||
}, {
|
||||
"level": 14,
|
||||
"level_exp": 3400
|
||||
}, {
|
||||
"level": 15,
|
||||
"level_exp": 4200
|
||||
}, {
|
||||
"level": 16,
|
||||
"level_exp": 5100
|
||||
}, {
|
||||
"level": 17,
|
||||
"level_exp": 6100
|
||||
}, {
|
||||
"level": 18,
|
||||
"level_exp": 7200
|
||||
}, {
|
||||
"level": 19,
|
||||
"level_exp": 8500
|
||||
}, {
|
||||
"level": 20,
|
||||
"level_exp": 10000
|
||||
}, {
|
||||
"level": 21,
|
||||
"level_exp": 11500
|
||||
}, {
|
||||
"level": 22,
|
||||
"level_exp": 13000
|
||||
}, {
|
||||
"level": 23,
|
||||
"level_exp": 14500
|
||||
}, {
|
||||
"level": 24,
|
||||
"level_exp": 16000
|
||||
}, {
|
||||
"level": 25,
|
||||
"level_exp": 17500
|
||||
}, {
|
||||
"level": 26,
|
||||
"level_exp": 19000
|
||||
}, {
|
||||
"level": 27,
|
||||
"level_exp": 20500
|
||||
}, {
|
||||
"level": 28,
|
||||
"level_exp": 22000
|
||||
}, {
|
||||
"level": 29,
|
||||
"level_exp": 23500
|
||||
}, {
|
||||
"level": 30,
|
||||
"level_exp": 25000
|
||||
}],
|
||||
"world_ranking_enabled": False,
|
||||
"is_byd_chapter_unlocked": True
|
||||
}
|
||||
}, {
|
||||
"id": 4,
|
||||
"value": []
|
||||
}, {
|
||||
"id": 5,
|
||||
"value": {
|
||||
"current_map": server.arcworld.get_current_map(user_id),
|
||||
"user_id": user_id,
|
||||
"maps": server.arcworld.get_world_all(user_id)
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
import sqlite3
|
||||
import server.arcworld
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_recent_score(c, user_id):
|
||||
# 得到用户最近一次的成绩,返回列表
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if x[11] is not None:
|
||||
c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', {
|
||||
'u': user_id, 's': x[11], 'd': x[12]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
best_clear_type = y[0]
|
||||
else:
|
||||
best_clear_type = x[21]
|
||||
|
||||
return [{
|
||||
"rating": x[22],
|
||||
"modifier": x[19],
|
||||
"time_played": x[20],
|
||||
"health": x[18],
|
||||
"best_clear_type": best_clear_type,
|
||||
"clear_type": x[21],
|
||||
"miss_count": x[17],
|
||||
"near_count": x[16],
|
||||
"perfect_count": x[15],
|
||||
"shiny_perfect_count": x[14],
|
||||
"score": x[13],
|
||||
"difficulty": x[12],
|
||||
"song_id": x[11]
|
||||
}]
|
||||
return []
|
||||
|
||||
|
||||
def get_user_character(c, user_id):
|
||||
# 得到用户拥有的角色列表,返回列表
|
||||
c.execute('''select * from user_char where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
s = []
|
||||
for i in x:
|
||||
char_name = ''
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': i[1]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
char_name = y[0]
|
||||
s.append({
|
||||
"is_uncapped_override": int2b(i[14]),
|
||||
"is_uncapped": int2b(i[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": i[12],
|
||||
"skill_id_uncap": i[11],
|
||||
"skill_requires_uncap": int2b(i[10]),
|
||||
"skill_unlock_level": i[9],
|
||||
"skill_id": i[8],
|
||||
"overdrive": i[7],
|
||||
"prog": i[6],
|
||||
"frag": i[5],
|
||||
"level_exp": i[4],
|
||||
"exp": i[3],
|
||||
"level": i[2],
|
||||
"name": char_name,
|
||||
"character_id": i[1]
|
||||
})
|
||||
|
||||
return s
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_user_friend(c, user_id):
|
||||
# 得到用户的朋友列表,返回列表
|
||||
c.execute('''select user_id_other from friend where user_id_me = :user_id''', {
|
||||
'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
s = []
|
||||
if x != [] and x[0][0] is not None:
|
||||
|
||||
for i in x:
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': i[0], 'y': user_id})
|
||||
if c.fetchone() == (1,):
|
||||
is_mutual = True
|
||||
else:
|
||||
is_mutual = False
|
||||
|
||||
c.execute('''select * from user where user_id = :x''', {'x': i[0]})
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
s.append({
|
||||
"is_mutual": is_mutual,
|
||||
"is_char_uncapped_override": int2b(y[9]),
|
||||
"is_char_uncapped": int2b(y[8]),
|
||||
"is_skill_sealed": int2b(y[7]),
|
||||
"rating": y[5],
|
||||
"join_date": int(y[3]),
|
||||
"character": y[6],
|
||||
"recent_score": get_recent_score(c, i[0]),
|
||||
"name": y[1],
|
||||
"user_id": i[0]
|
||||
})
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def get_value_0(c, user_id):
|
||||
# 构造value id=0的数据,返回字典
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
x = c.fetchone()
|
||||
r = {}
|
||||
if x is not None:
|
||||
user_character = get_user_character(c, user_id)
|
||||
characters = []
|
||||
for i in user_character:
|
||||
characters.append(i['character_id'])
|
||||
|
||||
r = {"is_aprilfools": False,
|
||||
"curr_available_maps": [],
|
||||
"character_stats": user_character,
|
||||
"friends": get_user_friend(c, user_id),
|
||||
"settings": {
|
||||
"favorite_character": x[23],
|
||||
"is_hide_rating": int2b(x[10]),
|
||||
"max_stamina_notification_enabled": int2b(x[24])
|
||||
},
|
||||
"user_id": user_id,
|
||||
"name": x[1],
|
||||
"user_code": x[4],
|
||||
"display_name": x[1],
|
||||
"ticket": 114514,
|
||||
"character": x[6],
|
||||
"is_locked_name_duplicate": False,
|
||||
"is_skill_sealed": int2b(x[7]),
|
||||
"current_map": x[25],
|
||||
"prog_boost": 0,
|
||||
"next_fragstam_ts": -1,
|
||||
"max_stamina_ts": 1586274871917,
|
||||
"stamina": 12,
|
||||
"world_unlocks": [],
|
||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "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"],
|
||||
"singles": ["dataerror", "yourvoiceso", "crosssoul", "impurebird", "auxesia", "modelista", "yozakurafubuki", "surrender", "metallicpunisher", "carminescythe", "bethere", "callmyname", "fallensquare", "dropdead", "alexandrite", "astraltale", "phantasia", "empireofwinter", "libertas", "dottodot", "dreadnought", "mirzam", "heavenlycaress", "filament", "avantraze", "battlenoone", "saikyostronger", "izana", "einherjar", "laqryma", "amygdata", "altale", "feelssoright", "scarletcage", "teriqma", "mahoroba", "badtek", "maliciousmischance", "buchigireberserker", "galaxyfriends", "buchigireberserker2", "xeraphinite"],
|
||||
"packs": ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"],
|
||||
"characters": characters,
|
||||
"cores": [],
|
||||
"recent_score": get_recent_score(c, user_id),
|
||||
"max_friend": 50,
|
||||
"rating": x[5],
|
||||
"join_date": int(x[3])
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def arc_aggregate_small(user_id):
|
||||
# 返回用户数据
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
}]}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_aggregate_big(user_id):
|
||||
# 返回用户数据和地图歌曲信息
|
||||
# 因为没有整理地图和曲包数据(不需要世界模式),所以直接复制了
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
}, {
|
||||
"id": 1,
|
||||
"value": [{
|
||||
"name": "core",
|
||||
"items": [{
|
||||
"id": "core",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "shiawase",
|
||||
"items": [{
|
||||
"id": "shiawase",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "kou",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "dynamix",
|
||||
"items": [{
|
||||
"id": "dynamix",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "sapphire",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "mirai",
|
||||
"items": [{
|
||||
"id": "mirai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "lethe",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "yugamu",
|
||||
"items": [{
|
||||
"id": "yugamu",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "lanota",
|
||||
"items": [{
|
||||
"id": "lanota",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "nijuusei",
|
||||
"items": [{
|
||||
"id": "nijuusei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "rei",
|
||||
"items": [{
|
||||
"id": "rei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "tonesphere",
|
||||
"items": [{
|
||||
"id": "tonesphere",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "groovecoaster",
|
||||
"items": [{
|
||||
"id": "groovecoaster",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "zettai",
|
||||
"items": [{
|
||||
"id": "zettai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "chunithm",
|
||||
"items": [{
|
||||
"id": "chunithm",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 300,
|
||||
"orig_price": 300
|
||||
}, {
|
||||
"name": "prelude",
|
||||
"items": [{
|
||||
"id": "prelude",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 400,
|
||||
"orig_price": 400
|
||||
}, {
|
||||
"name": "omatsuri",
|
||||
"items": [{
|
||||
"id": "omatsuri",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "vs",
|
||||
"items": [{
|
||||
"id": "vs",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "extend",
|
||||
"items": [{
|
||||
"id": "extend",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 700,
|
||||
"orig_price": 700
|
||||
}]
|
||||
}, {
|
||||
"id": 2,
|
||||
"value": {}
|
||||
}, {
|
||||
"id": 3,
|
||||
"value": {
|
||||
"max_stamina": 12,
|
||||
"stamina_recover_tick": 1800000,
|
||||
"core_exp": 250,
|
||||
"curr_ts": 1599547606825,
|
||||
"level_steps": [{
|
||||
"level": 1,
|
||||
"level_exp": 0
|
||||
}, {
|
||||
"level": 2,
|
||||
"level_exp": 50
|
||||
}, {
|
||||
"level": 3,
|
||||
"level_exp": 100
|
||||
}, {
|
||||
"level": 4,
|
||||
"level_exp": 150
|
||||
}, {
|
||||
"level": 5,
|
||||
"level_exp": 200
|
||||
}, {
|
||||
"level": 6,
|
||||
"level_exp": 300
|
||||
}, {
|
||||
"level": 7,
|
||||
"level_exp": 450
|
||||
}, {
|
||||
"level": 8,
|
||||
"level_exp": 650
|
||||
}, {
|
||||
"level": 9,
|
||||
"level_exp": 900
|
||||
}, {
|
||||
"level": 10,
|
||||
"level_exp": 1200
|
||||
}, {
|
||||
"level": 11,
|
||||
"level_exp": 1600
|
||||
}, {
|
||||
"level": 12,
|
||||
"level_exp": 2100
|
||||
}, {
|
||||
"level": 13,
|
||||
"level_exp": 2700
|
||||
}, {
|
||||
"level": 14,
|
||||
"level_exp": 3400
|
||||
}, {
|
||||
"level": 15,
|
||||
"level_exp": 4200
|
||||
}, {
|
||||
"level": 16,
|
||||
"level_exp": 5100
|
||||
}, {
|
||||
"level": 17,
|
||||
"level_exp": 6100
|
||||
}, {
|
||||
"level": 18,
|
||||
"level_exp": 7200
|
||||
}, {
|
||||
"level": 19,
|
||||
"level_exp": 8500
|
||||
}, {
|
||||
"level": 20,
|
||||
"level_exp": 10000
|
||||
}, {
|
||||
"level": 21,
|
||||
"level_exp": 11500
|
||||
}, {
|
||||
"level": 22,
|
||||
"level_exp": 13000
|
||||
}, {
|
||||
"level": 23,
|
||||
"level_exp": 14500
|
||||
}, {
|
||||
"level": 24,
|
||||
"level_exp": 16000
|
||||
}, {
|
||||
"level": 25,
|
||||
"level_exp": 17500
|
||||
}, {
|
||||
"level": 26,
|
||||
"level_exp": 19000
|
||||
}, {
|
||||
"level": 27,
|
||||
"level_exp": 20500
|
||||
}, {
|
||||
"level": 28,
|
||||
"level_exp": 22000
|
||||
}, {
|
||||
"level": 29,
|
||||
"level_exp": 23500
|
||||
}, {
|
||||
"level": 30,
|
||||
"level_exp": 25000
|
||||
}],
|
||||
"world_ranking_enabled": False,
|
||||
"is_byd_chapter_unlocked": True
|
||||
}
|
||||
}, {
|
||||
"id": 4,
|
||||
"value": []
|
||||
}, {
|
||||
"id": 5,
|
||||
"value": {
|
||||
"current_map": server.arcworld.get_current_map(user_id),
|
||||
"user_id": user_id,
|
||||
"maps": server.arcworld.get_world_all(user_id)
|
||||
}
|
||||
}
|
||||
]}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
@@ -1,155 +1,155 @@
|
||||
import sqlite3
|
||||
import server.info
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def change_char(user_id, character_id, skill_sealed):
|
||||
# 角色改变,包括技能封印的改变,返回成功与否的布尔值
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if skill_sealed == 'false':
|
||||
skill_sealed = False
|
||||
else:
|
||||
skill_sealed = True
|
||||
c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
|
||||
'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
|
||||
def change_char_uncap(user_id, character_id):
|
||||
# 角色觉醒改变,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x is not None and x[0] == 1:
|
||||
c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id})
|
||||
c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id})
|
||||
c.execute('''select * from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
y = c.fetchone()
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': y[1]})
|
||||
z = c.fetchone()
|
||||
if z is not None:
|
||||
char_name = z[0]
|
||||
if y is not None:
|
||||
r = {
|
||||
"is_uncapped_override": int2b(y[14]),
|
||||
"is_uncapped": int2b(y[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": y[12],
|
||||
"skill_id_uncap": y[11],
|
||||
"skill_requires_uncap": int2b(y[10]),
|
||||
"skill_unlock_level": y[9],
|
||||
"skill_id": y[8],
|
||||
"overdrive": y[7],
|
||||
"prog": y[6],
|
||||
"frag": y[5],
|
||||
"level_exp": y[4],
|
||||
"exp": y[3],
|
||||
"level": y[2],
|
||||
"name": char_name,
|
||||
"character_id": y[1]
|
||||
}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_sys_set(user_id, value, set_arg):
|
||||
# 三个设置,PTT隐藏、体力满通知、最爱角色,无返回
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if 'favorite_character' in set_arg:
|
||||
value = int(value)
|
||||
c.execute('''update user set favorite_character = :a where user_id = :b''', {
|
||||
'a': value, 'b': user_id})
|
||||
|
||||
else:
|
||||
if value == 'false':
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
|
||||
if 'is_hide_rating' in set_arg:
|
||||
c.execute('''update user set is_hide_rating = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
if 'max_stamina_notification_enabled' in set_arg:
|
||||
c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_add_friend(user_id, friend_id):
|
||||
# 加好友,返回好友列表,或者是错误码602、604
|
||||
if user_id == friend_id:
|
||||
return 604
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into friend values(:a, :b)''',
|
||||
{'a': user_id, 'b': friend_id})
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
else:
|
||||
return 602
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_delete_friend(user_id, friend_id):
|
||||
# 删好友,返回好友列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
import sqlite3
|
||||
import server.info
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def change_char(user_id, character_id, skill_sealed):
|
||||
# 角色改变,包括技能封印的改变,返回成功与否的布尔值
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if skill_sealed == 'false':
|
||||
skill_sealed = False
|
||||
else:
|
||||
skill_sealed = True
|
||||
c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
|
||||
'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
|
||||
def change_char_uncap(user_id, character_id):
|
||||
# 角色觉醒改变,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x is not None and x[0] == 1:
|
||||
c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id})
|
||||
c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id})
|
||||
c.execute('''select * from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
y = c.fetchone()
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': y[1]})
|
||||
z = c.fetchone()
|
||||
if z is not None:
|
||||
char_name = z[0]
|
||||
if y is not None:
|
||||
r = {
|
||||
"is_uncapped_override": int2b(y[14]),
|
||||
"is_uncapped": int2b(y[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": y[12],
|
||||
"skill_id_uncap": y[11],
|
||||
"skill_requires_uncap": int2b(y[10]),
|
||||
"skill_unlock_level": y[9],
|
||||
"skill_id": y[8],
|
||||
"overdrive": y[7],
|
||||
"prog": y[6],
|
||||
"frag": y[5],
|
||||
"level_exp": y[4],
|
||||
"exp": y[3],
|
||||
"level": y[2],
|
||||
"name": char_name,
|
||||
"character_id": y[1]
|
||||
}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_sys_set(user_id, value, set_arg):
|
||||
# 三个设置,PTT隐藏、体力满通知、最爱角色,无返回
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if 'favorite_character' in set_arg:
|
||||
value = int(value)
|
||||
c.execute('''update user set favorite_character = :a where user_id = :b''', {
|
||||
'a': value, 'b': user_id})
|
||||
|
||||
else:
|
||||
if value == 'false':
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
|
||||
if 'is_hide_rating' in set_arg:
|
||||
c.execute('''update user set is_hide_rating = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
if 'max_stamina_notification_enabled' in set_arg:
|
||||
c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_add_friend(user_id, friend_id):
|
||||
# 加好友,返回好友列表,或者是错误码602、604
|
||||
if user_id == friend_id:
|
||||
return 604
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into friend values(:a, :b)''',
|
||||
{'a': user_id, 'b': friend_id})
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
else:
|
||||
return 602
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_delete_friend(user_id, friend_id):
|
||||
# 删好友,返回好友列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
@@ -1,3 +1,3 @@
|
||||
[CONFIG]
|
||||
HOST = 192.168.1.113
|
||||
[CONFIG]
|
||||
HOST = 192.168.1.113
|
||||
PORT = 80
|
||||
@@ -1,217 +1,217 @@
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
background: #eee;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: serif;
|
||||
color: #377ba8;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #377ba8;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid lightgray;
|
||||
}
|
||||
|
||||
nav {
|
||||
background: lightgray;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
nav h1 {
|
||||
flex: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav h1 a {
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li a,
|
||||
nav ul li span,
|
||||
header .action {
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.content>header {
|
||||
border-bottom: 1px solid lightgray;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.content>header h1 {
|
||||
flex: auto;
|
||||
margin: 1rem 0 0.25rem 0;
|
||||
}
|
||||
|
||||
.flash {
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
background: #cae6f6;
|
||||
border: 1px solid #377ba8;
|
||||
}
|
||||
|
||||
.post>header {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.post>header>div:first-of-type {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.post>header h1 {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.post .about {
|
||||
color: slategray;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post .body {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.content:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.content form {
|
||||
margin: 1em 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.content input,
|
||||
.content textarea {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.content textarea {
|
||||
min-height: 12em;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
input.danger {
|
||||
color: #cc2f2e;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
align-self: start;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
|
||||
.score-item {
|
||||
margin-bottom: 10px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.song-title {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.difficulty_pst {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(10, 130, 190);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_prs {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(100, 140, 60);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_ftr {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(80, 25, 75);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_byd {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(130, 35, 40);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.rank {
|
||||
font-size: 0.8em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.rank_big {
|
||||
font-size: 1.2em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.song-detail {
|
||||
font-size: 0.8em;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.song-score {
|
||||
font-size: 1.375em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.song-clear-type {
|
||||
font-size: 0.875em;
|
||||
padding-left: 0.625em;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.375em;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 1.12em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.footer{
|
||||
font-size: 0.5em;
|
||||
color: grey;
|
||||
text-align: center;
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
background: #eee;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: serif;
|
||||
color: #377ba8;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #377ba8;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid lightgray;
|
||||
}
|
||||
|
||||
nav {
|
||||
background: lightgray;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
nav h1 {
|
||||
flex: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav h1 a {
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li a,
|
||||
nav ul li span,
|
||||
header .action {
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.content>header {
|
||||
border-bottom: 1px solid lightgray;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.content>header h1 {
|
||||
flex: auto;
|
||||
margin: 1rem 0 0.25rem 0;
|
||||
}
|
||||
|
||||
.flash {
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
background: #cae6f6;
|
||||
border: 1px solid #377ba8;
|
||||
}
|
||||
|
||||
.post>header {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.post>header>div:first-of-type {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.post>header h1 {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.post .about {
|
||||
color: slategray;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post .body {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.content:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.content form {
|
||||
margin: 1em 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.content input,
|
||||
.content textarea {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.content textarea {
|
||||
min-height: 12em;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
input.danger {
|
||||
color: #cc2f2e;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
align-self: start;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
|
||||
.score-item {
|
||||
margin-bottom: 10px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.song-title {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.difficulty_pst {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(10, 130, 190);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_prs {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(100, 140, 60);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_ftr {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(80, 25, 75);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_byd {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(130, 35, 40);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.rank {
|
||||
font-size: 0.8em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.rank_big {
|
||||
font-size: 1.2em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.song-detail {
|
||||
font-size: 0.8em;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.song-score {
|
||||
font-size: 1.375em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.song-clear-type {
|
||||
font-size: 0.875em;
|
||||
padding-left: 0.625em;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.375em;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 1.12em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.footer{
|
||||
font-size: 0.5em;
|
||||
color: grey;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
<!doctype html>
|
||||
<title>{% block title %}{% endblock %} - Arcaea Server</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<nav>
|
||||
<h1>Arcaea Server</h1>
|
||||
<ul>
|
||||
{% if g.user %}
|
||||
<li><span>{{ g.user['username'] }}</span>
|
||||
<li><a href="{{ url_for('index.index') }}">Home</a>
|
||||
<li><a href="{{ url_for('login.logout') }}">Log Out</a> {% else %}
|
||||
<li><a href="{{ url_for('login.login') }}">Log In</a> {% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="content">
|
||||
<header>
|
||||
{% block header %}{% endblock %}
|
||||
</header>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<div class="flash">{{ message }}</div>
|
||||
{% endfor %} {% block content %}{% endblock %}
|
||||
</section>
|
||||
|
||||
<!doctype html>
|
||||
<title>{% block title %}{% endblock %} - Arcaea Server</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<nav>
|
||||
<h1>Arcaea Server</h1>
|
||||
<ul>
|
||||
{% if g.user %}
|
||||
<li><span>{{ g.user['username'] }}</span>
|
||||
<li><a href="{{ url_for('index.index') }}">Home</a>
|
||||
<li><a href="{{ url_for('login.logout') }}">Log Out</a> {% else %}
|
||||
<li><a href="{{ url_for('login.login') }}">Log In</a> {% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="content">
|
||||
<header>
|
||||
{% block header %}{% endblock %}
|
||||
</header>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<div class="flash">{{ message }}</div>
|
||||
{% endfor %} {% block content %}{% endblock %}
|
||||
</section>
|
||||
|
||||
<footer id="footer" class="footer">Made by Lost@2020</footer>
|
||||
@@ -1,81 +1,81 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All players{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}
|
||||
{% for user in posts %}
|
||||
|
||||
<div id="user-info">
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All players{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}
|
||||
{% for user in posts %}
|
||||
|
||||
<div id="user-info">
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,48 +1,48 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}<br />
|
||||
{% for song in posts %}
|
||||
|
||||
<div class="score-item">
|
||||
<span>Sid: </span>
|
||||
<span class="song-title">{{song['song_id']}}</span>
|
||||
<br />
|
||||
<span>Name_en: </span>
|
||||
<span class="song-title">{{song['name_en']}}</span>
|
||||
<br />
|
||||
<div>铺面定数 Chart const: </div>
|
||||
{% if song['rating_pst'] %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
<span class="song-rating">{{song['rating_pst']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_prs'] %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
<span class="song-rating">{{song['rating_prs']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_ftr'] %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
<span class="song-rating">{{song['rating_ftr']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_byn'] %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
<span class="song-rating">{{song['rating_byn']}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}<br />
|
||||
{% for song in posts %}
|
||||
|
||||
<div class="score-item">
|
||||
<span>Sid: </span>
|
||||
<span class="song-title">{{song['song_id']}}</span>
|
||||
<br />
|
||||
<span>Name_en: </span>
|
||||
<span class="song-title">{{song['name_en']}}</span>
|
||||
<br />
|
||||
<div>铺面定数 Chart const: </div>
|
||||
{% if song['rating_pst'] %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
<span class="song-rating">{{song['rating_pst']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_prs'] %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
<span class="song-rating">{{song['rating_prs']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_ftr'] %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
<span class="song-rating">{{song['rating_ftr']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_byn'] %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
<span class="song-rating">{{song['rating_byn']}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,35 +1,35 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Change the songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="/web/changesong/addsong" method="post">
|
||||
<div class="title">Add the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
<label for="name_en">English name of the song(Not important but neccessary)</label>
|
||||
<input name="name_en" id="name_en" required>
|
||||
|
||||
<label for="rating_pst">Past chart const</label>
|
||||
<input name="rating_pst" id="rating_pst" required>
|
||||
<label for="rating_prs">Present chart const</label>
|
||||
<input name="rating_prs" id="rating_prs" required>
|
||||
<label for="rating_ftr">Future chart const</label>
|
||||
<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">If there is no some chart, fill in -1 please.</div>
|
||||
<input type="submit" value="Add">
|
||||
</form>
|
||||
<br />
|
||||
<hr />
|
||||
<form action="/web/changesong/deletesong" method="post">
|
||||
<div class="title">Delete the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
|
||||
<input type="submit" value="Delete">
|
||||
</form>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Change the songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="/web/changesong/addsong" method="post">
|
||||
<div class="title">Add the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
<label for="name_en">English name of the song(Not important but neccessary)</label>
|
||||
<input name="name_en" id="name_en" required>
|
||||
|
||||
<label for="rating_pst">Past chart const</label>
|
||||
<input name="rating_pst" id="rating_pst" required>
|
||||
<label for="rating_prs">Present chart const</label>
|
||||
<input name="rating_prs" id="rating_prs" required>
|
||||
<label for="rating_ftr">Future chart const</label>
|
||||
<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">If there is no some chart, fill in -1 please.</div>
|
||||
<input type="submit" value="Add">
|
||||
</form>
|
||||
<br />
|
||||
<hr />
|
||||
<form action="/web/changesong/deletesong" method="post">
|
||||
<div class="title">Delete the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
|
||||
<input type="submit" value="Delete">
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,24 +1,24 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Index{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>说明 Statement</h1>
|
||||
<p>这是Arcaea Server的后台管理协助系统,可以进行一些简单的操作</br>
|
||||
This is the background management assistance system of Arcaea Server, which can be used to do some simple
|
||||
operations.
|
||||
</p>
|
||||
<h1>游戏方面 Game</h1>
|
||||
<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.single_chart_top') }}">单个铺面排行榜查询 Single song chart tops</a>
|
||||
<hr>
|
||||
<h1>系统方面 System</h1>
|
||||
<a href="{{ url_for('index.update_database') }}">数据库更新 Update databases</a></br></br>
|
||||
<a href="{{ url_for('index.change_song') }}">歌曲修改 Change the songs</a>
|
||||
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Index{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>说明 Statement</h1>
|
||||
<p>这是Arcaea Server的后台管理协助系统,可以进行一些简单的操作</br>
|
||||
This is the background management assistance system of Arcaea Server, which can be used to do some simple
|
||||
operations.
|
||||
</p>
|
||||
<h1>游戏方面 Game</h1>
|
||||
<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.single_chart_top') }}">单个铺面排行榜查询 Single song chart tops</a>
|
||||
<hr>
|
||||
<h1>系统方面 System</h1>
|
||||
<a href="{{ url_for('index.update_database') }}">数据库更新 Update databases</a></br></br>
|
||||
<a href="{{ url_for('index.change_song') }}">歌曲修改 Change the songs</a>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,14 +1,14 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Log In{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="username">Username</label>
|
||||
<input name="username" id="username" required>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" required>
|
||||
<input type="submit" value="Log In">
|
||||
</form>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Log In{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="username">Username</label>
|
||||
<input name="username" id="username" required>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" required>
|
||||
<input type="submit" value="Log In">
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,108 +1,108 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single chart top{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="sid">SID of the song</label>
|
||||
<span>模糊查询,只返回第一个</span>
|
||||
<span>Fuzzy query,and only return the first one.</span>
|
||||
<input name="sid" id="sid">
|
||||
<label for="difficulty">Difficulty</label>
|
||||
<select name='difficulty' id='difficulty'>
|
||||
<option value="0" selected>Past</option>
|
||||
<option value="1">Present</option>
|
||||
<option value="2">Future</option>
|
||||
<option value="3">Beyond</option>
|
||||
</select>
|
||||
<br />
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% if song_id %}
|
||||
<div>
|
||||
<span class="song-title">
|
||||
{{song_id}}
|
||||
</span>
|
||||
|
||||
{% if difficulty == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif difficulty == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif difficulty == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
|
||||
{% endif %}
|
||||
<br />
|
||||
<div class="song-title">
|
||||
{{song_name_en}}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<br />
|
||||
<hr />
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<div>
|
||||
<span class='rank_big'>{{'#' ~ post['rank']}}</span>
|
||||
<span class="name">
|
||||
{{post['name']}}
|
||||
</span>
|
||||
<span class="rank">UID: {{post['user_id']}}</span>
|
||||
</div>
|
||||
|
||||
<div class="song-detail">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single chart top{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="sid">SID of the song</label>
|
||||
<span>模糊查询,只返回第一个</span>
|
||||
<span>Fuzzy query,and only return the first one.</span>
|
||||
<input name="sid" id="sid">
|
||||
<label for="difficulty">Difficulty</label>
|
||||
<select name='difficulty' id='difficulty'>
|
||||
<option value="0" selected>Past</option>
|
||||
<option value="1">Present</option>
|
||||
<option value="2">Future</option>
|
||||
<option value="3">Beyond</option>
|
||||
</select>
|
||||
<br />
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% if song_id %}
|
||||
<div>
|
||||
<span class="song-title">
|
||||
{{song_id}}
|
||||
</span>
|
||||
|
||||
{% if difficulty == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif difficulty == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif difficulty == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
|
||||
{% endif %}
|
||||
<br />
|
||||
<div class="song-title">
|
||||
{{song_name_en}}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<br />
|
||||
<hr />
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<div>
|
||||
<span class='rank_big'>{{'#' ~ post['rank']}}</span>
|
||||
<span class="name">
|
||||
{{post['name']}}
|
||||
</span>
|
||||
<span class="rank">UID: {{post['user_id']}}</span>
|
||||
</div>
|
||||
|
||||
<div class="song-detail">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,85 +1,85 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player score{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
</br>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player score{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
</br>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,191 +1,191 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player ptt{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% if user %}
|
||||
<hr />
|
||||
|
||||
<div id="user-info">
|
||||
<div class="title">玩家信息 Player information</div>
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div class="ptt">Best 30 PTT: {{bestptt}}</div>
|
||||
<div class="ptt">Recent 10 PTT: {{recentptt}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{% if posts %}
|
||||
<div class="title">Best 30</div>
|
||||
{% endif %}
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr />
|
||||
|
||||
{% if recent %}
|
||||
<div class="title">Recent 30</div>
|
||||
{% for i in recent %}
|
||||
|
||||
{% if i %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{i['song_id']}}
|
||||
</span>
|
||||
{% if i['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif i['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif i['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{loop.index}}</span>
|
||||
<div class="song-rating">成绩评价 Rating: {{i['rating']}}</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</form>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player ptt{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% if user %}
|
||||
<hr />
|
||||
|
||||
<div id="user-info">
|
||||
<div class="title">玩家信息 Player information</div>
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div class="ptt">Best 30 PTT: {{bestptt}}</div>
|
||||
<div class="ptt">Recent 10 PTT: {{recentptt}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{% if posts %}
|
||||
<div class="title">Best 30</div>
|
||||
{% endif %}
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr />
|
||||
|
||||
{% if recent %}
|
||||
<div class="title">Recent 30</div>
|
||||
{% for i in recent %}
|
||||
|
||||
{% if i %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{i['song_id']}}
|
||||
</span>
|
||||
{% if i['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif i['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif i['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{loop.index}}</span>
|
||||
<div class="song-rating">成绩评价 Rating: {{i['rating']}}</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,21 +1,21 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Update databases{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<label for="name">Old database</label>
|
||||
<input type="file" name="file">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
<div class="content">
|
||||
这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。<br />
|
||||
可上传文件: arcaea_database.db和arcsong.db<br />
|
||||
新数据库不存在的数据会被添加,存在的数据将不会被改变。<br /><br />
|
||||
Here you can synchronize the old version of the database to the new version of the database and refresh the list of
|
||||
characters owned by players.<br />
|
||||
Uploadable files: arcaea_database.db & arcsong.db<br />
|
||||
Data that does not exist in the new database will be added and the existing data will not be changed.
|
||||
</div>
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Update databases{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<label for="name">Old database</label>
|
||||
<input type="file" name="file">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
<div class="content">
|
||||
这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。<br />
|
||||
可上传文件: arcaea_database.db和arcsong.db<br />
|
||||
新数据库不存在的数据会被添加,存在的数据将不会被改变。<br /><br />
|
||||
Here you can synchronize the old version of the database to the new version of the database and refresh the list of
|
||||
characters owned by players.<br />
|
||||
Uploadable files: arcaea_database.db & arcsong.db<br />
|
||||
Data that does not exist in the new database will be added and the existing data will not be changed.
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,360 +1,360 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
from web.login import login_required
|
||||
from werkzeug.utils import secure_filename
|
||||
import sqlite3
|
||||
import web.webscore
|
||||
import web.system
|
||||
import time
|
||||
import server.arcscore
|
||||
import os
|
||||
|
||||
UPLOAD_FOLDER = 'database'
|
||||
ALLOWED_EXTENSIONS = {'db'}
|
||||
|
||||
bp = Blueprint('index', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
def is_number(s):
|
||||
try: # 判断字符串s是浮点数
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
@bp.route('/index')
|
||||
@bp.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
# 主页
|
||||
return render_template('web/index.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayer', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_score():
|
||||
# 单个玩家分数查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
posts = web.webscore.get_user_score(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayer.html', posts=posts)
|
||||
|
||||
return render_template('web/singleplayer.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayerptt', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_ptt():
|
||||
# 单个玩家PTT详情查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
user = web.webscore.get_user(c, user_id)
|
||||
posts = web.webscore.get_user_score(c, user_id, 30)
|
||||
recent, recentptt = web.webscore.get_user_recent30(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
bestptt = 0
|
||||
for i in posts:
|
||||
if i['rating']:
|
||||
bestptt += i['rating']
|
||||
bestptt = bestptt / 30
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayerptt.html', posts=posts, user=user, recent=recent, recentptt=recentptt, bestptt=bestptt)
|
||||
|
||||
return render_template('web/singleplayerptt.html')
|
||||
|
||||
|
||||
@bp.route('/allplayer', methods=['GET'])
|
||||
@login_required
|
||||
def all_player():
|
||||
# 所有玩家数据,按照ptt排序
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user order by rating_ptt DESC''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
join_data = None
|
||||
time_played = None
|
||||
if i[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[3])//1000))
|
||||
if i[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[20])//1000))
|
||||
posts.append({'name': i[1],
|
||||
'user_id': i[0],
|
||||
'join_date': join_date,
|
||||
'user_code': i[4],
|
||||
'rating_ptt': i[5],
|
||||
'song_id': i[11],
|
||||
'difficulty': i[12],
|
||||
'score': i[13],
|
||||
'shiny_perfect_count': i[14],
|
||||
'perfect_count': i[15],
|
||||
'near_count': i[16],
|
||||
'miss_count': i[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': i[21],
|
||||
'rating': i[22]
|
||||
})
|
||||
else:
|
||||
error = '没有玩家数据 No player data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allplayer.html')
|
||||
else:
|
||||
return render_template('web/allplayer.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/allsong', methods=['GET'])
|
||||
@login_required
|
||||
def all_song():
|
||||
# 所有歌曲数据
|
||||
def defnum(x):
|
||||
# 定数转换
|
||||
if x >= 0:
|
||||
return x / 10
|
||||
else:
|
||||
return None
|
||||
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from songs''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
posts.append({'song_id': i[0],
|
||||
'name_en': i[1],
|
||||
'rating_pst': defnum(i[12]),
|
||||
'rating_prs': defnum(i[13]),
|
||||
'rating_ftr': defnum(i[14]),
|
||||
'rating_byn': defnum(i[15])
|
||||
})
|
||||
else:
|
||||
error = '没有铺面数据 No song data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allsong.html')
|
||||
else:
|
||||
return render_template('web/allsong.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/singlecharttop', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def single_chart_top():
|
||||
# 歌曲排行榜
|
||||
if request.method == 'POST':
|
||||
song_name = request.form['sid']
|
||||
difficulty = request.form['difficulty']
|
||||
if difficulty.isdigit():
|
||||
difficulty = int(difficulty)
|
||||
error = None
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
song_name = '%'+song_name+'%'
|
||||
c.execute('''select sid, name_en from songs where sid like :a limit 1''',
|
||||
{'a': song_name})
|
||||
x = c.fetchone()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print(x)
|
||||
if x:
|
||||
song_id = x[0]
|
||||
posts = server.arcscore.arc_score_top(song_id, difficulty, -1)
|
||||
for i in posts:
|
||||
i['time_played'] = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(i['time_played']))
|
||||
else:
|
||||
error = '查询为空 No song.'
|
||||
|
||||
if not error:
|
||||
return render_template('web/singlecharttop.html', posts=posts, song_name_en=x[1], song_id=song_id, difficulty=difficulty)
|
||||
else:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/singlecharttop.html')
|
||||
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
@bp.route('/updatedatabase', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def update_database():
|
||||
# 更新数据库
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
if 'file' not in request.files:
|
||||
flash('无文件 No file part.')
|
||||
return redirect(request.url)
|
||||
file = request.files['file']
|
||||
if file.filename == '':
|
||||
flash('未选择文件 No selected file.')
|
||||
return redirect(request.url)
|
||||
|
||||
if file and allowed_file(file.filename):
|
||||
filename = 'old_' + secure_filename(file.filename)
|
||||
file.save(os.path.join(UPLOAD_FOLDER, filename))
|
||||
flash('上传成功 Success upload.')
|
||||
try:
|
||||
web.system.update_database()
|
||||
flash('数据更新成功 Success update data.')
|
||||
except:
|
||||
flash('数据更新失败 Cannot update data.')
|
||||
else:
|
||||
error = '上传失败 Upload error.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/changesong', methods=['GET'])
|
||||
@login_required
|
||||
def change_song():
|
||||
# 修改歌曲数据
|
||||
return render_template('web/changesong.html')
|
||||
|
||||
|
||||
@bp.route('/changesong/addsong', methods=['POST'])
|
||||
@login_required
|
||||
def add_song():
|
||||
# 添加歌曲数据
|
||||
def get_rating(x):
|
||||
# 换算定数
|
||||
if is_number(x):
|
||||
x = float(x)
|
||||
if x >= 0:
|
||||
return int(x*10)
|
||||
else:
|
||||
return -1
|
||||
else:
|
||||
return -1
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
name_en = request.form['name_en']
|
||||
rating_pst = get_rating(request.form['rating_pst'])
|
||||
rating_prs = get_rating(request.form['rating_prs'])
|
||||
rating_ftr = get_rating(request.form['rating_ftr'])
|
||||
rating_byd = get_rating(request.form['rating_byd'])
|
||||
if len(song_id) >= 256:
|
||||
song_id = song_id[:200]
|
||||
if len(name_en) >= 256:
|
||||
name_en = name_en[:200]
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into songs(sid,name_en,rating_pst,rating_prs,rating_ftr,rating_byn) values(:a,:b,:c,:d,:e,:f)''', {
|
||||
'a': song_id, 'b': name_en, 'c': rating_pst, 'd': rating_prs, 'e': rating_ftr, 'f': rating_byd})
|
||||
flash('歌曲添加成功 Successfully add the song.')
|
||||
else:
|
||||
error = '歌曲已存在 The song exists.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
|
||||
|
||||
@bp.route('/changesong/deletesong', methods=['POST'])
|
||||
@login_required
|
||||
def delete_song():
|
||||
# 删除歌曲数据
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from songs where sid=:a''', {'a': song_id})
|
||||
flash('歌曲删除成功 Successfully delete the song.')
|
||||
else:
|
||||
error = "歌曲不存在 The song doesn't exist."
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
from web.login import login_required
|
||||
from werkzeug.utils import secure_filename
|
||||
import sqlite3
|
||||
import web.webscore
|
||||
import web.system
|
||||
import time
|
||||
import server.arcscore
|
||||
import os
|
||||
|
||||
UPLOAD_FOLDER = 'database'
|
||||
ALLOWED_EXTENSIONS = {'db'}
|
||||
|
||||
bp = Blueprint('index', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
def is_number(s):
|
||||
try: # 判断字符串s是浮点数
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
@bp.route('/index')
|
||||
@bp.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
# 主页
|
||||
return render_template('web/index.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayer', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_score():
|
||||
# 单个玩家分数查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
posts = web.webscore.get_user_score(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayer.html', posts=posts)
|
||||
|
||||
return render_template('web/singleplayer.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayerptt', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_ptt():
|
||||
# 单个玩家PTT详情查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
user = web.webscore.get_user(c, user_id)
|
||||
posts = web.webscore.get_user_score(c, user_id, 30)
|
||||
recent, recentptt = web.webscore.get_user_recent30(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
bestptt = 0
|
||||
for i in posts:
|
||||
if i['rating']:
|
||||
bestptt += i['rating']
|
||||
bestptt = bestptt / 30
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayerptt.html', posts=posts, user=user, recent=recent, recentptt=recentptt, bestptt=bestptt)
|
||||
|
||||
return render_template('web/singleplayerptt.html')
|
||||
|
||||
|
||||
@bp.route('/allplayer', methods=['GET'])
|
||||
@login_required
|
||||
def all_player():
|
||||
# 所有玩家数据,按照ptt排序
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user order by rating_ptt DESC''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
join_data = None
|
||||
time_played = None
|
||||
if i[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[3])//1000))
|
||||
if i[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[20])//1000))
|
||||
posts.append({'name': i[1],
|
||||
'user_id': i[0],
|
||||
'join_date': join_date,
|
||||
'user_code': i[4],
|
||||
'rating_ptt': i[5],
|
||||
'song_id': i[11],
|
||||
'difficulty': i[12],
|
||||
'score': i[13],
|
||||
'shiny_perfect_count': i[14],
|
||||
'perfect_count': i[15],
|
||||
'near_count': i[16],
|
||||
'miss_count': i[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': i[21],
|
||||
'rating': i[22]
|
||||
})
|
||||
else:
|
||||
error = '没有玩家数据 No player data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allplayer.html')
|
||||
else:
|
||||
return render_template('web/allplayer.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/allsong', methods=['GET'])
|
||||
@login_required
|
||||
def all_song():
|
||||
# 所有歌曲数据
|
||||
def defnum(x):
|
||||
# 定数转换
|
||||
if x >= 0:
|
||||
return x / 10
|
||||
else:
|
||||
return None
|
||||
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from songs''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
posts.append({'song_id': i[0],
|
||||
'name_en': i[1],
|
||||
'rating_pst': defnum(i[12]),
|
||||
'rating_prs': defnum(i[13]),
|
||||
'rating_ftr': defnum(i[14]),
|
||||
'rating_byn': defnum(i[15])
|
||||
})
|
||||
else:
|
||||
error = '没有铺面数据 No song data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allsong.html')
|
||||
else:
|
||||
return render_template('web/allsong.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/singlecharttop', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def single_chart_top():
|
||||
# 歌曲排行榜
|
||||
if request.method == 'POST':
|
||||
song_name = request.form['sid']
|
||||
difficulty = request.form['difficulty']
|
||||
if difficulty.isdigit():
|
||||
difficulty = int(difficulty)
|
||||
error = None
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
song_name = '%'+song_name+'%'
|
||||
c.execute('''select sid, name_en from songs where sid like :a limit 1''',
|
||||
{'a': song_name})
|
||||
x = c.fetchone()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print(x)
|
||||
if x:
|
||||
song_id = x[0]
|
||||
posts = server.arcscore.arc_score_top(song_id, difficulty, -1)
|
||||
for i in posts:
|
||||
i['time_played'] = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(i['time_played']))
|
||||
else:
|
||||
error = '查询为空 No song.'
|
||||
|
||||
if not error:
|
||||
return render_template('web/singlecharttop.html', posts=posts, song_name_en=x[1], song_id=song_id, difficulty=difficulty)
|
||||
else:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/singlecharttop.html')
|
||||
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
@bp.route('/updatedatabase', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def update_database():
|
||||
# 更新数据库
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
if 'file' not in request.files:
|
||||
flash('无文件 No file part.')
|
||||
return redirect(request.url)
|
||||
file = request.files['file']
|
||||
if file.filename == '':
|
||||
flash('未选择文件 No selected file.')
|
||||
return redirect(request.url)
|
||||
|
||||
if file and allowed_file(file.filename) and file.filename in ['arcsong.db', 'arcaea_database.db']:
|
||||
filename = 'old_' + secure_filename(file.filename)
|
||||
file.save(os.path.join(UPLOAD_FOLDER, filename))
|
||||
flash('上传成功 Success upload.')
|
||||
try:
|
||||
web.system.update_database()
|
||||
flash('数据更新成功 Success update data.')
|
||||
except:
|
||||
flash('数据更新失败 Cannot update data.')
|
||||
else:
|
||||
error = '上传失败 Upload error.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/changesong', methods=['GET'])
|
||||
@login_required
|
||||
def change_song():
|
||||
# 修改歌曲数据
|
||||
return render_template('web/changesong.html')
|
||||
|
||||
|
||||
@bp.route('/changesong/addsong', methods=['POST'])
|
||||
@login_required
|
||||
def add_song():
|
||||
# 添加歌曲数据
|
||||
def get_rating(x):
|
||||
# 换算定数
|
||||
if is_number(x):
|
||||
x = float(x)
|
||||
if x >= 0:
|
||||
return int(x*10)
|
||||
else:
|
||||
return -1
|
||||
else:
|
||||
return -1
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
name_en = request.form['name_en']
|
||||
rating_pst = get_rating(request.form['rating_pst'])
|
||||
rating_prs = get_rating(request.form['rating_prs'])
|
||||
rating_ftr = get_rating(request.form['rating_ftr'])
|
||||
rating_byd = get_rating(request.form['rating_byd'])
|
||||
if len(song_id) >= 256:
|
||||
song_id = song_id[:200]
|
||||
if len(name_en) >= 256:
|
||||
name_en = name_en[:200]
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into songs(sid,name_en,rating_pst,rating_prs,rating_ftr,rating_byn) values(:a,:b,:c,:d,:e,:f)''', {
|
||||
'a': song_id, 'b': name_en, 'c': rating_pst, 'd': rating_prs, 'e': rating_ftr, 'f': rating_byd})
|
||||
flash('歌曲添加成功 Successfully add the song.')
|
||||
else:
|
||||
error = '歌曲已存在 The song exists.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
|
||||
|
||||
@bp.route('/changesong/deletesong', methods=['POST'])
|
||||
@login_required
|
||||
def delete_song():
|
||||
# 删除歌曲数据
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from songs where sid=:a''', {'a': song_id})
|
||||
flash('歌曲删除成功 Successfully delete the song.')
|
||||
else:
|
||||
error = "歌曲不存在 The song doesn't exist."
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
@@ -1,50 +1,50 @@
|
||||
#import sqlite3
|
||||
from flask import (Blueprint, flash, g, redirect,
|
||||
render_template, request, session, url_for)
|
||||
import functools
|
||||
|
||||
bp = Blueprint('login', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
@bp.route('/login', methods=('GET', 'POST'))
|
||||
def login():
|
||||
# 登录
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
error = None
|
||||
|
||||
if username != 'admin' and password != 'admin':
|
||||
error = '错误的用户名或密码 Incorrect username or password.'
|
||||
|
||||
if error is None:
|
||||
session.clear()
|
||||
session['user_id'] = 'admin'
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
flash(error)
|
||||
|
||||
return render_template('web/login.html')
|
||||
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
# 登出
|
||||
session.clear()
|
||||
flash('成功登出 Successfully log out.')
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
|
||||
def login_required(view):
|
||||
# 登录验证,写成了修饰器
|
||||
@functools.wraps(view)
|
||||
def wrapped_view(**kwargs):
|
||||
x = session.get('user_id')
|
||||
# 少用户存在验证
|
||||
if x is None:
|
||||
return redirect(url_for('login.login'))
|
||||
|
||||
g.user = {'user_id': x, 'username': 'admin'}
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
#import sqlite3
|
||||
from flask import (Blueprint, flash, g, redirect,
|
||||
render_template, request, session, url_for)
|
||||
import functools
|
||||
|
||||
bp = Blueprint('login', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
@bp.route('/login', methods=('GET', 'POST'))
|
||||
def login():
|
||||
# 登录
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
error = None
|
||||
|
||||
if username != 'admin' and password != 'admin':
|
||||
error = '错误的用户名或密码 Incorrect username or password.'
|
||||
|
||||
if error is None:
|
||||
session.clear()
|
||||
session['user_id'] = 'admin'
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
flash(error)
|
||||
|
||||
return render_template('web/login.html')
|
||||
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
# 登出
|
||||
session.clear()
|
||||
flash('成功登出 Successfully log out.')
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
|
||||
def login_required(view):
|
||||
# 登录验证,写成了修饰器
|
||||
@functools.wraps(view)
|
||||
def wrapped_view(**kwargs):
|
||||
x = session.get('user_id')
|
||||
# 少用户存在验证
|
||||
if x is None:
|
||||
return redirect(url_for('login.login'))
|
||||
|
||||
g.user = {'user_id': x, 'username': 'admin'}
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
@@ -1,113 +1,113 @@
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
|
||||
def update_user_char(c):
|
||||
# 用character数据更新user_char
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
c.execute('''select user_id from user''')
|
||||
y = c.fetchall()
|
||||
if x and y:
|
||||
for j in y:
|
||||
for i in x:
|
||||
c.execute('''delete from user_char where user_id=:a and character_id=:b''', {
|
||||
'a': j[0], 'b': i[0]})
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': j[0], 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
|
||||
def update_database():
|
||||
# 将old数据库不存在数据加入到新数据库上,并删除old数据库
|
||||
# 对于arcaea_datebase.db,更新best_score,friend,recent30,user,user_world并用character数据更新user_char
|
||||
# 对于arcsong.db,更新songs
|
||||
if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile("database/arcaea_database.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcaea_database.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcaea_database.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
# user
|
||||
c1.execute('''select * from user''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from user where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into user values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25]})
|
||||
|
||||
# friend
|
||||
c1.execute('''select * from friend''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from friend where user_id_me=:a and user_id_other=:b)''', {'a': i[0], 'b': i[1]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into friend values(:a,:b)''', {
|
||||
'a': i[0], 'b': i[1]})
|
||||
|
||||
# best_score
|
||||
c1.execute('''select * from best_score''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute('''select exists(select * from best_score where user_id=:a and song_id=:b and difficulty=:c)''', {
|
||||
'a': i[0], 'b': i[1], 'c': i[2]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into best_score values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13]})
|
||||
|
||||
# recent30
|
||||
c1.execute('''select * from recent30''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from recent30 where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into recent30 values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27,:a28,:a29,:a30,:a31,:a32,:a33,:a34,:a35,:a36,:a37,:a38,:a39,:a40,:a41,:a42,:a43,:a44,:a45,:a46,:a47,:a48,:a49,:a50,:a51,:a52,:a53,:a54,:a55,:a56,:a57,:a58,:a59,:a60)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[
|
||||
18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27], 'a28': i[28], 'a29': i[29], 'a30': i[30], 'a31': i[31], 'a32': i[32], 'a33': i[33], 'a34': i[34], 'a35': i[35], 'a36': i[36], 'a37': i[37], 'a38': i[38], 'a39': i[39], 'a40': i[40], 'a41': i[41], 'a42': i[42], 'a43': i[43], 'a44': i[44], 'a45': i[45], 'a46': i[46], 'a47': i[47], 'a48': i[48], 'a49': i[49], 'a50': i[50], 'a51': i[51], 'a52': i[52], 'a53': i[53], 'a54': i[54], 'a55': i[55], 'a56': i[56], 'a57': i[57], 'a58': i[58], 'a59': i[59], 'a60': i[60]})
|
||||
|
||||
# user_world
|
||||
c1.execute('''select * from user_world''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from user_world where user_id=:a and map_id=:b)''', {'a': i[0], 'b': i[1]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into user_world values(:a0,:a1,:a2,:a3,:a4)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4]})
|
||||
|
||||
update_user_char(c2)
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcaea_database.db')
|
||||
|
||||
# songs
|
||||
if os.path.isfile("database/old_arcsong.db") and os.path.isfile("database/arcsong.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcsong.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcsong.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
c1.execute('''select * from songs''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into songs values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[
|
||||
8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27]})
|
||||
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcsong.db')
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
|
||||
def update_user_char(c):
|
||||
# 用character数据更新user_char
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
c.execute('''select user_id from user''')
|
||||
y = c.fetchall()
|
||||
if x and y:
|
||||
for j in y:
|
||||
for i in x:
|
||||
c.execute('''delete from user_char where user_id=:a and character_id=:b''', {
|
||||
'a': j[0], 'b': i[0]})
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': j[0], 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
|
||||
def update_database():
|
||||
# 将old数据库不存在数据加入到新数据库上,并删除old数据库
|
||||
# 对于arcaea_datebase.db,更新best_score,friend,recent30,user,user_world并用character数据更新user_char
|
||||
# 对于arcsong.db,更新songs
|
||||
if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile("database/arcaea_database.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcaea_database.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcaea_database.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
# user
|
||||
c1.execute('''select * from user''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from user where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into user values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25]})
|
||||
|
||||
# friend
|
||||
c1.execute('''select * from friend''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from friend where user_id_me=:a and user_id_other=:b)''', {'a': i[0], 'b': i[1]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into friend values(:a,:b)''', {
|
||||
'a': i[0], 'b': i[1]})
|
||||
|
||||
# best_score
|
||||
c1.execute('''select * from best_score''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute('''select exists(select * from best_score where user_id=:a and song_id=:b and difficulty=:c)''', {
|
||||
'a': i[0], 'b': i[1], 'c': i[2]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into best_score values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13]})
|
||||
|
||||
# recent30
|
||||
c1.execute('''select * from recent30''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from recent30 where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into recent30 values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27,:a28,:a29,:a30,:a31,:a32,:a33,:a34,:a35,:a36,:a37,:a38,:a39,:a40,:a41,:a42,:a43,:a44,:a45,:a46,:a47,:a48,:a49,:a50,:a51,:a52,:a53,:a54,:a55,:a56,:a57,:a58,:a59,:a60)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[
|
||||
18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27], 'a28': i[28], 'a29': i[29], 'a30': i[30], 'a31': i[31], 'a32': i[32], 'a33': i[33], 'a34': i[34], 'a35': i[35], 'a36': i[36], 'a37': i[37], 'a38': i[38], 'a39': i[39], 'a40': i[40], 'a41': i[41], 'a42': i[42], 'a43': i[43], 'a44': i[44], 'a45': i[45], 'a46': i[46], 'a47': i[47], 'a48': i[48], 'a49': i[49], 'a50': i[50], 'a51': i[51], 'a52': i[52], 'a53': i[53], 'a54': i[54], 'a55': i[55], 'a56': i[56], 'a57': i[57], 'a58': i[58], 'a59': i[59], 'a60': i[60]})
|
||||
|
||||
# user_world
|
||||
c1.execute('''select * from user_world''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from user_world where user_id=:a and map_id=:b)''', {'a': i[0], 'b': i[1]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into user_world values(:a0,:a1,:a2,:a3,:a4)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4]})
|
||||
|
||||
update_user_char(c2)
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcaea_database.db')
|
||||
|
||||
# songs
|
||||
if os.path.isfile("database/old_arcsong.db") and os.path.isfile("database/arcsong.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcsong.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcsong.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
c1.execute('''select * from songs''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into songs values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[
|
||||
8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27]})
|
||||
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcsong.db')
|
||||
@@ -1,104 +1,104 @@
|
||||
import time
|
||||
|
||||
|
||||
def get_user_score(c, user_id, limit=-1):
|
||||
# 返回用户的所有歌曲数据,带排名,返回字典列表
|
||||
if limit >= 0:
|
||||
c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b''',
|
||||
{'a': user_id, 'b': limit})
|
||||
else:
|
||||
c.execute(
|
||||
'''select * from best_score where user_id =:a order by rating DESC''', {'a': user_id})
|
||||
x = c.fetchall()
|
||||
r = []
|
||||
if x:
|
||||
rank = 0
|
||||
for i in x:
|
||||
rank += 1
|
||||
r.append({
|
||||
"song_id": i[1],
|
||||
"difficulty": i[2],
|
||||
"score": i[3],
|
||||
"shiny_perfect_count": i[4],
|
||||
"perfect_count": i[5],
|
||||
"near_count": i[6],
|
||||
"miss_count": i[7],
|
||||
"health": i[8],
|
||||
"modifier": i[9],
|
||||
"time_played": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(i[10])),
|
||||
"best_clear_type": i[11],
|
||||
"clear_type": i[12],
|
||||
"rating": i[13],
|
||||
"rank": rank
|
||||
})
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user(c, user_id):
|
||||
# 得到user表部分用户信息,返回字典
|
||||
c.execute('''select * from user where user_id = :a''', {'a': user_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x:
|
||||
join_date = None
|
||||
time_played = None
|
||||
if x[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[3])//1000))
|
||||
if x[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[20])//1000))
|
||||
|
||||
r = {'name': x[1],
|
||||
'user_id': user_id,
|
||||
'join_date': join_date,
|
||||
'user_code': x[4],
|
||||
'rating_ptt': x[5],
|
||||
'song_id': x[11],
|
||||
'difficulty': x[12],
|
||||
'score': x[13],
|
||||
'shiny_perfect_count': x[14],
|
||||
'perfect_count': x[15],
|
||||
'near_count': x[16],
|
||||
'miss_count': x[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': x[21],
|
||||
'rating': x[22]
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user_recent30(c, user_id):
|
||||
# 获取玩家recent30信息并计算这一部分的ptt,返回字典列表和一个值
|
||||
c.execute('''select * from recent30 where user_id=:a''', {'a': user_id})
|
||||
sumr = 0
|
||||
x = c.fetchone()
|
||||
r = []
|
||||
if x is not None:
|
||||
r30 = []
|
||||
s30 = []
|
||||
for i in range(1, 61, 2):
|
||||
if x[i] is not None:
|
||||
r30.append(float(x[i]))
|
||||
s30.append(x[i+1])
|
||||
else:
|
||||
r30.append(0)
|
||||
s30.append('')
|
||||
r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True)))
|
||||
songs = []
|
||||
i = 0
|
||||
while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None:
|
||||
if s30[i] not in songs:
|
||||
sumr += r30[i]
|
||||
songs.append(s30[i])
|
||||
i += 1
|
||||
for i in range(0, 30):
|
||||
if s30[i]:
|
||||
r.append({
|
||||
'song_id': s30[i][:-1],
|
||||
'difficulty': int(s30[i][-1]),
|
||||
'rating': r30[i]
|
||||
})
|
||||
return r, sumr / 10
|
||||
import time
|
||||
|
||||
|
||||
def get_user_score(c, user_id, limit=-1):
|
||||
# 返回用户的所有歌曲数据,带排名,返回字典列表
|
||||
if limit >= 0:
|
||||
c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b''',
|
||||
{'a': user_id, 'b': limit})
|
||||
else:
|
||||
c.execute(
|
||||
'''select * from best_score where user_id =:a order by rating DESC''', {'a': user_id})
|
||||
x = c.fetchall()
|
||||
r = []
|
||||
if x:
|
||||
rank = 0
|
||||
for i in x:
|
||||
rank += 1
|
||||
r.append({
|
||||
"song_id": i[1],
|
||||
"difficulty": i[2],
|
||||
"score": i[3],
|
||||
"shiny_perfect_count": i[4],
|
||||
"perfect_count": i[5],
|
||||
"near_count": i[6],
|
||||
"miss_count": i[7],
|
||||
"health": i[8],
|
||||
"modifier": i[9],
|
||||
"time_played": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(i[10])),
|
||||
"best_clear_type": i[11],
|
||||
"clear_type": i[12],
|
||||
"rating": i[13],
|
||||
"rank": rank
|
||||
})
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user(c, user_id):
|
||||
# 得到user表部分用户信息,返回字典
|
||||
c.execute('''select * from user where user_id = :a''', {'a': user_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x:
|
||||
join_date = None
|
||||
time_played = None
|
||||
if x[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[3])//1000))
|
||||
if x[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[20])//1000))
|
||||
|
||||
r = {'name': x[1],
|
||||
'user_id': user_id,
|
||||
'join_date': join_date,
|
||||
'user_code': x[4],
|
||||
'rating_ptt': x[5],
|
||||
'song_id': x[11],
|
||||
'difficulty': x[12],
|
||||
'score': x[13],
|
||||
'shiny_perfect_count': x[14],
|
||||
'perfect_count': x[15],
|
||||
'near_count': x[16],
|
||||
'miss_count': x[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': x[21],
|
||||
'rating': x[22]
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user_recent30(c, user_id):
|
||||
# 获取玩家recent30信息并计算这一部分的ptt,返回字典列表和一个值
|
||||
c.execute('''select * from recent30 where user_id=:a''', {'a': user_id})
|
||||
sumr = 0
|
||||
x = c.fetchone()
|
||||
r = []
|
||||
if x is not None:
|
||||
r30 = []
|
||||
s30 = []
|
||||
for i in range(1, 61, 2):
|
||||
if x[i] is not None:
|
||||
r30.append(float(x[i]))
|
||||
s30.append(x[i+1])
|
||||
else:
|
||||
r30.append(0)
|
||||
s30.append('')
|
||||
r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True)))
|
||||
songs = []
|
||||
i = 0
|
||||
while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None:
|
||||
if s30[i] not in songs:
|
||||
sumr += r30[i]
|
||||
songs.append(s30[i])
|
||||
i += 1
|
||||
for i in range(0, 30):
|
||||
if s30[i]:
|
||||
r.append({
|
||||
'song_id': s30[i][:-1],
|
||||
'difficulty': int(s30[i][-1]),
|
||||
'rating': r30[i]
|
||||
})
|
||||
return r, sumr / 10
|
||||
1242
v1.0/arcscore.py
1242
v1.0/arcscore.py
File diff suppressed because it is too large
Load Diff
141
v1.0/auth.py
141
v1.0/auth.py
@@ -1,141 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
|
||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
||||
'name': name, 'password': hash_pwd})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = str(x[0])
|
||||
now = int(time.time() * 1000)
|
||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||
|
||||
if c.fetchone() == (1,): # 删掉多余token
|
||||
c.execute('''delete from login where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_register(name: str, password: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
# 生成9位的user_code,用的自然是随机
|
||||
import random
|
||||
flag = True
|
||||
while flag:
|
||||
user_code = ''.join([str(random.randint(0, 9)) for i in range(9)])
|
||||
c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if c.fetchone() == (0,):
|
||||
flag = False
|
||||
return user_code
|
||||
|
||||
def build_user_id(c):
|
||||
# 生成user_id,往后加1
|
||||
c.execute('''select max(user_id) from user''')
|
||||
x = c.fetchone()
|
||||
if x[0] is not None:
|
||||
return x[0] + 1
|
||||
else:
|
||||
return 2000001
|
||||
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36]:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return user_id, token, 0
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None, None, 101
|
||||
|
||||
|
||||
def token_get_id(token: str):
|
||||
# 用token获取id,没有考虑不同用户token相同情况,说不定会有bug
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from login where access_token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def code_get_id(user_code):
|
||||
# 用user_code获取id
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from user where user_code = :a''',
|
||||
{'a': user_code})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,204 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists user(user_id int primary key,
|
||||
name text unique,
|
||||
password text not null,
|
||||
join_date char(20),
|
||||
user_code char(10),
|
||||
rating_ptt int,
|
||||
character_id int,
|
||||
is_skill_sealed int,
|
||||
is_char_uncapped int,
|
||||
is_char_uncapped_override int,
|
||||
is_hide_rating int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
favorite_character int,
|
||||
max_stamina_notification_enabled int
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
last_login_time int,
|
||||
last_login_ip text,
|
||||
last_login_device text
|
||||
);''')
|
||||
c.execute('''create table if not exists friend(user_id_me int,
|
||||
user_id_other int,
|
||||
primary key (user_id_me, user_id_other)
|
||||
);''')
|
||||
c.execute('''create table if not exists best_score(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
best_clear_type int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_char(user_id int,
|
||||
character_id int,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag int,
|
||||
prog int,
|
||||
overdrive int,
|
||||
skill_id text,
|
||||
skill_unlock_level int,
|
||||
skill_requires_uncap int,
|
||||
skill_id_uncap text,
|
||||
char_type int,
|
||||
is_uncapped int,
|
||||
is_uncapped_override int,
|
||||
primary key(user_id, character_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists character(character_id int primary key,
|
||||
name text
|
||||
);''')
|
||||
c.execute('''create table if not exists recent30(user_id int primary key,
|
||||
r0 real,
|
||||
song_id0 text,
|
||||
r1 real,
|
||||
song_id1 text,
|
||||
r2 real,
|
||||
song_id2 text,
|
||||
r3 real,
|
||||
song_id3 text,
|
||||
r4 real,
|
||||
song_id4 text,
|
||||
r5 real,
|
||||
song_id5 text,
|
||||
r6 real,
|
||||
song_id6 text,
|
||||
r7 real,
|
||||
song_id7 text,
|
||||
r8 real,
|
||||
song_id8 text,
|
||||
r9 real,
|
||||
song_id9 text,
|
||||
r10 real,
|
||||
song_id10 text,
|
||||
r11 real,
|
||||
song_id11 text,
|
||||
r12 real,
|
||||
song_id12 text,
|
||||
r13 real,
|
||||
song_id13 text,
|
||||
r14 real,
|
||||
song_id14 text,
|
||||
r15 real,
|
||||
song_id15 text,
|
||||
r16 real,
|
||||
song_id16 text,
|
||||
r17 real,
|
||||
song_id17 text,
|
||||
r18 real,
|
||||
song_id18 text,
|
||||
r19 real,
|
||||
song_id19 text,
|
||||
r20 real,
|
||||
song_id20 text,
|
||||
r21 real,
|
||||
song_id21 text,
|
||||
r22 real,
|
||||
song_id22 text,
|
||||
r23 real,
|
||||
song_id23 text,
|
||||
r24 real,
|
||||
song_id24 text,
|
||||
r25 real,
|
||||
song_id25 text,
|
||||
r26 real,
|
||||
song_id26 text,
|
||||
r27 real,
|
||||
song_id27 text,
|
||||
r28 real,
|
||||
song_id28 text,
|
||||
r29 real,
|
||||
song_id29 text
|
||||
);''')
|
||||
|
||||
char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)'
|
||||
,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna'
|
||||
,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)'
|
||||
,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin'
|
||||
,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C'
|
||||
,'Tairitsu(Tempest)','Brillante','Ilith(Summer)']
|
||||
|
||||
for i in range(0, 38):
|
||||
c.execute("insert into character values("+str(i)+",'"+char[i]+"');")
|
||||
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
|
||||
def insert_user_char(c, user_id):
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36]:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200000,3,3,10.8)''')
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
4060
v1.0/info.py
4060
v1.0/info.py
File diff suppressed because it is too large
Load Diff
418
v1.0/main.py
418
v1.0/main.py
@@ -1,418 +0,0 @@
|
||||
from flask import Flask, request, jsonify, make_response
|
||||
import configparser
|
||||
import base64
|
||||
import auth
|
||||
import info
|
||||
import setme
|
||||
import arcscore
|
||||
|
||||
app = Flask(__name__)
|
||||
wsgi_app = app.wsgi_app
|
||||
|
||||
|
||||
def error_return(error_code): # 错误返回
|
||||
# 100 无法在此ip地址下登录游戏
|
||||
# 101 用户名占用
|
||||
# 102 电子邮箱已注册
|
||||
# 103 已有一个账号由此设备创建
|
||||
# 104 用户名密码错误
|
||||
# 105 24小时内登入两台设备
|
||||
# 106 账户冻结
|
||||
# 107 你没有足够的体力
|
||||
# 401 用户不存在
|
||||
# 403 无法连接至服务器
|
||||
# 501 502 此物品目前无法获取
|
||||
# 504 无效的序列码
|
||||
# 505 此序列码已被使用
|
||||
# 506 你已拥有了此物品
|
||||
# 601 好友列表已满
|
||||
# 602 此用户已是好友
|
||||
# 604 你不能加自己为好友
|
||||
# 其它 发生未知错误
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error_code": error_code
|
||||
})
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
|
||||
@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口
|
||||
def login():
|
||||
headers = request.headers
|
||||
id_pwd = headers['Authorization']
|
||||
id_pwd = base64.b64decode(id_pwd[6:]).decode()
|
||||
name, password = id_pwd.split(':', 1)
|
||||
|
||||
try:
|
||||
token = auth.arc_login(name, password)
|
||||
if token is not None:
|
||||
r = {"success": True, "token_type": "Bearer"}
|
||||
r['access_token'] = token
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(104) # 用户名或密码错误
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/', methods=['POST']) # 注册接口
|
||||
def register():
|
||||
name = request.form['name']
|
||||
password = request.form['password']
|
||||
try:
|
||||
user_id, token, error_code = auth.arc_register(name, password)
|
||||
if user_id is not None:
|
||||
r = {"success": True, "value": {
|
||||
'user_id': user_id, 'access_token': token}}
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取
|
||||
def aggregate():
|
||||
calls = request.args.get('calls')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种
|
||||
r = info.arc_aggregate_small(user_id)
|
||||
else:
|
||||
r = info.arc_aggregate_big(user_id)
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换
|
||||
def character_change():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
character_id = request.form['character']
|
||||
skill_sealed = request.form['skill_sealed']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
flag = setme.change_char(user_id, character_id, skill_sealed)
|
||||
if flag:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": character_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
||||
def character_uncap(path):
|
||||
character_id = int(path[22:])
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = setme.change_char_uncap(user_id, character_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": [r]
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友
|
||||
def add_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_code = request.form['friend_code']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
friend_id = auth.code_get_id(friend_code)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = setme.arc_add_friend(user_id, friend_id)
|
||||
if r is not None and r != 602 and r != 604:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
if r is not None:
|
||||
return error_return(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友
|
||||
def delete_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_id = int(request.form['friend_id'])
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = setme.arc_delete_friend(user_id, friend_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
||||
def song_score_friend():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_friend(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
||||
def song_score_me():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_me(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['GET']) # TOP20
|
||||
def song_score_top():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_top(song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传
|
||||
def song_score_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
song_id = request.form['song_id']
|
||||
difficulty = int(request.form['difficulty'])
|
||||
score = int(request.form['score'])
|
||||
shiny_perfect_count = int(request.form['shiny_perfect_count'])
|
||||
perfect_count = int(request.form['perfect_count'])
|
||||
near_count = int(request.form['near_count'])
|
||||
miss_count = int(request.form['miss_count'])
|
||||
health = int(request.form['health'])
|
||||
modifier = int(request.form['modifier'])
|
||||
beyond_gauge = int(request.form['beyond_gauge'])
|
||||
clear_type = int(request.form['clear_type'])
|
||||
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count,
|
||||
perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {"user_rating": r}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
||||
def score_token():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"token": "1145141919810"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步
|
||||
def cloud_get():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_all_get(user_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步
|
||||
def cloud_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
scores_data = request.form['scores_data']
|
||||
clearlamps_data = request.form['clearlamps_data']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
arcscore.arc_all_post(user_id, scores_data, clearlamps_data)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用
|
||||
def redeem():
|
||||
return error_return(504)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
||||
def sys_set(path):
|
||||
set_arg = path[10:]
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
value = request.form['value']
|
||||
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
setme.arc_sys_set(user_id, value, set_arg)
|
||||
r = info.arc_aggregate_small(user_id)
|
||||
r['value'] = r['value'][0]['value']
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
def main():
|
||||
config = configparser.ConfigParser()
|
||||
path = r'setting.ini'
|
||||
config.read(path, encoding="utf-8")
|
||||
HOST = config.get('CONFIG','HOST')
|
||||
PORT = config.get('CONFIG','PORT')
|
||||
app.run(HOST, PORT)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
## Made By Lost 2020.9.11
|
||||
155
v1.0/setme.py
155
v1.0/setme.py
@@ -1,155 +0,0 @@
|
||||
import sqlite3
|
||||
import info
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def change_char(user_id, character_id, skill_sealed):
|
||||
# 角色改变,包括技能封印的改变,返回成功与否的布尔值
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if skill_sealed == 'false':
|
||||
skill_sealed = False
|
||||
else:
|
||||
skill_sealed = True
|
||||
c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
|
||||
'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
|
||||
def change_char_uncap(user_id, character_id):
|
||||
# 角色觉醒改变,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x is not None and x[0] == 1:
|
||||
c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id})
|
||||
c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id})
|
||||
c.execute('''select * from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
y = c.fetchone()
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': y[1]})
|
||||
z = c.fetchone()
|
||||
if z is not None:
|
||||
char_name = z[0]
|
||||
if y is not None:
|
||||
r = {
|
||||
"is_uncapped_override": int2b(y[14]),
|
||||
"is_uncapped": int2b(y[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": y[12],
|
||||
"skill_id_uncap": y[11],
|
||||
"skill_requires_uncap": int2b(y[10]),
|
||||
"skill_unlock_level": y[9],
|
||||
"skill_id": y[8],
|
||||
"overdrive": y[7],
|
||||
"prog": y[6],
|
||||
"frag": y[5],
|
||||
"level_exp": y[4],
|
||||
"exp": y[3],
|
||||
"level": y[2],
|
||||
"name": char_name,
|
||||
"character_id": y[1]
|
||||
}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_sys_set(user_id, value, set_arg):
|
||||
# 三个设置,PTT隐藏、体力满通知、最爱角色,无返回
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if 'favorite_character' in set_arg:
|
||||
value = int(value)
|
||||
c.execute('''update user set favorite_character = :a where user_id = :b''', {
|
||||
'a': value, 'b': user_id})
|
||||
|
||||
else:
|
||||
if value == 'false':
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
|
||||
if 'is_hide_rating' in set_arg:
|
||||
c.execute('''update user set is_hide_rating = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
if 'max_stamina_notification_enabled' in set_arg:
|
||||
c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_add_friend(user_id, friend_id):
|
||||
# 加好友,返回好友列表,或者是错误码602、604
|
||||
if user_id == friend_id:
|
||||
return 604
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into friend values(:a, :b)''',
|
||||
{'a': user_id, 'b': friend_id})
|
||||
r = info.get_user_friend(c, user_id)
|
||||
|
||||
else:
|
||||
return 602
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_delete_friend(user_id, friend_id):
|
||||
# 删好友,返回好友列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
|
||||
r = info.get_user_friend(c, user_id)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
@@ -1,3 +0,0 @@
|
||||
[CONFIG]
|
||||
HOST = 192.168.1.112
|
||||
PORT = 80
|
||||
1242
v1.1/arcscore.py
1242
v1.1/arcscore.py
File diff suppressed because it is too large
Load Diff
141
v1.1/auth.py
141
v1.1/auth.py
@@ -1,141 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
|
||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
||||
'name': name, 'password': hash_pwd})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = str(x[0])
|
||||
now = int(time.time() * 1000)
|
||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||
|
||||
if c.fetchone() == (1,): # 删掉多余token
|
||||
c.execute('''delete from login where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_register(name: str, password: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
# 生成9位的user_code,用的自然是随机
|
||||
import random
|
||||
flag = True
|
||||
while flag:
|
||||
user_code = ''.join([str(random.randint(0, 9)) for i in range(9)])
|
||||
c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if c.fetchone() == (0,):
|
||||
flag = False
|
||||
return user_code
|
||||
|
||||
def build_user_id(c):
|
||||
# 生成user_id,往后加1
|
||||
c.execute('''select max(user_id) from user''')
|
||||
x = c.fetchone()
|
||||
if x[0] is not None:
|
||||
return x[0] + 1
|
||||
else:
|
||||
return 2000001
|
||||
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return user_id, token, 0
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None, None, 101
|
||||
|
||||
|
||||
def token_get_id(token: str):
|
||||
# 用token获取id,没有考虑不同用户token相同情况,说不定会有bug
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from login where access_token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def code_get_id(user_code):
|
||||
# 用user_code获取id
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from user where user_code = :a''',
|
||||
{'a': user_code})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,204 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists user(user_id int primary key,
|
||||
name text unique,
|
||||
password text not null,
|
||||
join_date char(20),
|
||||
user_code char(10),
|
||||
rating_ptt int,
|
||||
character_id int,
|
||||
is_skill_sealed int,
|
||||
is_char_uncapped int,
|
||||
is_char_uncapped_override int,
|
||||
is_hide_rating int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
favorite_character int,
|
||||
max_stamina_notification_enabled int
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
last_login_time int,
|
||||
last_login_ip text,
|
||||
last_login_device text
|
||||
);''')
|
||||
c.execute('''create table if not exists friend(user_id_me int,
|
||||
user_id_other int,
|
||||
primary key (user_id_me, user_id_other)
|
||||
);''')
|
||||
c.execute('''create table if not exists best_score(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
best_clear_type int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_char(user_id int,
|
||||
character_id int,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag int,
|
||||
prog int,
|
||||
overdrive int,
|
||||
skill_id text,
|
||||
skill_unlock_level int,
|
||||
skill_requires_uncap int,
|
||||
skill_id_uncap text,
|
||||
char_type int,
|
||||
is_uncapped int,
|
||||
is_uncapped_override int,
|
||||
primary key(user_id, character_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists character(character_id int primary key,
|
||||
name text
|
||||
);''')
|
||||
c.execute('''create table if not exists recent30(user_id int primary key,
|
||||
r0 real,
|
||||
song_id0 text,
|
||||
r1 real,
|
||||
song_id1 text,
|
||||
r2 real,
|
||||
song_id2 text,
|
||||
r3 real,
|
||||
song_id3 text,
|
||||
r4 real,
|
||||
song_id4 text,
|
||||
r5 real,
|
||||
song_id5 text,
|
||||
r6 real,
|
||||
song_id6 text,
|
||||
r7 real,
|
||||
song_id7 text,
|
||||
r8 real,
|
||||
song_id8 text,
|
||||
r9 real,
|
||||
song_id9 text,
|
||||
r10 real,
|
||||
song_id10 text,
|
||||
r11 real,
|
||||
song_id11 text,
|
||||
r12 real,
|
||||
song_id12 text,
|
||||
r13 real,
|
||||
song_id13 text,
|
||||
r14 real,
|
||||
song_id14 text,
|
||||
r15 real,
|
||||
song_id15 text,
|
||||
r16 real,
|
||||
song_id16 text,
|
||||
r17 real,
|
||||
song_id17 text,
|
||||
r18 real,
|
||||
song_id18 text,
|
||||
r19 real,
|
||||
song_id19 text,
|
||||
r20 real,
|
||||
song_id20 text,
|
||||
r21 real,
|
||||
song_id21 text,
|
||||
r22 real,
|
||||
song_id22 text,
|
||||
r23 real,
|
||||
song_id23 text,
|
||||
r24 real,
|
||||
song_id24 text,
|
||||
r25 real,
|
||||
song_id25 text,
|
||||
r26 real,
|
||||
song_id26 text,
|
||||
r27 real,
|
||||
song_id27 text,
|
||||
r28 real,
|
||||
song_id28 text,
|
||||
r29 real,
|
||||
song_id29 text
|
||||
);''')
|
||||
|
||||
char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)'
|
||||
,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna'
|
||||
,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)'
|
||||
,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin'
|
||||
,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C'
|
||||
,'Tairitsu(Tempest)','Brillante','Ilith(Summer)']
|
||||
|
||||
for i in range(0, 38):
|
||||
c.execute("insert into character values("+str(i)+",'"+char[i]+"');")
|
||||
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
|
||||
def insert_user_char(c, user_id):
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200000,3,3,10.8)''')
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
4060
v1.1/info.py
4060
v1.1/info.py
File diff suppressed because it is too large
Load Diff
418
v1.1/main.py
418
v1.1/main.py
@@ -1,418 +0,0 @@
|
||||
from flask import Flask, request, jsonify, make_response
|
||||
import configparser
|
||||
import base64
|
||||
import auth
|
||||
import info
|
||||
import setme
|
||||
import arcscore
|
||||
|
||||
app = Flask(__name__)
|
||||
wsgi_app = app.wsgi_app
|
||||
|
||||
|
||||
def error_return(error_code): # 错误返回
|
||||
# 100 无法在此ip地址下登录游戏
|
||||
# 101 用户名占用
|
||||
# 102 电子邮箱已注册
|
||||
# 103 已有一个账号由此设备创建
|
||||
# 104 用户名密码错误
|
||||
# 105 24小时内登入两台设备
|
||||
# 106 账户冻结
|
||||
# 107 你没有足够的体力
|
||||
# 401 用户不存在
|
||||
# 403 无法连接至服务器
|
||||
# 501 502 此物品目前无法获取
|
||||
# 504 无效的序列码
|
||||
# 505 此序列码已被使用
|
||||
# 506 你已拥有了此物品
|
||||
# 601 好友列表已满
|
||||
# 602 此用户已是好友
|
||||
# 604 你不能加自己为好友
|
||||
# 其它 发生未知错误
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error_code": error_code
|
||||
})
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
|
||||
@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口
|
||||
def login():
|
||||
headers = request.headers
|
||||
id_pwd = headers['Authorization']
|
||||
id_pwd = base64.b64decode(id_pwd[6:]).decode()
|
||||
name, password = id_pwd.split(':', 1)
|
||||
|
||||
try:
|
||||
token = auth.arc_login(name, password)
|
||||
if token is not None:
|
||||
r = {"success": True, "token_type": "Bearer"}
|
||||
r['access_token'] = token
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(104) # 用户名或密码错误
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/', methods=['POST']) # 注册接口
|
||||
def register():
|
||||
name = request.form['name']
|
||||
password = request.form['password']
|
||||
try:
|
||||
user_id, token, error_code = auth.arc_register(name, password)
|
||||
if user_id is not None:
|
||||
r = {"success": True, "value": {
|
||||
'user_id': user_id, 'access_token': token}}
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取
|
||||
def aggregate():
|
||||
calls = request.args.get('calls')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种
|
||||
r = info.arc_aggregate_small(user_id)
|
||||
else:
|
||||
r = info.arc_aggregate_big(user_id)
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换
|
||||
def character_change():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
character_id = request.form['character']
|
||||
skill_sealed = request.form['skill_sealed']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
flag = setme.change_char(user_id, character_id, skill_sealed)
|
||||
if flag:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": character_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
||||
def character_uncap(path):
|
||||
character_id = int(path[22:])
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = setme.change_char_uncap(user_id, character_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": [r]
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友
|
||||
def add_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_code = request.form['friend_code']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
friend_id = auth.code_get_id(friend_code)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = setme.arc_add_friend(user_id, friend_id)
|
||||
if r is not None and r != 602 and r != 604:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
if r is not None:
|
||||
return error_return(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友
|
||||
def delete_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_id = int(request.form['friend_id'])
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = setme.arc_delete_friend(user_id, friend_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
||||
def song_score_friend():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_friend(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
||||
def song_score_me():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_me(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['GET']) # TOP20
|
||||
def song_score_top():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_top(song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传
|
||||
def song_score_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
song_id = request.form['song_id']
|
||||
difficulty = int(request.form['difficulty'])
|
||||
score = int(request.form['score'])
|
||||
shiny_perfect_count = int(request.form['shiny_perfect_count'])
|
||||
perfect_count = int(request.form['perfect_count'])
|
||||
near_count = int(request.form['near_count'])
|
||||
miss_count = int(request.form['miss_count'])
|
||||
health = int(request.form['health'])
|
||||
modifier = int(request.form['modifier'])
|
||||
beyond_gauge = int(request.form['beyond_gauge'])
|
||||
clear_type = int(request.form['clear_type'])
|
||||
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count,
|
||||
perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {"user_rating": r}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
||||
def score_token():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"token": "1145141919810"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步
|
||||
def cloud_get():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = arcscore.arc_all_get(user_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步
|
||||
def cloud_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
scores_data = request.form['scores_data']
|
||||
clearlamps_data = request.form['clearlamps_data']
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
arcscore.arc_all_post(user_id, scores_data, clearlamps_data)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用
|
||||
def redeem():
|
||||
return error_return(504)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
||||
def sys_set(path):
|
||||
set_arg = path[10:]
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
value = request.form['value']
|
||||
|
||||
try:
|
||||
user_id = auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
setme.arc_sys_set(user_id, value, set_arg)
|
||||
r = info.arc_aggregate_small(user_id)
|
||||
r['value'] = r['value'][0]['value']
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
def main():
|
||||
config = configparser.ConfigParser()
|
||||
path = r'setting.ini'
|
||||
config.read(path, encoding="utf-8")
|
||||
HOST = config.get('CONFIG','HOST')
|
||||
PORT = config.get('CONFIG','PORT')
|
||||
app.run(HOST, PORT)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
## Made By Lost 2020.9.11
|
||||
@@ -1 +0,0 @@
|
||||
python main.py
|
||||
155
v1.1/setme.py
155
v1.1/setme.py
@@ -1,155 +0,0 @@
|
||||
import sqlite3
|
||||
import info
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def change_char(user_id, character_id, skill_sealed):
|
||||
# 角色改变,包括技能封印的改变,返回成功与否的布尔值
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if skill_sealed == 'false':
|
||||
skill_sealed = False
|
||||
else:
|
||||
skill_sealed = True
|
||||
c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
|
||||
'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
|
||||
def change_char_uncap(user_id, character_id):
|
||||
# 角色觉醒改变,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x is not None and x[0] == 1:
|
||||
c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id})
|
||||
c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id})
|
||||
c.execute('''select * from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
y = c.fetchone()
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': y[1]})
|
||||
z = c.fetchone()
|
||||
if z is not None:
|
||||
char_name = z[0]
|
||||
if y is not None:
|
||||
r = {
|
||||
"is_uncapped_override": int2b(y[14]),
|
||||
"is_uncapped": int2b(y[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": y[12],
|
||||
"skill_id_uncap": y[11],
|
||||
"skill_requires_uncap": int2b(y[10]),
|
||||
"skill_unlock_level": y[9],
|
||||
"skill_id": y[8],
|
||||
"overdrive": y[7],
|
||||
"prog": y[6],
|
||||
"frag": y[5],
|
||||
"level_exp": y[4],
|
||||
"exp": y[3],
|
||||
"level": y[2],
|
||||
"name": char_name,
|
||||
"character_id": y[1]
|
||||
}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_sys_set(user_id, value, set_arg):
|
||||
# 三个设置,PTT隐藏、体力满通知、最爱角色,无返回
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if 'favorite_character' in set_arg:
|
||||
value = int(value)
|
||||
c.execute('''update user set favorite_character = :a where user_id = :b''', {
|
||||
'a': value, 'b': user_id})
|
||||
|
||||
else:
|
||||
if value == 'false':
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
|
||||
if 'is_hide_rating' in set_arg:
|
||||
c.execute('''update user set is_hide_rating = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
if 'max_stamina_notification_enabled' in set_arg:
|
||||
c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_add_friend(user_id, friend_id):
|
||||
# 加好友,返回好友列表,或者是错误码602、604
|
||||
if user_id == friend_id:
|
||||
return 604
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into friend values(:a, :b)''',
|
||||
{'a': user_id, 'b': friend_id})
|
||||
r = info.get_user_friend(c, user_id)
|
||||
|
||||
else:
|
||||
return 602
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_delete_friend(user_id, friend_id):
|
||||
# 删好友,返回好友列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
|
||||
r = info.get_user_friend(c, user_id)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,233 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists user(user_id int primary key,
|
||||
name text unique,
|
||||
password text not null,
|
||||
join_date char(20),
|
||||
user_code char(10),
|
||||
rating_ptt int,
|
||||
character_id int,
|
||||
is_skill_sealed int,
|
||||
is_char_uncapped int,
|
||||
is_char_uncapped_override int,
|
||||
is_hide_rating int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
favorite_character int,
|
||||
max_stamina_notification_enabled int
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
last_login_time int,
|
||||
last_login_ip text,
|
||||
last_login_device text
|
||||
);''')
|
||||
c.execute('''create table if not exists friend(user_id_me int,
|
||||
user_id_other int,
|
||||
primary key (user_id_me, user_id_other)
|
||||
);''')
|
||||
c.execute('''create table if not exists best_score(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
score int,
|
||||
shiny_perfect_count int,
|
||||
perfect_count int,
|
||||
near_count int,
|
||||
miss_count int,
|
||||
health int,
|
||||
modifier int,
|
||||
time_played int,
|
||||
best_clear_type int,
|
||||
clear_type int,
|
||||
rating real,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_char(user_id int,
|
||||
character_id int,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag int,
|
||||
prog int,
|
||||
overdrive int,
|
||||
skill_id text,
|
||||
skill_unlock_level int,
|
||||
skill_requires_uncap int,
|
||||
skill_id_uncap text,
|
||||
char_type int,
|
||||
is_uncapped int,
|
||||
is_uncapped_override int,
|
||||
primary key(user_id, character_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists character(character_id int primary key,
|
||||
name text,
|
||||
level int,
|
||||
exp real,
|
||||
level_exp real,
|
||||
frag int,
|
||||
prog int,
|
||||
overdrive int,
|
||||
skill_id text,
|
||||
skill_unlock_level int,
|
||||
skill_requires_uncap int,
|
||||
skill_id_uncap text,
|
||||
char_type int,
|
||||
uncap_cores text,
|
||||
is_uncapped int,
|
||||
is_uncapped_override int
|
||||
);''')
|
||||
c.execute('''create table if not exists recent30(user_id int primary key,
|
||||
r0 real,
|
||||
song_id0 text,
|
||||
r1 real,
|
||||
song_id1 text,
|
||||
r2 real,
|
||||
song_id2 text,
|
||||
r3 real,
|
||||
song_id3 text,
|
||||
r4 real,
|
||||
song_id4 text,
|
||||
r5 real,
|
||||
song_id5 text,
|
||||
r6 real,
|
||||
song_id6 text,
|
||||
r7 real,
|
||||
song_id7 text,
|
||||
r8 real,
|
||||
song_id8 text,
|
||||
r9 real,
|
||||
song_id9 text,
|
||||
r10 real,
|
||||
song_id10 text,
|
||||
r11 real,
|
||||
song_id11 text,
|
||||
r12 real,
|
||||
song_id12 text,
|
||||
r13 real,
|
||||
song_id13 text,
|
||||
r14 real,
|
||||
song_id14 text,
|
||||
r15 real,
|
||||
song_id15 text,
|
||||
r16 real,
|
||||
song_id16 text,
|
||||
r17 real,
|
||||
song_id17 text,
|
||||
r18 real,
|
||||
song_id18 text,
|
||||
r19 real,
|
||||
song_id19 text,
|
||||
r20 real,
|
||||
song_id20 text,
|
||||
r21 real,
|
||||
song_id21 text,
|
||||
r22 real,
|
||||
song_id22 text,
|
||||
r23 real,
|
||||
song_id23 text,
|
||||
r24 real,
|
||||
song_id24 text,
|
||||
r25 real,
|
||||
song_id25 text,
|
||||
r26 real,
|
||||
song_id26 text,
|
||||
r27 real,
|
||||
song_id27 text,
|
||||
r28 real,
|
||||
song_id28 text,
|
||||
r29 real,
|
||||
song_id29 text
|
||||
);''')
|
||||
|
||||
char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)'
|
||||
,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna'
|
||||
,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)'
|
||||
,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin'
|
||||
,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C'
|
||||
,'Tairitsu(Tempest)','Brillante','Ilith(Summer)']
|
||||
|
||||
for i in range(0, 38):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',1,1)'''
|
||||
c.execute(sql)
|
||||
else:
|
||||
if i != 5:
|
||||
sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',0,0)'''
|
||||
c.execute(sql)
|
||||
|
||||
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
|
||||
## def insert_user_char(c, user_id):
|
||||
## for i in range(0, 38):
|
||||
## if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
## c.execute(sql)
|
||||
## else:
|
||||
## if i != 5:
|
||||
## sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
## c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
conn = sqlite3.connect('arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200,3,3,10.8)''')
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
425
v1.2/main.py
425
v1.2/main.py
@@ -1,425 +0,0 @@
|
||||
from flask import Flask, request, jsonify, make_response
|
||||
import configparser
|
||||
import base64
|
||||
import server.auth
|
||||
import server.info
|
||||
import server.setme
|
||||
import server.arcscore
|
||||
import web.login
|
||||
import web.index
|
||||
|
||||
app = Flask(__name__)
|
||||
wsgi_app = app.wsgi_app
|
||||
|
||||
|
||||
def error_return(error_code): # 错误返回
|
||||
# 100 无法在此ip地址下登录游戏
|
||||
# 101 用户名占用
|
||||
# 102 电子邮箱已注册
|
||||
# 103 已有一个账号由此设备创建
|
||||
# 104 用户名密码错误
|
||||
# 105 24小时内登入两台设备
|
||||
# 106 账户冻结
|
||||
# 107 你没有足够的体力
|
||||
# 401 用户不存在
|
||||
# 403 无法连接至服务器
|
||||
# 501 502 此物品目前无法获取
|
||||
# 504 无效的序列码
|
||||
# 505 此序列码已被使用
|
||||
# 506 你已拥有了此物品
|
||||
# 601 好友列表已满
|
||||
# 602 此用户已是好友
|
||||
# 604 你不能加自己为好友
|
||||
# 其它 发生未知错误
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error_code": error_code
|
||||
})
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
|
||||
@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口
|
||||
def login():
|
||||
headers = request.headers
|
||||
id_pwd = headers['Authorization']
|
||||
id_pwd = base64.b64decode(id_pwd[6:]).decode()
|
||||
name, password = id_pwd.split(':', 1)
|
||||
|
||||
try:
|
||||
token = server.auth.arc_login(name, password)
|
||||
if token is not None:
|
||||
r = {"success": True, "token_type": "Bearer"}
|
||||
r['access_token'] = token
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(104) # 用户名或密码错误
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/', methods=['POST']) # 注册接口
|
||||
def register():
|
||||
name = request.form['name']
|
||||
password = request.form['password']
|
||||
try:
|
||||
user_id, token, error_code = server.auth.arc_register(name, password)
|
||||
if user_id is not None:
|
||||
r = {"success": True, "value": {
|
||||
'user_id': user_id, 'access_token': token}}
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取
|
||||
def aggregate():
|
||||
calls = request.args.get('calls')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种
|
||||
r = server.info.arc_aggregate_small(user_id)
|
||||
else:
|
||||
r = server.info.arc_aggregate_big(user_id)
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换
|
||||
def character_change():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
character_id = request.form['character']
|
||||
skill_sealed = request.form['skill_sealed']
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
flag = server.setme.change_char(
|
||||
user_id, character_id, skill_sealed)
|
||||
if flag:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": character_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
||||
def character_uncap(path):
|
||||
character_id = int(path[22:])
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.setme.change_char_uncap(user_id, character_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"character": [r]
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友
|
||||
def add_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_code = request.form['friend_code']
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
friend_id = server.auth.code_get_id(friend_code)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = server.setme.arc_add_friend(user_id, friend_id)
|
||||
if r is not None and r != 602 and r != 604:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
if r is not None:
|
||||
return error_return(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友
|
||||
def delete_friend():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
friend_id = int(request.form['friend_id'])
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None and friend_id is not None:
|
||||
r = server.setme.arc_delete_friend(user_id, friend_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id,
|
||||
"updatedAt": "2020-09-07T07:32:12.740Z",
|
||||
"createdAt": "2020-09-06T10:05:18.471Z",
|
||||
"friends": r
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
if friend_id is None:
|
||||
return error_return(401)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
||||
def song_score_friend():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.arcscore.arc_score_friend(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
||||
def song_score_me():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.arcscore.arc_score_me(user_id, song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['GET']) # TOP20
|
||||
def song_score_top():
|
||||
song_id = request.args.get('song_id')
|
||||
difficulty = request.args.get('difficulty')
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.arcscore.arc_score_top(song_id, difficulty)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传
|
||||
def song_score_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
song_id = request.form['song_id']
|
||||
difficulty = int(request.form['difficulty'])
|
||||
score = int(request.form['score'])
|
||||
shiny_perfect_count = int(request.form['shiny_perfect_count'])
|
||||
perfect_count = int(request.form['perfect_count'])
|
||||
near_count = int(request.form['near_count'])
|
||||
miss_count = int(request.form['miss_count'])
|
||||
health = int(request.form['health'])
|
||||
modifier = int(request.form['modifier'])
|
||||
beyond_gauge = int(request.form['beyond_gauge'])
|
||||
clear_type = int(request.form['clear_type'])
|
||||
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count,
|
||||
perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {"user_rating": r}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
||||
def score_token():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"token": "1145141919810"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步
|
||||
def cloud_get():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
r = server.arcscore.arc_all_get(user_id)
|
||||
if r is not None:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": r
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步
|
||||
def cloud_post():
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
scores_data = request.form['scores_data']
|
||||
clearlamps_data = request.form['clearlamps_data']
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
server.arcscore.arc_all_post(user_id, scores_data, clearlamps_data)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"value": {
|
||||
"user_id": user_id
|
||||
}
|
||||
})
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用
|
||||
def redeem():
|
||||
return error_return(504)
|
||||
|
||||
|
||||
@app.route('/coffee/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
||||
def sys_set(path):
|
||||
set_arg = path[10:]
|
||||
headers = request.headers
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
value = request.form['value']
|
||||
|
||||
try:
|
||||
user_id = server.auth.token_get_id(token)
|
||||
if user_id is not None:
|
||||
server.setme.arc_sys_set(user_id, value, set_arg)
|
||||
r = server.info.arc_aggregate_small(user_id)
|
||||
r['value'] = r['value'][0]['value']
|
||||
return jsonify(r)
|
||||
else:
|
||||
return error_return(108)
|
||||
except:
|
||||
return error_return(108)
|
||||
|
||||
|
||||
def main():
|
||||
config = configparser.ConfigParser()
|
||||
path = r'setting.ini'
|
||||
config.read(path, encoding="utf-8")
|
||||
HOST = config.get('CONFIG', 'HOST')
|
||||
PORT = config.get('CONFIG', 'PORT')
|
||||
app.config.from_mapping(SECRET_KEY='1145141919810')
|
||||
app.register_blueprint(web.login.bp)
|
||||
app.register_blueprint(web.index.bp)
|
||||
|
||||
app.run(HOST, PORT)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
# Made By Lost 2020.9.11
|
||||
@@ -1 +0,0 @@
|
||||
python main.py
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +0,0 @@
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
|
||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
||||
'name': name, 'password': hash_pwd})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = str(x[0])
|
||||
now = int(time.time() * 1000)
|
||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||
|
||||
if c.fetchone() == (1,): # 删掉多余token
|
||||
c.execute('''delete from login where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return token
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_register(name: str, password: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
# 生成9位的user_code,用的自然是随机
|
||||
import random
|
||||
flag = True
|
||||
while flag:
|
||||
user_code = ''.join([str(random.randint(0, 9)) for i in range(9)])
|
||||
c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if c.fetchone() == (0,):
|
||||
flag = False
|
||||
return user_code
|
||||
|
||||
def build_user_id(c):
|
||||
# 生成user_id,往后加1
|
||||
c.execute('''select max(user_id) from user''')
|
||||
x = c.fetchone()
|
||||
if x[0] is not None:
|
||||
return x[0] + 1
|
||||
else:
|
||||
return 2000001
|
||||
|
||||
# def insert_user_char(c, user_id):
|
||||
# # 为用户添加所有可用角色
|
||||
# for i in range(0, 38):
|
||||
# if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)'''
|
||||
# c.execute(sql)
|
||||
# else:
|
||||
# if i != 5:
|
||||
# sql = 'insert into user_char values('+str(user_id)+','+str(
|
||||
# i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)'''
|
||||
# c.execute(sql)
|
||||
def insert_user_char(c, user_id):
|
||||
# 为用户添加所有可用角色
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
if x != []:
|
||||
for i in x:
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if c.fetchone() == (0,):
|
||||
user_code = build_user_code(c)
|
||||
user_id = build_user_id(c)
|
||||
now = int(time.time() * 1000)
|
||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||
'user_id': user_id, 'access_token': token})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return user_id, token, 0
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None, None, 101
|
||||
|
||||
|
||||
def token_get_id(token: str):
|
||||
# 用token获取id,没有考虑不同用户token相同情况,说不定会有bug
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from login where access_token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def code_get_id(user_code):
|
||||
# 用user_code获取id
|
||||
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select user_id from user where user_code = :a''',
|
||||
{'a': user_code})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return x[0]
|
||||
else:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
4060
v1.2/server/info.py
4060
v1.2/server/info.py
File diff suppressed because it is too large
Load Diff
@@ -1,155 +0,0 @@
|
||||
import sqlite3
|
||||
import server.info
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def change_char(user_id, character_id, skill_sealed):
|
||||
# 角色改变,包括技能封印的改变,返回成功与否的布尔值
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
if skill_sealed == 'false':
|
||||
skill_sealed = False
|
||||
else:
|
||||
skill_sealed = True
|
||||
c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
|
||||
'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
|
||||
def change_char_uncap(user_id, character_id):
|
||||
# 角色觉醒改变,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x is not None and x[0] == 1:
|
||||
c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id})
|
||||
c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', {
|
||||
'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id})
|
||||
c.execute('''select * from user_char where user_id = :a and character_id = :b''',
|
||||
{'a': user_id, 'b': character_id})
|
||||
y = c.fetchone()
|
||||
c.execute(
|
||||
'''select name from character where character_id = :x''', {'x': y[1]})
|
||||
z = c.fetchone()
|
||||
if z is not None:
|
||||
char_name = z[0]
|
||||
if y is not None:
|
||||
r = {
|
||||
"is_uncapped_override": int2b(y[14]),
|
||||
"is_uncapped": int2b(y[13]),
|
||||
"uncap_cores": [],
|
||||
"char_type": y[12],
|
||||
"skill_id_uncap": y[11],
|
||||
"skill_requires_uncap": int2b(y[10]),
|
||||
"skill_unlock_level": y[9],
|
||||
"skill_id": y[8],
|
||||
"overdrive": y[7],
|
||||
"prog": y[6],
|
||||
"frag": y[5],
|
||||
"level_exp": y[4],
|
||||
"exp": y[3],
|
||||
"level": y[2],
|
||||
"name": char_name,
|
||||
"character_id": y[1]
|
||||
}
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_sys_set(user_id, value, set_arg):
|
||||
# 三个设置,PTT隐藏、体力满通知、最爱角色,无返回
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if 'favorite_character' in set_arg:
|
||||
value = int(value)
|
||||
c.execute('''update user set favorite_character = :a where user_id = :b''', {
|
||||
'a': value, 'b': user_id})
|
||||
|
||||
else:
|
||||
if value == 'false':
|
||||
value = False
|
||||
else:
|
||||
value = True
|
||||
|
||||
if 'is_hide_rating' in set_arg:
|
||||
c.execute('''update user set is_hide_rating = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
if 'max_stamina_notification_enabled' in set_arg:
|
||||
c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', {
|
||||
'a': b2int(value), 'b': user_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
|
||||
def arc_add_friend(user_id, friend_id):
|
||||
# 加好友,返回好友列表,或者是错误码602、604
|
||||
if user_id == friend_id:
|
||||
return 604
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into friend values(:a, :b)''',
|
||||
{'a': user_id, 'b': friend_id})
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
else:
|
||||
return 602
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
|
||||
def arc_delete_friend(user_id, friend_id):
|
||||
# 删好友,返回好友列表
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
r = None
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
|
||||
{'x': user_id, 'y': friend_id})
|
||||
|
||||
r = server.info.get_user_friend(c, user_id)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return r
|
||||
@@ -1,3 +0,0 @@
|
||||
[CONFIG]
|
||||
HOST = 192.168.1.113
|
||||
PORT = 80
|
||||
@@ -1,81 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All players{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}
|
||||
{% for user in posts %}
|
||||
|
||||
<div id="user-info">
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,35 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Change the songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="/web/changesong/addsong" method="post">
|
||||
<div class="title">Add the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
<label for="name_en">English name of the song(Not important but neccessary)</label>
|
||||
<input name="name_en" id="name_en" required>
|
||||
|
||||
<label for="rating_pst">Past chart const</label>
|
||||
<input name="rating_pst" id="rating_pst" required>
|
||||
<label for="rating_prs">Present chart const</label>
|
||||
<input name="rating_prs" id="rating_prs" required>
|
||||
<label for="rating_ftr">Future chart const</label>
|
||||
<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">If there is no some chart, fill in -1 please.</div>
|
||||
<input type="submit" value="Add">
|
||||
</form>
|
||||
<br />
|
||||
<hr />
|
||||
<form action="/web/changesong/deletesong" method="post">
|
||||
<div class="title">Delete the song</div>
|
||||
<label for="sid">SID of the song</label>
|
||||
<input name="sid" id="sid" required>
|
||||
|
||||
<input type="submit" value="Delete">
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,24 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Index{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>说明 Statement</h1>
|
||||
<p>这是Arcaea Server的后台管理协助系统,可以进行一些简单的操作</br>
|
||||
This is the background management assistance system of Arcaea Server, which can be used to do some simple
|
||||
operations.
|
||||
</p>
|
||||
<h1>游戏方面 Game</h1>
|
||||
<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.single_chart_top') }}">单个铺面排行榜查询 Single song chart tops</a>
|
||||
<hr>
|
||||
<h1>系统方面 System</h1>
|
||||
<a href="{{ url_for('index.update_database') }}">数据库更新 Update databases</a></br></br>
|
||||
<a href="{{ url_for('index.change_song') }}">歌曲修改 Change the songs</a>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,191 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player ptt{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% if user %}
|
||||
<hr />
|
||||
|
||||
<div id="user-info">
|
||||
<div class="title">玩家信息 Player information</div>
|
||||
<div class="name">{{user['name']}}
|
||||
<span class="rank">UID: {{user['user_id']}}</span>
|
||||
<span class="rank">User code: {{user['user_code']}}</span>
|
||||
</div>
|
||||
<div class="join-date">注册于 Registered in: {{user['join_date']}}</div>
|
||||
<div class="ptt">PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}</div>
|
||||
<div class="ptt">Best 30 PTT: {{bestptt}}</div>
|
||||
<div class="ptt">Recent 10 PTT: {{recentptt}}</div>
|
||||
<div>
|
||||
<div>Recent plays: </div>
|
||||
<div>
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{user['song_id']}}
|
||||
</span>
|
||||
{% if user['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif user['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif user['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{user['perfect_count']}}</td>
|
||||
<td> {{'(' ~ user['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{user['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{user['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{user['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if user['clear_type'] == 3 %}Pure Memory
|
||||
{% elif user['clear_type'] == 2 %}Full Recall
|
||||
{% elif user['clear_type'] == 5 %}Hard Clear
|
||||
{% elif user['clear_type'] == 1 %}Normal Clear
|
||||
{% elif user['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{user['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{user['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{% if posts %}
|
||||
<div class="title">Best 30</div>
|
||||
{% endif %}
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr />
|
||||
|
||||
{% if recent %}
|
||||
<div class="title">Recent 30</div>
|
||||
{% set rank = 0 %}
|
||||
{% for i in recent %}
|
||||
{% if i %}
|
||||
{% set rank = rank + 1 %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{i['song_id']}}
|
||||
</span>
|
||||
{% if i['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif i['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif i['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{rank}}</span>
|
||||
<div class="song-rating">成绩评价 Rating: {{i['rating']}}</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,357 +0,0 @@
|
||||
from flask import (
|
||||
Blueprint, flash, g, redirect, render_template, request, url_for
|
||||
)
|
||||
from web.login import login_required
|
||||
from werkzeug.utils import secure_filename
|
||||
import sqlite3
|
||||
import web.webscore
|
||||
import web.system
|
||||
import time
|
||||
import server.arcscore
|
||||
import os
|
||||
|
||||
UPLOAD_FOLDER = 'database'
|
||||
ALLOWED_EXTENSIONS = {'db'}
|
||||
|
||||
bp = Blueprint('index', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
def is_number(s):
|
||||
try: # 判断字符串s是浮点数
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
@bp.route('/index')
|
||||
@bp.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
# 主页
|
||||
return render_template('web/index.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayer', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_score():
|
||||
# 单个玩家分数查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
posts = web.webscore.get_user_score(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayer.html', posts=posts)
|
||||
|
||||
return render_template('web/singleplayer.html')
|
||||
|
||||
|
||||
@bp.route('/singleplayerptt', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
def single_player_ptt():
|
||||
# 单个玩家PTT详情查询
|
||||
if request.method == 'POST':
|
||||
name = request.form['name']
|
||||
user_code = request.form['user_code']
|
||||
error = None
|
||||
if name or user_code:
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
if user_code:
|
||||
c.execute('''select user_id from user where user_code=:a''', {
|
||||
'a': user_code})
|
||||
else:
|
||||
c.execute(
|
||||
'''select user_id from user where name=:a''', {'a': name})
|
||||
|
||||
user_id = c.fetchone()
|
||||
posts = []
|
||||
if user_id:
|
||||
user_id = user_id[0]
|
||||
user = web.webscore.get_user(c, user_id)
|
||||
posts = web.webscore.get_user_score(c, user_id, 30)
|
||||
recent, recentptt = web.webscore.get_user_recent30(c, user_id)
|
||||
if not posts:
|
||||
error = '无成绩 No score.'
|
||||
else:
|
||||
bestptt = 0
|
||||
for i in posts:
|
||||
if i['rating']:
|
||||
bestptt += i['rating']
|
||||
bestptt = bestptt / 30
|
||||
else:
|
||||
error = '玩家不存在 The player does not exist.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
else:
|
||||
error = '输入为空 Null Input.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
return render_template('web/singleplayerptt.html', posts=posts, user=user, recent=recent, recentptt=recentptt, bestptt=bestptt)
|
||||
|
||||
return render_template('web/singleplayerptt.html')
|
||||
|
||||
|
||||
@bp.route('/allplayer', methods=['GET'])
|
||||
@login_required
|
||||
def all_player():
|
||||
# 所有玩家数据,按照ptt排序
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from user order by rating_ptt DESC''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
join_data = None
|
||||
time_played = None
|
||||
if i[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[3])//1000))
|
||||
if i[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(i[20])//1000))
|
||||
posts.append({'name': i[1],
|
||||
'user_id': i[0],
|
||||
'join_date': join_date,
|
||||
'user_code': i[4],
|
||||
'rating_ptt': i[5],
|
||||
'song_id': i[11],
|
||||
'difficulty': i[12],
|
||||
'score': i[13],
|
||||
'shiny_perfect_count': i[14],
|
||||
'perfect_count': i[15],
|
||||
'near_count': i[16],
|
||||
'miss_count': i[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': i[21],
|
||||
'rating': i[22]
|
||||
})
|
||||
else:
|
||||
error = '没有玩家数据 No player data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allplayer.html')
|
||||
else:
|
||||
return render_template('web/allplayer.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/allsong', methods=['GET'])
|
||||
@login_required
|
||||
def all_song():
|
||||
# 所有歌曲数据
|
||||
def defnum(x):
|
||||
# 定数转换
|
||||
if x >= 0:
|
||||
return x / 10
|
||||
else:
|
||||
return None
|
||||
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from songs''')
|
||||
x = c.fetchall()
|
||||
error = None
|
||||
if x:
|
||||
posts = []
|
||||
for i in x:
|
||||
posts.append({'song_id': i[0],
|
||||
'name_en': i[1],
|
||||
'rating_pst': defnum(i[12]),
|
||||
'rating_prs': defnum(i[13]),
|
||||
'rating_ftr': defnum(i[14]),
|
||||
'rating_byn': defnum(i[15])
|
||||
})
|
||||
else:
|
||||
error = '没有铺面数据 No song data.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
return render_template('web/allsong.html')
|
||||
else:
|
||||
return render_template('web/allsong.html', posts=posts)
|
||||
|
||||
|
||||
@bp.route('/singlecharttop', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def single_chart_top():
|
||||
# 歌曲排行榜
|
||||
if request.method == 'POST':
|
||||
song_name = request.form['sid']
|
||||
difficulty = request.form['difficulty']
|
||||
if difficulty.isdigit():
|
||||
difficulty = int(difficulty)
|
||||
error = None
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
song_name = '%'+song_name+'%'
|
||||
c.execute('''select sid, name_en from songs where sid like :a limit 1''',
|
||||
{'a': song_name})
|
||||
x = c.fetchone()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print(x)
|
||||
if x:
|
||||
song_id = x[0]
|
||||
posts = server.arcscore.arc_score_top(song_id, difficulty, -1)
|
||||
for i in posts:
|
||||
i['time_played'] = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(i['time_played']))
|
||||
else:
|
||||
error = '查询为空 No song.'
|
||||
|
||||
if not error:
|
||||
return render_template('web/singlecharttop.html', posts=posts, song_name_en=x[1], song_id=song_id, difficulty=difficulty)
|
||||
else:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/singlecharttop.html')
|
||||
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
@bp.route('/updatedatabase', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def update_database():
|
||||
# 更新数据库
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
if 'file' not in request.files:
|
||||
flash('无文件 No file part.')
|
||||
return redirect(request.url)
|
||||
file = request.files['file']
|
||||
if file.filename == '':
|
||||
flash('未选择文件 No selected file.')
|
||||
return redirect(request.url)
|
||||
|
||||
if file and allowed_file(file.filename):
|
||||
filename = 'old_' + secure_filename(file.filename)
|
||||
file.save(os.path.join(UPLOAD_FOLDER, filename))
|
||||
flash('上传成功 Success upload.')
|
||||
web.system.update_database()
|
||||
flash('数据更新成功 Success update data.')
|
||||
else:
|
||||
error = '上传失败 Upload error.'
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/changesong', methods=['GET'])
|
||||
@login_required
|
||||
def change_song():
|
||||
# 修改歌曲数据
|
||||
return render_template('web/changesong.html')
|
||||
|
||||
|
||||
@bp.route('/changesong/addsong', methods=['POST'])
|
||||
@login_required
|
||||
def add_song():
|
||||
# 添加歌曲数据
|
||||
def get_rating(x):
|
||||
# 换算定数
|
||||
if is_number(x):
|
||||
x = float(x)
|
||||
if x >= 0:
|
||||
return int(x*10)
|
||||
else:
|
||||
return -1
|
||||
else:
|
||||
return -1
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
name_en = request.form['name_en']
|
||||
rating_pst = get_rating(request.form['rating_pst'])
|
||||
rating_prs = get_rating(request.form['rating_prs'])
|
||||
rating_ftr = get_rating(request.form['rating_ftr'])
|
||||
rating_byd = get_rating(request.form['rating_byd'])
|
||||
if len(song_id) >= 256:
|
||||
song_id = song_id[:200]
|
||||
if len(name_en) >= 256:
|
||||
name_en = name_en[:200]
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (0,):
|
||||
c.execute('''insert into songs(sid,name_en,rating_pst,rating_prs,rating_ftr,rating_byn) values(:a,:b,:c,:d,:e,:f)''', {
|
||||
'a': song_id, 'b': name_en, 'c': rating_pst, 'd': rating_prs, 'e': rating_ftr, 'f': rating_byd})
|
||||
flash('歌曲添加成功 Successfully add the song.')
|
||||
else:
|
||||
error = '歌曲已存在 The song exists.'
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
|
||||
|
||||
@bp.route('/changesong/deletesong', methods=['POST'])
|
||||
@login_required
|
||||
def delete_song():
|
||||
# 删除歌曲数据
|
||||
|
||||
error = None
|
||||
song_id = request.form['sid']
|
||||
conn = sqlite3.connect('./database/arcsong.db')
|
||||
c = conn.cursor()
|
||||
c.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': song_id})
|
||||
if c.fetchone() == (1,):
|
||||
c.execute('''delete from songs where sid=:a''', {'a': song_id})
|
||||
flash('歌曲删除成功 Successfully delete the song.')
|
||||
else:
|
||||
error = "歌曲不存在 The song doesn't exist."
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if error:
|
||||
flash(error)
|
||||
|
||||
return redirect(url_for('index.change_song'))
|
||||
@@ -1,102 +0,0 @@
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
|
||||
def update_user_char(c):
|
||||
# 用character数据更新user_char
|
||||
c.execute('''select * from character''')
|
||||
x = c.fetchall()
|
||||
c.execute('''select user_id from user''')
|
||||
y = c.fetchall()
|
||||
if x and y:
|
||||
for j in y:
|
||||
for i in x:
|
||||
c.execute('''delete from user_char where user_id=:a and character_id=:b''', {
|
||||
'a': j[0], 'b': i[0]})
|
||||
c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', {
|
||||
'a': j[0], 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]})
|
||||
|
||||
|
||||
def update_database():
|
||||
# 将old数据库不存在数据加入到新数据库上,并删除old数据库
|
||||
# 对于arcaea_datebase.db,更新best_score,friend,recent30,user,并用character数据更新user_char
|
||||
# 对于arcsong.db,更新songs
|
||||
if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile("database/arcaea_database.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcaea_database.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcaea_database.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
# user
|
||||
c1.execute('''select * from user''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from user where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into user values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24]})
|
||||
|
||||
# friend
|
||||
c1.execute('''select * from friend''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from friend where user_id_me=:a and user_id_other=:b)''', {'a': i[0], 'b': i[1]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into friend values(:a,:b)''', {
|
||||
'a': i[0], 'b': i[1]})
|
||||
|
||||
# best_score
|
||||
c1.execute('''select * from best_score''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute('''select exists(select * from best_score where user_id=:a and song_id=:b and difficulty=:c)''', {
|
||||
'a': i[0], 'b': i[1], 'c': i[2]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into best_score values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13)''', {
|
||||
'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13]})
|
||||
|
||||
# recent30
|
||||
c1.execute('''select * from recent30''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from recent30 where user_id=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into recent30 values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27,:a28,:a29,:a30,:a31,:a32,:a33,:a34,:a35,:a36,:a37,:a38,:a39,:a40,:a41,:a42,:a43,:a44,:a45,:a46,:a47,:a48,:a49,:a50,:a51,:a52,:a53,:a54,:a55,:a56,:a57,:a58,:a59,:a60)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[
|
||||
18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27], 'a28': i[28], 'a29': i[29], 'a30': i[30], 'a31': i[31], 'a32': i[32], 'a33': i[33], 'a34': i[34], 'a35': i[35], 'a36': i[36], 'a37': i[37], 'a38': i[38], 'a39': i[39], 'a40': i[40], 'a41': i[41], 'a42': i[42], 'a43': i[43], 'a44': i[44], 'a45': i[45], 'a46': i[46], 'a47': i[47], 'a48': i[48], 'a49': i[49], 'a50': i[50], 'a51': i[51], 'a52': i[52], 'a53': i[53], 'a54': i[54], 'a55': i[55], 'a56': i[56], 'a57': i[57], 'a58': i[58], 'a59': i[59], 'a60': i[60]})
|
||||
|
||||
update_user_char(c2)
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcaea_database.db')
|
||||
|
||||
# songs
|
||||
if os.path.isfile("database/old_arcsong.db") and os.path.isfile("database/arcsong.db"):
|
||||
conn1 = sqlite3.connect('./database/old_arcsong.db')
|
||||
c1 = conn1.cursor()
|
||||
conn2 = sqlite3.connect('./database/arcsong.db')
|
||||
c2 = conn2.cursor()
|
||||
|
||||
c1.execute('''select * from songs''')
|
||||
x = c1.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
c2.execute(
|
||||
'''select exists(select * from songs where sid=:a)''', {'a': i[0]})
|
||||
if c2.fetchone() == (0,):
|
||||
c2.execute('''insert into songs values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[
|
||||
8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27]})
|
||||
|
||||
conn1.commit()
|
||||
conn1.close()
|
||||
conn2.commit()
|
||||
conn2.close()
|
||||
os.remove('database/old_arcsong.db')
|
||||
@@ -1 +0,0 @@
|
||||
python main.py
|
||||
@@ -1,3 +0,0 @@
|
||||
[CONFIG]
|
||||
HOST = 192.168.1.113
|
||||
PORT = 80
|
||||
@@ -1,217 +0,0 @@
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
background: #eee;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: serif;
|
||||
color: #377ba8;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #377ba8;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid lightgray;
|
||||
}
|
||||
|
||||
nav {
|
||||
background: lightgray;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
nav h1 {
|
||||
flex: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav h1 a {
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li a,
|
||||
nav ul li span,
|
||||
header .action {
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.content>header {
|
||||
border-bottom: 1px solid lightgray;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.content>header h1 {
|
||||
flex: auto;
|
||||
margin: 1rem 0 0.25rem 0;
|
||||
}
|
||||
|
||||
.flash {
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
background: #cae6f6;
|
||||
border: 1px solid #377ba8;
|
||||
}
|
||||
|
||||
.post>header {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.post>header>div:first-of-type {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.post>header h1 {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.post .about {
|
||||
color: slategray;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post .body {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.content:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.content form {
|
||||
margin: 1em 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.content input,
|
||||
.content textarea {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.content textarea {
|
||||
min-height: 12em;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
input.danger {
|
||||
color: #cc2f2e;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
align-self: start;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
|
||||
.score-item {
|
||||
margin-bottom: 10px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.song-title {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.difficulty_pst {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(10, 130, 190);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_prs {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(100, 140, 60);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_ftr {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(80, 25, 75);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.difficulty_byd {
|
||||
font-size: 0.9em;
|
||||
background-color: rgb(130, 35, 40);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.rank {
|
||||
font-size: 0.8em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.rank_big {
|
||||
font-size: 1.2em;
|
||||
margin-left: 4px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.song-detail {
|
||||
font-size: 0.8em;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.song-score {
|
||||
font-size: 1.375em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.song-clear-type {
|
||||
font-size: 0.875em;
|
||||
padding-left: 0.625em;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.375em;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 1.12em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.footer{
|
||||
font-size: 0.5em;
|
||||
color: grey;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<!doctype html>
|
||||
<title>{% block title %}{% endblock %} - Arcaea Server</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<nav>
|
||||
<h1>Arcaea Server</h1>
|
||||
<ul>
|
||||
{% if g.user %}
|
||||
<li><span>{{ g.user['username'] }}</span>
|
||||
<li><a href="{{ url_for('index.index') }}">Home</a>
|
||||
<li><a href="{{ url_for('login.logout') }}">Log Out</a> {% else %}
|
||||
<li><a href="{{ url_for('login.login') }}">Log In</a> {% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="content">
|
||||
<header>
|
||||
{% block header %}{% endblock %}
|
||||
</header>
|
||||
{% for message in get_flashed_messages() %}
|
||||
<div class="flash">{{ message }}</div>
|
||||
{% endfor %} {% block content %}{% endblock %}
|
||||
</section>
|
||||
|
||||
<footer id="footer" class="footer">Made by Lost@2020</footer>
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}All songs{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if posts %}<br />
|
||||
{% for song in posts %}
|
||||
|
||||
<div class="score-item">
|
||||
<span>Sid: </span>
|
||||
<span class="song-title">{{song['song_id']}}</span>
|
||||
<br />
|
||||
<span>Name_en: </span>
|
||||
<span class="song-title">{{song['name_en']}}</span>
|
||||
<br />
|
||||
<div>铺面定数 Chart const: </div>
|
||||
{% if song['rating_pst'] %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
<span class="song-rating">{{song['rating_pst']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_prs'] %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
<span class="song-rating">{{song['rating_prs']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_ftr'] %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
<span class="song-rating">{{song['rating_ftr']}}</span>
|
||||
{% endif %}
|
||||
<br />
|
||||
{% if song['rating_byn'] %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
<span class="song-rating">{{song['rating_byn']}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<br />
|
||||
<hr />
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -1,14 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Log In{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="username">Username</label>
|
||||
<input name="username" id="username" required>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" required>
|
||||
<input type="submit" value="Log In">
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,108 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single chart top{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="sid">SID of the song</label>
|
||||
<span>模糊查询,只返回第一个</span>
|
||||
<span>Fuzzy query,and only return the first one.</span>
|
||||
<input name="sid" id="sid">
|
||||
<label for="difficulty">Difficulty</label>
|
||||
<select name='difficulty' id='difficulty'>
|
||||
<option value="0" selected>Past</option>
|
||||
<option value="1">Present</option>
|
||||
<option value="2">Future</option>
|
||||
<option value="3">Beyond</option>
|
||||
</select>
|
||||
<br />
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% if song_id %}
|
||||
<div>
|
||||
<span class="song-title">
|
||||
{{song_id}}
|
||||
</span>
|
||||
|
||||
{% if difficulty == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif difficulty == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif difficulty == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
|
||||
{% endif %}
|
||||
<br />
|
||||
<div class="song-title">
|
||||
{{song_name_en}}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<br />
|
||||
<hr />
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<div>
|
||||
<span class='rank_big'>{{'#' ~ post['rank']}}</span>
|
||||
<span class="name">
|
||||
{{post['name']}}
|
||||
</span>
|
||||
<span class="rank">UID: {{post['user_id']}}</span>
|
||||
</div>
|
||||
|
||||
<div class="song-detail">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,85 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Single player score{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<label for="name">Arcaea Username</label>
|
||||
<input name="name" id="name">
|
||||
or<br />
|
||||
<label for="user_code">Arcaea User Code</label>
|
||||
<input name="user_code" id="user_code">
|
||||
<input type="submit" value="Find">
|
||||
</br>
|
||||
</br>
|
||||
</br>
|
||||
{% for post in posts %}
|
||||
<div class="score-item">
|
||||
<span class="song-title">
|
||||
{{post['song_id']}}
|
||||
</span>
|
||||
{% if post['difficulty'] == 0 %}
|
||||
<span class="difficulty_pst">PST</span>
|
||||
{% elif post['difficulty'] == 1 %}
|
||||
<span class="difficulty_prs">PRS</span>
|
||||
{% elif post['difficulty'] == 2 %}
|
||||
<span class="difficulty_ftr">FTR</span>
|
||||
{% else %}
|
||||
<span class="difficulty_byd">BYD</span>
|
||||
{% endif %}
|
||||
<span class='rank'>{{'#' ~ post['rank']}}</span>
|
||||
|
||||
<div class="song-detail">
|
||||
</br>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PURE: </td>
|
||||
<td>{{post['perfect_count']}}</td>
|
||||
<td> {{'(' ~ post['shiny_perfect_count'] ~ ')'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FAR: </td>
|
||||
<td>{{post['near_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LOST: </td>
|
||||
<td>{{post['miss_count']}}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="song-score">{{post['score']}}</div>
|
||||
<div class="song-clear-type">
|
||||
{% if post['clear_type'] == 3 %}Pure Memory
|
||||
{% elif post['clear_type'] == 2 %}Full Recall
|
||||
{% elif post['clear_type'] == 5 %}Hard Clear
|
||||
{% elif post['clear_type'] == 1 %}Normal Clear
|
||||
{% elif post['clear_type'] == 4 %}Easy Clear
|
||||
{% else%}Track Lost
|
||||
{% endif %}
|
||||
<span class="song-clear-type" style="margin-left: 1.875em;">
|
||||
{% if post['best_clear_type'] == 3 %}(Pure Memory)
|
||||
{% elif post['best_clear_type'] == 2 %}(Full Recall)
|
||||
{% elif post['best_clear_type'] == 5 %}(Hard Clear)
|
||||
{% elif post['best_clear_type'] == 1 %}(Normal Clear)
|
||||
{% elif post['best_clear_type'] == 4 %}(Easy Clear)
|
||||
{% else%}(Track Lost)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="song-rating">成绩评价 Rating: {{post['rating']}}</div>
|
||||
<div class="song-clear-date">日期 Date:
|
||||
{{post['time_played']}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not loop.last %}
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,21 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block header %}
|
||||
<h1>{% block title %}Update databases{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<label for="name">Old database</label>
|
||||
<input type="file" name="file">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
<div class="content">
|
||||
这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。<br />
|
||||
可上传文件: arcaea_database.db和arcsong.db<br />
|
||||
新数据库不存在的数据会被添加,存在的数据将不会被改变。<br /><br />
|
||||
Here you can synchronize the old version of the database to the new version of the database and refresh the list of
|
||||
characters owned by players.<br />
|
||||
Uploadable files: arcaea_database.db & arcsong.db<br />
|
||||
Data that does not exist in the new database will be added and the existing data will not be changed.
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,50 +0,0 @@
|
||||
#import sqlite3
|
||||
from flask import (Blueprint, flash, g, redirect,
|
||||
render_template, request, session, url_for)
|
||||
import functools
|
||||
|
||||
bp = Blueprint('login', __name__, url_prefix='/web')
|
||||
|
||||
|
||||
@bp.route('/login', methods=('GET', 'POST'))
|
||||
def login():
|
||||
# 登录
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
error = None
|
||||
|
||||
if username != 'admin' and password != 'admin':
|
||||
error = '错误的用户名或密码 Incorrect username or password.'
|
||||
|
||||
if error is None:
|
||||
session.clear()
|
||||
session['user_id'] = 'admin'
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
flash(error)
|
||||
|
||||
return render_template('web/login.html')
|
||||
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
# 登出
|
||||
session.clear()
|
||||
flash('成功登出 Successfully log out.')
|
||||
return redirect(url_for('index.index'))
|
||||
|
||||
|
||||
def login_required(view):
|
||||
# 登录验证,写成了修饰器
|
||||
@functools.wraps(view)
|
||||
def wrapped_view(**kwargs):
|
||||
x = session.get('user_id')
|
||||
# 少用户存在验证
|
||||
if x is None:
|
||||
return redirect(url_for('login.login'))
|
||||
|
||||
g.user = {'user_id': x, 'username': 'admin'}
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
@@ -1,104 +0,0 @@
|
||||
import time
|
||||
|
||||
|
||||
def get_user_score(c, user_id, limit=-1):
|
||||
# 返回用户的所有歌曲数据,带排名,返回字典列表
|
||||
if limit >= 0:
|
||||
c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b''',
|
||||
{'a': user_id, 'b': limit})
|
||||
else:
|
||||
c.execute(
|
||||
'''select * from best_score where user_id =:a order by rating DESC''', {'a': user_id})
|
||||
x = c.fetchall()
|
||||
r = []
|
||||
if x:
|
||||
rank = 0
|
||||
for i in x:
|
||||
rank += 1
|
||||
r.append({
|
||||
"song_id": i[1],
|
||||
"difficulty": i[2],
|
||||
"score": i[3],
|
||||
"shiny_perfect_count": i[4],
|
||||
"perfect_count": i[5],
|
||||
"near_count": i[6],
|
||||
"miss_count": i[7],
|
||||
"health": i[8],
|
||||
"modifier": i[9],
|
||||
"time_played": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(i[10])),
|
||||
"best_clear_type": i[11],
|
||||
"clear_type": i[12],
|
||||
"rating": i[13],
|
||||
"rank": rank
|
||||
})
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user(c, user_id):
|
||||
# 得到user表部分用户信息,返回字典
|
||||
c.execute('''select * from user where user_id = :a''', {'a': user_id})
|
||||
x = c.fetchone()
|
||||
r = None
|
||||
if x:
|
||||
join_date = None
|
||||
time_played = None
|
||||
if x[3]:
|
||||
join_date = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[3])//1000))
|
||||
if x[20]:
|
||||
time_played = time.strftime('%Y-%m-%d %H:%M:%S',
|
||||
time.localtime(int(x[20])//1000))
|
||||
|
||||
r = {'name': x[1],
|
||||
'user_id': user_id,
|
||||
'join_date': join_date,
|
||||
'user_code': x[4],
|
||||
'rating_ptt': x[5],
|
||||
'song_id': x[11],
|
||||
'difficulty': x[12],
|
||||
'score': x[13],
|
||||
'shiny_perfect_count': x[14],
|
||||
'perfect_count': x[15],
|
||||
'near_count': x[16],
|
||||
'miss_count': x[17],
|
||||
'time_played': time_played,
|
||||
'clear_type': x[21],
|
||||
'rating': x[22]
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user_recent30(c, user_id):
|
||||
# 获取玩家recent30信息并计算这一部分的ptt,返回字典列表和一个值
|
||||
c.execute('''select * from recent30 where user_id=:a''', {'a': user_id})
|
||||
sumr = 0
|
||||
x = c.fetchone()
|
||||
r = []
|
||||
if x is not None:
|
||||
r30 = []
|
||||
s30 = []
|
||||
for i in range(1, 61, 2):
|
||||
if x[i] is not None:
|
||||
r30.append(float(x[i]))
|
||||
s30.append(x[i+1])
|
||||
else:
|
||||
r30.append(0)
|
||||
s30.append('')
|
||||
r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True)))
|
||||
songs = []
|
||||
i = 0
|
||||
while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None:
|
||||
if s30[i] not in songs:
|
||||
sumr += r30[i]
|
||||
songs.append(s30[i])
|
||||
i += 1
|
||||
for i in range(0, 30):
|
||||
if s30[i]:
|
||||
r.append({
|
||||
'song_id': s30[i][:-1],
|
||||
'difficulty': int(s30[i][-1]),
|
||||
'rating': r30[i]
|
||||
})
|
||||
return r, sumr / 10
|
||||
Reference in New Issue
Block a user