diff --git a/latest version/api/api_code.py b/latest version/api/api_code.py index bf7a807..2a59e37 100644 --- a/latest version/api/api_code.py +++ b/latest version/api/api_code.py @@ -32,6 +32,7 @@ CODE_MSG = { -210: 'Username exists', -211: 'Email address exists', -212: 'User code exists', + -213: 'Too many register attempts', -999: 'Unknown error' } diff --git a/latest version/core/config_manager.py b/latest version/core/config_manager.py index 504832f..5b2aaab 100644 --- a/latest version/core/config_manager.py +++ b/latest version/core/config_manager.py @@ -100,6 +100,8 @@ class Config: GAME_LOGIN_RATE_LIMIT = '30/5 minutes' API_LOGIN_RATE_LIMIT = '10/5 minutes' + GAME_REGISTER_IP_RATE_LIMIT = '10/1 day' + GAME_REGISTER_DEVICE_RATE_LIMIT = '3/1 day' NOTIFICATION_EXPIRE_TIME = 3 * 60 * 1000 diff --git a/latest version/core/constant.py b/latest version/core/constant.py index ff066de..113ce59 100644 --- a/latest version/core/constant.py +++ b/latest version/core/constant.py @@ -1,6 +1,6 @@ from .config_manager import Config -ARCAEA_SERVER_VERSION = 'v2.11.3.19' +ARCAEA_SERVER_VERSION = 'v2.11.3.20' ARCAEA_DATABASE_VERSION = 'v2.11.3.19' ARCAEA_LOG_DATBASE_VERSION = 'v1.1' diff --git a/latest version/core/score.py b/latest version/core/score.py index 095409b..5b030c8 100644 --- a/latest version/core/score.py +++ b/latest version/core/score.py @@ -131,7 +131,7 @@ class Score: # 谱面定数小于等于 0 视为 unranked,返回值会为 0 if not defnum or defnum <= 0: return 0 - + all_note = perfect_count + near_count + miss_count if all_note == 0: return 0 @@ -281,7 +281,8 @@ class UserPlay(UserScore): if songfile_hash and songfile_hash != self.song_hash: return False - x = f'''{self.song_token}{self.song_hash}{self.song.song_id}{self.song.difficulty}{self.score}{self.shiny_perfect_count}{self.perfect_count}{self.near_count}{self.miss_count}{self.health}{self.modifier}{self.clear_type}''' + x = f'''{self.song_token}{self.song_hash}{self.song.song_id}{self.song.difficulty}{self.score}{self.shiny_perfect_count}{ + self.perfect_count}{self.near_count}{self.miss_count}{self.health}{self.modifier}{self.clear_type}''' if self.combo_interval_bonus is not None: if self.combo_interval_bonus < 0 or self.combo_interval_bonus > self.all_note_count / 150: return False @@ -569,6 +570,18 @@ class Potential: (self.user.user_id, r_index, user_score.time_played, user_score.song.song_id, user_score.song.difficulty, user_score.score, user_score.shiny_perfect_count, user_score.perfect_count, user_score.near_count, user_score.miss_count, user_score.health, user_score.modifier, user_score.clear_type, user_score.rating)) + # 更新内存中的数据 + x = (r_index, user_score.song.song_id, + user_score.song.difficulty, user_score.rating) + if len(self.r30_tuples) < 30: + self.r30_tuples.append(x) + return + + for i in range(30): + if self.r30_tuples[i][0] == r_index: + self.r30_tuples[i] = x + break + def r30_push_score(self, user_score: 'UserPlay | UserScore') -> None: '''根据新成绩调整 r30''' if self.r30_tuples is None: diff --git a/latest version/core/user.py b/latest version/core/user.py index b7aec10..ae168a0 100644 --- a/latest version/core/user.py +++ b/latest version/core/user.py @@ -54,6 +54,12 @@ class User: class UserRegister(User): + + limiter_ip = ArcLimiter( + Config.GAME_REGISTER_IP_RATE_LIMIT, 'game_register_ip') + limiter_device = ArcLimiter( + Config.GAME_REGISTER_DEVICE_RATE_LIMIT, 'game_register_device') + def __init__(self, c) -> None: super().__init__() self.c = c @@ -141,7 +147,13 @@ class UserRegister(User): self.c.execute('''insert or replace into user_char_full values(?,?,?,?,?,?,0)''', (self.user_id, i[0], i[1], exp, i[2], 0)) - def register(self): + def register(self, device_id: str = None, ip: str = None): + if device_id is not None and not self.limiter_device.hit(device_id): + raise RateLimit(f'''Too many register attempts of device `{ + device_id}`''', 124, -213) + if ip is not None and ip != '127.0.0.1' and not self.limiter_ip.hit(ip): + raise RateLimit(f'''Too many register attempts of ip `{ + ip}`''', 124, -213) now = int(time.time() * 1000) if self.user_code is None: self._build_user_code() diff --git a/latest version/server/user.py b/latest version/server/user.py index 123c673..9a08fcc 100644 --- a/latest version/server/user.py +++ b/latest version/server/user.py @@ -32,12 +32,12 @@ def register(): else: device_id = 'low_version' - new_user.register() + ip = request.remote_addr + new_user.register(device_id, ip) # 注册后自动登录 user = UserLogin(c) - user.login(new_user.name, new_user.password, - device_id, request.remote_addr) + user.login(new_user.name, new_user.password, device_id, ip) current_app.logger.info(f'New user `{user.user_id}` registered') return success_return({'user_id': user.user_id, 'access_token': user.token})