前端在身份码错误时跳到帮助页面,不再重试连接

This commit is contained in:
John Smith 2023-09-13 00:13:11 +08:00
parent 8bfceb4b32
commit 05fc89dbbe
9 changed files with 119 additions and 19 deletions

View File

@ -31,6 +31,7 @@ class Command(enum.IntEnum):
ADD_SUPER_CHAT = 5
DEL_SUPER_CHAT = 6
UPDATE_TRANSLATION = 7
FATAL_ERROR = 8
class ContentType(enum.IntEnum):
@ -38,6 +39,10 @@ class ContentType(enum.IntEnum):
EMOTICON = 1
class FatalErrorType(enum.IntEnum):
AUTH_CODE_ERROR = 1
def make_message_body(cmd, data):
return json.dumps(
{

View File

@ -35,7 +35,7 @@ class TransportError(Exception):
class BusinessError(Exception):
"""业务返回码错误"""
def __init__(self, data: dict):
super().__init__(f"message={data['message']}, request_id={data['request_id']}")
super().__init__(f"code={data['code']}, message={data['message']}, request_id={data['request_id']}")
self.data = data
@property
@ -115,19 +115,22 @@ async def _read_response(req_ctx_mgr: AsyncContextManager[aiohttp.ClientResponse
def _validate_auth_code(auth_code):
if re.fullmatch(r'[0-9A-Z]{11,16}', auth_code):
# 我也不知道是不是一定是这个格式,先临时这么处理
if re.fullmatch(r'[0-9A-Z]{12,14}', auth_code):
return
logger.warning('Auth code error! auth_code=%s', auth_code)
raise BusinessError({
'code': 7007,
'message': '身份码错误',
'data': {},
'request_id': '0'
'request_id': '0',
'data': None
})
class _OpenLiveHandlerBase(api.base.ApiHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.res: Optional[dict] = None
def prepare(self):
super().prepare()
if not isinstance(self.json_args, dict):
@ -147,14 +150,14 @@ class _PublicHandlerBase(_OpenLiveHandlerBase):
async def post(self):
try:
res = await request_open_live_or_common_server(
self.res = await request_open_live_or_common_server(
self._OPEN_LIVE_URL, self._COMMON_SERVER_URL, self.json_args
)
except TransportError:
raise tornado.web.HTTPError(500)
except BusinessError as e:
res = e.data
self.write(res)
self.res = e.data
self.write(self.res)
class _PrivateHandlerBase(_OpenLiveHandlerBase):
@ -167,21 +170,41 @@ class _PrivateHandlerBase(_OpenLiveHandlerBase):
raise tornado.web.HTTPError(501)
try:
res = await _request_open_live(self._OPEN_LIVE_URL, self.json_args)
self.res = await _request_open_live(self._OPEN_LIVE_URL, self.json_args)
except TransportError:
raise tornado.web.HTTPError(500)
except BusinessError as e:
res = e.data
self.write(res)
self.res = e.data
self.write(self.res)
class StartGamePublicHandler(_PublicHandlerBase):
class _StartGameMixin(_OpenLiveHandlerBase):
_OPEN_LIVE_URL = START_GAME_OPEN_LIVE_URL
_COMMON_SERVER_URL = START_GAME_COMMON_SERVER_URL
async def post(self):
await super().post() # noqa
if self.res is None:
return
class StartGamePrivateHandler(_PrivateHandlerBase):
_OPEN_LIVE_URL = START_GAME_OPEN_LIVE_URL
try:
room_id = self.res['data']['anchor_info']['room_id']
except (TypeError, KeyError):
room_id = None
code = self.res['code']
logger.info('room_id=%s start game res: %s %s', room_id, code, self.res['message'])
if code == 7007:
# 身份码错误
# 让我看看是哪个混蛋把房间ID、UID当做身份码
logger.warning('Auth code error! auth_code=%s', self.json_args.get('code', None))
class StartGamePublicHandler(_StartGameMixin, _PublicHandlerBase):
pass
class StartGamePrivateHandler(_StartGameMixin, _PrivateHandlerBase):
pass
class EndGamePublicHandler(_PublicHandlerBase):

View File

@ -51,10 +51,18 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase {
app_id: 0
})).data
if (res.code !== 0) {
throw Error(`code=${res.code}, message=${res.message}, request_id=${res.request_id}`)
let msg = `code=${res.code}, message=${res.message}, request_id=${res.request_id}`
if (res.code === 7007) {
// 身份码错误
throw new chat.ChatClientFatalError(chat.FATAL_ERROR_TYPE_AUTH_CODE_ERROR, msg)
}
throw Error(msg)
}
} catch (e) {
console.error('startGame failed:', e)
if (e instanceof chat.ChatClientFatalError) {
throw e
}
return false
}

View File

@ -1,6 +1,8 @@
import { BrotliDecode } from './brotli_decode'
import { inflate } from 'pako'
import * as chat from '..'
const HEADER_SIZE = 16
export const WS_BODY_PROTOCOL_VERSION_NORMAL = 0
@ -50,6 +52,8 @@ export default class ChatClientOfficialBase {
this.onDelSuperChat = null
this.onUpdateTranslation = null
this.onFatalError = null
this.needInitRoom = true
this.websocket = null
this.retryCount = 0
@ -116,7 +120,18 @@ export default class ChatClientOfficialBase {
return
}
if (!await this.initRoom()) {
let res
try {
res = await this.initRoom()
} catch (e) {
res = false
console.error('initRoom exception:', e)
if (e instanceof chat.ChatClientFatalError && this.onFatalError) {
this.onFatalError(e)
}
}
if (!res) {
this.onWsClose()
throw Error('initRoom failed')
}

View File

@ -1,3 +1,5 @@
import * as chat from '.'
const COMMAND_HEARTBEAT = 0
const COMMAND_JOIN_ROOM = 1
const COMMAND_ADD_TEXT = 2
@ -6,6 +8,7 @@ const COMMAND_ADD_MEMBER = 4
const COMMAND_ADD_SUPER_CHAT = 5
const COMMAND_DEL_SUPER_CHAT = 6
const COMMAND_UPDATE_TRANSLATION = 7
const COMMAND_FATAL_ERROR = 8
// const CONTENT_TYPE_TEXT = 0
const CONTENT_TYPE_EMOTICON = 1
@ -24,6 +27,8 @@ export default class ChatClientRelay {
this.onDelSuperChat = null
this.onUpdateTranslation = null
this.onFatalError = null
this.websocket = null
this.retryCount = 0
this.isDestroying = false
@ -176,6 +181,14 @@ export default class ChatClientRelay {
this.onUpdateTranslation(data)
break
}
case COMMAND_FATAL_ERROR: {
if (!this.onFatalError) {
break
}
let error = new chat.ChatClientFatalError(data.type, data.msg)
this.onFatalError(error)
break
}
}
}
}

View File

@ -238,6 +238,8 @@ export default class ChatClientTest {
this.onDelSuperChat = null
this.onUpdateTranslation = null
this.onFatalError = null
this.timerId = null
}

View File

@ -1,5 +1,14 @@
import axios from 'axios'
export const FATAL_ERROR_TYPE_AUTH_CODE_ERROR = 1
export class ChatClientFatalError extends Error {
constructor(type, message) {
super(message)
this.type = type
}
}
export const DEFAULT_AVATAR_URL = '//static.hdslb.com/images/member/noface.gif'
export function processAvatarUrl(avatarUrl) {

View File

@ -88,7 +88,7 @@ export default {
//
this.$message({
message: 'Loaded',
duration: '500'
duration: 500
})
},
beforeDestroy() {
@ -165,6 +165,7 @@ export default {
this.chatClient.onAddSuperChat = this.onAddSuperChat
this.chatClient.onDelSuperChat = this.onDelSuperChat
this.chatClient.onUpdateTranslation = this.onUpdateTranslation
this.chatClient.onFatalError = this.onFatalError
this.chatClient.start()
},
async initTextEmoticons() {
@ -266,6 +267,18 @@ export default {
}
this.$refs.renderer.updateMessage(data.id, { translation: data.translation })
},
onFatalError(error) {
this.$message.error({
message: error.toString(),
duration: 10 * 1000
})
this.chatClient.stop()
if (error.type === chat.FATAL_ERROR_TYPE_AUTH_CODE_ERROR) {
// Read The Fucking Manual
this.$router.push({ name: 'help' })
}
},
filterTextMessage(data) {
if (this.config.blockGiftDanmaku && data.isGiftDanmaku) {

View File

@ -176,8 +176,20 @@ class OpenLiveClient(blivedm.OpenLiveClient):
except api_open_live.TransportError:
logger.error('_start_game() failed')
return False
except api_open_live.BusinessError:
except api_open_live.BusinessError as e:
logger.warning('_start_game() failed')
if e.code == 7007:
# 身份码错误
# 让我看看是哪个混蛋把房间ID、UID当做身份码
logger.warning('Auth code error! auth_code=%s', self._room_owner_auth_code)
room = client_room_manager.get_room(self.room_key)
if room is not None:
room.send_cmd_data(api.chat.Command.FATAL_ERROR, {
'type': api.chat.FatalErrorType.AUTH_CODE_ERROR,
'msg': str(e)
})
return False
return self._parse_start_game(data['data'])