mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2026-02-05 06:17:57 +08:00
@@ -1,6 +1,11 @@
|
||||
import os
|
||||
import hashlib
|
||||
from flask import url_for
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
time_limit = 3000 # 每个玩家24小时下载次数限制
|
||||
time_gap_limit = 1000 # 下载链接有效秒数
|
||||
|
||||
|
||||
def get_file_md5(file_path):
|
||||
@@ -18,31 +23,105 @@ def get_file_md5(file_path):
|
||||
return myhash.hexdigest()
|
||||
|
||||
|
||||
def get_one_song(song_id, file_dir='./database/songs'):
|
||||
def get_one_song(c, user_id, song_id, file_dir='./database/songs'):
|
||||
# 获取一首歌的下载链接,返回字典
|
||||
dir_list = os.listdir(os.path.join(file_dir, song_id))
|
||||
re = {}
|
||||
now = int(time.time())
|
||||
c.execute('''delete from download_token where user_id=:a and song_id=:b''', {
|
||||
'a': user_id, 'b': 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']:
|
||||
token = hashlib.md5(
|
||||
(str(user_id) + song_id + i + str(now)).encode(encoding='UTF-8')).hexdigest()
|
||||
token = token[:8]
|
||||
|
||||
if i == 'base.ogg':
|
||||
re['audio'] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, 'base.ogg')),
|
||||
"url": url_for('download', file_path=song_id+'/base.ogg', _external=True)}
|
||||
"url": url_for('download', file_path=song_id+'/base.ogg', t=token, _external=True)}
|
||||
else:
|
||||
if 'chart' not in re:
|
||||
re['chart'] = {}
|
||||
|
||||
re['chart'][i[0]] = {"checksum": get_file_md5(os.path.join(file_dir, song_id, i)),
|
||||
"url": url_for('download', file_path=song_id+'/'+i, _external=True)}
|
||||
"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)''', {
|
||||
'a': user_id, 'b': song_id, 'c': i, 'd': token, 'e': now})
|
||||
|
||||
return {song_id: re}
|
||||
|
||||
|
||||
def get_all_songs(file_dir='./database/songs'):
|
||||
def get_all_songs(user_id, file_dir='./database/songs'):
|
||||
# 获取所有歌的下载链接,返回字典
|
||||
dir_list = os.listdir(file_dir)
|
||||
re = {}
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
for i in dir_list:
|
||||
if os.path.isdir(os.path.join(file_dir, i)):
|
||||
re.update(get_one_song(i))
|
||||
re.update(get_one_song(c, user_id, i))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def get_some_songs(user_id, song_ids):
|
||||
# 获取一些歌的下载链接,返回字典
|
||||
re = {}
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
for song_id in song_ids:
|
||||
re.update(get_one_song(c, user_id, song_id))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def is_token_able_download(t):
|
||||
# token是否可以下载,返回错误码,0即可以
|
||||
errorcode = 0
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select * from download_token where token = :t limit 1''',
|
||||
{'t': t})
|
||||
x = c.fetchone()
|
||||
now = int(time.time())
|
||||
if x and now - x[4] <= time_gap_limit:
|
||||
c.execute(
|
||||
'''select count(*) from user_download where user_id = :a''', {'a': x[0]})
|
||||
y = c.fetchone()
|
||||
if y and y[0] <= time_limit:
|
||||
c.execute('''insert into user_download values(:a,:b,:c)''', {
|
||||
'a': x[0], 'b': x[3], 'c': now})
|
||||
else:
|
||||
errorcode = 903
|
||||
else:
|
||||
errorcode = 108
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return errorcode
|
||||
|
||||
|
||||
def is_able_download(user_id):
|
||||
# 是否可以下载,返回布尔值
|
||||
f = True
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
now = int(time.time())
|
||||
c.execute(
|
||||
'''delete from user_download where user_id = :a and time <= :b''', {'a': user_id, 'b': now - 24*3600})
|
||||
c.execute(
|
||||
'''select count(*) from user_download where user_id = :a''', {'a': user_id})
|
||||
y = c.fetchone()
|
||||
if y and y[0] <= time_limit:
|
||||
pass
|
||||
else:
|
||||
f = False
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return f
|
||||
|
||||
122
latest version/server/arcpurchase.py
Normal file
122
latest version/server/arcpurchase.py
Normal file
@@ -0,0 +1,122 @@
|
||||
import sqlite3
|
||||
|
||||
|
||||
def int2b(x):
|
||||
# int与布尔值转换
|
||||
if x is None or x == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def get_item(c, type='pack'):
|
||||
# 读取packs内容,返回字典列表
|
||||
c.execute('''select * from item where type = :a''', {'a': type})
|
||||
x = c.fetchall()
|
||||
if not x:
|
||||
return []
|
||||
|
||||
re = []
|
||||
for i in x:
|
||||
r = {"name": i[0],
|
||||
"items": [{
|
||||
"type": i[1],
|
||||
"id": i[0],
|
||||
"is_available": int2b(i[2])
|
||||
}],
|
||||
"price": i[3],
|
||||
"orig_price": i[4]}
|
||||
|
||||
if i[5] > 0:
|
||||
r['discount_from'] = i[5]
|
||||
if i[6] > 0:
|
||||
r['discount_to'] = i[6]
|
||||
|
||||
re.append(r)
|
||||
|
||||
return re
|
||||
|
||||
|
||||
def get_single_purchase():
|
||||
# main里面没开数据库,这里写一下代替
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
re = get_item(c, type='single')
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return re
|
||||
|
||||
|
||||
def buy_pack(user_id, pack_id):
|
||||
# 曲包购买,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select price from item where item_id = :a''', {'a': pack_id})
|
||||
price = c.fetchone()
|
||||
if price:
|
||||
price = price[0]
|
||||
else:
|
||||
price = 0
|
||||
|
||||
c.execute('''select ticket from user where user_id = :a''', {'a': user_id})
|
||||
ticket = c.fetchone()
|
||||
if ticket:
|
||||
ticket = ticket[0]
|
||||
else:
|
||||
ticket = 0
|
||||
|
||||
if ticket < price:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return {
|
||||
"success": False
|
||||
}
|
||||
|
||||
c.execute('''update user set ticket = :b where user_id = :a''',
|
||||
{'a': user_id, 'b': ticket-price})
|
||||
c.execute('''insert into user_item values(:a,:b,'pack')''',
|
||||
{'a': user_id, 'b': pack_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return {
|
||||
"success": True
|
||||
}
|
||||
|
||||
|
||||
def buy_single(user_id, single_id):
|
||||
# 单曲购买,返回字典
|
||||
conn = sqlite3.connect('./database/arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''select price from item where item_id = :a''',
|
||||
{'a': single_id})
|
||||
price = c.fetchone()
|
||||
if price:
|
||||
price = price[0]
|
||||
else:
|
||||
price = 0
|
||||
|
||||
c.execute('''select ticket from user where user_id = :a''', {'a': user_id})
|
||||
ticket = c.fetchone()
|
||||
if ticket:
|
||||
ticket = ticket[0]
|
||||
else:
|
||||
ticket = 0
|
||||
|
||||
if ticket < price:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return {
|
||||
"success": False
|
||||
}
|
||||
|
||||
c.execute('''update user set ticket = :b where user_id = :a''',
|
||||
{'a': user_id, 'b': ticket-price})
|
||||
c.execute('''insert into user_item values(:a,:b,'single')''',
|
||||
{'a': user_id, 'b': single_id})
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return {
|
||||
"success": True
|
||||
}
|
||||
@@ -1390,7 +1390,18 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"complete": 1,
|
||||
"unlock_key": "dreaminattraction|1|0"
|
||||
}]
|
||||
}, {
|
||||
"complete": 1,
|
||||
"unlock_key": "buchigireberserker|2|0"
|
||||
}, {
|
||||
"complete": 1,
|
||||
"unlock_key": "gothiveofra|2|0"
|
||||
}, {
|
||||
"complete": 1,
|
||||
"unlock_key": "gothiveofra|1|0"
|
||||
}
|
||||
|
||||
]
|
||||
}, "clearedsongs": {
|
||||
"": song_1
|
||||
},
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import sqlite3
|
||||
import server.arcworld
|
||||
import server.arcpurchase
|
||||
import time
|
||||
|
||||
|
||||
def int2b(x):
|
||||
@@ -56,7 +58,7 @@ def get_user_character(c, user_id):
|
||||
y = c.fetchone()
|
||||
if y is not None:
|
||||
char_name = y[0]
|
||||
s.append({
|
||||
char = {
|
||||
"is_uncapped_override": int2b(i[14]),
|
||||
"is_uncapped": int2b(i[13]),
|
||||
"uncap_cores": [],
|
||||
@@ -73,7 +75,10 @@ def get_user_character(c, user_id):
|
||||
"level": i[2],
|
||||
"name": char_name,
|
||||
"character_id": i[1]
|
||||
})
|
||||
}
|
||||
if i[1] == 21:
|
||||
char["voice"] = [0, 1, 2, 3, 100, 1000, 1001]
|
||||
s.append(char)
|
||||
|
||||
return s
|
||||
else:
|
||||
@@ -115,6 +120,34 @@ def get_user_friend(c, user_id):
|
||||
return s
|
||||
|
||||
|
||||
def get_user_singles(c, user_id):
|
||||
# 得到用户的单曲,返回列表
|
||||
c.execute('''select * from user_item where user_id = :user_id and type = "single"''',
|
||||
{'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
if not x:
|
||||
return []
|
||||
|
||||
re = []
|
||||
for i in x:
|
||||
re.append(i[1])
|
||||
return re
|
||||
|
||||
|
||||
def get_user_packs(c, user_id):
|
||||
# 得到用户的曲包,返回列表
|
||||
c.execute('''select * from user_item where user_id = :user_id and type = "pack"''',
|
||||
{'user_id': user_id})
|
||||
x = c.fetchall()
|
||||
if not x:
|
||||
return []
|
||||
|
||||
re = []
|
||||
for i in x:
|
||||
re.append(i[1])
|
||||
return re
|
||||
|
||||
|
||||
def get_value_0(c, user_id):
|
||||
# 构造value id=0的数据,返回字典
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
@@ -148,10 +181,11 @@ def get_value_0(c, user_id):
|
||||
"next_fragstam_ts": -1,
|
||||
"max_stamina_ts": 1586274871917,
|
||||
"stamina": 12,
|
||||
"world_unlocks": [],
|
||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream"],
|
||||
"singles": ["dataerror", "yourvoiceso", "crosssoul", "impurebird", "auxesia", "modelista", "yozakurafubuki", "surrender", "metallicpunisher", "carminescythe", "bethere", "callmyname", "fallensquare", "dropdead", "alexandrite", "astraltale", "phantasia", "empireofwinter", "libertas", "dottodot", "dreadnought", "mirzam", "heavenlycaress", "filament", "avantraze", "battlenoone", "saikyostronger", "izana", "einherjar", "laqryma", "amygdata", "altale", "feelssoright", "scarletcage", "teriqma", "mahoroba", "badtek", "maliciousmischance", "buchigireberserker", "galaxyfriends", "buchigireberserker2", "xeraphinite", "xanatos"],
|
||||
"packs": ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"],
|
||||
"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"],
|
||||
"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),
|
||||
# ["vs", "extend", "dynamix", "prelude", "core", "yugamu", "omatsuri", "zettai", "mirai", "shiawase", "chunithm", "nijuusei", "groovecoaster", "rei", "tonesphere", "lanota"]
|
||||
"characters": characters,
|
||||
"cores": [],
|
||||
"recent_score": get_recent_score(c, user_id),
|
||||
@@ -189,185 +223,7 @@ def arc_aggregate_big(user_id):
|
||||
"value": get_value_0(c, user_id)
|
||||
}, {
|
||||
"id": 1,
|
||||
"value": [{
|
||||
"name": "core",
|
||||
"items": [{
|
||||
"id": "core",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "shiawase",
|
||||
"items": [{
|
||||
"id": "shiawase",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "kou",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "dynamix",
|
||||
"items": [{
|
||||
"id": "dynamix",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "sapphire",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "mirai",
|
||||
"items": [{
|
||||
"id": "mirai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}, {
|
||||
"id": "lethe",
|
||||
"type": "character",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1552089600000,
|
||||
"discount_to": 1552694399000
|
||||
}, {
|
||||
"name": "yugamu",
|
||||
"items": [{
|
||||
"id": "yugamu",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "lanota",
|
||||
"items": [{
|
||||
"id": "lanota",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "nijuusei",
|
||||
"items": [{
|
||||
"id": "nijuusei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "rei",
|
||||
"items": [{
|
||||
"id": "rei",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "tonesphere",
|
||||
"items": [{
|
||||
"id": "tonesphere",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "groovecoaster",
|
||||
"items": [{
|
||||
"id": "groovecoaster",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "zettai",
|
||||
"items": [{
|
||||
"id": "zettai",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1583712000000,
|
||||
"discount_to": 1584316799000
|
||||
}, {
|
||||
"name": "chunithm",
|
||||
"items": [{
|
||||
"id": "chunithm",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 300,
|
||||
"orig_price": 300
|
||||
}, {
|
||||
"name": "prelude",
|
||||
"items": [{
|
||||
"id": "prelude",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 400,
|
||||
"orig_price": 400
|
||||
}, {
|
||||
"name": "omatsuri",
|
||||
"items": [{
|
||||
"id": "omatsuri",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "vs",
|
||||
"items": [{
|
||||
"id": "vs",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 500,
|
||||
"orig_price": 500
|
||||
}, {
|
||||
"name": "extend",
|
||||
"items": [{
|
||||
"id": "extend",
|
||||
"type": "pack",
|
||||
"is_available": True
|
||||
}],
|
||||
"price": 700,
|
||||
"orig_price": 700
|
||||
}]
|
||||
"value": server.arcpurchase.get_item(c, 'pack')
|
||||
}, {
|
||||
"id": 2,
|
||||
"value": {}
|
||||
@@ -377,7 +233,7 @@ def arc_aggregate_big(user_id):
|
||||
"max_stamina": 12,
|
||||
"stamina_recover_tick": 1800000,
|
||||
"core_exp": 250,
|
||||
"curr_ts": 1599547606825,
|
||||
"curr_ts": int(time.time())*1000,
|
||||
"level_steps": [{
|
||||
"level": 1,
|
||||
"level_exp": 0
|
||||
|
||||
Reference in New Issue
Block a user