[Bug Fix][Enhance] PTT update lately & Register rate limiter

- Fix a bug that PTT updates delay to next play.
- Add the IP and the device rate limiters for user register.
This commit is contained in:
Lost-MSth
2024-09-28 14:59:24 +08:00
parent dc1ca344e5
commit 9c9af892bd
6 changed files with 35 additions and 7 deletions

View File

@@ -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'
}

View File

@@ -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

View File

@@ -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'

View File

@@ -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:

View File

@@ -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()

View File

@@ -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})