Update to v2.8.6 without release

- Code refactoring
- Update the song database
- Fix a bug of the friend system which arose in the last version
- Fix a bug of duplicate calculating finishing states when players finish playing the chart in Link Play.
This commit is contained in:
Lost-MSth
2022-05-26 18:56:33 +08:00
parent 96fbd26342
commit 9de62d3645
18 changed files with 756 additions and 218 deletions

View File

@@ -1,6 +1,9 @@
from .error import ArcError, InputError, DataExist, NoAccess, NoData, UserBan
from .error import ArcError, InputError, DataExist, NoAccess, NoData, UserBan, FriendError
from .constant import Constant
from .character import UserCharacter
from .score import Score
from .world import Map
from .item import get_user_cores
from setting import Config
import hashlib
import base64
@@ -8,23 +11,42 @@ import time
from os import urandom
class User:
name = None
email = None
password = None
user_id = None
user_code = None
def code_get_id(c, user_code: str) -> int:
# 用user_code获取user_id
c.execute('''select user_id from user where user_code = :a''',
{'a': user_code})
x = c.fetchone()
if x is not None:
user_id = int(x[0])
else:
raise NoData('No user.', 401, -3)
return user_id
class User:
def __init__(self) -> None:
pass
self.name = None
self.email = None
self.password = None
self.user_id = None
self.user_code = None
self.join_date = None
self.rating_ptt = None
self.ticket = None
self.world_rank_score = None
self.ban_flag = None
class UserRegister(User):
hash_pwd = None
def __init__(self, c) -> None:
super().__init__()
self.c = c
self.hash_pwd = None
def set_name(self, name: str):
if 3 <= len(name) <= 16:
@@ -115,15 +137,14 @@ class UserRegister(User):
class UserLogin(User):
# 密码和token的加密方式为 SHA-256
device_id = None
ip = None
hash_pwd = None
token = None
now = 0
def __init__(self, c) -> None:
super().__init__()
self.c = c
self.device_id = None
self.ip = None
self.hash_pwd = None
self.token = None
self.now = 0
def set_name(self, name: str):
self.name = name
@@ -230,11 +251,10 @@ class UserLogin(User):
class UserAuth(User):
token = None
def __init__(self, c) -> None:
super().__init__()
self.c = c
self.token = None
def token_get_id(self):
# 用token获取id没有考虑不同用户token相同情况说不定会有bug
@@ -248,33 +268,155 @@ class UserAuth(User):
return self.user_id
def code_get_id(self):
# 用user_code获取id
self.c.execute('''select user_id from user where user_code = :a''',
{'a': self.user_code})
x = self.c.fetchone()
if x is not None:
self.user_id = x[0]
else:
raise NoData('No user.', 401, -3)
return self.user_id
class UserOnline(User):
character = None
def __init__(self, c, user_id=None) -> None:
super().__init__()
self.c = c
self.user_id = user_id
self.character = None
self.is_skill_sealed = False
self.is_hide_rating = False
self.recent_score = Score()
self.favorite_character = -1
self.max_stamina_notification_enabled = False
self.prog_boost = 0
self.__cores = None
self.__friends = None
@property
def cores(self) -> list:
if self.__cores is None:
self.__cores = get_user_cores(self.c, self)
return self.__cores
@property
def friends(self) -> list:
# 得到用户的朋友列表
if self.__friends is None:
self.c.execute('''select user_id_other from friend where user_id_me = :user_id''', {
'user_id': self.user_id})
x = self.c.fetchall()
s = []
if x != [] and x[0][0] is not None:
for i in x:
self.c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
{'x': i[0], 'y': self.user_id})
is_mutual = True if self.c.fetchone() == (1,) else False
you = UserOnline(self.c, i[0])
you.select_user()
character = you.character if you.favorite_character is None else you.favorite_character
character.select_character_uncap_condition(you)
rating = you.rating_ptt if not you.is_hide_rating else -1
s.append({
"is_mutual": is_mutual,
"is_char_uncapped_override": character.is_uncapped_override,
"is_char_uncapped": character.is_uncapped,
"is_skill_sealed": you.is_skill_sealed,
"rating": rating,
"join_date": you.join_date,
"character": character.character_id,
"recent_score": you.recent_score_list,
"name": you.name,
"user_id": you.user_id
})
s.sort(key=lambda item: item["recent_score"][0]["time_played"] if len(
item["recent_score"]) > 0 else 0, reverse=True)
self.__friends = s
return self.__friends
@property
def recent_score_list(self) -> list:
# 用户最近一次成绩,是列表
if self.name is None:
self.select_user()
if self.recent_score.song.song_id is None:
return []
self.c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', {
'u': self.user_id, 's': self.recent_score.song.song_id, 'd': self.recent_score.song.difficulty})
y = self.c.fetchone()
best_clear_type = y[0] if y is not None else self.recent_score.clear_type
r = self.recent_score.to_dict
r["best_clear_type"] = best_clear_type
return [r]
def change_character(self, character_id: int, skill_sealed: bool = False):
# 用户角色改变,包括技能封印的改变
self.character = UserCharacter(self.c, character_id)
self.character.select_character_uncap_condition(self)
self.is_skill_sealed = skill_sealed
self.c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', {
'a': 1 if skill_sealed else 0, 'b': self.character.character_id, 'c': self.character.is_uncapped, 'd': self.character.is_uncapped_override, 'e': self.user_id})
'a': 1 if self.is_skill_sealed else 0, 'b': self.character.character_id, 'c': self.character.is_uncapped, 'd': self.character.is_uncapped_override, 'e': self.user_id})
def select_user(self):
# 查user表所有信息
self.c.execute(
'''select * from user where user_id = :x''', {'x': self.user_id})
x = self.c.fetchone()
if not x:
raise NoData('No user.', 108, -3)
self.name = x[1]
self.join_date = int(x[3])
self.user_code = x[4]
self.rating_ptt = x[5]
self.character = UserCharacter(self.c, x[6])
self.is_skill_sealed = x[7] == 1
self.character.is_uncapped = x[8] == 1
self.character.is_uncapped_override = x[9] == 1
self.is_hide_rating = x[10] == 1
self.recent_score.song.song_id = x[11]
self.recent_score.song.difficulty = x[12]
self.recent_score.set_score(
x[13], x[14], x[15], x[16], x[17], x[18], x[19], x[20], x[21])
self.recent_score.rating = x[22]
self.favorite_character = None if x[23] == - \
1 else UserCharacter(self.c, x[23])
self.max_stamina_notification_enabled = x[24] == 1
self.current_map = Map(x[25])
self.ticket = x[26]
self.prog_boost = x[27]
self.email = x[28]
self.world_rank_score = x[29]
self.ban_flag = x[30]
self.next_fragstam_ts = x[31]
self.max_stamina_ts = x[32]
self.stamina = x[33]
def add_friend(self, friend_id: int):
# 加好友
if self.user_id == friend_id:
raise FriendError('Add yourself as a friend.', 604)
self.c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
{'x': self.user_id, 'y': friend_id})
if self.c.fetchone() == (0,):
self.c.execute('''insert into friend values(:a, :b)''', {
'a': self.user_id, 'b': friend_id})
else:
raise FriendError('The user has been your friend.', 602)
def delete_friend(self, friend_id: int):
# 删好友
self.c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''',
{'x': self.user_id, 'y': friend_id})
if self.c.fetchone() == (1,):
self.c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''',
{'x': self.user_id, 'y': friend_id})
else:
raise FriendError('No user or the user is not your friend.', 401)