import StateMachine from 'javascript-state-machine';
import LobbyConnection, { ROOM_LIST_UPDATED_EVENT } from './LobbyConnection';
import Event from './Event';
import PlayError from './PlayError';
import PlayErrorCode from './PlayErrorCode';
import { debug } from './Logger';
/**
* 大厅类,用来请求和接收大厅相关事件
*/
export default class Lobby {
constructor(client) {
this._client = client;
this._fsm = new StateMachine({
init: 'init',
final: 'closed',
transitions: [
{ name: 'join', from: 'init', to: 'joining' },
{ name: 'joined', from: 'joining', to: 'lobby' },
{ name: 'joinFailed', from: 'joining', to: 'init' },
{ name: 'leave', from: 'lobby', to: 'leaving' },
{
name: 'close',
from: ['init', 'joining', 'lobby', 'leaving'],
to: 'closed',
},
],
methods: {
onEnterLobby: () => {
this._lobbyConn.on(ROOM_LIST_UPDATED_EVENT, roomList => {
// 房间列表更新
this._lobbyRoomList = roomList;
this._client.emit(Event.LOBBY_ROOM_LIST_UPDATED);
});
},
onExitLobby: () => {
this._lobbyConn.removeAllListeners();
},
},
});
}
async join() {
if (this._fsm.cannot('join')) {
throw new PlayError(
PlayErrorCode.STATE_ERROR,
`Error state: ${this._fsm.state}`
);
}
this._fsm.join();
let lobbyInfo = null;
try {
const { _lobbyService } = this._client;
lobbyInfo = await _lobbyService.authorize();
} catch (e) {
this._fsm.joinFailed();
throw e;
}
try {
const { url, sessionToken } = lobbyInfo;
const { _appId, _gameVersion, _userId } = this._client;
this._lobbyConn = new LobbyConnection();
// 微信小程序不支持使用 http 协议构造 WebSocket
const lobbyUrl = url
.replace('https://', 'wss://')
.replace('http://', 'ws://');
debug(`lobby url: ${lobbyUrl}`);
await this._lobbyConn.connect(
_appId,
lobbyUrl,
_gameVersion,
_userId,
sessionToken
);
await this._lobbyConn.joinLobby();
this._fsm.joined();
} catch (e) {
if (this._lobbyConn) {
await this._lobbyConn.close();
}
this._fsm.joinFailed();
throw e;
}
}
async leave() {
try {
await this._lobbyConn.leaveLobby();
} finally {
await this._lobbyConn.close();
}
}
async close() {
if (this._fsm.can('close')) {
await this._lobbyConn.close();
}
}
}