mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2026-02-09 09:17:26 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0e6128826 | ||
|
|
08872399cc | ||
|
|
29a6cfaac1 | ||
|
|
f25bd4130e | ||
|
|
68c757f9d7 | ||
|
|
26216bf84a | ||
|
|
5771d0c669 | ||
|
|
80122d749e | ||
|
|
5c02ecdf37 |
28
README.md
28
README.md
@@ -19,6 +19,8 @@ This is a small local Arcaea server based on Python and Flask, which can simulat
|
|||||||
- 自定义世界模式 Customizable World Mode
|
- 自定义世界模式 Customizable World Mode
|
||||||
- 自定义歌曲下载 Customizable songs download
|
- 自定义歌曲下载 Customizable songs download
|
||||||
- 单曲和曲包购买(没啥用) Single songs and song packs purchase(useless)
|
- 单曲和曲包购买(没啥用) Single songs and song packs purchase(useless)
|
||||||
|
- 奖励系统 Present system
|
||||||
|
- 兑换码系统 Redeem code system
|
||||||
- 全角色立绘 All character drawings
|
- 全角色立绘 All character drawings
|
||||||
- 角色技能 Character skills
|
- 角色技能 Character skills
|
||||||
- 自定义角色属性 Customizable characters attributes
|
- 自定义角色属性 Customizable characters attributes
|
||||||
@@ -30,12 +32,11 @@ This is a small local Arcaea server based on Python and Flask, which can simulat
|
|||||||
|
|
||||||
没有以下 We don't have:
|
没有以下 We don't have:
|
||||||
- 角色数值 Character characteristic value
|
- 角色数值 Character characteristic value
|
||||||
- 数据同步的时间和设备记录 The record of time and device for data synchronization
|
|
||||||
- 服务器安全性保证 Server security assurance
|
- 服务器安全性保证 Server security assurance
|
||||||
|
|
||||||
可能有问题 There may be problems:
|
可能有问题 There may be problems:
|
||||||
- Recent 30
|
- Recent 30
|
||||||
- 一些歌曲的解锁 Some Songs' unlocking
|
- 一些歌曲的解锁 Some songs' unlocking
|
||||||
|
|
||||||
## 说明 Statement
|
## 说明 Statement
|
||||||
只是很有趣,用处探索中。
|
只是很有趣,用处探索中。
|
||||||
@@ -54,17 +55,24 @@ It is just so interesting. What it can do is under exploration.
|
|||||||
>
|
>
|
||||||
> Tips: When updating, please keep the original database in case of data loss.
|
> Tips: When updating, please keep the original database in case of data loss.
|
||||||
|
|
||||||
### Version 1.7
|
### Version 2.0
|
||||||
- 仍然适用于Arcaea 3.2.3版本 Still for Arcaea 3.2.3
|
- 适用于Arcaea 3.4.1版本 For Arcaea 3.4.1
|
||||||
|
- 更新API接口至13 Update API interface to 13.
|
||||||
- 更新了歌曲数据库 Update the song database.
|
- 更新了歌曲数据库 Update the song database.
|
||||||
- 新增了购买系统,包括单曲购买和曲包购买 Add purchase system, including single purchase and pack purchase.
|
- 新增了兑换码系统 Add the redeem code system.
|
||||||
- 后台查询与修改项目增多 Increase background query and modification items.
|
- 优化了下载时文件MD5的读取速度 Optimize the reading speed of MD5 when downloading.
|
||||||
- 新增用户下载量限制和下载校验 Add user download limit and download verification.
|
- 新增初见保护 Add initial protection.
|
||||||
- 新增了**梦**的语音 Add the voice of **Yume**.
|
- EX保护机制修改,现在重复歌曲若分数较高,会刷新r30中最早的记录,并保证ptt不下降,仍不清楚能否正常起效 EX protection mechanism has been modified. If the score of one repetitive song is higher, it will refresh the earliest record in r30 and ensure that PTT won't not drop. It is still unclear whether it can work normally.
|
||||||
- 新增了网站图标 Add a favicon.
|
- 数据迁移机制修改,现在重复数据以旧数据库数据为准 The database migration mechanism has been modified. Now the duplicate data is subject to the old database data.
|
||||||
- 尝试解锁了所有的场景 Try to unlock all the scenes.
|
- 机制修改,数据库缺少歌曲定数会当做Unrank处理 The mechanism has been modified. The lack of chart constant of songs in the database will be treated as unrank.
|
||||||
|
- 后台新增用户密码修改、用户封禁和成绩清除 Add user password modification, user ban and score clearance in the background.
|
||||||
|
- 游戏内数据同步将记录同步时间 Data synchronization in game will record synchronization time.
|
||||||
- 修复了一些Bug Fix some bugs.
|
- 修复了一些Bug Fix some bugs.
|
||||||
|
|
||||||
|
> 提醒:本次更新针对了API接口更新,将无法兼容Arcaea 3.4.1以下版本
|
||||||
|
>
|
||||||
|
> Tips: This update includes API interface update, and will not be compatible with the version below Arcaea 3.4.1.
|
||||||
|
|
||||||
## 运行环境与依赖 Running environment and requirements
|
## 运行环境与依赖 Running environment and requirements
|
||||||
- Windows操作系统 Windows operating system
|
- Windows操作系统 Windows operating system
|
||||||
- Python 3
|
- Python 3
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -36,7 +36,7 @@ current_map text,
|
|||||||
ticket int
|
ticket int
|
||||||
);''')
|
);''')
|
||||||
c.execute('''create table if not exists login(access_token text,
|
c.execute('''create table if not exists login(access_token text,
|
||||||
user_id int,
|
user_id int primary key,
|
||||||
last_login_time int,
|
last_login_time int,
|
||||||
last_login_ip text,
|
last_login_ip text,
|
||||||
last_login_device text
|
last_login_device text
|
||||||
@@ -199,17 +199,50 @@ item_id text,
|
|||||||
type text,
|
type text,
|
||||||
primary key(user_id, item_id, type)
|
primary key(user_id, item_id, type)
|
||||||
);''')
|
);''')
|
||||||
|
c.execute('''create table if not exists user_save(user_id int primary key,
|
||||||
|
scores_data text,
|
||||||
|
clearlamps_data text,
|
||||||
|
clearedsongs_data text,
|
||||||
|
unlocklist_data text,
|
||||||
|
installid_data text,
|
||||||
|
devicemodelname_data text,
|
||||||
|
story_data text,
|
||||||
|
createdAt int
|
||||||
|
);''')
|
||||||
|
c.execute('''create table if not exists present(present_id text primary key,
|
||||||
|
expire_ts int,
|
||||||
|
items text,
|
||||||
|
description text
|
||||||
|
);''')
|
||||||
|
c.execute('''create table if not exists user_present(user_id int,
|
||||||
|
present_id text,
|
||||||
|
primary key(user_id, present_id)
|
||||||
|
);''')
|
||||||
|
c.execute('''create table if not exists songfile(song_id text,
|
||||||
|
file_type int,
|
||||||
|
md5 text,
|
||||||
|
primary key(song_id, file_type)
|
||||||
|
);''')
|
||||||
|
c.execute('''create table if not exists redeem(code text primary key,
|
||||||
|
items text,
|
||||||
|
type int
|
||||||
|
);''')
|
||||||
|
c.execute('''create table if not exists user_redeem(user_id int,
|
||||||
|
code text,
|
||||||
|
primary key(user_id, code)
|
||||||
|
);''')
|
||||||
|
|
||||||
|
|
||||||
char = ['Hikari', 'Tairitsu', 'Kou', 'Sapphire', 'Lethe', '', 'Tairitsu(Axium)', 'Tairitsu(Grievous Lady)', 'Stella', 'Hikari & Fisica', 'Ilith', 'Eto', 'Luna', 'Shirabe', 'Hikari(Zero)', 'Hikari(Fracture)', 'Hikari(Summer)', 'Tairitsu(Summer)', 'Tairitsu & Trin',
|
char = ['Hikari', 'Tairitsu', 'Kou', 'Sapphire', 'Lethe', '', 'Tairitsu(Axium)', 'Tairitsu(Grievous Lady)', 'Stella', 'Hikari & Fisica', 'Ilith', 'Eto', 'Luna', 'Shirabe', 'Hikari(Zero)', 'Hikari(Fracture)', 'Hikari(Summer)', 'Tairitsu(Summer)', 'Tairitsu & Trin',
|
||||||
'Ayu', 'Eto&Luna', 'Yume', 'Seine & Hikari', 'Saya', 'Tairitsu & Chuni Penguin', 'Chuni Penguin', 'Haruna', 'Nono', 'MTA-XXX', 'MDA-21', 'Kanae', 'Hikari(Fantasia)', 'Tairitsu(Sonata)', 'Sia', 'DORO*C', 'Tairitsu(Tempest)', 'Brillante', 'Ilith(Summer)', 'Etude']
|
'Ayu', 'Eto & Luna', 'Yume', 'Seine & Hikari', 'Saya', 'Tairitsu & Chuni Penguin', 'Chuni Penguin', 'Haruna', 'Nono', 'MTA-XXX', 'MDA-21', 'Kanae', 'Hikari(Fantasia)', 'Tairitsu(Sonata)', 'Sia', 'DORO*C', 'Tairitsu(Tempest)', 'Brillante', 'Ilith(Summer)', 'Etude', 'Alice & Tenniel', 'Luna & Mia']
|
||||||
|
|
||||||
skill_id = ['gauge_easy', '', '', '', 'note_mirror', '', '', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
skill_id = ['gauge_easy', '', '', '', 'note_mirror', '', '', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
||||||
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', '', '', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', '']
|
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', '', '', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', '', 'note_mirror|visual_hide_far', 'frags_ongeki']
|
||||||
|
|
||||||
skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', '', '', 'shirabe_entry_fee',
|
skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', '', '', 'shirabe_entry_fee',
|
||||||
'', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
|
'', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
|
||||||
|
|
||||||
for i in range(0, 39):
|
for i in range(0, 41):
|
||||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]:
|
||||||
sql = 'insert into character values('+str(
|
sql = 'insert into character values('+str(
|
||||||
i)+',"'+char[i]+'''",30,25000,25000,90,90,90,"'''+skill_id[i]+'''",0,0,"'''+skill_id_uncap[i]+'''",0,'',1,1)'''
|
i)+',"'+char[i]+'''",30,25000,25000,90,90,90,"'''+skill_id[i]+'''",0,0,"'''+skill_id_uncap[i]+'''",0,'',1,1)'''
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "core",
|
"id": "core",
|
||||||
"_id": "5fb5b68a68273a03de60f205",
|
"_id": "5ff79fc6a6e343038b058bd3",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "shiawase",
|
"id": "shiawase",
|
||||||
"_id": "5fb5b68a68273a03de60f234",
|
"_id": "5ff79fc6a6e343038b058c18",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}, {
|
}, {
|
||||||
"type": "character",
|
"type": "character",
|
||||||
"id": "kou",
|
"id": "kou",
|
||||||
"_id": "5fb5b68a68273a03de60f233",
|
"_id": "5ff79fc6a6e343038b058c17",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "dynamix",
|
"id": "dynamix",
|
||||||
"_id": "5fb5b68a68273a03de60f238",
|
"_id": "5ff79fc6a6e343038b058c1c",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}, {
|
}, {
|
||||||
"type": "character",
|
"type": "character",
|
||||||
"id": "sapphire",
|
"id": "sapphire",
|
||||||
"_id": "5fb5b68a68273a03de60f237",
|
"_id": "5ff79fc6a6e343038b058c1b",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -49,12 +49,12 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "mirai",
|
"id": "mirai",
|
||||||
"_id": "5fb5b68a68273a03de60f23e",
|
"_id": "5ff79fc6a6e343038b058c10",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}, {
|
}, {
|
||||||
"type": "character",
|
"type": "character",
|
||||||
"id": "lethe",
|
"id": "lethe",
|
||||||
"_id": "5fb5b68a68273a03de60f23d",
|
"_id": "5ff79fc6a6e343038b058c0f",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "yugamu",
|
"id": "yugamu",
|
||||||
"_id": "5fb5b68a68273a03de60f206",
|
"_id": "5ff79fc6a6e343038b058bd4",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "lanota",
|
"id": "lanota",
|
||||||
"_id": "5fb5b68a68273a03de60f211",
|
"_id": "5ff79fc6a6e343038b058bf9",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "nijuusei",
|
"id": "nijuusei",
|
||||||
"_id": "5fb5b68a68273a03de60f207",
|
"_id": "5ff79fc6a6e343038b058bd5",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "rei",
|
"id": "rei",
|
||||||
"_id": "5fb5b68a68273a03de60f1fd",
|
"_id": "5ff79fc6a6e343038b058c06",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "tonesphere",
|
"id": "tonesphere",
|
||||||
"_id": "5fb5b68a68273a03de60f213",
|
"_id": "5ff79fc6a6e343038b058bfb",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "groovecoaster",
|
"id": "groovecoaster",
|
||||||
"_id": "5fb5b68a68273a03de60f22c",
|
"_id": "5ff79fc6a6e343038b058bf0",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "zettai",
|
"id": "zettai",
|
||||||
"_id": "5fb5b68a68273a03de60f1ff",
|
"_id": "5ff79fc6a6e343038b058c08",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "chunithm",
|
"id": "chunithm",
|
||||||
"_id": "5fb5b68a68273a03de60f221",
|
"_id": "5ff79fc6a6e343038b058be4",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 300,
|
"price": 300,
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "prelude",
|
"id": "prelude",
|
||||||
"_id": "5fb5b68a68273a03de60f22d",
|
"_id": "5ff79fc6a6e343038b058bf1",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 400,
|
"price": 400,
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "omatsuri",
|
"id": "omatsuri",
|
||||||
"_id": "5fb5b68a68273a03de60f200",
|
"_id": "5ff79fc6a6e343038b058c09",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "vs",
|
"id": "vs",
|
||||||
"_id": "5fb5b68a68273a03de60f224",
|
"_id": "5ff79fc6a6e343038b058be7",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 500,
|
"price": 500,
|
||||||
@@ -190,9 +190,49 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "pack",
|
"type": "pack",
|
||||||
"id": "extend",
|
"id": "extend",
|
||||||
"_id": "5fb5b68a68273a03de60f230",
|
"_id": "5ff79fc6a6e343038b058bf4",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 700,
|
"price": 700,
|
||||||
"orig_price": 700
|
"orig_price": 700
|
||||||
|
}, {
|
||||||
|
"name": "alice",
|
||||||
|
"items": [{
|
||||||
|
"type": "pack",
|
||||||
|
"id": "alice",
|
||||||
|
"_id": "5ff79fc6a6e343038b058c0e",
|
||||||
|
"is_available": true
|
||||||
|
}],
|
||||||
|
"orig_price": 500,
|
||||||
|
"price": 500
|
||||||
|
}, {
|
||||||
|
"name": "alice_append_1",
|
||||||
|
"items": [{
|
||||||
|
"type": "pack",
|
||||||
|
"id": "alice_append_1",
|
||||||
|
"_id": "5ff79fc6a6e343038b058bde",
|
||||||
|
"is_available": true
|
||||||
|
}],
|
||||||
|
"orig_price": 300,
|
||||||
|
"price": 300
|
||||||
|
}, {
|
||||||
|
"name": "ongeki",
|
||||||
|
"items": [{
|
||||||
|
"type": "pack",
|
||||||
|
"id": "ongeki",
|
||||||
|
"_id": "5ff79fc6a6e343038b058bea",
|
||||||
|
"is_available": true
|
||||||
|
}],
|
||||||
|
"orig_price": 400,
|
||||||
|
"price": 400
|
||||||
|
}, {
|
||||||
|
"name": "maimai",
|
||||||
|
"items": [{
|
||||||
|
"type": "pack",
|
||||||
|
"id": "maimai",
|
||||||
|
"_id": "5ff79fc6a6e343038b058bf7",
|
||||||
|
"is_available": true
|
||||||
|
}],
|
||||||
|
"orig_price": 400,
|
||||||
|
"price": 400
|
||||||
}]
|
}]
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"id": "dataerror",
|
"id": "dataerror",
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"_id": "5fb5b68a68273a03de60f210",
|
"_id": "5ff79fc6a6e343038b058beb",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"id": "yourvoiceso",
|
"id": "yourvoiceso",
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"_id": "5fb5b68a68273a03de60f227",
|
"_id": "5ff79fc6a6e343038b058bf8",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"id": "crosssoul",
|
"id": "crosssoul",
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"_id": "5fb5b68a68273a03de60f21b",
|
"_id": "5ff79fc6a6e343038b058c03",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "impurebird",
|
"id": "impurebird",
|
||||||
"_id": "5fb5b68a68273a03de60f21c",
|
"_id": "5ff79fc6a6e343038b058bdf",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "auxesia",
|
"id": "auxesia",
|
||||||
"_id": "5fb5b68a68273a03de60f228",
|
"_id": "5ff79fc6a6e343038b058bec",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "modelista",
|
"id": "modelista",
|
||||||
"_id": "5fb5b68a68273a03de60f1fb",
|
"_id": "5ff79fc6a6e343038b058c04",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "yozakurafubuki",
|
"id": "yozakurafubuki",
|
||||||
"_id": "5fb5b68a68273a03de60f21d",
|
"_id": "5ff79fc6a6e343038b058be0",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "surrender",
|
"id": "surrender",
|
||||||
"_id": "5fb5b68a68273a03de60f229",
|
"_id": "5ff79fc6a6e343038b058bed",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "metallicpunisher",
|
"id": "metallicpunisher",
|
||||||
"_id": "5fb5b68a68273a03de60f1fc",
|
"_id": "5ff79fc6a6e343038b058c05",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "carminescythe",
|
"id": "carminescythe",
|
||||||
"_id": "5fb5b68a68273a03de60f21e",
|
"_id": "5ff79fc6a6e343038b058be1",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "bethere",
|
"id": "bethere",
|
||||||
"_id": "5fb5b68a68273a03de60f22a",
|
"_id": "5ff79fc6a6e343038b058bee",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "callmyname",
|
"id": "callmyname",
|
||||||
"_id": "5fb5b68a68273a03de60f212",
|
"_id": "5ff79fc6a6e343038b058bfa",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "fallensquare",
|
"id": "fallensquare",
|
||||||
"_id": "5fb5b68a68273a03de60f208",
|
"_id": "5ff79fc6a6e343038b058bd6",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "dropdead",
|
"id": "dropdead",
|
||||||
"_id": "5fb5b68a68273a03de60f21f",
|
"_id": "5ff79fc6a6e343038b058be2",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "alexandrite",
|
"id": "alexandrite",
|
||||||
"_id": "5fb5b68a68273a03de60f22b",
|
"_id": "5ff79fc6a6e343038b058bef",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "astraltale",
|
"id": "astraltale",
|
||||||
"_id": "5fb5b68a68273a03de60f1fe",
|
"_id": "5ff79fc6a6e343038b058c07",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "phantasia",
|
"id": "phantasia",
|
||||||
"_id": "5fb5b68a68273a03de60f209",
|
"_id": "5ff79fc6a6e343038b058bd7",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "empireofwinter",
|
"id": "empireofwinter",
|
||||||
"_id": "5fb5b68a68273a03de60f220",
|
"_id": "5ff79fc6a6e343038b058be3",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "libertas",
|
"id": "libertas",
|
||||||
"_id": "5fb5b68a68273a03de60f214",
|
"_id": "5ff79fc6a6e343038b058bfc",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "dottodot",
|
"id": "dottodot",
|
||||||
"_id": "5fb5b68a68273a03de60f20a",
|
"_id": "5ff79fc6a6e343038b058bd8",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "dreadnought",
|
"id": "dreadnought",
|
||||||
"_id": "5fb5b68a68273a03de60f215",
|
"_id": "5ff79fc6a6e343038b058bfd",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "mirzam",
|
"id": "mirzam",
|
||||||
"_id": "5fb5b68a68273a03de60f20b",
|
"_id": "5ff79fc6a6e343038b058bd9",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "heavenlycaress",
|
"id": "heavenlycaress",
|
||||||
"_id": "5fb5b68a68273a03de60f222",
|
"_id": "5ff79fc6a6e343038b058be5",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "filament",
|
"id": "filament",
|
||||||
"_id": "5fb5b68a68273a03de60f22e",
|
"_id": "5ff79fc6a6e343038b058bf2",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -288,7 +288,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "avantraze",
|
"id": "avantraze",
|
||||||
"_id": "5fb5b68a68273a03de60f216",
|
"_id": "5ff79fc6a6e343038b058bfe",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "battlenoone",
|
"id": "battlenoone",
|
||||||
"_id": "5fb5b68a68273a03de60f201",
|
"_id": "5ff79fc6a6e343038b058c0a",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -308,7 +308,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "saikyostronger",
|
"id": "saikyostronger",
|
||||||
"_id": "5fb5b68a68273a03de60f20c",
|
"_id": "5ff79fc6a6e343038b058bda",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -318,7 +318,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "izana",
|
"id": "izana",
|
||||||
"_id": "5fb5b68a68273a03de60f223",
|
"_id": "5ff79fc6a6e343038b058be6",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -328,7 +328,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "einherjar",
|
"id": "einherjar",
|
||||||
"_id": "5fb5b68a68273a03de60f22f",
|
"_id": "5ff79fc6a6e343038b058bf3",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -338,7 +338,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "laqryma",
|
"id": "laqryma",
|
||||||
"_id": "5fb5b68a68273a03de60f217",
|
"_id": "5ff79fc6a6e343038b058bff",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -348,7 +348,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "amygdata",
|
"id": "amygdata",
|
||||||
"_id": "5fb5b68a68273a03de60f202",
|
"_id": "5ff79fc6a6e343038b058c0b",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -358,7 +358,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "altale",
|
"id": "altale",
|
||||||
"_id": "5fb5b68a68273a03de60f20d",
|
"_id": "5ff79fc6a6e343038b058bdb",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -368,7 +368,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "feelssoright",
|
"id": "feelssoright",
|
||||||
"_id": "5fb5b68a68273a03de60f218",
|
"_id": "5ff79fc6a6e343038b058c00",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -378,7 +378,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "scarletcage",
|
"id": "scarletcage",
|
||||||
"_id": "5fb5b68a68273a03de60f203",
|
"_id": "5ff79fc6a6e343038b058c0c",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -388,7 +388,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "teriqma",
|
"id": "teriqma",
|
||||||
"_id": "5fb5b68a68273a03de60f20e",
|
"_id": "5ff79fc6a6e343038b058bdc",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -398,7 +398,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "mahoroba",
|
"id": "mahoroba",
|
||||||
"_id": "5fb5b68a68273a03de60f225",
|
"_id": "5ff79fc6a6e343038b058be8",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -408,7 +408,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "badtek",
|
"id": "badtek",
|
||||||
"_id": "5fb5b68a68273a03de60f219",
|
"_id": "5ff79fc6a6e343038b058c01",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -418,7 +418,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "maliciousmischance",
|
"id": "maliciousmischance",
|
||||||
"_id": "5fb5b68a68273a03de60f231",
|
"_id": "5ff79fc6a6e343038b058c0d",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -428,7 +428,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "buchigireberserker",
|
"id": "buchigireberserker",
|
||||||
"_id": "5fb5b68a68273a03de60f20f",
|
"_id": "5ff79fc6a6e343038b058bdd",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -438,7 +438,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "galaxyfriends",
|
"id": "galaxyfriends",
|
||||||
"_id": "5fb5b68a68273a03de60f226",
|
"_id": "5ff79fc6a6e343038b058be9",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
@@ -448,7 +448,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "xeraphinite",
|
"id": "xeraphinite",
|
||||||
"_id": "5fb5b68a68273a03de60f232",
|
"_id": "5ff79fc6a6e343038b058bf6",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"orig_price": 100,
|
"orig_price": 100,
|
||||||
@@ -458,7 +458,7 @@
|
|||||||
"items": [{
|
"items": [{
|
||||||
"type": "single",
|
"type": "single",
|
||||||
"id": "xanatos",
|
"id": "xanatos",
|
||||||
"_id": "5fb5b68a68273a03de60f21a",
|
"_id": "5ff79fc6a6e343038b058c02",
|
||||||
"is_available": true
|
"is_available": true
|
||||||
}],
|
}],
|
||||||
"price": 100,
|
"price": 100,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from flask import Flask, request, jsonify, make_response, send_from_directory
|
from flask import Flask, request, jsonify, make_response, send_from_directory
|
||||||
|
from logging.config import dictConfig
|
||||||
import configparser
|
import configparser
|
||||||
import base64
|
import base64
|
||||||
import server.auth
|
import server.auth
|
||||||
@@ -80,7 +81,7 @@ def favicon():
|
|||||||
return app.send_static_file('favicon.ico')
|
return app.send_static_file('favicon.ico')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口
|
@app.route('/latte/13/auth/login', methods=['POST']) # 登录接口
|
||||||
def login():
|
def login():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
id_pwd = headers['Authorization']
|
id_pwd = headers['Authorization']
|
||||||
@@ -88,18 +89,18 @@ def login():
|
|||||||
name, password = id_pwd.split(':', 1)
|
name, password = id_pwd.split(':', 1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
token = server.auth.arc_login(name, password)
|
token, error_code = server.auth.arc_login(name, password)
|
||||||
if token is not None:
|
if not error_code:
|
||||||
r = {"success": True, "token_type": "Bearer"}
|
r = {"success": True, "token_type": "Bearer"}
|
||||||
r['access_token'] = token
|
r['access_token'] = token
|
||||||
return jsonify(r)
|
return jsonify(r)
|
||||||
else:
|
else:
|
||||||
return error_return(104) # 用户名或密码错误
|
return error_return(error_code)
|
||||||
except:
|
except:
|
||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/user/', methods=['POST']) # 注册接口
|
@app.route('/latte/13/user/', methods=['POST']) # 注册接口
|
||||||
def register():
|
def register():
|
||||||
name = request.form['name']
|
name = request.form['name']
|
||||||
password = request.form['password']
|
password = request.form['password']
|
||||||
@@ -116,7 +117,7 @@ def register():
|
|||||||
|
|
||||||
|
|
||||||
# 集成式请求,没想到什么好办法处理,就先这样写着
|
# 集成式请求,没想到什么好办法处理,就先这样写着
|
||||||
@app.route('/coffee/12/compose/aggregate', methods=['GET'])
|
@app.route('/latte/13/compose/aggregate', methods=['GET'])
|
||||||
def aggregate():
|
def aggregate():
|
||||||
calls = request.args.get('calls')
|
calls = request.args.get('calls')
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
@@ -136,7 +137,7 @@ def aggregate():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换
|
@app.route('/latte/13/user/me/character', methods=['POST']) # 角色切换
|
||||||
def character_change():
|
def character_change():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -164,7 +165,7 @@ def character_change():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
@app.route('/latte/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
||||||
def character_uncap(path):
|
def character_uncap(path):
|
||||||
character_id = int(path[22:])
|
character_id = int(path[22:])
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
@@ -190,7 +191,7 @@ def character_uncap(path):
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友
|
@app.route('/latte/13/friend/me/add', methods=['POST']) # 加好友
|
||||||
def add_friend():
|
def add_friend():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -225,7 +226,7 @@ def add_friend():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友
|
@app.route('/latte/13/friend/me/delete', methods=['POST']) # 删好友
|
||||||
def delete_friend():
|
def delete_friend():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -256,7 +257,7 @@ def delete_friend():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
@app.route('/latte/13/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
||||||
def song_score_friend():
|
def song_score_friend():
|
||||||
song_id = request.args.get('song_id')
|
song_id = request.args.get('song_id')
|
||||||
difficulty = request.args.get('difficulty')
|
difficulty = request.args.get('difficulty')
|
||||||
@@ -280,7 +281,7 @@ def song_score_friend():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
@app.route('/latte/13/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
||||||
def song_score_me():
|
def song_score_me():
|
||||||
song_id = request.args.get('song_id')
|
song_id = request.args.get('song_id')
|
||||||
difficulty = request.args.get('difficulty')
|
difficulty = request.args.get('difficulty')
|
||||||
@@ -304,7 +305,7 @@ def song_score_me():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/score/song', methods=['GET']) # TOP20
|
@app.route('/latte/13/score/song', methods=['GET']) # TOP20
|
||||||
def song_score_top():
|
def song_score_top():
|
||||||
song_id = request.args.get('song_id')
|
song_id = request.args.get('song_id')
|
||||||
difficulty = request.args.get('difficulty')
|
difficulty = request.args.get('difficulty')
|
||||||
@@ -328,7 +329,7 @@ def song_score_top():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传
|
@app.route('/latte/13/score/song', methods=['POST']) # 成绩上传
|
||||||
def song_score_post():
|
def song_score_post():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -376,7 +377,7 @@ def song_score_post():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
@app.route('/latte/13/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
||||||
def score_token():
|
def score_token():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
@@ -387,7 +388,7 @@ def score_token():
|
|||||||
|
|
||||||
|
|
||||||
# 世界模式成绩上传所需的token,无验证
|
# 世界模式成绩上传所需的token,无验证
|
||||||
@app.route('/coffee/12/score/token/world', methods=['GET'])
|
@app.route('/latte/13/score/token/world', methods=['GET'])
|
||||||
def score_token_world():
|
def score_token_world():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -411,7 +412,7 @@ def score_token_world():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步
|
@app.route('/latte/13/user/me/save', methods=['GET']) # 从云端同步
|
||||||
def cloud_get():
|
def cloud_get():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -433,17 +434,23 @@ def cloud_get():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步
|
@app.route('/latte/13/user/me/save', methods=['POST']) # 向云端同步
|
||||||
def cloud_post():
|
def cloud_post():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
token = token[7:]
|
token = token[7:]
|
||||||
scores_data = request.form['scores_data']
|
scores_data = request.form['scores_data']
|
||||||
clearlamps_data = request.form['clearlamps_data']
|
clearlamps_data = request.form['clearlamps_data']
|
||||||
|
clearedsongs_data = request.form['clearedsongs_data']
|
||||||
|
unlocklist_data = request.form['unlocklist_data']
|
||||||
|
installid_data = request.form['installid_data']
|
||||||
|
devicemodelname_data = request.form['devicemodelname_data']
|
||||||
|
story_data = request.form['story_data']
|
||||||
try:
|
try:
|
||||||
user_id = server.auth.token_get_id(token)
|
user_id = server.auth.token_get_id(token)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
server.arcscore.arc_all_post(user_id, scores_data, clearlamps_data)
|
server.arcscore.arc_all_post(user_id, scores_data, clearlamps_data, clearedsongs_data,
|
||||||
|
unlocklist_data, installid_data, devicemodelname_data, story_data)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"value": {
|
"value": {
|
||||||
@@ -456,28 +463,67 @@ def cloud_post():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,依然没有用
|
@app.route('/latte/13/purchase/me/redeem', methods=['POST']) # 兑换码
|
||||||
def redeem():
|
def redeem():
|
||||||
return error_return(504)
|
headers = request.headers
|
||||||
|
token = headers['Authorization']
|
||||||
|
token = token[7:]
|
||||||
|
code = request.form['code']
|
||||||
|
try:
|
||||||
|
user_id = server.auth.token_get_id(token)
|
||||||
|
if user_id is not None:
|
||||||
|
fragment, error_code = server.arcpurchase.claim_user_redeem(
|
||||||
|
user_id, code)
|
||||||
|
if not error_code:
|
||||||
|
if fragment > 0:
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"value": {"coupon": "fragment"+str(fragment)}
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"value": {"coupon": ""}
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return error_return(error_code)
|
||||||
|
else:
|
||||||
|
return error_return(108)
|
||||||
|
except:
|
||||||
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
# 礼物确认
|
# 礼物确认
|
||||||
@app.route('/coffee/12/present/me/claim/<present_id>', methods=['POST'])
|
@app.route('/latte/13/present/me/claim/<present_id>', methods=['POST'])
|
||||||
def claim_present(present_id):
|
def claim_present(present_id):
|
||||||
|
headers = request.headers
|
||||||
|
token = headers['Authorization']
|
||||||
|
token = token[7:]
|
||||||
|
try:
|
||||||
|
user_id = server.auth.token_get_id(token)
|
||||||
|
if user_id is not None:
|
||||||
|
flag = server.arcpurchase.claim_user_present(user_id, present_id)
|
||||||
|
if flag:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True
|
"success": True
|
||||||
})
|
})
|
||||||
|
else:
|
||||||
|
return error_return(108)
|
||||||
|
else:
|
||||||
|
return error_return(108)
|
||||||
|
except:
|
||||||
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
# 购买,为了world模式boost一下
|
# 购买,为了world模式boost一下
|
||||||
@app.route('/coffee/12/purchase/me/item', methods=['POST'])
|
@app.route('/latte/13/purchase/me/item', methods=['POST'])
|
||||||
def item():
|
def item():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True
|
"success": True
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/purchase/me/pack', methods=['POST']) # 曲包和单曲购买
|
@app.route('/latte/13/purchase/me/pack', methods=['POST']) # 曲包和单曲购买
|
||||||
def pack():
|
def pack():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -498,7 +544,7 @@ def pack():
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/purchase/bundle/single', methods=['GET']) # 单曲购买信息获取
|
@app.route('/latte/13/purchase/bundle/single', methods=['GET']) # 单曲购买信息获取
|
||||||
def single():
|
def single():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
@@ -506,7 +552,7 @@ def single():
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/world/map/me', methods=['GET']) # 获得世界模式信息,所有地图
|
@app.route('/latte/13/world/map/me', methods=['GET']) # 获得世界模式信息,所有地图
|
||||||
def world_all():
|
def world_all():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -529,7 +575,7 @@ def world_all():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/world/map/me/', methods=['POST']) # 进入地图
|
@app.route('/latte/13/world/map/me/', methods=['POST']) # 进入地图
|
||||||
def world_in():
|
def world_in():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -548,7 +594,7 @@ def world_in():
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/world/map/me/<map_id>', methods=['GET']) # 获得单个地图完整信息
|
@app.route('/latte/13/world/map/me/<map_id>', methods=['GET']) # 获得单个地图完整信息
|
||||||
def world_one(map_id):
|
def world_one(map_id):
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -571,7 +617,7 @@ def world_one(map_id):
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/12/serve/download/me/song', methods=['GET']) # 歌曲下载
|
@app.route('/latte/13/serve/download/me/song', methods=['GET']) # 歌曲下载
|
||||||
def download_song():
|
def download_song():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
token = headers['Authorization']
|
token = headers['Authorization']
|
||||||
@@ -616,7 +662,7 @@ def download(file_path):
|
|||||||
return error_return(108)
|
return error_return(108)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/coffee/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
@app.route('/latte/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
||||||
def sys_set(path):
|
def sys_set(path):
|
||||||
set_arg = path[10:]
|
set_arg = path[10:]
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
@@ -647,6 +693,26 @@ def main():
|
|||||||
app.register_blueprint(web.login.bp)
|
app.register_blueprint(web.login.bp)
|
||||||
app.register_blueprint(web.index.bp)
|
app.register_blueprint(web.index.bp)
|
||||||
|
|
||||||
|
dictConfig({
|
||||||
|
'version': 1,
|
||||||
|
'formatters': {'default': {
|
||||||
|
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
|
||||||
|
}},
|
||||||
|
'root': {
|
||||||
|
'level': 'INFO'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.logger.info("Start to initialize data in 'songfile' table...")
|
||||||
|
try:
|
||||||
|
error = server.arcdownload.initialize_songfile()
|
||||||
|
except:
|
||||||
|
error = 'Something wrong.'
|
||||||
|
if error:
|
||||||
|
app.logger.warning(error)
|
||||||
|
else:
|
||||||
|
app.logger.info('Complete!')
|
||||||
|
|
||||||
app.run(HOST, PORT)
|
app.run(HOST, PORT)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,27 @@ def get_one_song(c, user_id, song_id, file_dir='./database/songs'):
|
|||||||
token = token[:8]
|
token = token[:8]
|
||||||
|
|
||||||
if i == 'base.ogg':
|
if i == 'base.ogg':
|
||||||
re['audio'] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, 'base.ogg')),
|
c.execute(
|
||||||
|
'''select md5 from songfile where song_id=:a and file_type=-1''', {'a': song_id})
|
||||||
|
x = c.fetchone()
|
||||||
|
if x:
|
||||||
|
checksum = x[0]
|
||||||
|
else:
|
||||||
|
checksum = get_file_md5(os.path.join(
|
||||||
|
file_dir, song_id, 'base.ogg'))
|
||||||
|
re['audio'] = {"checksum": checksum,
|
||||||
"url": url_for('download', file_path=song_id+'/base.ogg', t=token, _external=True)}
|
"url": url_for('download', file_path=song_id+'/base.ogg', t=token, _external=True)}
|
||||||
else:
|
else:
|
||||||
if 'chart' not in re:
|
if 'chart' not in re:
|
||||||
re['chart'] = {}
|
re['chart'] = {}
|
||||||
re['chart'][i[0]] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, i)),
|
c.execute(
|
||||||
|
'''select md5 from songfile where song_id=:a and file_type=:b''', {'a': song_id, 'b': int(i[0])})
|
||||||
|
x = c.fetchone()
|
||||||
|
if x:
|
||||||
|
checksum = x[0]
|
||||||
|
else:
|
||||||
|
checksum = get_file_md5(os.path.join(file_dir, song_id, i))
|
||||||
|
re['chart'][i[0]] = {"checksum": checksum,
|
||||||
"url": url_for('download', file_path=song_id+'/'+i, t=token, _external=True)}
|
"url": url_for('download', file_path=song_id+'/'+i, t=token, _external=True)}
|
||||||
|
|
||||||
c.execute('''insert into download_token values(:a,:b,:c,:d,:e)''', {
|
c.execute('''insert into download_token values(:a,:b,:c,:d,:e)''', {
|
||||||
@@ -60,7 +75,7 @@ def get_all_songs(user_id, file_dir='./database/songs'):
|
|||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
for i in dir_list:
|
for i in dir_list:
|
||||||
if os.path.isdir(os.path.join(file_dir, i)):
|
if os.path.isdir(os.path.join(file_dir, i)):
|
||||||
re.update(get_one_song(c, user_id, i))
|
re.update(get_one_song(c, user_id, i, file_dir))
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
@@ -125,3 +140,45 @@ def is_able_download(user_id):
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_one_songfile(c, song_id, file_dir='./database/songs'):
|
||||||
|
# 计算并添加歌曲md5到表中,无返回
|
||||||
|
dir_list = os.listdir(os.path.join(file_dir, song_id))
|
||||||
|
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':
|
||||||
|
c.execute('''insert into songfile values(:a,-1,:c)''', {
|
||||||
|
'a': song_id, 'c': get_file_md5(os.path.join(file_dir, song_id, 'base.ogg'))})
|
||||||
|
else:
|
||||||
|
c.execute('''insert into songfile values(:a,:b,:c)''', {
|
||||||
|
'a': song_id, 'b': int(i[0]), 'c': get_file_md5(os.path.join(file_dir, song_id, i))})
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_songfile(file_dir='./database/songs'):
|
||||||
|
# 初始化歌曲数据的md5表,返回错误信息
|
||||||
|
error = None
|
||||||
|
try:
|
||||||
|
dir_list = os.listdir(file_dir)
|
||||||
|
except:
|
||||||
|
error = 'OS error!'
|
||||||
|
return error
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
except:
|
||||||
|
error = 'Database error!'
|
||||||
|
return error
|
||||||
|
try:
|
||||||
|
c.execute('''delete from songfile''')
|
||||||
|
for i in dir_list:
|
||||||
|
if os.path.isdir(os.path.join(file_dir, i)):
|
||||||
|
initialize_one_songfile(c, i, file_dir)
|
||||||
|
except:
|
||||||
|
error = 'Initialization error!'
|
||||||
|
finally:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return error
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
def int2b(x):
|
def int2b(x):
|
||||||
@@ -120,3 +122,106 @@ def buy_single(user_id, single_id):
|
|||||||
return {
|
return {
|
||||||
"success": True
|
"success": True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_present(c, user_id):
|
||||||
|
# 获取用户奖励,返回字典列表
|
||||||
|
c.execute(
|
||||||
|
'''select * from present where present_id in (select present_id from user_present where user_id=:a)''', {'a': user_id})
|
||||||
|
x = c.fetchall()
|
||||||
|
re = []
|
||||||
|
now = int(time.time() * 1000)
|
||||||
|
if x:
|
||||||
|
for i in x:
|
||||||
|
if now <= int(i[1]):
|
||||||
|
re.append({'expire_ts': i[1],
|
||||||
|
'description': i[3],
|
||||||
|
'present_id': i[0],
|
||||||
|
'items': json.loads(i[2])
|
||||||
|
})
|
||||||
|
|
||||||
|
return re
|
||||||
|
|
||||||
|
|
||||||
|
def claim_user_present(user_id, present_id):
|
||||||
|
# 确认并删除用户奖励,返回成功与否的布尔值
|
||||||
|
flag = False
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
c.execute('''select exists(select * from user_present where user_id=:a and present_id=:b)''',
|
||||||
|
{'a': user_id, 'b': present_id})
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
flag = True
|
||||||
|
c.execute('''delete from user_present where user_id=:a and present_id=:b''',
|
||||||
|
{'a': user_id, 'b': present_id})
|
||||||
|
c.execute('''select * from present where present_id=:b''',
|
||||||
|
{'b': present_id})
|
||||||
|
x = c.fetchone()
|
||||||
|
now = int(time.time() * 1000)
|
||||||
|
if now <= int(x[1]):
|
||||||
|
# 处理memory
|
||||||
|
items = json.loads(x[2])
|
||||||
|
for i in items:
|
||||||
|
if i['id'] == 'memory':
|
||||||
|
c.execute('''select ticket from user where user_id=:a''', {
|
||||||
|
'a': user_id})
|
||||||
|
ticket = int(c.fetchone()[0])
|
||||||
|
ticket += int(i['amount'])
|
||||||
|
c.execute('''update user set ticket=:b where user_id=:a''', {
|
||||||
|
'a': user_id, 'b': ticket})
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 过期
|
||||||
|
flag = False
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return flag
|
||||||
|
|
||||||
|
|
||||||
|
def claim_user_redeem(user_id, code):
|
||||||
|
# 处理兑换码,返回碎片数量和错误码
|
||||||
|
fragment = 0
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''select * from redeem where code=:a''', {'a': code})
|
||||||
|
x = c.fetchone()
|
||||||
|
if not x:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return 0, 504
|
||||||
|
|
||||||
|
if x[2] == 0: # 一次性
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from user_redeem where code=:a)''', {'a': code})
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return 0, 505
|
||||||
|
elif x[2] == 1: # 每个玩家一次
|
||||||
|
c.execute('''select exists(select * from user_redeem where code=:a and user_id=:b)''',
|
||||||
|
{'a': code, 'b': user_id})
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return 0, 506
|
||||||
|
|
||||||
|
c.execute('''insert into user_redeem values(:b,:a)''',
|
||||||
|
{'a': code, 'b': user_id})
|
||||||
|
|
||||||
|
items = json.loads(x[1])
|
||||||
|
for i in items:
|
||||||
|
if i['type'] == 'fragment':
|
||||||
|
fragment = i['amount']
|
||||||
|
if i['type'] == 'memory':
|
||||||
|
c.execute('''select ticket from user where user_id=:a''', {
|
||||||
|
'a': user_id})
|
||||||
|
ticket = int(c.fetchone()[0])
|
||||||
|
ticket += int(i['amount'])
|
||||||
|
c.execute('''update user set ticket=:b where user_id=:a''', {
|
||||||
|
'a': user_id, 'b': ticket})
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return fragment, None
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,20 +5,27 @@ import server.arcworld
|
|||||||
|
|
||||||
|
|
||||||
def arc_login(name: str, password: str) -> str: # 登录判断
|
def arc_login(name: str, password: str) -> str: # 登录判断
|
||||||
# 查询数据库中的user表,验证账号密码,返回并记录token
|
# 查询数据库中的user表,验证账号密码,返回并记录token,多返回个error code
|
||||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||||
# 密码和token的加密方式为 SHA-256
|
# 密码和token的加密方式为 SHA-256
|
||||||
|
|
||||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
error_code = None
|
||||||
|
token = None
|
||||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||||
c.execute('''select user_id from user where name = :name and password = :password''', {
|
c.execute('''select user_id, password from user where name = :name''', {
|
||||||
'name': name, 'password': hash_pwd})
|
'name': name})
|
||||||
x = c.fetchone()
|
x = c.fetchone()
|
||||||
if x is not None:
|
if x is not None:
|
||||||
|
if x[1] == '':
|
||||||
|
# 账号封禁
|
||||||
|
error_code = 106
|
||||||
|
elif x[1] == hash_pwd:
|
||||||
user_id = str(x[0])
|
user_id = str(x[0])
|
||||||
now = int(time.time() * 1000)
|
now = int(time.time() * 1000)
|
||||||
token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest()
|
token = hashlib.sha256(
|
||||||
|
(user_id + str(now)).encode("utf8")).hexdigest()
|
||||||
c.execute(
|
c.execute(
|
||||||
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
'''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id})
|
||||||
|
|
||||||
@@ -28,13 +35,16 @@ def arc_login(name: str, password: str) -> str: # 登录判断
|
|||||||
|
|
||||||
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', {
|
||||||
'user_id': user_id, 'access_token': token})
|
'user_id': user_id, 'access_token': token})
|
||||||
conn.commit()
|
else:
|
||||||
conn.close()
|
# 密码错误
|
||||||
return token
|
error_code = 104
|
||||||
|
else:
|
||||||
|
# 用户名错误
|
||||||
|
error_code = 104
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return None
|
return token, error_code
|
||||||
|
|
||||||
|
|
||||||
def arc_register(name: str, password: str): # 注册
|
def arc_register(name: str, password: str): # 注册
|
||||||
@@ -82,7 +92,7 @@ def arc_register(name: str, password: str): # 注册
|
|||||||
now = int(time.time() * 1000)
|
now = int(time.time() * 1000)
|
||||||
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map, ticket)
|
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map, ticket)
|
||||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '', 114514)
|
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '', 0)
|
||||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd})
|
''', {'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)''', {
|
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||||
'user_id': user_id})
|
'user_id': user_id})
|
||||||
|
|||||||
@@ -104,14 +104,26 @@ def get_user_friend(c, user_id):
|
|||||||
c.execute('''select * from user where user_id = :x''', {'x': i[0]})
|
c.execute('''select * from user where user_id = :x''', {'x': i[0]})
|
||||||
y = c.fetchone()
|
y = c.fetchone()
|
||||||
if y is not None:
|
if y is not None:
|
||||||
|
character = y[6]
|
||||||
|
is_char_uncapped = int2b(y[8])
|
||||||
|
is_char_uncapped_override = int2b(y[9])
|
||||||
|
if y[23] != -1:
|
||||||
|
character = y[23]
|
||||||
|
c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id=:a and character_id=:b''', {
|
||||||
|
'a': i[0], 'b': character})
|
||||||
|
z = c.fetchone()
|
||||||
|
if z:
|
||||||
|
is_char_uncapped = int2b(z[0])
|
||||||
|
is_char_uncapped_override = int2b(z[1])
|
||||||
|
|
||||||
s.append({
|
s.append({
|
||||||
"is_mutual": is_mutual,
|
"is_mutual": is_mutual,
|
||||||
"is_char_uncapped_override": int2b(y[9]),
|
"is_char_uncapped_override": is_char_uncapped_override,
|
||||||
"is_char_uncapped": int2b(y[8]),
|
"is_char_uncapped": is_char_uncapped,
|
||||||
"is_skill_sealed": int2b(y[7]),
|
"is_skill_sealed": int2b(y[7]),
|
||||||
"rating": y[5],
|
"rating": y[5],
|
||||||
"join_date": int(y[3]),
|
"join_date": int(y[3]),
|
||||||
"character": y[6],
|
"character": character,
|
||||||
"recent_score": get_recent_score(c, i[0]),
|
"recent_score": get_recent_score(c, i[0]),
|
||||||
"name": y[1],
|
"name": y[1],
|
||||||
"user_id": i[0]
|
"user_id": i[0]
|
||||||
@@ -182,7 +194,7 @@ def get_value_0(c, user_id):
|
|||||||
"max_stamina_ts": 1586274871917,
|
"max_stamina_ts": 1586274871917,
|
||||||
"stamina": 12,
|
"stamina": 12,
|
||||||
"world_unlocks": ["scenery_chap1", "scenery_chap2", "scenery_chap3", "scenery_chap4", "scenery_chap5"],
|
"world_unlocks": ["scenery_chap1", "scenery_chap2", "scenery_chap3", "scenery_chap4", "scenery_chap5"],
|
||||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3"],
|
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3"],
|
||||||
"singles": get_user_singles(c, user_id), # ["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", "xeraphinite", "xanatos"]
|
"singles": get_user_singles(c, user_id), # ["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", "xeraphinite", "xanatos"]
|
||||||
"packs": get_user_packs(c, user_id),
|
"packs": get_user_packs(c, user_id),
|
||||||
# ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"]
|
# ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"]
|
||||||
@@ -330,7 +342,7 @@ def arc_aggregate_big(user_id):
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"value": []
|
"value": server.arcpurchase.get_user_present(c, user_id)
|
||||||
}, {
|
}, {
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"value": {
|
"value": {
|
||||||
|
|||||||
37
latest version/templates/web/allpresent.html
Normal file
37
latest version/templates/web/allpresent.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}All presents{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if posts %}<br />
|
||||||
|
{% for present in posts %}
|
||||||
|
|
||||||
|
<div class="char-present">
|
||||||
|
<span>Id: </span>
|
||||||
|
<span class="name">{{present['present_id']}}</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<span>Expire time: </span>
|
||||||
|
<span class="char-num">{{present['expire_ts']}}</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<span>Description: </span>
|
||||||
|
<span class="char-num">{{present['description']}}</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<span>Items: </span>
|
||||||
|
<span class="char-num" style='white-space:pre'>{{present['items']}}</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<br />
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
39
latest version/templates/web/allredeem.html
Normal file
39
latest version/templates/web/allredeem.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}All redeem codes{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if posts %}<br />
|
||||||
|
{% for redeem in posts %}
|
||||||
|
|
||||||
|
<div class="char-redeem">
|
||||||
|
<span>Code: </span>
|
||||||
|
<span class="name">{{redeem['code']}}</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<span>Type: </span>
|
||||||
|
<span class="char-num">
|
||||||
|
{% if redeem['type'] == 0 %}
|
||||||
|
仅可使用一次 It can only be used once.
|
||||||
|
{% elif redeem['type'] == 1 %}
|
||||||
|
每个用户仅可以使用一次 Each user can only use it once.
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<span>Items: </span>
|
||||||
|
<span class="char-num" style='white-space:pre'>{{redeem['items']}}</span>
|
||||||
|
<br />
|
||||||
|
<div><a href="/web/redeem/{{redeem['code']}}">使用者 Players who have used it.</a></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<br />
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
37
latest version/templates/web/banuser.html
Normal file
37
latest version/templates/web/banuser.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Ban the user{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/banuser" method="post">
|
||||||
|
<div class="title">Ban the user</div>
|
||||||
|
<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">
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div class="content">提示:重设用户密码即可解封账号</div>
|
||||||
|
<div class="content">Tip: Reset the user password to unseal the account.</div>
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Execute">
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<form action="/web/banuser/deleteuserscore" method="post">
|
||||||
|
<div class="title">Delete all of the user's scores</div>
|
||||||
|
<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">
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div class="content">警告!这个操作具有破坏性,且不可恢复。</div>
|
||||||
|
<div class="content">Warning! This operation is destructive and unrecoverable.</div>
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Execute">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
39
latest version/templates/web/changepresent.html
Normal file
39
latest version/templates/web/changepresent.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Change the presents{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/changepresent/addpresent" method="post">
|
||||||
|
<div class="title">Add the present</div>
|
||||||
|
<label for="present_id">ID of the present</label>
|
||||||
|
<input name="present_id" id="present_id" required>
|
||||||
|
<label for="description">Description of the present</label>
|
||||||
|
<input name="description" id="description" required>
|
||||||
|
|
||||||
|
<label for="expire_ts">Expire time</label>
|
||||||
|
<input type="datetime-local" name="expire_ts" id="expire_ts" required>
|
||||||
|
<br />
|
||||||
|
<div>Items:</div>
|
||||||
|
<label for="fragment">Fragments</label>
|
||||||
|
<input name="fragment" id="fragment">
|
||||||
|
<label for="ticket">Memories</label>
|
||||||
|
<input name="ticket" id="ticket">
|
||||||
|
|
||||||
|
<div class="content">两种奖励只能有一个,另一个请留空。如果都填写,以记忆源点优先。</div>
|
||||||
|
<div class="content">There can only be one of the two kinds of present. Please leave the other one blank. If you
|
||||||
|
fill both, the memories will be given priority.</div>
|
||||||
|
<div class="content">时间填写是一个HTML5控件</div>
|
||||||
|
<div class="content">Time filling is an HTML5 control.</div>
|
||||||
|
<input type="submit" value="Add">
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<form action="/web/changepresent/deletepresent" method="post">
|
||||||
|
<div class="title">Delete the present</div>
|
||||||
|
<label for="present_id">ID of the present</label>
|
||||||
|
<input name="present_id" id="present_id" required>
|
||||||
|
|
||||||
|
<input type="submit" value="Delete">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
50
latest version/templates/web/changeredeem.html
Normal file
50
latest version/templates/web/changeredeem.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Change the redeem codes{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/changeredeem/addredeem" method="post">
|
||||||
|
<div class="title">Add the redeem</div>
|
||||||
|
<div>指定生成 Specify generation</div>
|
||||||
|
<label for="code">The redeem code</label>
|
||||||
|
<input name="code" id="code">
|
||||||
|
<div>Or</div>
|
||||||
|
<div>随机批量生成 Batch generation at random</div>
|
||||||
|
<label for="amount">Amount</label>
|
||||||
|
<input name="amount" id="amount">
|
||||||
|
<br />
|
||||||
|
<div>Type:
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<label><input type="radio" name="type" value="0" checked>仅可使用一次 It can only be used once.</label>
|
||||||
|
<br />
|
||||||
|
<label><input type="radio" name="type" value="1">每个用户仅可以使用一次 Each user can only use it once.</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div>Items:</div>
|
||||||
|
<label for="fragment">Fragments</label>
|
||||||
|
<input name="fragment" id="fragment">
|
||||||
|
<label for="ticket">Memories</label>
|
||||||
|
<input name="ticket" id="ticket">
|
||||||
|
|
||||||
|
<div class="content">两种奖励可以都有,不需要请留空。</div>
|
||||||
|
<div class="content">You can have both kinds of items. Please leave it blank if you don't need it.</div>
|
||||||
|
<div class="content">兑换码长度为10~20。</div>
|
||||||
|
<div class="content">The length of redeem code is 10 ~ 20.</div>
|
||||||
|
<div class="content">随机生成数量不得超过1000。</div>
|
||||||
|
<div class="content">The amount of batch generation should not be more than 1000.</div>
|
||||||
|
<input type="submit" value="Add">
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<form action="/web/changeredeem/deleteredeem" method="post">
|
||||||
|
<div class="title">Delete the redeem</div>
|
||||||
|
<label for="code">The redeem code</label>
|
||||||
|
<input name="code" id="code" required>
|
||||||
|
|
||||||
|
<input type="submit" value="Delete">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<br />
|
<br />
|
||||||
<hr />
|
<hr />
|
||||||
<form action="/web/changeuserpurchase/" method="post">
|
<form action="/web/changeuserpurchase/edituser" method="post">
|
||||||
<div class="title">Edit all the users</div>
|
<div class="title">Edit all the users</div>
|
||||||
<br />
|
<br />
|
||||||
<div>对所有单曲和曲包的操作 Operation to all singles and packs:
|
<div>对所有单曲和曲包的操作 Operation to all singles and packs:
|
||||||
|
|||||||
24
latest version/templates/web/changeuserpwd.html
Normal file
24
latest version/templates/web/changeuserpwd.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Change user password{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/changeuserpwd" method="post">
|
||||||
|
<div class="title">Edit the user's password</div>
|
||||||
|
<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">
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<label for="pwd">Password</label>
|
||||||
|
<input type="password" name="pwd" id="pwd" required>
|
||||||
|
<label for="pwd2">Enter again</label>
|
||||||
|
<input type="password" name="pwd2" id="pwd2" required>
|
||||||
|
|
||||||
|
<input type="submit" value="Edit">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
32
latest version/templates/web/deliverpresent.html
Normal file
32
latest version/templates/web/deliverpresent.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Deliver presents{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/deliverpresent" method="post">
|
||||||
|
<div class="title">Deliver to the user</div>
|
||||||
|
<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">
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<label for="present_id">ID of the present</label>
|
||||||
|
<input name="present_id" id="present_id" required>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Edit">
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<form action="/web/deliverpresent" method="post">
|
||||||
|
<div class="title">Deliver to all the users</div>
|
||||||
|
<label for="present_id">ID of the present</label>
|
||||||
|
<input name="present_id" id="present_id" required>
|
||||||
|
|
||||||
|
<input type="submit" value="Edit all">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -16,15 +16,24 @@
|
|||||||
<a href="{{ url_for('index.all_song') }}">铺面信息查询 All songs</a></br></br>
|
<a href="{{ url_for('index.all_song') }}">铺面信息查询 All songs</a></br></br>
|
||||||
<a href="{{ url_for('index.all_character') }}">角色信息查询 All characters</a></br></br>
|
<a href="{{ url_for('index.all_character') }}">角色信息查询 All characters</a></br></br>
|
||||||
<a href="{{ url_for('index.all_item') }}">购买信息查询 All items</a></br></br>
|
<a href="{{ url_for('index.all_item') }}">购买信息查询 All items</a></br></br>
|
||||||
|
<a href="{{ url_for('index.all_present') }}">奖励信息查询 All presents</a></br></br>
|
||||||
|
<a href="{{ url_for('index.all_redeem') }}">兑换码信息查询 All redeem codes</a></br></br>
|
||||||
<a href="{{ url_for('index.single_chart_top') }}">单个铺面排行榜查询 Single song chart tops</a>
|
<a href="{{ url_for('index.single_chart_top') }}">单个铺面排行榜查询 Single song chart tops</a>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>系统方面 System</h1>
|
<h1>系统方面 System</h1>
|
||||||
<a href="{{ url_for('index.update_database') }}">数据库更新 Update databases</a></br></br>
|
<a href="{{ url_for('index.update_database') }}">数据库更新 Update databases</a></br></br>
|
||||||
|
<a href="{{ url_for('index.edit_userpwd') }}">用户密码修改 Change user password</a></br></br>
|
||||||
|
<a href="{{ url_for('index.ban_user') }}">封禁用户 Ban the user</a></br></br>
|
||||||
|
<a href="{{ url_for('index.update_user_save') }}">用户存档更新 Update user saves</a></br></br>
|
||||||
<a href="{{ url_for('index.change_song') }}">歌曲修改 Change the songs</a></br></br>
|
<a href="{{ url_for('index.change_song') }}">歌曲修改 Change the songs</a></br></br>
|
||||||
<a href="{{ url_for('index.change_character') }}">角色修改 Change the characters</a></br></br>
|
<a href="{{ url_for('index.change_character') }}">角色修改 Change the characters</a></br></br>
|
||||||
<a href="{{ url_for('index.change_item') }}">购买信息修改 Change the items</a></br></br>
|
<a href="{{ url_for('index.change_item') }}">购买信息修改 Change the items</a></br></br>
|
||||||
<a href="{{ url_for('index.change_user') }}">用户信息修改 Change user information</a></br></br>
|
<a href="{{ url_for('index.change_user') }}">用户信息修改 Change user information</a></br></br>
|
||||||
<a href="{{ url_for('index.change_user_purchase') }}">用户购买信息修改 Change user purchase information</a>
|
<a href="{{ url_for('index.change_user_purchase') }}">用户购买信息修改 Change user purchase information</a></br></br>
|
||||||
|
<a href="{{ url_for('index.change_present') }}">奖励修改 Change the presents</a></br></br>
|
||||||
|
<a href="{{ url_for('index.deliver_present') }}">奖励分发 Deliver the presents</a></br></br>
|
||||||
|
<a href="{{ url_for('index.change_redeem') }}">兑换码修改 Change the redeem codes</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
24
latest version/templates/web/redeem.html
Normal file
24
latest version/templates/web/redeem.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Redeem - {{code}}{% 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>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<br />
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
<br />
|
||||||
|
<a href="{{ url_for('index.all_redeem') }}">Back</a>
|
||||||
|
{% endblock %}
|
||||||
@@ -12,10 +12,10 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。<br />
|
这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。<br />
|
||||||
可上传文件: arcaea_database.db和arcsong.db<br />
|
可上传文件: arcaea_database.db和arcsong.db<br />
|
||||||
新数据库不存在的数据会被添加,存在的数据将不会被改变。<br /><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
|
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 />
|
characters owned by players.<br />
|
||||||
Uploadable files: arcaea_database.db & arcsong.db<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.
|
Data that does not exist in the new database will be added and the existing duplicate data will also be changed.
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
30
latest version/templates/web/updateusersave.html
Normal file
30
latest version/templates/web/updateusersave.html
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block header %}
|
||||||
|
<h1>{% block title %}Update users' saves{% endblock %}</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="/web/updateusersave" method="post">
|
||||||
|
<div class="title">Update one user's saves to the database</div>
|
||||||
|
<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">
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<input type="submit" value="Update">
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<hr />
|
||||||
|
<form action="/web/updateusersave" method="post">
|
||||||
|
<div class="title">Update all users' saves to the database</div>
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Update all">
|
||||||
|
|
||||||
|
<div class="content">这里会将用户上传的存档覆盖到best_score表中,请注意是覆盖,不会进行分数比较。</div>
|
||||||
|
<div class="content">Here you can overlay the saves uploaded by users to best_score table. Please remember that it
|
||||||
|
is an overlay action, so scores will not be compared.</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -9,6 +9,7 @@ import web.system
|
|||||||
import time
|
import time
|
||||||
import server.arcscore
|
import server.arcscore
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
UPLOAD_FOLDER = 'database'
|
UPLOAD_FOLDER = 'database'
|
||||||
ALLOWED_EXTENSIONS = {'db'}
|
ALLOWED_EXTENSIONS = {'db'}
|
||||||
@@ -402,7 +403,7 @@ def all_character():
|
|||||||
def change_character():
|
def change_character():
|
||||||
# 修改角色数据
|
# 修改角色数据
|
||||||
skill_ids = ['No_skill', 'gauge_easy', 'note_mirror', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
skill_ids = ['No_skill', 'gauge_easy', 'note_mirror', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
||||||
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', 'frags_kou', 'visual_ink', 'shirabe_entry_fee', 'frags_yume']
|
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', 'frags_kou', 'visual_ink', 'shirabe_entry_fee', 'frags_yume', 'note_mirror|visual_hide_far', 'frags_ongeki']
|
||||||
return render_template('web/changechar.html', skill_ids=skill_ids)
|
return render_template('web/changechar.html', skill_ids=skill_ids)
|
||||||
|
|
||||||
|
|
||||||
@@ -564,7 +565,6 @@ def edit_user():
|
|||||||
'''select user_id from user where name=:a''', {'a': name})
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
user_id = c.fetchone()
|
user_id = c.fetchone()
|
||||||
posts = []
|
|
||||||
if user_id:
|
if user_id:
|
||||||
user_id = user_id[0]
|
user_id = user_id[0]
|
||||||
|
|
||||||
@@ -642,7 +642,6 @@ def edit_user_purchase():
|
|||||||
'''select user_id from user where name=:a''', {'a': name})
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
user_id = c.fetchone()
|
user_id = c.fetchone()
|
||||||
posts = []
|
|
||||||
if user_id:
|
if user_id:
|
||||||
user_id = user_id[0]
|
user_id = user_id[0]
|
||||||
|
|
||||||
@@ -717,11 +716,13 @@ def change_item():
|
|||||||
else:
|
else:
|
||||||
orig_price = None
|
orig_price = None
|
||||||
if discount_from:
|
if discount_from:
|
||||||
discount_from = int(time.mktime(time.strptime(discount_from, "%Y-%m-%dT%H:%M"))) * 1000
|
discount_from = int(time.mktime(time.strptime(
|
||||||
|
discount_from, "%Y-%m-%dT%H:%M"))) * 1000
|
||||||
else:
|
else:
|
||||||
discount_from = None
|
discount_from = None
|
||||||
if discount_to:
|
if discount_to:
|
||||||
discount_to = int(time.mktime(time.strptime(discount_to, "%Y-%m-%dT%H:%M"))) * 1000
|
discount_to = int(time.mktime(time.strptime(
|
||||||
|
discount_to, "%Y-%m-%dT%H:%M"))) * 1000
|
||||||
else:
|
else:
|
||||||
discount_to = None
|
discount_to = None
|
||||||
except:
|
except:
|
||||||
@@ -767,3 +768,500 @@ def change_item():
|
|||||||
flash(error)
|
flash(error)
|
||||||
|
|
||||||
return render_template('web/changeitem.html')
|
return render_template('web/changeitem.html')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/updateusersave', methods=['POST', 'GET'])
|
||||||
|
@login_required
|
||||||
|
def update_user_save():
|
||||||
|
# 将用户存档覆盖到分数表中
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('web/updateusersave.html')
|
||||||
|
|
||||||
|
error = None
|
||||||
|
flag = True
|
||||||
|
name = None
|
||||||
|
user_code = None
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
# 全修改
|
||||||
|
if 'name' not in request.form and 'user_code' not in request.form:
|
||||||
|
flag = False
|
||||||
|
web.system.update_all_save(c)
|
||||||
|
flash("全部用户存档同步成功 Successfully update all users' saves.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
name = request.form['name']
|
||||||
|
user_code = request.form['user_code']
|
||||||
|
|
||||||
|
# 指定修改
|
||||||
|
if name or user_code:
|
||||||
|
|
||||||
|
if user_code:
|
||||||
|
c.execute('''select user_id from user where user_code=:a''', {
|
||||||
|
'a': user_code})
|
||||||
|
else:
|
||||||
|
c.execute(
|
||||||
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
|
user_id = c.fetchone()
|
||||||
|
if user_id:
|
||||||
|
user_id = user_id[0]
|
||||||
|
web.system.update_one_save(c, user_id)
|
||||||
|
flash("用户存档同步成功 Successfully update the user's saves.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '玩家不存在 The player does not exist.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
if flag:
|
||||||
|
error = '输入为空 Null Input.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
|
||||||
|
return render_template('web/updateusersave.html')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/allpresent', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def all_present():
|
||||||
|
# 所有奖励数据
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''select * from present''')
|
||||||
|
x = c.fetchall()
|
||||||
|
error = None
|
||||||
|
if x:
|
||||||
|
posts = []
|
||||||
|
for i in x:
|
||||||
|
items = json.loads(i[2])
|
||||||
|
items_string = ''
|
||||||
|
for j in items:
|
||||||
|
items_string = items_string + '\n' + \
|
||||||
|
str(j['id']) + ': ' + str(j['amount'])
|
||||||
|
|
||||||
|
posts.append({'present_id': i[0],
|
||||||
|
'expire_ts': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(i[1])//1000)),
|
||||||
|
'items': items_string,
|
||||||
|
'description': i[3]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
error = '没有奖励数据 No present data.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
return render_template('web/allpresent.html')
|
||||||
|
else:
|
||||||
|
return render_template('web/allpresent.html', posts=posts)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changepresent', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def change_present():
|
||||||
|
# 修改奖励数据
|
||||||
|
return render_template('web/changepresent.html')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changepresent/addpresent', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def add_present():
|
||||||
|
# 添加奖励数据
|
||||||
|
present_id = request.form['present_id']
|
||||||
|
expire_ts = request.form['expire_ts']
|
||||||
|
description = request.form['description']
|
||||||
|
fragment = request.form['fragment']
|
||||||
|
ticket = request.form['ticket']
|
||||||
|
try:
|
||||||
|
if ticket:
|
||||||
|
ticket = int(ticket)
|
||||||
|
if fragment:
|
||||||
|
fragment = int(fragment)
|
||||||
|
expire_ts = int(time.mktime(time.strptime(
|
||||||
|
expire_ts, "%Y-%m-%dT%H:%M"))) * 1000
|
||||||
|
except:
|
||||||
|
flash('数据错误 Wrong data.')
|
||||||
|
return redirect(url_for('index.change_present'))
|
||||||
|
|
||||||
|
if len(present_id) >= 256:
|
||||||
|
present_id = present_id[:200]
|
||||||
|
if len(description) >= 256:
|
||||||
|
description = description[:200]
|
||||||
|
|
||||||
|
items = []
|
||||||
|
if ticket:
|
||||||
|
items.append({'type': 'memory', 'id': 'memory', 'amount': ticket})
|
||||||
|
if fragment:
|
||||||
|
items.append(
|
||||||
|
{'type': 'fragment', 'id': 'fragment', 'amount': fragment})
|
||||||
|
if items == []:
|
||||||
|
flash('奖励为空 No items.')
|
||||||
|
return redirect(url_for('index.change_present'))
|
||||||
|
|
||||||
|
message = web.system.add_one_present(
|
||||||
|
present_id, expire_ts, description, json.dumps(items))
|
||||||
|
|
||||||
|
if message:
|
||||||
|
flash(message)
|
||||||
|
|
||||||
|
return redirect(url_for('index.change_present'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changepresent/deletepresent', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def delete_present():
|
||||||
|
# 删除奖励数据
|
||||||
|
present_id = request.form['present_id']
|
||||||
|
message = web.system.delete_one_present(present_id)
|
||||||
|
|
||||||
|
if message:
|
||||||
|
flash(message)
|
||||||
|
|
||||||
|
return redirect(url_for('index.change_present'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/deliverpresent', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def deliver_present():
|
||||||
|
# 分发奖励
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('web/deliverpresent.html')
|
||||||
|
|
||||||
|
error = None
|
||||||
|
flag = True
|
||||||
|
name = None
|
||||||
|
user_code = None
|
||||||
|
present_id = request.form['present_id']
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
if not web.system.is_present_available(c, present_id):
|
||||||
|
flash("奖励不存在 The present does not exist.")
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return render_template('web/deliverpresent.html')
|
||||||
|
|
||||||
|
# 全修改
|
||||||
|
if 'name' not in request.form and 'user_code' not in request.form:
|
||||||
|
flag = False
|
||||||
|
web.system.deliver_all_user_present(c, present_id)
|
||||||
|
flash("全部用户奖励分发成功 Successfully deliver the present to all users.")
|
||||||
|
else:
|
||||||
|
name = request.form['name']
|
||||||
|
user_code = request.form['user_code']
|
||||||
|
|
||||||
|
# 指定修改f
|
||||||
|
if name or user_code:
|
||||||
|
if user_code:
|
||||||
|
c.execute('''select user_id from user where user_code=:a''', {
|
||||||
|
'a': user_code})
|
||||||
|
else:
|
||||||
|
c.execute(
|
||||||
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
|
user_id = c.fetchone()
|
||||||
|
if user_id:
|
||||||
|
user_id = user_id[0]
|
||||||
|
web.system.deliver_one_user_present(c, present_id, user_id)
|
||||||
|
flash("用户奖励分发成功 Successfully deliver the present to the user.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '玩家不存在 The player does not exist.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
if flag:
|
||||||
|
error = '输入为空 Null Input.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
|
||||||
|
return render_template('web/deliverpresent.html')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/allredeem', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def all_redeem():
|
||||||
|
# 所有兑换码数据
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''select * from redeem''')
|
||||||
|
x = c.fetchall()
|
||||||
|
error = None
|
||||||
|
if x:
|
||||||
|
posts = []
|
||||||
|
for i in x:
|
||||||
|
items = json.loads(i[1])
|
||||||
|
items_string = ''
|
||||||
|
for j in items:
|
||||||
|
items_string = items_string + '\n' + \
|
||||||
|
str(j['id']) + ': ' + str(j['amount'])
|
||||||
|
|
||||||
|
posts.append({'code': i[0],
|
||||||
|
'items': items_string,
|
||||||
|
'type': i[2]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
error = '没有兑换码数据 No redeem code data.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
return render_template('web/allredeem.html')
|
||||||
|
else:
|
||||||
|
return render_template('web/allredeem.html', posts=posts)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changeredeem', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def change_redeem():
|
||||||
|
# 修改兑换码数据
|
||||||
|
return render_template('web/changeredeem.html')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changeredeem/addredeem', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def add_redeem():
|
||||||
|
# 添加兑换码数据
|
||||||
|
print(request.form)
|
||||||
|
code = request.form['code']
|
||||||
|
amount = request.form['amount']
|
||||||
|
redeem_type = request.form['type']
|
||||||
|
fragment = request.form['fragment']
|
||||||
|
ticket = request.form['ticket']
|
||||||
|
try:
|
||||||
|
if amount:
|
||||||
|
amount = int(amount)
|
||||||
|
if ticket:
|
||||||
|
ticket = int(ticket)
|
||||||
|
if fragment:
|
||||||
|
fragment = int(fragment)
|
||||||
|
except:
|
||||||
|
flash('数据错误 Wrong data.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
items = []
|
||||||
|
if ticket:
|
||||||
|
items.append({'type': 'memory', 'id': 'memory', 'amount': ticket})
|
||||||
|
if fragment:
|
||||||
|
items.append(
|
||||||
|
{'type': 'fragment', 'id': 'fragment', 'amount': fragment})
|
||||||
|
if items == []:
|
||||||
|
flash('奖励为空 No items.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
if code and not amount:
|
||||||
|
if len(code) > 20 or len(code) < 10:
|
||||||
|
flash('兑换码长度不合适 Inappropriate length of redeem code.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
message = web.system.add_one_redeem(
|
||||||
|
code, redeem_type, json.dumps(items))
|
||||||
|
elif amount and not code:
|
||||||
|
if amount <= 0 or amount > 1000:
|
||||||
|
flash('数量错误 Wrong amount.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
message = web.system.add_some_random_redeem(
|
||||||
|
amount, redeem_type, json.dumps(items))
|
||||||
|
elif amount and code:
|
||||||
|
flash('只能使用一种添加方式 Only one add method can be used.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
else:
|
||||||
|
flash('空输入 Null input.')
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
if message:
|
||||||
|
flash(message)
|
||||||
|
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changeredeem/deleteredeem', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def delete_redeem():
|
||||||
|
# 删除兑换码数据
|
||||||
|
code = request.form['code']
|
||||||
|
message = web.system.delete_one_redeem(code)
|
||||||
|
|
||||||
|
if message:
|
||||||
|
flash(message)
|
||||||
|
|
||||||
|
return redirect(url_for('index.change_redeem'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/redeem/<code>', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def one_redeem(code):
|
||||||
|
# 某个兑换码的用户使用情况数据
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
'''select user_id, name, user_code from user where user_id in (select user_id from user_redeem where code=:a)''', {'a': code})
|
||||||
|
x = c.fetchall()
|
||||||
|
error = None
|
||||||
|
if x:
|
||||||
|
posts = []
|
||||||
|
for i in x:
|
||||||
|
posts.append({'user_id': i[0],
|
||||||
|
'name': i[1],
|
||||||
|
'user_code': i[2]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
error = '没有数据 No data.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
return render_template('web/redeem.html', code=code)
|
||||||
|
else:
|
||||||
|
return render_template('web/redeem.html', posts=posts, code=code)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/changeuserpwd', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def edit_userpwd():
|
||||||
|
# 修改用户密码
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('web/changeuserpwd.html')
|
||||||
|
|
||||||
|
error = None
|
||||||
|
|
||||||
|
name = request.form['name']
|
||||||
|
user_code = request.form['user_code']
|
||||||
|
pwd = request.form['pwd']
|
||||||
|
pwd2 = request.form['pwd2']
|
||||||
|
if pwd != pwd2:
|
||||||
|
flash('两次输入的密码不一致 Entered passwords differ!')
|
||||||
|
return render_template('web/changeuserpwd.html')
|
||||||
|
else:
|
||||||
|
if len(pwd) < 8 or len(pwd) > 20:
|
||||||
|
flash('密码太长或太短 Password is too long or too short!')
|
||||||
|
return render_template('web/changeuserpwd.html')
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
if name or user_code:
|
||||||
|
|
||||||
|
if user_code:
|
||||||
|
c.execute('''select user_id from user where user_code=:a''', {
|
||||||
|
'a': user_code})
|
||||||
|
else:
|
||||||
|
c.execute(
|
||||||
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
|
user_id = c.fetchone()
|
||||||
|
if user_id:
|
||||||
|
user_id = user_id[0]
|
||||||
|
web.system.change_userpwd(c, user_id, pwd)
|
||||||
|
flash('用户密码修改成功 Successfully edit the user information.')
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '玩家不存在 The player does not exist.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '输入为空 Null Input.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
|
||||||
|
return redirect(url_for('index.edit_userpwd'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/banuser', methods=['POST', 'GET'])
|
||||||
|
@login_required
|
||||||
|
def ban_user():
|
||||||
|
# 封禁用户
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('web/banuser.html')
|
||||||
|
|
||||||
|
error = None
|
||||||
|
|
||||||
|
name = request.form['name']
|
||||||
|
user_code = request.form['user_code']
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
if name or user_code:
|
||||||
|
if user_code:
|
||||||
|
c.execute('''select user_id from user where user_code=:a''', {
|
||||||
|
'a': user_code})
|
||||||
|
else:
|
||||||
|
c.execute(
|
||||||
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
|
user_id = c.fetchone()
|
||||||
|
if user_id:
|
||||||
|
user_id = user_id[0]
|
||||||
|
web.system.ban_one_user(c, user_id)
|
||||||
|
flash('用户封禁成功 Successfully ban the user.')
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '玩家不存在 The player does not exist.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '输入为空 Null Input.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
|
||||||
|
return redirect(url_for('index.ban_user'))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/banuser/deleteuserscore', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def delete_user_score():
|
||||||
|
# 删除用户所有成绩
|
||||||
|
error = None
|
||||||
|
|
||||||
|
name = request.form['name']
|
||||||
|
user_code = request.form['user_code']
|
||||||
|
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
if name or user_code:
|
||||||
|
if user_code:
|
||||||
|
c.execute('''select user_id from user where user_code=:a''', {
|
||||||
|
'a': user_code})
|
||||||
|
else:
|
||||||
|
c.execute(
|
||||||
|
'''select user_id from user where name=:a''', {'a': name})
|
||||||
|
|
||||||
|
user_id = c.fetchone()
|
||||||
|
if user_id:
|
||||||
|
user_id = user_id[0]
|
||||||
|
web.system.clear_user_score(c, user_id)
|
||||||
|
flash("用户成绩删除成功 Successfully delete the user's scores.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '玩家不存在 The player does not exist.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
error = '输入为空 Null Input.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
if error:
|
||||||
|
flash(error)
|
||||||
|
|
||||||
|
return redirect(url_for('index.ban_user'))
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import time
|
import time
|
||||||
|
import json
|
||||||
|
import server.arcscore
|
||||||
|
import hashlib
|
||||||
|
from random import Random
|
||||||
|
|
||||||
|
|
||||||
def int2b(x):
|
def int2b(x):
|
||||||
@@ -11,6 +15,17 @@ def int2b(x):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def random_str(randomlength=10):
|
||||||
|
# 随机生成字符串
|
||||||
|
s = ''
|
||||||
|
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
|
||||||
|
length = len(chars) - 1
|
||||||
|
random = Random()
|
||||||
|
for i in range(randomlength):
|
||||||
|
s += chars[random.randint(0, length)]
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
def get_table_info(c, table_name):
|
def get_table_info(c, table_name):
|
||||||
# 得到表结构,返回主键列表和字段名列表
|
# 得到表结构,返回主键列表和字段名列表
|
||||||
pk = []
|
pk = []
|
||||||
@@ -83,8 +98,25 @@ def get_sql_insert_table(table_name, field, value):
|
|||||||
return sql, sql_dict
|
return sql, sql_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_sql_delete_table(table_name, where_field=[], where_value=[]):
|
||||||
|
# sql语句拼接,delete from ... where ...
|
||||||
|
sql = 'delete from ' + table_name
|
||||||
|
sql_dict = {}
|
||||||
|
|
||||||
|
if where_field and where_value:
|
||||||
|
sql += ' where '
|
||||||
|
sql += where_field[0] + '=:' + where_field[0]
|
||||||
|
sql_dict[where_field[0]] = where_value[0]
|
||||||
|
if len(where_field) >= 1:
|
||||||
|
for i in range(1, len(where_field)):
|
||||||
|
sql_dict[where_field[i]] = where_value[i]
|
||||||
|
sql += ' and ' + where_field[i] + '=:' + where_field[i]
|
||||||
|
|
||||||
|
return sql, sql_dict
|
||||||
|
|
||||||
|
|
||||||
def update_one_table(c1, c2, table_name):
|
def update_one_table(c1, c2, table_name):
|
||||||
# 从c1向c2更新数据表,c2中存在的信息不变
|
# 从c1向c2更新数据表,c1中存在的信息不变
|
||||||
c1.execute(
|
c1.execute(
|
||||||
'''select * from sqlite_master where type = 'table' and name = :a''', {'a': table_name})
|
'''select * from sqlite_master where type = 'table' and name = :a''', {'a': table_name})
|
||||||
c2.execute(
|
c2.execute(
|
||||||
@@ -115,7 +147,11 @@ def update_one_table(c1, c2, table_name):
|
|||||||
sql = 'select exists(' + sql + ')'
|
sql = 'select exists(' + sql + ')'
|
||||||
c2.execute(sql, sql_dict)
|
c2.execute(sql, sql_dict)
|
||||||
|
|
||||||
if c2.fetchone() == (0,):
|
if c2.fetchone() == (1,): # 如果c2里存在,先删除
|
||||||
|
sql, sql_dict = get_sql_delete_table(
|
||||||
|
table_name, db1_pk, list(x[i]))
|
||||||
|
c2.execute(sql, sql_dict)
|
||||||
|
|
||||||
sql, sql_dict = get_sql_insert_table(
|
sql, sql_dict = get_sql_insert_table(
|
||||||
table_name, field, list(y[i]))
|
table_name, field, list(y[i]))
|
||||||
c2.execute(sql, sql_dict)
|
c2.execute(sql, sql_dict)
|
||||||
@@ -140,7 +176,7 @@ def update_user_char(c):
|
|||||||
|
|
||||||
def update_database():
|
def update_database():
|
||||||
# 将old数据库不存在数据加入到新数据库上,并删除old数据库
|
# 将old数据库不存在数据加入到新数据库上,并删除old数据库
|
||||||
# 对于arcaea_datebase.db,更新best_score,friend,recent30,user,user_world, user_item并用character数据更新user_char
|
# 对于arcaea_datebase.db,更新一些表,并用character数据更新user_char
|
||||||
# 对于arcsong.db,更新songs
|
# 对于arcsong.db,更新songs
|
||||||
if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile("database/arcaea_database.db"):
|
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')
|
conn1 = sqlite3.connect('./database/old_arcaea_database.db')
|
||||||
@@ -153,7 +189,14 @@ def update_database():
|
|||||||
update_one_table(c1, c2, 'best_score')
|
update_one_table(c1, c2, 'best_score')
|
||||||
update_one_table(c1, c2, 'recent30')
|
update_one_table(c1, c2, 'recent30')
|
||||||
update_one_table(c1, c2, 'user_world')
|
update_one_table(c1, c2, 'user_world')
|
||||||
|
update_one_table(c1, c2, 'item')
|
||||||
update_one_table(c1, c2, 'user_item')
|
update_one_table(c1, c2, 'user_item')
|
||||||
|
update_one_table(c1, c2, 'user_save')
|
||||||
|
update_one_table(c1, c2, 'login')
|
||||||
|
update_one_table(c1, c2, 'present')
|
||||||
|
update_one_table(c1, c2, 'user_present')
|
||||||
|
update_one_table(c1, c2, 'redeem')
|
||||||
|
update_one_table(c1, c2, 'user_redeem')
|
||||||
|
|
||||||
update_user_char(c2)
|
update_user_char(c2)
|
||||||
|
|
||||||
@@ -243,3 +286,221 @@ def get_all_item():
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return re
|
return re
|
||||||
|
|
||||||
|
|
||||||
|
def update_one_save(c, user_id):
|
||||||
|
# 同步指定用户存档
|
||||||
|
# 注意,best_score表不比较,直接覆盖
|
||||||
|
|
||||||
|
c.execute('''select scores_data, clearlamps_data from user_save where user_id=:a''', {
|
||||||
|
'a': user_id})
|
||||||
|
x = c.fetchone()
|
||||||
|
if x:
|
||||||
|
scores = json.loads(x[0])[""]
|
||||||
|
clearlamps = json.loads(x[1])[""]
|
||||||
|
clear_song_id_difficulty = []
|
||||||
|
clear_state = []
|
||||||
|
for i in clearlamps:
|
||||||
|
clear_song_id_difficulty.append(i['song_id']+str(i['difficulty']))
|
||||||
|
clear_state.append(i['clear_type'])
|
||||||
|
|
||||||
|
for i in scores:
|
||||||
|
rating = server.arcscore.get_one_ptt(
|
||||||
|
i['song_id'], i['difficulty'], i['score'])
|
||||||
|
if rating < 0:
|
||||||
|
rating = 0
|
||||||
|
try:
|
||||||
|
index = clear_song_id_difficulty.index(
|
||||||
|
i['song_id'] + str(i['difficulty']))
|
||||||
|
except:
|
||||||
|
index = -1
|
||||||
|
if index != -1:
|
||||||
|
clear_type = clear_state[index]
|
||||||
|
else:
|
||||||
|
clear_type = 0
|
||||||
|
c.execute('''delete from best_score where user_id=:a and song_id=:b and difficulty=:c''', {
|
||||||
|
'a': user_id, 'b': i['song_id'], 'c': i['difficulty']})
|
||||||
|
c.execute('''insert into best_score values(:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, :l, :m, :n)''', {
|
||||||
|
'a': user_id, 'b': i['song_id'], 'c': i['difficulty'], 'd': i['score'], 'e': i['shiny_perfect_count'], 'f': i['perfect_count'], 'g': i['near_count'], 'h': i['miss_count'], 'i': i['health'], 'j': i['modifier'], 'k': i['time_played'], 'l': clear_type, 'm': clear_type, 'n': rating})
|
||||||
|
|
||||||
|
ptt = server.arcscore.get_user_ptt(c, user_id) # 更新PTT
|
||||||
|
c.execute('''update user set rating_ptt=:a where user_id=:b''', {
|
||||||
|
'a': ptt, 'b': user_id})
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def update_all_save(c):
|
||||||
|
# 同步所有用户存档
|
||||||
|
|
||||||
|
c.execute('''select user_id from user_save''')
|
||||||
|
x = c.fetchall()
|
||||||
|
if x:
|
||||||
|
for i in x:
|
||||||
|
update_one_save(c, i[0])
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def add_one_present(present_id, expire_ts, description, items):
|
||||||
|
# 添加一个奖励
|
||||||
|
|
||||||
|
message = None
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from present where present_id=:a)''', {'a': present_id})
|
||||||
|
if c.fetchone() == (0,):
|
||||||
|
c.execute('''insert into present values(:a,:b,:c,:d)''', {
|
||||||
|
'a': present_id, 'b': expire_ts, 'c': items, 'd': description})
|
||||||
|
message = '添加成功 Successfully add it.'
|
||||||
|
else:
|
||||||
|
message = '奖励已存在 The present exists.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def delete_one_present(present_id):
|
||||||
|
# 删除一个奖励
|
||||||
|
|
||||||
|
message = None
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from present where present_id=:a)''', {'a': present_id})
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
c.execute('''delete from present where present_id = :a''',
|
||||||
|
{'a': present_id})
|
||||||
|
c.execute('''delete from user_present where present_id =:a''', {
|
||||||
|
'a': present_id})
|
||||||
|
message = '删除成功 Successfully delete it.'
|
||||||
|
else:
|
||||||
|
message = '奖励不存在 The present does not exist.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def is_present_available(c, present_id):
|
||||||
|
# 判断present_id是否有效
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from present where present_id = :a)''', {'a': present_id})
|
||||||
|
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def deliver_one_user_present(c, present_id, user_id):
|
||||||
|
# 为指定玩家添加奖励,重复添加不会提示
|
||||||
|
c.execute('''select exists(select * from user_present where user_id=:a and present_id=:b)''',
|
||||||
|
{'a': user_id, 'b': present_id})
|
||||||
|
if c.fetchone() == (0,):
|
||||||
|
c.execute('''insert into user_present values(:a,:b)''',
|
||||||
|
{'a': user_id, 'b': present_id})
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def deliver_all_user_present(c, present_id):
|
||||||
|
# 为所有玩家添加奖励
|
||||||
|
c.execute('''select user_id from user''')
|
||||||
|
x = c.fetchall()
|
||||||
|
if x:
|
||||||
|
c.execute('''delete from user_present where present_id=:b''',
|
||||||
|
{'b': present_id})
|
||||||
|
for i in x:
|
||||||
|
c.execute('''insert into user_present values(:a,:b)''',
|
||||||
|
{'a': i[0], 'b': present_id})
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def add_one_redeem(code, redeem_type, items):
|
||||||
|
# 添加一个兑换码
|
||||||
|
|
||||||
|
message = None
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from redeem where code=:a)''', {'a': code})
|
||||||
|
if c.fetchone() == (0,):
|
||||||
|
c.execute('''insert into redeem values(:a,:b,:c)''', {
|
||||||
|
'a': code, 'b': items, 'c': redeem_type})
|
||||||
|
message = '添加成功 Successfully add it.'
|
||||||
|
else:
|
||||||
|
message = '兑换码已存在 The redeem code exists.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def add_some_random_redeem(amount, redeem_type, items):
|
||||||
|
# 随机生成一堆10位的兑换码
|
||||||
|
|
||||||
|
message = None
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
i = 0
|
||||||
|
while i <= amount:
|
||||||
|
code = random_str()
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from redeem where code=:a)''', {'a': code})
|
||||||
|
if c.fetchone() == (0,):
|
||||||
|
c.execute('''insert into redeem values(:a,:b,:c)''',
|
||||||
|
{'a': code, 'b': items, 'c': redeem_type})
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
message = '添加成功 Successfully add it.'
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def delete_one_redeem(code):
|
||||||
|
# 删除一个兑换码
|
||||||
|
|
||||||
|
message = None
|
||||||
|
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute(
|
||||||
|
'''select exists(select * from redeem where code=:a)''', {'a': code})
|
||||||
|
if c.fetchone() == (1,):
|
||||||
|
c.execute('''delete from redeem where code = :a''', {'a': code})
|
||||||
|
c.execute('''delete from user_redeem where code =:a''', {'a': code})
|
||||||
|
message = '删除成功 Successfully delete it.'
|
||||||
|
else:
|
||||||
|
message = '兑换码不存在 The redeem code does not exist.'
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def change_userpwd(c, user_id, password):
|
||||||
|
# 修改用户密码
|
||||||
|
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||||
|
c.execute('''update user set password =:a where user_id=:b''',
|
||||||
|
{'a': hash_pwd, 'b': user_id})
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def ban_one_user(c, user_id):
|
||||||
|
# 封禁用户
|
||||||
|
c.execute('''update user set password = '' where user_id=:a''',
|
||||||
|
{'a': user_id})
|
||||||
|
c.execute('''delete from login where user_id=:a''', {'a': user_id})
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def clear_user_score(c, user_id):
|
||||||
|
# 清除用户所有成绩,包括best_score和recent30,以及recent数据,但不包括云端存档
|
||||||
|
c.execute('''update user set rating_ptt=0, song_id='', difficulty=0, score=0, shiny_perfect_count=0, perfect_count=0, near_count=0, miss_count=0, health=0, time_played=0, rating=0 where user_id=:a''',
|
||||||
|
{'a': user_id})
|
||||||
|
c.execute('''delete from best_score where user_id=:a''', {'a': user_id})
|
||||||
|
c.execute('''delete from recent30 where user_id=:a''', {'a': user_id})
|
||||||
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user