bedrock-portal 0.3.1 → 0.5.0
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/README.md +75 -5
- package/examples/portal.js +13 -4
- package/examples/realm.js +58 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +1 -1
- package/src/modules/inviteOnMessage.js +68 -0
- package/src/modules/redirectFromRealm.js +81 -0
- package/src/rest.js +3 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
[](http://npmjs.com/package/bedrock-portal)
|
|
3
3
|
[](https://discord.gg/KTyd9HWuBD)
|
|
4
4
|
|
|
5
|
-
Handles and creates a Minecraft Bedrock game session which will redirect players to the specified server
|
|
5
|
+
Handles and creates a Minecraft Bedrock game session which will redirect players to the specified server. Join our [Discord](https://discord.com/invite/KTyd9HWuBD) for support.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
```shell
|
|
@@ -57,6 +57,43 @@ main();
|
|
|
57
57
|
|
|
58
58
|
Modules are used to extend the functionality of the BedrockPortal class.
|
|
59
59
|
|
|
60
|
+
### redirectFromRealm
|
|
61
|
+
|
|
62
|
+
> Requires [bedrock-protocol](https://github.com/PrismarineJS/bedrock-protocol) to be installed. `npm install bedrock-protocol`
|
|
63
|
+
|
|
64
|
+
Invites players when they join a Realm to the specified server or if they use the chat command. `#.use(Modules.redirectFromRealm, options);`
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
- **clientOptions**: ClientOptions - The client options to use when connecting to the Realm. These are passed directly to a [bedrock-protocol createClient](https://github.com/PrismarineJS/bedrock-protocol/blob/master/docs/API.md#becreateclientoptions--client) function. See the documentation for more information.
|
|
68
|
+
- **chatCommand**: object - Options for the chat command
|
|
69
|
+
- **enabled**: boolean - Whether sending the command in chat should trigger an invite (default: true)
|
|
70
|
+
- **message**: string - The message to send in chat to run the command (default: 'invite')
|
|
71
|
+
- **cooldown**: number - The cooldown between being able to send the command in chat (default: 60000ms)
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
const { BedrockPortal, Modules } = require('bedrock-portal');
|
|
75
|
+
|
|
76
|
+
const portal = new BedrockPortal(auth, { ... })
|
|
77
|
+
|
|
78
|
+
portal.use(Modules.redirectFromRealm, {
|
|
79
|
+
// The client options to use when connecting to the Realm.
|
|
80
|
+
clientOptions: {
|
|
81
|
+
realms: {
|
|
82
|
+
realmInvite: ''
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Options for the chat command
|
|
86
|
+
chatCommand: {
|
|
87
|
+
// Whether sending the command in chat should trigger an invite (optional - defaults to true)
|
|
88
|
+
enabled: true,
|
|
89
|
+
// The message to send in chat to run the command (optional - defaults to 'invite')
|
|
90
|
+
message: 'invite',
|
|
91
|
+
// The cooldown between being able to send the command in chat (optional - defaults to 60000ms)
|
|
92
|
+
cooldown: 60000,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
60
97
|
### autoFriendAdd
|
|
61
98
|
|
|
62
99
|
Automatically adds the account's followers as friends and invites them to the game. `#.use(Modules.autoFriendAdd);`
|
|
@@ -78,11 +115,41 @@ portal.use(Modules.autoFriendAdd);
|
|
|
78
115
|
// or
|
|
79
116
|
|
|
80
117
|
portal.use(Modules.autoFriendAdd, {
|
|
118
|
+
// When a friend is added, automatically invite them to the game
|
|
81
119
|
inviteOnAdd: true,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
120
|
+
// Only add friends that are online and remove friends that are offline
|
|
121
|
+
conditionToMeet: (player) => player.presenceState === 'Online',
|
|
122
|
+
// How often to check for friends to add/remove (optional - defaults to 30000ms)
|
|
123
|
+
checkInterval: 30000,
|
|
124
|
+
// How long to wait between adding friends (optional - defaults to 2000ms)
|
|
125
|
+
addInterval: 2000,
|
|
126
|
+
// How long to wait between removing friends (optional - defaults to 2000ms)
|
|
127
|
+
removeInterval: 2000,
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### inviteOnMessage
|
|
132
|
+
|
|
133
|
+
Automatically invites players to the game when they send a message in the chat. `#.use(Modules.inviteOnMessage);`
|
|
134
|
+
|
|
135
|
+
Options:
|
|
136
|
+
- **command**: string - The command to use to invite players (default: 'invite')
|
|
137
|
+
- **checkInterval**: number - How often to check for messages (default: 30000ms)
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
const { BedrockPortal, Modules } = require('bedrock-portal');
|
|
141
|
+
|
|
142
|
+
const portal = new BedrockPortal(auth, { ... })
|
|
143
|
+
|
|
144
|
+
portal.use(Modules.inviteOnMessage);
|
|
145
|
+
|
|
146
|
+
// or
|
|
147
|
+
|
|
148
|
+
portal.use(Modules.inviteOnMessage, {
|
|
149
|
+
// The command to use to invite players (optional - defaults to 'invite')
|
|
150
|
+
command: 'invite',
|
|
151
|
+
// How often to check for messages (optional - defaults to 30000ms)
|
|
152
|
+
checkInterval: 30000,
|
|
86
153
|
});
|
|
87
154
|
```
|
|
88
155
|
|
|
@@ -157,6 +224,9 @@ Emitted when a player is removed as a friend. This event is only emitted when th
|
|
|
157
224
|
**Parameters**
|
|
158
225
|
- player - [Player](#player) object
|
|
159
226
|
|
|
227
|
+
### portal.on('messageRecieved', (message) => {})
|
|
228
|
+
Emitted when a message is recieved from a player. This event is only emitted when the `inviteOnMessage` module is enabled.
|
|
229
|
+
|
|
160
230
|
## Objects
|
|
161
231
|
|
|
162
232
|
### Player
|
package/examples/portal.js
CHANGED
|
@@ -23,10 +23,15 @@ const main = async () => {
|
|
|
23
23
|
|
|
24
24
|
portal.use(Modules.autoFriendAdd, { // Automatically adds friends to the session
|
|
25
25
|
inviteOnAdd: true,
|
|
26
|
-
conditionToMeet: (player) => player.presenceState === 'Online', // Only add friends that are online and remove friends that are offline
|
|
27
|
-
// checkInterval: 30000,
|
|
28
|
-
addInterval: 2000,
|
|
29
|
-
removeInterval: 2000,
|
|
26
|
+
// conditionToMeet: (player) => player.presenceState === 'Online', // Only add friends that are online and remove friends that are offline
|
|
27
|
+
// checkInterval: 30000, // How often to check for friends to add/remove (optional - defaults to 30000ms)
|
|
28
|
+
// addInterval: 2000, // How long to wait between adding friends (optional - defaults to 2000ms)
|
|
29
|
+
// removeInterval: 2000, // How long to wait between removing friends (optional - defaults to 2000ms)
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
portal.use(Modules.inviteOnMessage, { // Automatically invites players when they send a message with the specified command
|
|
33
|
+
command: 'invite', // The command to use to invite players (optional - defaults to 'invite')
|
|
34
|
+
checkInterval: 30000, // How often to check for messages (optional - defaults to 30000ms)
|
|
30
35
|
});
|
|
31
36
|
|
|
32
37
|
// Put your event listeners before portal.start() to ensure you don't miss any events
|
|
@@ -59,6 +64,10 @@ const main = async () => {
|
|
|
59
64
|
console.log('Friend Removed: ', player);
|
|
60
65
|
});
|
|
61
66
|
|
|
67
|
+
portal.on('messageRecieved', (message) => { // Emits when a message is received. Only emitted if inviteOnMessage module is used
|
|
68
|
+
console.log('Message Received: ', message);
|
|
69
|
+
});
|
|
70
|
+
|
|
62
71
|
await portal.start(); // Starts the session
|
|
63
72
|
|
|
64
73
|
await portal.invitePlayer('p3'); // gamertag or xuid to invite
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* eslint-disable no-multi-spaces */
|
|
2
|
+
|
|
3
|
+
const { BedrockPortal, Modules, Joinability } = require('bedrock-portal');
|
|
4
|
+
const { Authflow, Titles } = require('prismarine-auth');
|
|
5
|
+
|
|
6
|
+
const main = async () => {
|
|
7
|
+
const auth = new Authflow('example', './', { authTitle: Titles.MinecraftNintendoSwitch, deviceType: 'Nintendo', flow: 'live' });
|
|
8
|
+
|
|
9
|
+
const portal = new BedrockPortal(auth, {
|
|
10
|
+
ip: 'geyserconnect.net',
|
|
11
|
+
port: 19132, // The port of the server (optional - defaults to 19132)
|
|
12
|
+
joinability: Joinability.FriendsOfFriends, // The joinability of the session (optional - defaults to Joinability.FriendsOfFriends)
|
|
13
|
+
disableAltCheck: false, // Disables the alt check (optional - defaults to false)
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
portal.use(Modules.redirectFromRealm, { // Automatically invite players to the server when they join a Realm
|
|
17
|
+
clientOptions: { // Options for the bedrock-protocol client, see https://github.com/PrismarineJS/bedrock-protocol for options
|
|
18
|
+
realms: {
|
|
19
|
+
realmId: '', // The realm ID of the realm to invite players from
|
|
20
|
+
realmInvite: '', // The invite code of the realm to invite players from
|
|
21
|
+
pickRealm: (realms) => realms[0], // A function to pick a realm from the list of realms
|
|
22
|
+
},
|
|
23
|
+
onMsaCode: console.log, // A function to handle the MSA code
|
|
24
|
+
},
|
|
25
|
+
chatCommand: { // Options for the chat command
|
|
26
|
+
enabled: true, // Whether sending the command in chat should trigger an invite (optional - defaults to true)
|
|
27
|
+
cooldown: 60000, // The cooldown of the command in milliseconds (optional - defaults to 60000)
|
|
28
|
+
message: 'invite', // The message to send in chat to run the command (optional - defaults to 'invite')
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Put your event listeners before portal.start() to ensure you don't miss any events
|
|
33
|
+
|
|
34
|
+
portal.on('rtaEvent', (event) => { // Emits when an RTA event is received
|
|
35
|
+
console.log('RTA Event: ', event);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
portal.on('sessionCreated', (session) => { // Emits when the session is created'
|
|
39
|
+
console.log('Session Created: ', session);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
portal.on('sessionUpdated', (session) => { // Emits when the session is updated
|
|
43
|
+
console.log('Session Updated: ', session);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
portal.on('playerJoin', (player) => { // Emits when a player joins the session
|
|
47
|
+
console.log('Player Join: ', player);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
portal.on('playerLeave', (player) => { // Emits when a player leaves the session
|
|
51
|
+
console.log('Player Leave: ', player);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
await portal.start(); // Starts the session
|
|
55
|
+
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
main();
|
package/index.d.ts
CHANGED
|
@@ -173,6 +173,8 @@ declare module 'bedrock-portal' {
|
|
|
173
173
|
* })
|
|
174
174
|
*/
|
|
175
175
|
autoFriendAdd: InstanceType<typeof ExtendedModule>
|
|
176
|
+
inviteOnMessage: InstanceType<typeof ExtendedModule>
|
|
177
|
+
redirectFromRealm: InstanceType<typeof ExtendedModule>
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
export interface RTAEvent {
|
package/index.js
CHANGED
|
@@ -3,6 +3,8 @@ module.exports = {
|
|
|
3
3
|
Module : require('./src/classes/Module'),
|
|
4
4
|
Modules: {
|
|
5
5
|
autoFriendAdd: require('./src/modules/autoFriendAdd'),
|
|
6
|
+
inviteOnMessage: require('./src/modules/inviteOnMessage'),
|
|
7
|
+
redirectFromRealm: require('./src/modules/redirectFromRealm'),
|
|
6
8
|
},
|
|
7
9
|
Joinability: {
|
|
8
10
|
InviteOnly: 'invite_only',
|
package/package.json
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* eslint-disable no-constant-condition */
|
|
2
|
+
const Module = require('../classes/Module.js');
|
|
3
|
+
|
|
4
|
+
class IniteOnMessage extends Module {
|
|
5
|
+
constructor() {
|
|
6
|
+
super('initeOnMessage', 'Automatically invite players to the server when they message you');
|
|
7
|
+
this.options = {
|
|
8
|
+
command: 'invite',
|
|
9
|
+
checkInterval: 30000,
|
|
10
|
+
};
|
|
11
|
+
this.cache = [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async run(portal, { rest, rta }) {
|
|
15
|
+
|
|
16
|
+
const initeOnMessage = async () => {
|
|
17
|
+
const primaryMessages = await rest.get('https://xblmessaging.xboxlive.com/network/xbox/users/me/inbox/primary', { contractVersion: 1 });
|
|
18
|
+
const secondaryMessages = await rest.get('https://xblmessaging.xboxlive.com/network/xbox/users/me/inbox/secondary', { contractVersion: 1 });
|
|
19
|
+
|
|
20
|
+
const messages = [...primaryMessages.conversations, ...secondaryMessages.conversations];
|
|
21
|
+
|
|
22
|
+
const contentMessages = messages.filter(message => message.lastMessage.type === 'ContentMessage');
|
|
23
|
+
|
|
24
|
+
this.debug(`Found ${contentMessages.length} content message(s)`);
|
|
25
|
+
|
|
26
|
+
if (this.cache.length === 0) return this.cache = contentMessages;
|
|
27
|
+
|
|
28
|
+
// use #.lastMessage.messageId
|
|
29
|
+
const newMessages = contentMessages.filter(message => this.cache.some(cacheMessage => cacheMessage.lastMessage.messageId !== message.lastMessage.messageId && cacheMessage.conversationId === message.conversationId));
|
|
30
|
+
|
|
31
|
+
this.debug(`Found ${newMessages.length} new message(s)`);
|
|
32
|
+
|
|
33
|
+
if (newMessages.length === 0) return;
|
|
34
|
+
|
|
35
|
+
for (const message of newMessages) {
|
|
36
|
+
portal.emit('messageRecieved', message.lastMessage);
|
|
37
|
+
|
|
38
|
+
const senderXuid = message.lastMessage.sender;
|
|
39
|
+
|
|
40
|
+
if (senderXuid === '0') continue;
|
|
41
|
+
|
|
42
|
+
this.debug(`Received message from ${senderXuid}`);
|
|
43
|
+
|
|
44
|
+
const content = message.lastMessage.contentPayload.content.parts.find(part => part.contentType === 'text')?.text;
|
|
45
|
+
|
|
46
|
+
if (!content) continue;
|
|
47
|
+
|
|
48
|
+
if (content.toLowerCase() === this.options.command.toLowerCase()) {
|
|
49
|
+
await portal.invitePlayer(senderXuid);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.cache = contentMessages;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
while (!this.stopped) {
|
|
57
|
+
try {
|
|
58
|
+
await initeOnMessage();
|
|
59
|
+
await new Promise(resolve => setTimeout(resolve, this.options.checkInterval));
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
this.debug(`Error: ${error.message}`, error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = IniteOnMessage;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const Module = require('../classes/Module.js');
|
|
2
|
+
|
|
3
|
+
const cd = new Set();
|
|
4
|
+
|
|
5
|
+
class RedirectFromRealm extends Module {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('redirectFromRealm', 'Automatically invite players to the server when they join a Realm');
|
|
8
|
+
this.options = {
|
|
9
|
+
clientOptions: { }, // Options for the bedrock-protocol client
|
|
10
|
+
chatCommand: {
|
|
11
|
+
enabled: true,
|
|
12
|
+
cooldown: 60000,
|
|
13
|
+
message: 'invite',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
this.bedrock = require('bedrock-protocol');
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
console.trace('bedrock-protocol is not installed, please run "npm i bedrock-protocol" to use this module');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async run(portal, { rest, rta }) {
|
|
26
|
+
|
|
27
|
+
const { clientOptions } = this.options;
|
|
28
|
+
|
|
29
|
+
const client = await this.initClient(clientOptions, portal).catch(error => ({ error }));
|
|
30
|
+
|
|
31
|
+
if (client.error) return console.error(`Error connecting to Realm - ${client.error.message}. BedrockPortal will continue to run, but will not be able to redirect players from this realm.`);
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async initClient(options, portal) {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
|
|
38
|
+
this.client = this.bedrock.createClient(options);
|
|
39
|
+
|
|
40
|
+
this.client.once('error', (e) => (this.client = null, reject(e)));
|
|
41
|
+
this.client.once('disconnect', (e) => (this.client = null, reject(e)));
|
|
42
|
+
|
|
43
|
+
this.client.once('spawn', () => {
|
|
44
|
+
this.heartbeat = setInterval(async () => {
|
|
45
|
+
this.debug(`Sending heartbeat to Realm - Status: ${this.client?.status}`);
|
|
46
|
+
if (this.client === null || this.client.status === 0) {
|
|
47
|
+
this.client = null;
|
|
48
|
+
clearInterval(this.heartbeat);
|
|
49
|
+
this.debug('Attempting to reconnect to Realm');
|
|
50
|
+
return await this.initClient(options, portal).catch(err => {
|
|
51
|
+
this.debug(`Error reconnecting to Realm - ${err.message}`);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}, 30000);
|
|
55
|
+
resolve(this.client);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.client.on('player_list', async packet => {
|
|
59
|
+
if (packet.records.type === 'add') {
|
|
60
|
+
for (const record of packet.records.records) {
|
|
61
|
+
try { await await portal.invitePlayer(record.xbox_user_id); }
|
|
62
|
+
catch (e) { this.debug(`Failed to invite ${record.xbox_user_id} - ${e.message}`); }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.client.on('text', async (packet) => {
|
|
68
|
+
if (!this.options.chatCommand.enabled || packet.type !== 'chat' || cd.has(packet.xuid)) return;
|
|
69
|
+
if (packet.message.toLowerCase() === this.options.chatCommand.message.toLowerCase()) {
|
|
70
|
+
cd.add(packet.xuid);
|
|
71
|
+
setTimeout(() => cd.delete(packet.xuid), this.options.chatCommand.cooldown);
|
|
72
|
+
try { await await portal.invitePlayer(packet.xuid); }
|
|
73
|
+
catch (e) { this.debug(`Failed to invite ${packet.xuid} - ${e.message}`); }
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = RedirectFromRealm;
|
package/src/rest.js
CHANGED
|
@@ -81,7 +81,9 @@ module.exports = class Rest {
|
|
|
81
81
|
const response = await this.get(`https://profile.xboxlive.com/users/${target}/profile/settings`, { params: { settings }, contractVersion: 2 });
|
|
82
82
|
|
|
83
83
|
const [avatar, gamerscore, gamertag, tier, reputation, colour, realname, bio, location, modernGamertag, modernGamertagSuffix, uniqueModernGamertag, realnameOverride, tenureLevel, watermarks, isQuarantined, linkedAccounts] = response.profileUsers[0].settings.map(e=> e.value);
|
|
84
|
-
const colourData = await axios.get(colour
|
|
84
|
+
const colourData = await axios.get(colour, { timeout: 5000 })
|
|
85
|
+
.then(e => e.data)
|
|
86
|
+
.catch(() => ({ primaryColor: '000000', secondaryColor: '000000', tertiaryColor: '000000' }));
|
|
85
87
|
|
|
86
88
|
return {
|
|
87
89
|
xuid: response.profileUsers[0].id,
|