125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
import MWSEEventTarget from './EventTarget.js';
|
|
import { RoomInfo } from './RoomInfo.js';
|
|
|
|
export default class Room extends MWSEEventTarget {
|
|
constructor(mwse) {
|
|
super();
|
|
this.mwse = mwse;
|
|
this.peers = new Map();
|
|
this.info = new RoomInfo(this);
|
|
|
|
this.options = undefined;
|
|
this.config = undefined;
|
|
this.roomId = undefined;
|
|
this.accessType = undefined;
|
|
this.joinType = undefined;
|
|
this.name = undefined;
|
|
this.owner = undefined;
|
|
}
|
|
|
|
setRoomOptions(options) {
|
|
if (typeof options === 'string') {
|
|
this.roomId = options;
|
|
} else {
|
|
const defaults = {
|
|
joinType: 'free',
|
|
ifexistsJoin: true,
|
|
accessType: 'private',
|
|
notifyActionInvite: true,
|
|
notifyActionJoined: true,
|
|
notifyActionEjected: true,
|
|
autoFetchInfo: true
|
|
};
|
|
this.config = Object.assign(defaults, options);
|
|
}
|
|
}
|
|
|
|
setRoomId(uuid) {
|
|
this.roomId = uuid;
|
|
}
|
|
|
|
async createRoom(roomOptions) {
|
|
const config = this.config || roomOptions;
|
|
const result = await this.mwse.EventPooling.request({ type: 'create-room', ...config });
|
|
|
|
if (result.status === 'fail') {
|
|
if (result.message === 'ALREADY-EXISTS' && this.config?.ifexistsJoin) {
|
|
return this.join();
|
|
}
|
|
throw new Error(result.message || result.messages);
|
|
}
|
|
|
|
this.options = { ...this.config, ...result.room };
|
|
this.roomId = result.room.id;
|
|
this.mwse.rooms.set(this.roomId, this);
|
|
}
|
|
|
|
async join() {
|
|
const result = await this.mwse.EventPooling.request({
|
|
type: 'joinroom',
|
|
name: this.config.name,
|
|
credential: this.config.credential,
|
|
autoFetchInfo: this.config.autoFetchInfo || false
|
|
});
|
|
|
|
if (result.status === 'fail') throw new Error(result.message);
|
|
|
|
this.options = { ...this.config, ...result.room };
|
|
if (result.info) this.info.info = result.info;
|
|
this.roomId = result.room.id;
|
|
this.mwse.rooms.set(this.roomId, this);
|
|
}
|
|
|
|
async eject() {
|
|
const { type } = await this.mwse.EventPooling.request({
|
|
type: 'ejectroom',
|
|
roomId: this.roomId
|
|
});
|
|
this.peers.clear();
|
|
if (type === 'success') this.mwse.rooms.delete(this.roomId);
|
|
}
|
|
|
|
async send(pack, wom = false, handshake = false) {
|
|
if (!this.mwse.writable) {
|
|
console.warn('MWSE: socket is not writable');
|
|
return;
|
|
}
|
|
if (handshake) {
|
|
const { type } = await this.mwse.EventPooling.request({
|
|
type: 'pack/room', pack, to: this.roomId, wom, handshake
|
|
});
|
|
if (type === 'fail') throw new Error('Cannot send message to room');
|
|
} else {
|
|
// WOM broadcast — fire-and-forget, no waiter (#33).
|
|
this.mwse.EventPooling.only({ type: 'pack/room', pack, to: this.roomId, wom, handshake });
|
|
}
|
|
}
|
|
|
|
async fetchPeers(filter, onlyNumber = false) {
|
|
if (onlyNumber) {
|
|
const { count } = await this.mwse.EventPooling.request({
|
|
type: 'room/peer-count',
|
|
roomId: this.roomId,
|
|
filter: filter || {}
|
|
});
|
|
return count;
|
|
}
|
|
|
|
const { status, peers } = await this.mwse.EventPooling.request({
|
|
type: 'room-peers',
|
|
roomId: this.roomId,
|
|
filter: filter || {}
|
|
});
|
|
|
|
if (status === 'fail') throw new Error('Cannot fetch peers from room');
|
|
|
|
const result = [];
|
|
for (const peerId of peers) {
|
|
const peer = this.mwse.peer(peerId, true);
|
|
result.push(peer);
|
|
this.peers.set(peerId, peer);
|
|
}
|
|
return result;
|
|
}
|
|
}
|