@zimi/remote 0.2.1-alpha.7 → 0.2.1-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adaptors/dao3/client.d.ts +28 -0
- package/dist/adaptors/dao3/client.js +36 -0
- package/dist/adaptors/dao3/client.js.map +1 -0
- package/dist/adaptors/dao3/server.d.ts +65 -0
- package/dist/adaptors/dao3/server.js +89 -0
- package/dist/adaptors/dao3/server.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/remoteValue/exposeToRemote.d.ts +1 -0
- package/dist/remoteValue/exposeToRemote.js +3 -0
- package/dist/remoteValue/exposeToRemote.js.map +1 -1
- package/package.json +1 -1
- package/src/adaptors/dao3/client.ts +43 -0
- package/src/adaptors/dao3/server.ts +123 -0
- package/src/index.ts +4 -1
- package/src/remoteValue/exposeToRemote.ts +4 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { type AdaptorPackageData } from '../../index';
|
|
3
|
+
interface RemoteChannel {
|
|
4
|
+
onClientEvent(fn: (e: unknown) => void): void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
|
|
8
|
+
* ```ts
|
|
9
|
+
* const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
|
|
10
|
+
*
|
|
11
|
+
* export const remoteAdaptor = {
|
|
12
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
13
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
14
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
15
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
16
|
+
* emit: (e) => {
|
|
17
|
+
* remoteChannel.sendServerEvent(e)
|
|
18
|
+
* },
|
|
19
|
+
* } satisfies Adaptor
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class ClientSideRemoteChannelEventManager extends EventEmitter<{
|
|
23
|
+
[key: string]: [AdaptorPackageData];
|
|
24
|
+
}> {
|
|
25
|
+
constructor(remoteChannel: RemoteChannel);
|
|
26
|
+
onEvery(fn: (args: AdaptorPackageData) => void): void;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { isRemoteAdaptorData } from '../../index';
|
|
3
|
+
/**
|
|
4
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
|
|
5
|
+
* ```ts
|
|
6
|
+
* const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
|
|
7
|
+
*
|
|
8
|
+
* export const remoteAdaptor = {
|
|
9
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
10
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
11
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
12
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
13
|
+
* emit: (e) => {
|
|
14
|
+
* remoteChannel.sendServerEvent(e)
|
|
15
|
+
* },
|
|
16
|
+
* } satisfies Adaptor
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class ClientSideRemoteChannelEventManager extends EventEmitter {
|
|
20
|
+
constructor(remoteChannel) {
|
|
21
|
+
super();
|
|
22
|
+
remoteChannel.onClientEvent((e) => {
|
|
23
|
+
if (!isRemoteAdaptorData(e)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!e.name.startsWith('__REMOTE_VALUE_REQ__')) {
|
|
27
|
+
this.emit('__remote_every__', e);
|
|
28
|
+
}
|
|
29
|
+
this.emit(e.name, e);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
onEvery(fn) {
|
|
33
|
+
this.on('__remote_every__', fn);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/client.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAA2B,MAAM,aAAa,CAAA;AAM1E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,mCAAoC,SAAQ,YAEvD;IACA,YAAY,aAA4B;QACtC,KAAK,EAAE,CAAA;QACP,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,OAAM;YACR,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;YAClC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,EAAsC;QAC5C,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { type AdaptorPackageData } from '../../index';
|
|
3
|
+
interface GamePlayerEntityLike {
|
|
4
|
+
player: {
|
|
5
|
+
userKey: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
interface RemoteChannel<T extends GamePlayerEntityLike> {
|
|
9
|
+
onServerEvent(fn: (e: {
|
|
10
|
+
args: unknown;
|
|
11
|
+
entity: T;
|
|
12
|
+
}) => void): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
|
|
16
|
+
* ```ts
|
|
17
|
+
* const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
|
|
18
|
+
*
|
|
19
|
+
* world.onPlayerLeave(
|
|
20
|
+
* remoteManager.onPlayerLeave.bind(remoteManager)
|
|
21
|
+
* )
|
|
22
|
+
*
|
|
23
|
+
* export const remoteAdaptor = {
|
|
24
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
25
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
26
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
27
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
28
|
+
* emit: (e) => {
|
|
29
|
+
* const entity = getEntity(e.targetDeviceId)
|
|
30
|
+
* if (!entity) {
|
|
31
|
+
* console.error('entity not found')
|
|
32
|
+
* return
|
|
33
|
+
* }
|
|
34
|
+
* remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
|
|
35
|
+
* },
|
|
36
|
+
* } satisfies Adaptor
|
|
37
|
+
*
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class ServerSideRemoteChannelEventManager<T extends GamePlayerEntityLike> extends EventEmitter<{
|
|
41
|
+
[key: string]: [AdaptorPackageData];
|
|
42
|
+
}> {
|
|
43
|
+
entityMap: [string, T][];
|
|
44
|
+
constructor(remoteChannel: RemoteChannel<T>);
|
|
45
|
+
onPlayerLeave(e: {
|
|
46
|
+
entity: T;
|
|
47
|
+
}): void;
|
|
48
|
+
onEvery(fn: (args: AdaptorPackageData) => void): void;
|
|
49
|
+
waitForRegister(entity: T): Promise<void>;
|
|
50
|
+
getEntity(deviceId: string): T | undefined;
|
|
51
|
+
getIdByEntity(entity: T): string | undefined;
|
|
52
|
+
remoteTo(config: {
|
|
53
|
+
target: T;
|
|
54
|
+
}): {
|
|
55
|
+
targetDeviceId: string;
|
|
56
|
+
};
|
|
57
|
+
remoteTo(config: {
|
|
58
|
+
target: T;
|
|
59
|
+
timeoutMs: number;
|
|
60
|
+
}): {
|
|
61
|
+
targetDeviceId: string;
|
|
62
|
+
timeoutMs: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { isRemoteAdaptorData, isRemoteValueEvent, } from '../../index';
|
|
3
|
+
/**
|
|
4
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
|
|
5
|
+
* ```ts
|
|
6
|
+
* const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
|
|
7
|
+
*
|
|
8
|
+
* world.onPlayerLeave(
|
|
9
|
+
* remoteManager.onPlayerLeave.bind(remoteManager)
|
|
10
|
+
* )
|
|
11
|
+
*
|
|
12
|
+
* export const remoteAdaptor = {
|
|
13
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
14
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
15
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
16
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
17
|
+
* emit: (e) => {
|
|
18
|
+
* const entity = getEntity(e.targetDeviceId)
|
|
19
|
+
* if (!entity) {
|
|
20
|
+
* console.error('entity not found')
|
|
21
|
+
* return
|
|
22
|
+
* }
|
|
23
|
+
* remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
|
|
24
|
+
* },
|
|
25
|
+
* } satisfies Adaptor
|
|
26
|
+
*
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class ServerSideRemoteChannelEventManager extends EventEmitter {
|
|
30
|
+
constructor(remoteChannel) {
|
|
31
|
+
super();
|
|
32
|
+
Object.defineProperty(this, "entityMap", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: []
|
|
37
|
+
});
|
|
38
|
+
remoteChannel.onServerEvent((e) => {
|
|
39
|
+
const { args } = e;
|
|
40
|
+
if (!isRemoteAdaptorData(args)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const prevItem = this.entityMap.find((item) => item[1].player.userKey === e.entity.player.userKey);
|
|
44
|
+
if (prevItem) {
|
|
45
|
+
prevItem[0] = args.deviceId;
|
|
46
|
+
prevItem[1] = e.entity;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.entityMap.push([args.deviceId, e.entity]);
|
|
50
|
+
}
|
|
51
|
+
if (!isRemoteValueEvent(args.name)) {
|
|
52
|
+
this.emit('__remote_every__', args);
|
|
53
|
+
}
|
|
54
|
+
this.emit(args.name, args);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
onPlayerLeave(e) {
|
|
58
|
+
this.entityMap = this.entityMap.filter((item) => item[1].player.userKey !== e.entity.player.userKey);
|
|
59
|
+
}
|
|
60
|
+
onEvery(fn) {
|
|
61
|
+
this.on('__remote_every__', fn);
|
|
62
|
+
}
|
|
63
|
+
waitForRegister(entity) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
if (this.entityMap.some(([_, en]) => en.player.userKey === entity.player.userKey)) {
|
|
66
|
+
resolve();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.once('__remote_every__', () => {
|
|
70
|
+
resolve();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getEntity(deviceId) {
|
|
75
|
+
var _a;
|
|
76
|
+
return (_a = this.entityMap.find((item) => item[0] === deviceId)) === null || _a === void 0 ? void 0 : _a[1];
|
|
77
|
+
}
|
|
78
|
+
getIdByEntity(entity) {
|
|
79
|
+
var _a;
|
|
80
|
+
return (_a = this.entityMap.find((item) => item[1].player.userKey === entity.player.userKey)) === null || _a === void 0 ? void 0 : _a[0];
|
|
81
|
+
}
|
|
82
|
+
remoteTo({ target, ...rest }) {
|
|
83
|
+
return {
|
|
84
|
+
targetDeviceId: this.getIdByEntity(target),
|
|
85
|
+
...rest,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adaptors/dao3/server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export { createIframeAdaptor } from './adaptors/iframe';
|
|
|
5
5
|
export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
|
|
6
6
|
export type { ToFunc } from './remoteValue/type';
|
|
7
7
|
export { remoteValue } from './remoteValue/remoteValue';
|
|
8
|
-
export { exposeToRemote } from './remoteValue/exposeToRemote';
|
|
8
|
+
export { exposeToRemote, isRemoteValueEvent, } from './remoteValue/exposeToRemote';
|
package/dist/index.js
CHANGED
|
@@ -3,5 +3,5 @@ export { RemoteError, RemoteNotFoundError, RemoteTimeoutError, response, } from
|
|
|
3
3
|
export { createIframeAdaptor } from './adaptors/iframe';
|
|
4
4
|
export { createHttpAdaptor, remoteEventManager } from './adaptors/http';
|
|
5
5
|
export { remoteValue } from './remoteValue/remoteValue';
|
|
6
|
-
export { exposeToRemote } from './remoteValue/exposeToRemote';
|
|
6
|
+
export { exposeToRemote, isRemoteValueEvent, } from './remoteValue/exposeToRemote';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,EACL,cAAc,EACd,kBAAkB,GACnB,MAAM,8BAA8B,CAAA"}
|
|
@@ -11,5 +11,6 @@ interface ExposeProps {
|
|
|
11
11
|
*/
|
|
12
12
|
onRequest?: (e: AdaptorPackageData) => void | Promise<void>;
|
|
13
13
|
}
|
|
14
|
+
export declare function isRemoteValueEvent(eventName: string): boolean;
|
|
14
15
|
export declare function exposeToRemote<T extends object>(obj: T, options: ExposeProps): () => void;
|
|
15
16
|
export {};
|
|
@@ -2,6 +2,9 @@ import { RemoteError, response } from '../response';
|
|
|
2
2
|
function defaultOnRequest(e) {
|
|
3
3
|
return e;
|
|
4
4
|
}
|
|
5
|
+
export function isRemoteValueEvent(eventName) {
|
|
6
|
+
return eventName.startsWith('__REMOTE_VALUE_REQ__');
|
|
7
|
+
}
|
|
5
8
|
export function exposeToRemote(obj, options) {
|
|
6
9
|
const { globalName, adaptor, exposeTo, onRequest = defaultOnRequest, } = options;
|
|
7
10
|
const callback = async (e) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exposeToRemote.js","sourceRoot":"","sources":["../../src/remoteValue/exposeToRemote.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAenD,SAAS,gBAAgB,CAAC,CAAqB;IAC7C,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,cAAc,CAAmB,GAAM,EAAE,OAAoB;IAC3E,MAAM,EACJ,UAAU,EACV,OAAO,EACP,QAAQ,EACR,SAAS,GAAG,gBAAgB,GAC7B,GAAG,OAAO,CAAA;IACX,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAqB,EAAE,EAAE;;QAC/C,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,CAAC,CAAC,CAAA;YAClB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAA;YAC5C,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,IAA4C,CAAA;YACtE,IAAI,MAAM,GAAG,GAAG,CAAA;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAwB,CAAkB,CAAA;YACnE,CAAC;YACD,IAAI,GAAY,CAAA;YAChB,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;gBAC/B,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,MAAM,CAAA;YACd,CAAC;YACD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aAC5B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aACnD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC5D,CAAC,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"exposeToRemote.js","sourceRoot":"","sources":["../../src/remoteValue/exposeToRemote.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAenD,SAAS,gBAAgB,CAAC,CAAqB;IAC7C,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,SAAS,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAmB,GAAM,EAAE,OAAoB;IAC3E,MAAM,EACJ,UAAU,EACV,OAAO,EACP,QAAQ,EACR,SAAS,GAAG,gBAAgB,GAC7B,GAAG,OAAO,CAAA;IACX,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAqB,EAAE,EAAE;;QAC/C,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,CAAC,CAAC,CAAA;YAClB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAA;YAC5C,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,IAA4C,CAAA;YACtE,IAAI,MAAM,GAAG,GAAG,CAAA;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAwB,CAAkB,CAAA;YACnE,CAAC;YACD,IAAI,GAAY,CAAA;YAChB,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;gBAC/B,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,MAAM,CAAA;YACd,CAAC;YACD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aAC5B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAA,CAAC,CAAC,YAAY,mCAAI,6BAA6B;gBACrD,QAAQ,EAAE,CAAC,CAAC,cAAc;gBAC1B,cAAc,EAAE,CAAC,CAAC,QAAQ;gBAC1B,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aACnD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IACzD,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC5D,CAAC,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
import { isRemoteAdaptorData, type AdaptorPackageData } from '../../index'
|
|
3
|
+
|
|
4
|
+
interface RemoteChannel {
|
|
5
|
+
onClientEvent(fn: (e: unknown) => void): void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码客户端适配器。
|
|
10
|
+
* ```ts
|
|
11
|
+
* const remoteManager = new ClientSideRemoteChannelEventManager(remoteChannel)
|
|
12
|
+
*
|
|
13
|
+
* export const remoteAdaptor = {
|
|
14
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
15
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
16
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
17
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
18
|
+
* emit: (e) => {
|
|
19
|
+
* remoteChannel.sendServerEvent(e)
|
|
20
|
+
* },
|
|
21
|
+
* } satisfies Adaptor
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class ClientSideRemoteChannelEventManager extends EventEmitter<{
|
|
25
|
+
[key: string]: [AdaptorPackageData]
|
|
26
|
+
}> {
|
|
27
|
+
constructor(remoteChannel: RemoteChannel) {
|
|
28
|
+
super()
|
|
29
|
+
remoteChannel.onClientEvent((e) => {
|
|
30
|
+
if (!isRemoteAdaptorData(e)) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if (!e.name.startsWith('__REMOTE_VALUE_REQ__')) {
|
|
34
|
+
this.emit('__remote_every__', e)
|
|
35
|
+
}
|
|
36
|
+
this.emit(e.name, e)
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onEvery(fn: (args: AdaptorPackageData) => void): void {
|
|
41
|
+
this.on('__remote_every__', fn)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3'
|
|
2
|
+
import {
|
|
3
|
+
isRemoteAdaptorData,
|
|
4
|
+
isRemoteValueEvent,
|
|
5
|
+
type AdaptorPackageData,
|
|
6
|
+
} from '../../index'
|
|
7
|
+
|
|
8
|
+
interface GamePlayerEntityLike {
|
|
9
|
+
player: {
|
|
10
|
+
userKey: string
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface RemoteChannel<T extends GamePlayerEntityLike> {
|
|
15
|
+
onServerEvent(fn: (e: { args: unknown; entity: T }) => void): void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。
|
|
20
|
+
* ```ts
|
|
21
|
+
* const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)
|
|
22
|
+
*
|
|
23
|
+
* world.onPlayerLeave(
|
|
24
|
+
* remoteManager.onPlayerLeave.bind(remoteManager)
|
|
25
|
+
* )
|
|
26
|
+
*
|
|
27
|
+
* export const remoteAdaptor = {
|
|
28
|
+
* every: remoteManager.onEvery.bind(remoteManager),
|
|
29
|
+
* off: remoteManager.off.bind(remoteManager),
|
|
30
|
+
* on: remoteManager.on.bind(remoteManager),
|
|
31
|
+
* once: remoteManager.once.bind(remoteManager),
|
|
32
|
+
* emit: (e) => {
|
|
33
|
+
* const entity = getEntity(e.targetDeviceId)
|
|
34
|
+
* if (!entity) {
|
|
35
|
+
* console.error('entity not found')
|
|
36
|
+
* return
|
|
37
|
+
* }
|
|
38
|
+
* remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)
|
|
39
|
+
* },
|
|
40
|
+
* } satisfies Adaptor
|
|
41
|
+
*
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export class ServerSideRemoteChannelEventManager<
|
|
45
|
+
T extends GamePlayerEntityLike,
|
|
46
|
+
> extends EventEmitter<{
|
|
47
|
+
[key: string]: [AdaptorPackageData]
|
|
48
|
+
}> {
|
|
49
|
+
entityMap: [string, T][] = []
|
|
50
|
+
|
|
51
|
+
constructor(remoteChannel: RemoteChannel<T>) {
|
|
52
|
+
super()
|
|
53
|
+
remoteChannel.onServerEvent((e) => {
|
|
54
|
+
const { args } = e
|
|
55
|
+
if (!isRemoteAdaptorData(args)) {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
const prevItem = this.entityMap.find(
|
|
59
|
+
(item) => item[1].player.userKey === e.entity.player.userKey
|
|
60
|
+
)
|
|
61
|
+
if (prevItem) {
|
|
62
|
+
prevItem[0] = args.deviceId
|
|
63
|
+
prevItem[1] = e.entity
|
|
64
|
+
} else {
|
|
65
|
+
this.entityMap.push([args.deviceId, e.entity])
|
|
66
|
+
}
|
|
67
|
+
if (!isRemoteValueEvent(args.name)) {
|
|
68
|
+
this.emit('__remote_every__', args)
|
|
69
|
+
}
|
|
70
|
+
this.emit(args.name, args)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onPlayerLeave(e: { entity: T }) {
|
|
75
|
+
this.entityMap = this.entityMap.filter(
|
|
76
|
+
(item) => item[1].player.userKey !== e.entity.player.userKey
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
onEvery(fn: (args: AdaptorPackageData) => void): void {
|
|
81
|
+
this.on('__remote_every__', fn)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
waitForRegister(entity: T) {
|
|
85
|
+
return new Promise<void>((resolve) => {
|
|
86
|
+
if (
|
|
87
|
+
this.entityMap.some(
|
|
88
|
+
([_, en]) => en.player.userKey === entity.player.userKey
|
|
89
|
+
)
|
|
90
|
+
) {
|
|
91
|
+
resolve()
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
this.once('__remote_every__', () => {
|
|
95
|
+
resolve()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
getEntity(deviceId: string): T | undefined {
|
|
101
|
+
return this.entityMap.find((item) => item[0] === deviceId)?.[1]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
getIdByEntity(entity: T): string | undefined {
|
|
105
|
+
return this.entityMap.find(
|
|
106
|
+
(item) => item[1].player.userKey === entity.player.userKey
|
|
107
|
+
)?.[0]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
remoteTo(config: { target: T }): {
|
|
111
|
+
targetDeviceId: string
|
|
112
|
+
}
|
|
113
|
+
remoteTo(config: { target: T; timeoutMs: number }): {
|
|
114
|
+
targetDeviceId: string
|
|
115
|
+
timeoutMs: number
|
|
116
|
+
}
|
|
117
|
+
remoteTo({ target, ...rest }: { target: T; timeoutMs?: number }) {
|
|
118
|
+
return {
|
|
119
|
+
targetDeviceId: this.getIdByEntity(target),
|
|
120
|
+
...rest,
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -10,4 +10,7 @@ export { createIframeAdaptor } from './adaptors/iframe'
|
|
|
10
10
|
export { createHttpAdaptor, remoteEventManager } from './adaptors/http'
|
|
11
11
|
export type { ToFunc } from './remoteValue/type'
|
|
12
12
|
export { remoteValue } from './remoteValue/remoteValue'
|
|
13
|
-
export {
|
|
13
|
+
export {
|
|
14
|
+
exposeToRemote,
|
|
15
|
+
isRemoteValueEvent,
|
|
16
|
+
} from './remoteValue/exposeToRemote'
|
|
@@ -18,6 +18,10 @@ function defaultOnRequest(e: AdaptorPackageData) {
|
|
|
18
18
|
return e
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export function isRemoteValueEvent(eventName: string) {
|
|
22
|
+
return eventName.startsWith('__REMOTE_VALUE_REQ__')
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
export function exposeToRemote<T extends object>(obj: T, options: ExposeProps) {
|
|
22
26
|
const {
|
|
23
27
|
globalName,
|