Commit e19dda5f authored by 范雪寒's avatar 范雪寒

feat: networkHelper

parent 915199c0
No preview for this file type
{
"ver": "1.1.2",
"uuid": "d5f63b05-0201-428e-a578-4a52a688266d",
"uuid": "827d871e-1ae4-411e-9fe3-0411c5279abe",
"isBundle": false,
"bundleName": "",
"priority": 1,
......
export as namespace Play;
declare class EventEmitter<T> {
on<K extends keyof T>(event: K, listener: (payload: T[K]) => any): this;
on(evt: string, listener: Function): this;
once<K extends keyof T>(event: K, listener: (payload: T[K]) => any): this;
once(evt: string, listener: Function): this;
off<K extends keyof T>(evt: K | string, listener?: Function): this;
emit<K extends keyof T>(evt: K | string, ...args: any[]): boolean;
}
export enum Event {
/** 断开连接 */
DISCONNECTED = 'disconnected',
/** 加入到大厅 */
LOBBY_JOINED = 'lobbyJoined',
/** 大厅房间列表变化 */
LOBBY_ROOM_LIST_UPDATED = 'lobbyRoomListUpdate',
/** 有新玩家加入房间 */
PLAYER_ROOM_JOINED = 'newPlayerJoinedRoom',
/** 有玩家离开房间 */
PLAYER_ROOM_LEFT = 'playerLeftRoom',
/** 玩家活跃属性变化 */
PLAYER_ACTIVITY_CHANGED = 'playerActivityChanged',
/** 主机变更 */
MASTER_SWITCHED = 'masterSwitched',
/** 离开房间 */
ROOM_LEFT = 'roomLeft',
/** 被踢出房间 */
ROOM_KICKED = 'roomKicked',
/** 房间系统属性变化 */
ROOM_SYSTEM_PROPERTIES_CHANGED = 'roomSystemPropertiesChanged',
/** 房间自定义属性变化 */
ROOM_CUSTOM_PROPERTIES_CHANGED = 'roomCustomPropertiesChanged',
/** 玩家自定义属性变化 */
PLAYER_CUSTOM_PROPERTIES_CHANGED = 'playerCustomPropertiesChanged',
/** 自定义事件 */
CUSTOM_EVENT = 'customEvent',
/** 错误事件 */
ERROR = 'error',
}
export enum ReceiverGroup {
/** 其他人(除了自己之外的所有人) */
Others,
/** 所有人(包括自己) */
All,
/** 主机客户端 */
MasterClient,
}
interface CustomProperties {
[key: string]: any;
}
interface CustomEventData {
[key: string]: any;
}
interface ErrorEvent {
code: number;
detail: string;
}
declare interface PlayEvent {
connected: void;
connectFailed: ErrorEvent;
disconnected: void;
lobbyJoined: void;
lobbyLeft: void;
lobbyRoomListUpdate: void;
roomCreated: void;
roomCreateFailed: ErrorEvent;
roomJoined: void;
roomJoinFailed: ErrorEvent;
newPlayerJoinedRoom: {
newPlayer: Player;
};
playerLeftRoom: {
leftPlayer: Player;
};
playerActivityChanged: {
player: Player;
};
masterSwitched: {
newMaster: Player;
};
roomLeft: void;
roomKicked: {
code: number;
msg: string;
};
roomCustomPropertiesChanged: {
changedProps: CustomProperties;
};
roomSystemPropertiesChanged: {
changedProps: CustomProperties;
};
playerCustomPropertiesChanged: {
player: Player;
changedProps: CustomProperties;
};
customEvent: {
eventId: number;
eventData: CustomEventData;
senderId: number;
};
error: ErrorEvent;
}
export class LobbyRoom {
readonly roomName: string;
readonly maxPlayerCount: number;
readonly expectedUserIds: string[];
readonly emptyRoomTtl: number;
readonly playerTtl: number;
readonly playerCount: number;
readonly customRoomPropertiesForLobby: CustomProperties;
}
export class Player {
readonly userId: string;
readonly actorId: number;
readonly isLocal: boolean;
readonly isMaster: boolean;
readonly isActive: boolean;
setCustomProperties(
properties: CustomProperties,
opts?: {
expectedValues?: CustomProperties;
}
): Promise<void>;
readonly customProperties: CustomProperties;
}
export class Room {
readonly name: string;
readonly open: boolean;
readonly visible: boolean;
readonly maxPlayerCount: number;
readonly master: Player;
readonly masterId: number;
readonly expectedUserIds: string[];
readonly playerList: Player[];
getPlayer(actorId: number): Player;
setCustomProperties(
properties: CustomProperties,
opts?: {
expectedValues?: CustomProperties;
}
): Promise<void>;
readonly customProperties: CustomProperties;
setOpen(open: boolean): Promise<void>;
setVisible(visible: boolean): Promise<void>;
setRoomMaxPlayerCount(count: number): Promise<void>;
setRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
clearRoomExpectedUserIds(): Promise<void>;
addRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
removeRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
setMaster(newMasterId: number): Promise<void>;
sendEvent(
eventId: number,
eventData?: CustomEventData,
options?: {
receiverGroup?: ReceiverGroup;
targetActorIds?: number[];
}
): Promise<void>;
kickPlayer(
actorId: number,
opts?: {
code?: number;
msg?: string;
}
): Promise<void>;
leave(): Promise<void>;
}
export class Client extends EventEmitter<PlayEvent> {
readonly room: Room;
readonly player: Player;
readonly lobbyRoomList: LobbyRoom[];
userId: string;
constructor(opts: {
appId: string;
appKey: string;
userId: string;
ssl?: boolean;
feature?: string;
gameVersion?: string;
playServer?: string;
});
connect(): Promise<Client>;
reconnect(): Promise<Client>;
reconnectAndRejoin(): Promise<Room>;
close(): Promise<void>;
joinLobby(): Promise<void>;
leaveLobby(): Promise<void>;
createRoom(opts?: {
roomName?: string;
roomOptions?: Object;
expectedUserIds?: string[];
}): Promise<Room>;
joinRoom(
roomName: string,
opts?: {
expectedUserIds?: string[];
}
): Promise<Room>;
rejoinRoom(roomName: string): Promise<Room>;
joinOrCreateRoom(
roomName: string,
opts?: {
roomOptions?: Object;
expectedUserIds: string[];
}
): Promise<Room>;
joinRandomRoom(opts?: {
matchProperties?: Object;
expectedUserIds?: string[];
}): Promise<Room>;
matchRandom(
piggybackPeerId: string,
opts?: { matchProperties?: Object; expectedUserIds?: string[] }
): Promise<LobbyRoom>;
setRoomOpen(open: boolean): Promise<void>;
setRoomVisible(visible: boolean): Promise<void>;
setRoomMaxPlayerCount(count: number): Promise<void>;
setRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
clearRoomExpectedUserIds(): Promise<void>;
addRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
removeRoomExpectedUserIds(expectedUserIds: string[]): Promise<void>;
setMaster(newMasterId: number): Promise<void>;
sendEvent(
eventId: number,
eventData?: CustomEventData,
options?: {
receiverGroup?: ReceiverGroup;
targetActorIds?: number[];
}
): Promise<void>;
leaveRoom(): Promise<void>;
kickPlayer(
actorId: number,
opts?: {
code?: number;
msg?: string;
}
): Promise<void>;
pauseMessageQueue(): void;
resumeMessageQueue(): void;
}
export enum CreateRoomFlag {
FixedMaster = 1,
MasterUpdateRoomProperties = 2,
}
export function setAdapters(newAdapters: { WebSocket: Function }): void;
export enum LogLevel {
Debug = 'Debug',
Warn = 'Warn',
Error = 'Error',
}
export function setLogger(logger: {
Debug: (...args: any[]) => any;
Warn: (...args: any[]) => any;
Error: (...args: any[]) => any;
}): void;
export enum PlayErrorCode {
OPEN_WEBSOCKET_ERROR = 10001,
SEND_MESSAGE_STATE_ERROR = 10002,
}
export function registerType<T>(
type: T,
typeId: number,
serializeMethod: (obj: T) => Uint8Array,
deserializeMethod: (bytes: Uint8Array) => T
): void;
export function serializeObject(obj: Object): Uint8Array;
export function deserializeObject(bytes: Uint8Array): Object;
{
"ver": "2.0.0",
"uuid": "5bcc0ae2-0927-4b6b-9ac1-9c4bfe24b34d",
"subMetas": {}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"ver": "1.0.8",
"uuid": "92c53b26-dc66-4a71-9e9b-862df5cb12b5",
"uuid": "3e7a7ab3-dbdb-49c9-995d-757dbfe9f58b",
"isPlugin": true,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"loadPluginInEditor": true,
"subMetas": {}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
import { RandomInt } from "../script/util";
export class NetworkHelper {
_eventListeners: any = {};
ctor() {}
ctor() { }
on(eventName, func) {
this._eventListeners[eventName] = func;
}
async init(roomType: string, maxPlayers: number) {
this.initRoom();
try {
return await this.joinRoom(roomType, maxPlayers);
} catch (e) {
await this.initListener();
this.initRoom();
await this.initRoom();
return await this.joinRoom(roomType, maxPlayers);
}
}
async startGame() {
await this.startFrameSync();
......@@ -25,239 +20,137 @@ export class NetworkHelper {
async stopGame() {
await this.stopFrameSync();
await this.closeRoom();
await this.leaveRoom();
}
getRoomInfo() {
return this.room.roomInfo;
}
initListener() {
if (MGOBE.Player.id !== undefined) {
return;
}
return new Promise((resolve, reject) => {
const gameId = "obg-i4ql53h1"; //替换为控制台上的 游戏 ID
const secretKey = "060d81c7abaf24c8ce2afc5a725c152062676d35"; //替换为控制台上的 游戏 Key
const serverUrl = "i4ql53h1.wxlagame.com"; //替换为控制台上的 域名
const gameInfo = {
gameId: gameId,
openId: "openid_test" + Math.random(), //自定义的用户唯一ID
secretKey: secretKey,
};
const config = {
url: serverUrl,
reconnectMaxTimes: 5,
reconnectInterval: 1000,
resendInterval: 1000,
resendTimeout: 10000,
cacertNativeUrl: "",
};
MGOBE.DebuggerLog.enable = false;
// 如果是原生平台,则加载 Cert 证书,否则会提示 WSS 错误
if (cc.sys.isNative) {
let cacertFile;
const cacertNode = cc.find("cacertNode");
if (cacertNode) {
cacertFile = cacertNode.getComponent("cacert").cacertFile;
}
if (!cacertFile) {
this.log("没有cacertFile!!!");
}
config.cacertNativeUrl =
cc.loader.md5Pipe && cc.ENGINE_VERSION < "2.4.0"
? cc.loader.md5Pipe.transformURL(cacertFile.nativeUrl)
: cacertFile.nativeUrl;
}
listenerInited = false;
MGOBE.Listener.init(gameInfo, config, (event) => {
this.log(JSON.stringify(event));
if (event.code !== 0) {
this.log("初始化失败: " + event.code);
reject();
return;
}
this.log("初始化成功");
resolve(null);
});
room: any;
client: any;
async initRoom() {
const client = new globalThis.Play.Client({
appId: "lyn5nahSjCX0gpuRPugoMILM-gzGzoHsz",
appKey: "Nh9qGdBHq7MGjPbgUoLxm8oG",
userId: `${new Date().getTime()}_${RandomInt(100000000)}`,
playServer: 'https://lyn5nahs.lc-cn-n1-shared.com'
});
console.log('client = ', client);
await client.connect();
this.client = client;
console.log('连接成功');
}
room: MGOBE.Room;
initRoom() {
this.room = new MGOBE.Room();
MGOBE.Listener.add(this.room);
this.room.onJoinRoom = this.onJoinRoom.bind(this);
this.room.onLeaveRoom = this.onLeaveRoom.bind(this);
this.room.onRecvFromClient = this.onRecvFromClient.bind(this);
this.room.onRecvFrame = this.onRecvFrame.bind(this);
this.room.onChangePlayerNetworkState =
this.onChangePlayerNetworkState.bind(this);
this.room.onStartFrameSync = this.onStartFrameSync.bind(this);
this.room.onStopFrameSync = this.onStopFrameSync.bind(this);
this.room.onRecvFromGameSvr = this.onRecvFromGameSvr.bind(this);
this.log("this.room = " + JSON.stringify(this.room.roomInfo));
}
joinRoom(roomType: string, maxPlayers: number, customData: string = "") {
player: any;
joinRoom(roomType: string, maxPlayers: number) {
return new Promise((resolve, reject) => {
const playerName = "Tom" + Math.random();
const playerInfo = {
name: playerName,
customPlayerStatus: 0,
customProfile: customData,
};
const matchRoomPara = {
playerInfo,
maxPlayers: maxPlayers,
roomType: roomType,
const roomProp = { roomType, maxPlayers };
this.client.joinRandomRoom({
matchProperties: roomProp,
}).then((room) => {
resolve(this.onJoinRoomSuccess(room));
}).catch((error) => {
console.log('加入房间失败');
if (error.code == 4301) {
const options = {
visible: true,
playerTtl: 0,
emptyRoomTtl: 0,
maxPlayerCount: maxPlayers,
customRoomProperties: roomProp,
customRoomPropertyKeysForLobby: ['roomType', 'maxPlayers'],
flag: globalThis.Play.CreateRoomFlag.MasterUpdateRoomProperties
};
this.room.matchRoom(matchRoomPara, (event) => {
this.log(JSON.stringify(event));
if (event.code === 0) {
cc.log("匹配成功: " + event.data.roomInfo.id);
const player = event.data.roomInfo.playerList.find(
(player) => player.name == playerName
);
if (this.checkRoomOwnerOffLine()) {
if (this._eventListeners["playerOffLine"]) {
this._eventListeners["playerOffLine"](event);
}
cc.log("房主掉线了");
resolve(null);
return;
}
resolve(player.id);
} else {
cc.log("匹配失败");
reject(event);
}
});
this.client.createRoom({
roomOptions: options,
}).then((room) => {
resolve(this.onJoinRoomSuccess(room));
}).catch((error) => {
console.error(error.code, error.detail);
});
}
leaveRoom() {
return new Promise((resolve, reject) => {
this.room.leaveRoom({}, (event) => {
this.log(JSON.stringify(event));
if (event.code === 0) {
this.log("退房成功" + this.room.roomInfo.id);
// this.room.initRoom();
resolve(null);
} else {
this.log("退房失败");
}
});
});
}
closeRoom() {
return new Promise((resolve, reject) => {
this.room.changeRoom({ isForbidJoin: true }, (event) => {
console.log("关门");
this.log(JSON.stringify(event));
resolve(null);
onJoinRoomSuccess(room: globalThis.Play.Room) {
console.log('加入房间成功 room = ', room);
const playerMe = room.playerList.find(player => player.isLocal);
const masterPlayer = room.playerList.find(player => player.isMaster);
const masterId = masterPlayer.userId;
const playerId = playerMe.userId;
this.room = new FakeRoom(masterId);
this.room.players.push(this.room.player);
this.player = this.room.player;
this.client.on(globalThis.Play.Event.PLAYER_ROOM_LEFT, (event) => {
this.onLeaveRoom({ data: { leavePlayerId: event.leftPlayer.userId } });
});
this.client.on(globalThis.Play.Event.PLAYER_ROOM_JOINED, (event) => {
this.onJoinRoom({ playerId: event.newPlayer.userId });
});
this.client.on(globalThis.Play.Event.CUSTOM_EVENT, (event) => {
this.onRecvFrame({ data: event.eventData });
});
// this.room.onDisconnect(this.onDisconnect.bind(this));
// this.room.onDismiss(this.onDisconnect.bind(this));
return playerId;
}
sendMessage() {
const sendToClientPara = {
recvType: MGOBE.ENUM.RecvType.ROOM_ALL,
recvPlayerList: [],
msg: "hello" + Math.random(),
};
this.room.sendToClient(sendToClientPara, (event) => console.log(event));
async leaveRoom() {
await this.client.close();
console.log("退房成功");
}
startFrameSync() {
return new Promise((resolve, reject) => {
this.room.startFrameSync({}, (event) => {
this.log(JSON.stringify(event));
if (event.code === 0) {
cc.log("开始帧同步成功,请到控制台查看具体帧同步信息");
resolve(null);
} else {
reject();
async dismissRoom() {
if (this.room.ownerId == this.player.id) {
console.log("房间已解散");
}
});
});
}
stopFrameSync() {
return new Promise((resolve, reject) => {
if (!this.room) {
resolve(null);
return;
async closeRoom() {
// 设置房间不可见
await this.client.setRoomVisible(false);
console.log(this.client.room.visible);
}
this.room.stopFrameSync({}, (event) => {
this.log(JSON.stringify(event));
if (event.code === 0) {
this.log("停止帧同步成功");
resolve(null);
} else {
this.log("停止帧同步失败");
reject(event.code);
}
});
});
async startFrameSync() {
console.log("开始帧同步成功");
}
sendToServer() {
const sendToGameServerPara = {
data: {
cmd: 1,
},
};
this.room.sendToGameSvr(sendToGameServerPara, (event) =>
console.log(event)
);
async stopFrameSync() {
console.log("停止帧同步成功");
}
sendFrame(data: any) {
this.room.sendFrame({ data }, (err) => {
if (err.code != 0) {
console.log("err", err);
}
this.client.sendEvent(0, { frame: { items: [{ data: data }] } }, {
receiverGroup: globalThis.Play.ReceiverGroup.All,
});
}
onJoinRoom(event) {
console.log("新玩家加入", event);
if (this._eventListeners["playerJoin"]) {
this._eventListeners["playerJoin"](event);
}
console.log("新玩家加入", event.data.joinPlayerId);
this.room.players.forEach(player => {
console.log('player.playerId = ', player.playerId);
});
}
onLeaveRoom(event) {
console.log("onLeaveRoom");
if (this._eventListeners["playerLeave"]) {
this._eventListeners["playerLeave"](event);
}
console.log("玩家退出", event.data.leavePlayerId);
}
onRecvFromClient() {}
checkRoomOwnerOffLine() {
const owner = this.room.roomInfo.playerList.find(
(player) => player.id == this.room.roomInfo.owner
);
return (
owner.commonNetworkState == MGOBE.types.NetworkState.COMMON_OFFLINE ||
owner.relayNetworkState == MGOBE.types.NetworkState.RELAY_OFFLINE
);
}
onChangePlayerNetworkState(event) {
console.log("玩家网络变化: " + JSON.stringify(event));
if (this.checkRoomOwnerOffLine()) {
onRecvFromClient() { }
onDisconnect(event) {
this.log("玩家掉线了: " + JSON.stringify(event));
if (this._eventListeners["playerOffLine"]) {
this._eventListeners["playerOffLine"](event);
}
cc.log("房主掉线了");
}
}
onRecvFrame(event) {
......@@ -266,21 +159,25 @@ export class NetworkHelper {
}
}
onStartFrameSync(event) {
console.log('onStartFrameSync');
if (this._eventListeners["gameStart"]) {
this._eventListeners["gameStart"](event);
}
}
onStopFrameSync(event) {}
onRecvFromGameSvr() {}
onStopFrameSync(event) { }
onRecvFromGameSvr() { }
async onDestroy() {
try {
this.log("onDestroy1");
MGOBE.Listener.clear();
await this.stopGame();
this.log("onDestroy2");
console.log("onDestroy1");
// MGOBE.Listener.clear();
this.stopFrameSync();
this.closeRoom();
this.dismissRoom();
this.leaveRoom();
console.log("onDestroy2");
} catch (e) {
this.log(JSON.stringify(e));
console.log(JSON.stringify(e));
}
}
......@@ -292,4 +189,48 @@ export class NetworkHelper {
cc.log(str);
}
}
callNetworkApiGet(baseUrl, uri, data, callBack) {
let queryStr = "?";
const params = [];
for (const key in data) {
if (Object.hasOwnProperty.call(data, key)) {
params.push(`${key}=${data[key]}`);
}
}
queryStr += params.join("&");
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 400) {
callBack(xhr.responseText);
}
};
const url = `${baseUrl}${uri}${queryStr}`;
console.log("url = " + url);
xhr.open("GET", url, true);
xhr.send();
}
}
export function asyncDelay(time) {
return new Promise((resolve, reject) => {
cc.tween(cc.find("Canvas"))
.delay(time)
.call(() => {
resolve(null);
})
.start();
});
}
class FakeRoom {
ownerId;
players = [];
player: any;
roomInfo;
constructor(playerId) {
this.player = { playerId: playerId };
this.ownerId = playerId;
this.roomInfo = { owner: playerId }
}
}
\ No newline at end of file
......@@ -467,7 +467,7 @@ cc.Class({
try {
this.log("喵喵喵1");
this.playerId = await this.networkHelper.init("op_09_plus", 5);
this.playerId = await this.networkHelper.init("OP32_PLUS", 5);
this.log("喵喵喵2");
const room = this.networkHelper.room;
if (this.playerId == room.roomInfo.owner) {
......
{
"ver": "1.0.8",
"uuid": "f9688dab-f4fd-4e4b-9a97-a76b90f239f4",
"isPlugin": true,
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment