Update to v2.6

This commit is contained in:
Lost-MSth
2021-07-01 18:46:16 +08:00
parent b0647bedb6
commit 9286caf900
21 changed files with 1255 additions and 714 deletions

View File

@@ -165,10 +165,22 @@ def get_user_present(c, user_id):
if x:
for i in x:
if now <= int(i[1]):
c.execute(
'''select * from present_item where present_id=?''', (i[0],))
y = c.fetchall()
items = []
if y:
for j in y:
if j is not None:
items.append({
"type": j[2],
"id": j[1],
"amount": j[3]
})
re.append({'expire_ts': i[1],
'description': i[3],
'description': i[2],
'present_id': i[0],
'items': json.loads(i[2])
'items': items
})
return re
@@ -189,16 +201,16 @@ def claim_user_present(user_id, present_id):
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})
c.execute(
'''select * from present_item where present_id=?''', (x[0],))
y = c.fetchall()
flag = True
if y:
for j in y:
if j is not None:
flag = flag and server.item.claim_user_item(
c, user_id, j[1], j[2], j[3])
else:
# 过期
flag = False
@@ -216,12 +228,12 @@ def claim_user_redeem(user_id, code):
if not x:
return 0, 504
if x[2] == 0: # 一次性
if x[1] == 0: # 一次性
c.execute(
'''select exists(select * from user_redeem where code=:a)''', {'a': code})
if c.fetchone() == (1,):
return 0, 505
elif x[2] == 1: # 每个玩家一次
elif x[1] == 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,):
@@ -230,17 +242,17 @@ def claim_user_redeem(user_id, code):
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})
error_code = None
c.execute('''select * from redeem_item where code=?''', (code,))
x = c.fetchall()
flag = True
if x:
for i in x:
if i[2] == 'fragment':
fragment += i[3]
else:
flag = flag and server.item.claim_user_item(
c, user_id, i[1], i[2], i[3])
if flag:
error_code = None
return fragment, error_code

View File

@@ -3,7 +3,10 @@ from server.sql import Connect
from setting import Config
import server.item
import server.character
import server.info
import server.arcpurchase
import os
import time
def int2b(x):
@@ -14,6 +17,23 @@ def int2b(x):
return True
def calc_stamina(max_stamina_ts, curr_stamina):
# 计算体力,返回剩余体力数值
stamina = int(server.info.MAX_STAMINA - (max_stamina_ts -
int(time.time()*1000)) / server.info.STAMINA_RECOVER_TICK)
if stamina >= server.info.MAX_STAMINA:
if curr_stamina >= server.info.MAX_STAMINA:
stamina = curr_stamina
else:
stamina = server.info.MAX_STAMINA
if stamina < 0:
stamina = 0
return stamina
def get_world_name(file_dir='./database/map'):
# 获取所有地图名称,返回列表
L = []
@@ -45,7 +65,10 @@ def get_user_world_info(user_id, map_id):
info['curr_capture'] = x[3]
info['is_locked'] = int2b(x[4])
else:
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
info['curr_position'] = 0
info['curr_capture'] = 0
info['is_locked'] = True
c.execute('''insert into user_world values(:a,:b,0,0,1)''', {
'a': user_id, 'b': map_id})
return info
@@ -87,7 +110,10 @@ def get_world_all(user_id):
info['curr_capture'] = x[3]
info['is_locked'] = int2b(x[4])
else:
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
info['curr_position'] = 0
info['curr_capture'] = 0
info['is_locked'] = True
c.execute('''insert into user_world values(:a,:b,0,0,1)''', {
'a': user_id, 'b': map_id})
re.append(info)
@@ -106,7 +132,7 @@ def get_user_world(user_id, map_id):
"user_id": user_id,
"curr_position": 0,
"curr_capture": 0,
"is_locked": False,
"is_locked": True,
"map_id": map_id
}
if x:
@@ -114,12 +140,40 @@ def get_user_world(user_id, map_id):
re['curr_capture'] = x[3]
re['is_locked'] = int2b(x[4])
else:
c.execute('''insert into user_world values(:a,:b,0,0,0)''', {
c.execute('''insert into user_world values(:a,:b,0,0,1)''', {
'a': user_id, 'b': map_id})
return re
def unlock_user_world(user_id, map_id):
# 解锁用户的图,返回成功与否布尔值
with Connect() as c:
c.execute(
'''select is_locked from user_world where map_id=? and user_id=?''', (map_id, user_id))
x = c.fetchone()
if x:
is_locked = x[0]
else:
is_locked = 1
c.execute('''insert into user_world values(:a,:b,0,0,1)''', {
'a': user_id, 'b': map_id})
if is_locked == 1:
map_info = get_world_info(map_id)
if 'require_type' in map_info and map_info['require_type'] != '':
if map_info['require_type'] in ['pack', 'single']:
c.execute('''select exists(select * from user_item where user_id=? and item_id=? and type=?)''',
(user_id, map_info['require_id'], map_info['require_type']))
if c.fetchone() == (0,):
return False
c.execute(
'''update user_world set is_locked=0 where user_id=? and map_id=?''', (user_id, map_id))
return True
def change_user_current_map(user_id, map_id):
# 改变用户当前图
with Connect() as c:
@@ -129,7 +183,8 @@ def change_user_current_map(user_id, map_id):
def play_world_song(user_id, args):
# 声明是世界模式的打歌,并且记录加成信息
# 声明是世界模式的打歌,并且记录加成信息,返回字典
r = {}
with Connect() as c:
stamina_multiply = 1
fragment_multiply = 100
@@ -150,7 +205,34 @@ def play_world_song(user_id, args):
c.execute('''insert into world_songplay values(:a,:b,:c,:d,:e,:f)''', {
'a': user_id, 'b': args['song_id'], 'c': args['difficulty'], 'd': stamina_multiply, 'e': fragment_multiply, 'f': prog_boost_multiply})
return None
c.execute('''select current_map from user where user_id = :a''', {
'a': user_id})
map_id = c.fetchone()[0]
info = get_world_info(map_id)
# 体力计算
c.execute(
'''select max_stamina_ts, stamina from user where user_id=?''', (user_id,))
x = c.fetchone()
max_stamina_ts = x[0] if x and x[0] is not None else 0
stamina = x[1] if x and x[1] is not None else 12
now = int(time.time() * 1000)
# 体力不足
if calc_stamina(max_stamina_ts, stamina) < info['stamina_cost']:
return {}
stamina = calc_stamina(max_stamina_ts, stamina) - \
info['stamina_cost'] * stamina_multiply
max_stamina_ts = now + server.info.STAMINA_RECOVER_TICK * \
(server.info.MAX_STAMINA - stamina)
c.execute('''update user set max_stamina_ts=?, stamina=? where user_id=?''',
(max_stamina_ts, stamina, user_id))
r = {
"stamina": stamina,
"max_stamina_ts": max_stamina_ts,
"token": "13145201919810"
}
return r
def climb_step(user_id, map_id, step, prev_capture, prev_position):
@@ -263,9 +345,12 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
c.execute('''delete from world_songplay where user_id=:a and song_id=:b and difficulty=:c''', {
'a': user_id, 'b': song_id, 'c': difficulty})
c.execute('''select character_id from user where user_id=?''', (user_id,))
c.execute(
'''select character_id, max_stamina_ts, stamina from user where user_id=?''', (user_id,))
x = c.fetchone()
character_id = x[0] if x else 0
character_id = x[0] if x and x[0] is not None else 0
max_stamina_ts = x[1] if x and x[1] is not None else 0
stamina = x[2] if x and x[2] is not None else 12
c.execute('''select frag1,prog1,overdrive1,frag20,prog20,overdrive20,frag30,prog30,overdrive30 from character where character_id=?''', (character_id,))
x = c.fetchone()
@@ -317,6 +402,9 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
c.execute('''select * from user_world where user_id = :a and map_id =:b''',
{'a': user_id, 'b': map_id})
y = c.fetchone()
if y[4] == 1: # 图不可用
return {}
rewards, steps, curr_position, curr_capture, info = climb_step(
user_id, map_id, step, y[3], y[2])
for i in rewards: # 物品分发
@@ -324,6 +412,12 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
amount = j['amount'] if 'amount' in j else 1
item_id = j['id'] if 'id' in j else ''
server.item.claim_user_item(c, user_id, item_id, j['type'], amount)
if 'step_type' in steps[-1]:
if 'plusstamina' in steps[-1]['step_type'] and 'plus_stamina_value' in steps[-1]:
# 体力格子
max_stamina_ts, stamina = add_stamina(
c, user_id, int(steps[-1]['plus_stamina_value']))
# 角色升级
if not Config.CHARACTER_FULL_UNLOCK:
exp, level = server.character.calc_level_up(
@@ -357,8 +451,8 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
"prog": prog,
"overdrive": overdrive
},
"current_stamina": 12,
"max_stamina_ts": 1586274871917
"current_stamina": calc_stamina(max_stamina_ts, stamina),
"max_stamina_ts": max_stamina_ts
}
else:
re = {
@@ -384,8 +478,8 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
"prog": prog,
"overdrive": overdrive
},
"current_stamina": 12,
"max_stamina_ts": 1586274871917
"current_stamina": calc_stamina(max_stamina_ts, stamina),
"max_stamina_ts": max_stamina_ts
}
if stamina_multiply != 1:
@@ -401,3 +495,77 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
'a': curr_position, 'b': curr_capture, 'c': user_id, 'd': map_id})
return re
def add_stamina(c, user_id, add_stamina):
# 增添体力返回max_stamina_ts和stamina
now = int(time.time() * 1000)
c.execute(
'''select max_stamina_ts, stamina from user where user_id=?''', (user_id,))
x = c.fetchone()
if x and x[0] is not None and x[1] is not None:
stamina = calc_stamina(x[0], x[1]) + add_stamina
max_stamina_ts = now - \
(stamina-server.info.MAX_STAMINA) * \
server.info.STAMINA_RECOVER_TICK
else:
max_stamina_ts = now
stamina = server.info.MAX_STAMINA
c.execute('''update user set max_stamina_ts=?, stamina=? where user_id=?''',
(max_stamina_ts, stamina, user_id))
return max_stamina_ts, stamina
def buy_stamina_by_fragment(user_id):
# 残片买体力,返回字典和错误码
r = {}
with Connect() as c:
c.execute(
'''select next_fragstam_ts from user where user_id=?''', (user_id,))
x = c.fetchone()
if x:
now = int(time.time() * 1000)
next_fragstam_ts = x[0] if x[0] else 0
if now < next_fragstam_ts:
return {}, 905
next_fragstam_ts = now + 24*3600*1000
max_stamina_ts, stamina = add_stamina(c, user_id, 6)
c.execute('''update user set next_fragstam_ts=?, max_stamina_ts=?, stamina=? where user_id=?''',
(next_fragstam_ts, max_stamina_ts, stamina, user_id))
r = {
"user_id": user_id,
"stamina": stamina,
"max_stamina_ts": max_stamina_ts,
"next_fragstam_ts": next_fragstam_ts
}
return r, None
def buy_stamina_by_ticket(user_id):
# 源点买体力,返回字典和错误码
r = {}
with Connect() as c:
flag, ticket = server.arcpurchase.buy_item(c, user_id, 50)
if flag:
max_stamina_ts, stamina = add_stamina(c, user_id, 6)
c.execute('''update user set max_stamina_ts=?, stamina=? where user_id=?''',
(max_stamina_ts, stamina, user_id))
r = {
"user_id": user_id,
"stamina": stamina,
"max_stamina_ts": max_stamina_ts,
"ticket": ticket
}
else:
return None, 501
return r, None

View File

@@ -5,9 +5,11 @@ import functools
from setting import Config
from flask import jsonify
BAN_TIME = [1, 3, 7, 15, 31]
def arc_login(name: str, password: str, device_id: str, ip: str): # 登录判断
# 查询数据库中的user表验证账号密码返回并记录token多返回个error code
# 查询数据库中的user表验证账号密码返回并记录token多返回个error code和extra
# token采用user_id和时间戳连接后hash生成真的是瞎想的没用bear
# 密码和token的加密方式为 SHA-256
@@ -15,16 +17,21 @@ def arc_login(name: str, password: str, device_id: str, ip: str): # 登录判
token = None
with Connect() as c:
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
c.execute('''select user_id, password from user where name = :name''', {
c.execute('''select user_id, password, ban_flag from user where name = :name''', {
'name': name})
x = c.fetchone()
if x is not None:
now = int(time.time() * 1000)
if x[2] is not None and x[2] != '':
# 自动封号检查
ban_timestamp = int(x[2].split(':', 1)[1])
if ban_timestamp > now:
return None, 105, {'remaining_ts': ban_timestamp-now}
if x[1] == '':
# 账号封禁
error_code = 106
elif x[1] == hash_pwd:
user_id = str(x[0])
now = int(time.time() * 1000)
token = hashlib.sha256(
(user_id + str(now)).encode("utf8")).hexdigest()
c.execute(
@@ -49,6 +56,13 @@ def arc_login(name: str, password: str, device_id: str, ip: str): # 登录判
device_list) + 1 - device_list.count(device_id) - Config.LOGIN_DEVICE_NUMBER_LIMIT
if should_delete_num >= 1: # 删掉多余token
if not Config.ALLOW_LOGIN_SAME_DEVICE and Config.ALLOW_BAN_MULTIDEVICE_USER_AUTO: # 自动封号检查
c.execute(
'''select count(*) from login where user_id=? and login_time>?''', (user_id, now-86400000))
if c.fetchone()[0] >= Config.LOGIN_DEVICE_NUMBER_LIMIT:
remaining_ts = arc_auto_ban(c, user_id, now)
return None, 105, {'remaining_ts': remaining_ts}
c.execute('''delete from login where rowid in (select rowid from login where user_id=:user_id limit :a);''',
{'user_id': user_id, 'a': int(should_delete_num)})
@@ -62,7 +76,7 @@ def arc_login(name: str, password: str, device_id: str, ip: str): # 登录判
# 用户名错误
error_code = 104
return token, error_code
return token, error_code, None
def arc_register(name: str, password: str, device_id: str, email: str, ip: str): # 注册
@@ -195,3 +209,24 @@ def auth_required(request):
return wrapped_view
return decorator
def arc_auto_ban(c, user_id, now):
# 多设备自动封号机制,返回封号时长
c.execute('''delete from login where user_id=?''', (user_id, ))
c.execute('''select ban_flag from user where user_id=?''', (user_id,))
x = c.fetchone()
if x and x[0] != '' and x[0] is not None:
last_ban_time = int(x[0].split(':', 1)[0])
i = 0
while i < len(BAN_TIME) - 1 and BAN_TIME[i] <= last_ban_time:
i += 1
ban_time = BAN_TIME[i]
else:
ban_time = BAN_TIME[0]
ban_flag = ':'.join((str(ban_time), str(now + ban_time*24*60*60*1000)))
c.execute('''update user set ban_flag=? where user_id=?''',
(ban_flag, user_id))
return ban_time*24*60*60*1000

View File

@@ -1,5 +1,6 @@
from setting import Config
from server.sql import Connect
import server.info
import server.item
import server.setme
@@ -212,10 +213,10 @@ def char_use_core(user_id, character_id, amount):
x = c.fetchone()
if x:
exp, level = calc_level_up(
c, user_id, character_id, x[0], amount*250)
c.execute('''update user_char set level=?, exp=? where user_id=? and character_id=?''',
c, user_id, character_id, x[0], amount*server.info.CORE_EXP)
c.execute('''update user_char set level=?, exp=? where user_id=? and character_id=?''',
(level, exp, user_id, character_id))
server.item.claim_user_item(
server.item.claim_user_item(
c, user_id, 'core_generic', 'core', -amount)
r = {'character': [get_one_character(c, user_id, character_id)]}
@@ -244,10 +245,10 @@ def char_uncap(user_id, character_id):
break
if success:
for i in x:
server.item.claim_user_item(c, user_id, i[1], i[2], -i[3])
c.execute('''update user_char set is_uncapped=1, is_uncapped_override=0 where user_id=? and character_id=?''',
(user_id, character_id))
for i in x:
server.item.claim_user_item(c, user_id, i[1], i[2], -i[3])
r = {'character': [get_one_character(c, user_id, character_id)]}
r['cores'] = server.item.get_user_cores(c, user_id)

View File

@@ -7,6 +7,10 @@ import server.item
import time
from setting import Config
MAX_STAMINA = 12
STAMINA_RECOVER_TICK = 1800000
CORE_EXP = 250
def int2b(x):
# int与布尔值转换
@@ -100,7 +104,8 @@ def get_user_friend(c, user_id):
"user_id": i[0]
})
s.sort(key=lambda item: item["recent_score"][0]["time_played"] if len(item["recent_score"]) > 0 else 0, reverse=True)
s.sort(key=lambda item: item["recent_score"][0]["time_played"] if len(
item["recent_score"]) > 0 else 0, reverse=True)
return s
@@ -123,11 +128,12 @@ def get_user_me(c, user_id):
'''update user set character_id=0 where user_id=?''', (user_id,))
favorite_character_id = x[23]
if favorite_character_id not in characters:
if favorite_character_id not in characters: # 这是考虑有可能favourite_character设置了用户未拥有的角色
favorite_character_id = -1
c.execute(
'''update user set favorite_character=-1 where user_id=?''', (user_id,))
# 计算世界排名
c.execute(
'''select world_rank_score from user where user_id=?''', (user_id,))
y = c.fetchone()
@@ -142,10 +148,22 @@ def get_user_me(c, user_id):
else:
world_rank = 0
# 源点强化
prog_boost = 0
if x[27] and x[27] != 0:
prog_boost = 300
# 体力计算
next_fragstam_ts = -1
max_stamina_ts = 1586274871917
stamina = 12
if x[31]:
next_fragstam_ts = x[31]
if x[32]:
max_stamina_ts = x[32]
if x[33]:
stamina = x[33]
r = {"is_aprilfools": Config.IS_APRILFOOLS,
"curr_available_maps": [],
"character_stats": user_character,
@@ -165,9 +183,9 @@ def get_user_me(c, user_id):
"is_skill_sealed": int2b(x[7]),
"current_map": x[25],
"prog_boost": prog_boost,
"next_fragstam_ts": -1,
"max_stamina_ts": 1586274871917,
"stamina": 12,
"next_fragstam_ts": next_fragstam_ts,
"max_stamina_ts": max_stamina_ts,
"stamina": server.arcworld.calc_stamina(max_stamina_ts, stamina),
"world_unlocks": server.item.get_user_items(c, user_id, 'world_unlock'),
"world_songs": server.item.get_user_items(c, user_id, 'world_song'),
"singles": server.item.get_user_items(c, user_id, 'single'),
@@ -221,12 +239,12 @@ def arc_aggregate_big(user_id):
}, {
"id": 3,
"value": {
"max_stamina": 12,
"stamina_recover_tick": 1800000,
"core_exp": 250,
"curr_ts": int(time.time())*1000,
"max_stamina": MAX_STAMINA,
"stamina_recover_tick": STAMINA_RECOVER_TICK,
"core_exp": CORE_EXP,
"curr_ts": int(time.time()*1000),
"level_steps": server.character.get_level_steps(),
"world_ranking_enabled": False,
"world_ranking_enabled": True,
"is_byd_chapter_unlocked": True
}
}, {