@rustwirebot/rustplus.js 2.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.
Files changed (42) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +351 -0
  3. package/camera.js +425 -0
  4. package/cli/index.js +308 -0
  5. package/cli/pair.html +49 -0
  6. package/docs/API.md +101 -0
  7. package/docs/DownloadBundle.md +7 -0
  8. package/docs/PairingFlow.md +19 -0
  9. package/donate.md +10 -0
  10. package/examples/10_shoot_autoturret.js +100 -0
  11. package/examples/1_send_team_chat.js +16 -0
  12. package/examples/2_turn_smart_switch_on.js +21 -0
  13. package/examples/3_turn_smart_switch_off.js +21 -0
  14. package/examples/4_entity_changed_broadcasts.js +58 -0
  15. package/examples/5_download_map_jpeg.js +22 -0
  16. package/examples/6_async_requests.js +35 -0
  17. package/examples/7_render_camera.js +34 -0
  18. package/examples/8_move_ptz_camera.js +56 -0
  19. package/examples/9_zoom_ptz_camera.js +37 -0
  20. package/package.json +48 -0
  21. package/rustplus.js +380 -0
  22. package/rustplus.js.svg +34 -0
  23. package/rustplus.proto +431 -0
  24. package/vendor/push-receiver/LICENSE +21 -0
  25. package/vendor/push-receiver/NOTICE.md +32 -0
  26. package/vendor/push-receiver/android/fcm.js +134 -0
  27. package/vendor/push-receiver/client.js +216 -0
  28. package/vendor/push-receiver/constants.js +53 -0
  29. package/vendor/push-receiver/fcm/index.js +52 -0
  30. package/vendor/push-receiver/fcm/server-key/index.js +67 -0
  31. package/vendor/push-receiver/gcm/android_checkin.proto +96 -0
  32. package/vendor/push-receiver/gcm/checkin.proto +155 -0
  33. package/vendor/push-receiver/gcm/index.js +128 -0
  34. package/vendor/push-receiver/index.js +17 -0
  35. package/vendor/push-receiver/mcs.proto +328 -0
  36. package/vendor/push-receiver/parser.js +276 -0
  37. package/vendor/push-receiver/register/index.js +18 -0
  38. package/vendor/push-receiver/utils/base64/index.js +15 -0
  39. package/vendor/push-receiver/utils/decrypt/index.js +23 -0
  40. package/vendor/push-receiver/utils/http-request/index.js +43 -0
  41. package/vendor/push-receiver/utils/request/index.js +27 -0
  42. package/vendor/push-receiver/utils/timeout/index.js +7 -0
package/cli/index.js ADDED
@@ -0,0 +1,308 @@
1
+ #!/usr/bin/env node
2
+
3
+ const axios = require('axios');
4
+ const express = require('express');
5
+ const { v4: uuidv4 } = require('uuid');
6
+ const commandLineArgs = require('command-line-args');
7
+ const commandLineUsage = require('command-line-usage');
8
+ const ChromeLauncher = require('chrome-launcher');
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+ // Vendored locally (see /vendor/push-receiver) so this package keeps working
12
+ // even if @liamcottle/push-receiver is ever removed from npm.
13
+ const AndroidFCM = require('../vendor/push-receiver/android/fcm');
14
+ const PushReceiverClient = require('../vendor/push-receiver/client');
15
+
16
+ let server;
17
+ let fcmClient;
18
+
19
+ /**
20
+ * Get the path to the config file defined in command line options,
21
+ * or fallback to default config file in current directory.
22
+ */
23
+ function getConfigFile(options) {
24
+ return options['config-file'] || path.join(process.cwd(), 'rustplus.config.json');
25
+ }
26
+
27
+ /**
28
+ * Reads config file, or returns empty config on error
29
+ */
30
+ function readConfig(configFile) {
31
+ try {
32
+ return JSON.parse(fs.readFileSync(configFile));
33
+ } catch (err) {
34
+ return {};
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Merges new config into existing config and saves to config file
40
+ * @param configFile
41
+ * @param config
42
+ */
43
+ function updateConfig(configFile, config) {
44
+ // get current config
45
+ const currentConfig = readConfig(configFile);
46
+
47
+ // merge config into current config
48
+ const updatedConfig = {...currentConfig, ...config};
49
+
50
+ // convert to pretty json
51
+ const json = JSON.stringify(updatedConfig, null, 2);
52
+
53
+ // save updated config to config file
54
+ fs.writeFileSync(configFile, json, "utf8");
55
+ }
56
+
57
+ async function getExpoPushToken(fcmToken) {
58
+ const response = await axios.post('https://exp.host/--/api/v2/push/getExpoPushToken', {
59
+ type: 'fcm',
60
+ deviceId: uuidv4(),
61
+ development: false,
62
+ appId: 'com.facepunch.rust.companion',
63
+ deviceToken: fcmToken,
64
+ projectId: "49451aca-a822-41e6-ad59-955718d0ff9c",
65
+ });
66
+ return response.data.data.expoPushToken;
67
+ }
68
+
69
+ async function registerWithRustPlus(authToken, expoPushToken) {
70
+ return axios.post('https://companion-rust.facepunch.com:443/api/push/register', {
71
+ AuthToken: authToken,
72
+ DeviceId: 'rustplus.js',
73
+ PushKind: 3,
74
+ PushToken: expoPushToken,
75
+ })
76
+ }
77
+
78
+ async function linkSteamWithRustPlus() {
79
+ return new Promise((resolve, reject) => {
80
+ const app = express();
81
+
82
+ // register pair web page
83
+ app.get('/', (req, res) => {
84
+ res.sendFile(path.join(__dirname + '/pair.html'));
85
+ });
86
+
87
+ // register callback
88
+ app.get('/callback', async (req, res) => {
89
+ // we no longer need the Google Chrome instance
90
+ await ChromeLauncher.killAll();
91
+
92
+ // get token from callback
93
+ const authToken = req.query.token;
94
+ if (authToken) {
95
+ res.send('Steam Account successfully linked with rustplus.js, you can now close this window and go back to the console.');
96
+ resolve(authToken)
97
+ } else {
98
+ res.status(400).send('Token missing from request!');
99
+ reject(new Error('Token missing from request!'))
100
+ }
101
+
102
+ // we no longer need the express web server
103
+ server.close()
104
+ });
105
+
106
+ /**
107
+ * Start the express server before Google Chrome is launched.
108
+ * If the port is updated, make sure to also update it in pair.html
109
+ */
110
+ const port = 3000;
111
+ server = app.listen(port, async () => {
112
+ /**
113
+ * FIXME: Google Chrome is launched with Web Security disabled.
114
+ * This is bad, but it allows us to modify the window object of other domains, such as Rust+
115
+ * By doing so, we can inject a custom ReactNativeWebView.postMessage handler to capture Rust+ auth data.
116
+ *
117
+ * Rust+ recently changed the login flow, which no longer sends auth data in the URL callback.
118
+ * Auth data is now sent to a ReactNativeWebView.postMessage handler, which is available to the Rust+ app since
119
+ * it is a ReactNative app.
120
+ *
121
+ * We don't have access to ReactNative, but we can emulate the behaviour by registering our own window objects.
122
+ * However, to do so we need to disable Web Security to be able to manipulate the window of other origins.
123
+ */
124
+ await ChromeLauncher.launch({
125
+ startingUrl: `http://localhost:${port}`,
126
+ chromeFlags: [
127
+ '--disable-web-security', // allows us to manipulate rust+ window
128
+ '--disable-popup-blocking', // allows us to open rust+ login from our main window
129
+ '--disable-site-isolation-trials', // required for --disable-web-security to work
130
+ '--user-data-dir=/tmp/temporary-chrome-profile-dir-rustplus', // create a new chrome profile for pair.js
131
+ ],
132
+ handleSIGINT: false, // handled manually in shutdown
133
+ }).catch((error) => {
134
+ console.log(error);
135
+ console.log("pair.js failed to launch Google Chrome. Do you have it installed?");
136
+ process.exit(1);
137
+ });
138
+ });
139
+ });
140
+ }
141
+
142
+ var expoPushToken = null;
143
+ var rustplusAuthToken = null;
144
+
145
+ async function fcmRegister(options) {
146
+ console.log("Registering with FCM");
147
+ const apiKey = "AIzaSyB5y2y-Tzqb4-I4Qnlsh_9naYv_TD8pCvY";
148
+ const projectId = "rust-companion-app";
149
+ const gcmSenderId = "976529667804";
150
+ const gmsAppId = "1:976529667804:android:d6f1ddeb4403b338fea619";
151
+ const androidPackageName = "com.facepunch.rust.companion";
152
+ const androidPackageCert = "E28D05345FB78A7A1A63D70F4A302DBF426CA5AD";
153
+ const fcmCredentials = await AndroidFCM.register(apiKey, projectId, gcmSenderId, gmsAppId, androidPackageName, androidPackageCert);
154
+
155
+ console.log("Fetching Expo Push Token");
156
+ expoPushToken = await getExpoPushToken(fcmCredentials.fcm.token).catch((error) => {
157
+ console.log("Failed to fetch Expo Push Token");
158
+ console.log(error);
159
+ process.exit(1);
160
+ });
161
+
162
+ // show expo push token to user
163
+ console.log("Successfully fetched Expo Push Token");
164
+ console.log("Expo Push Token: " + expoPushToken);
165
+
166
+ // tell user to link steam with rust+ through Google Chrome
167
+ console.log("Google Chrome is launching so you can link your Steam account with Rust+");
168
+ rustplusAuthToken = await linkSteamWithRustPlus();
169
+
170
+ // show rust+ auth token to user
171
+ console.log("Successfully linked Steam account with Rust+");
172
+ console.log("Rust+ AuthToken: " + rustplusAuthToken);
173
+
174
+ console.log("Registering with Rust Companion API");
175
+ await registerWithRustPlus(rustplusAuthToken, expoPushToken).catch((error) => {
176
+ console.log("Failed to register with Rust Companion API");
177
+ console.log(error);
178
+ process.exit(1);
179
+ });
180
+ console.log("Successfully registered with Rust Companion API.");
181
+
182
+ // save to config
183
+ const configFile = getConfigFile(options);
184
+ updateConfig(configFile, {
185
+ fcm_credentials: fcmCredentials,
186
+ expo_push_token: expoPushToken,
187
+ rustplus_auth_token: rustplusAuthToken,
188
+ });
189
+ console.log("FCM, Expo and Rust+ auth tokens have been saved to " + configFile);
190
+ }
191
+
192
+ async function fcmListen(options) {
193
+ // read config file
194
+ const configFile = getConfigFile(options);
195
+ const config = readConfig(configFile);
196
+
197
+ // make sure fcm credentials are in config
198
+ if(!config.fcm_credentials){
199
+ console.error("FCM Credentials missing. Please run `fcm-register` first.");
200
+ process.exit(1);
201
+ return;
202
+ }
203
+
204
+ console.log("Listening for FCM Notifications");
205
+ const androidId = config.fcm_credentials.gcm.androidId;
206
+ const securityToken = config.fcm_credentials.gcm.securityToken;
207
+ const client = new PushReceiverClient(androidId, securityToken, []);
208
+ client.on('ON_DATA_RECEIVED', (data) => {
209
+
210
+ // generate timestamp
211
+ const timestamp = new Date().toLocaleString();
212
+
213
+ // log timestamp the notification was received (in green colour)
214
+ console.log('\x1b[32m%s\x1b[0m', `[${timestamp}] Notification Received`)
215
+
216
+ // log notification body
217
+ console.log(data);
218
+
219
+ });
220
+
221
+ // force exit on ctrl + c
222
+ process.on('SIGINT', async () => {
223
+ process.exit(0);
224
+ });
225
+
226
+ await client.connect();
227
+
228
+ }
229
+
230
+ function showUsage() {
231
+ const usage = commandLineUsage([
232
+ {
233
+ header: 'RustPlus',
234
+ content: 'A command line tool for things related to Rust+',
235
+ },
236
+ {
237
+ header: 'Usage',
238
+ content: '$ rustplus <options> <command>'
239
+ },
240
+ {
241
+ header: 'Command List',
242
+ content: [
243
+ { name: 'help', summary: 'Print this usage guide.' },
244
+ { name: 'fcm-register', summary: 'Registers with FCM, Expo and links your Steam account with Rust+ so you can listen for Pairing Notifications.' },
245
+ { name: 'fcm-listen', summary: 'Listens to notifications received from FCM, such as Rust+ Pairing Notifications.' },
246
+ ]
247
+ },
248
+ {
249
+ header: 'Options',
250
+ optionList: [
251
+ {
252
+ name: 'config-file',
253
+ typeLabel: '{underline file}',
254
+ description: 'Path to config file. (default: rustplus.config.json)',
255
+ },
256
+ ],
257
+ },
258
+ ]);
259
+ console.log(usage);
260
+ }
261
+
262
+ async function run() {
263
+ // parse command line args
264
+ const options = commandLineArgs([
265
+ { name: 'command', type: String, defaultOption: true },
266
+ { name: 'config-file', type: String },
267
+ ]);
268
+
269
+ // run command
270
+ switch(options.command){
271
+ case 'fcm-register': {
272
+ await fcmRegister(options);
273
+ break;
274
+ }
275
+ case 'fcm-listen': {
276
+ await fcmListen(options);
277
+ break;
278
+ }
279
+ case 'help': {
280
+ showUsage();
281
+ break;
282
+ }
283
+ default: {
284
+ showUsage();
285
+ break;
286
+ }
287
+ }
288
+ }
289
+
290
+ process.on('SIGTERM', shutdown);
291
+ process.on('SIGINT', shutdown);
292
+
293
+ async function shutdown() {
294
+ // close chrome instances launched by pair.js
295
+ await ChromeLauncher.killAll();
296
+
297
+ // close express server
298
+ if(server){
299
+ server.close()
300
+ }
301
+
302
+ // destroy fcm client
303
+ if(fcmClient){
304
+ fcmClient.destroy();
305
+ }
306
+ }
307
+
308
+ run();
package/cli/pair.html ADDED
@@ -0,0 +1,49 @@
1
+ <html lang="en">
2
+ <head>
3
+ <title>RustPlus Pairing</title>
4
+ </head>
5
+ <body>
6
+ <div>To pair rustplus.js with Rust+, you must allow popup windows. You may need to refresh this page after enabling popups.</div>
7
+ <script type="text/javascript">
8
+
9
+ /**
10
+ * Launch Rust+ login website in a popup window.
11
+ */
12
+ var popupWindow = window.open("https://companion-rust.facepunch.com/login", "", "");
13
+
14
+ /**
15
+ * Each time the popup window changes origins (rust+ -> steam -> rust+), our changes to the window object are reset.
16
+ * So, every 250ms check if our handler is not registered, and register it if needed.
17
+ */
18
+ var handlerInterval = setInterval(function() {
19
+ if(popupWindow.ReactNativeWebView === undefined){
20
+ console.log("registering ReactNativeWebView.postMessage handler");
21
+ popupWindow.ReactNativeWebView = {
22
+
23
+ /**
24
+ * Rust+ login website calls ReactNativeWebView.postMessage after successfully logging in with Steam.
25
+ * @param message json string with SteamId and Token
26
+ */
27
+ postMessage: function(message) {
28
+
29
+ // we no longer need the handler
30
+ clearInterval(handlerInterval);
31
+
32
+ // parse json message
33
+ var auth = JSON.parse(message);
34
+
35
+ // send the Token back to pair.js in the main window
36
+ window.location.href = "http://localhost:3000/callback?token=" + encodeURIComponent(auth.Token);
37
+
38
+ // close the popup window
39
+ popupWindow.close();
40
+
41
+ },
42
+
43
+ };
44
+ }
45
+ }, 250);
46
+
47
+ </script>
48
+ </body>
49
+ </html>
package/docs/API.md ADDED
@@ -0,0 +1,101 @@
1
+ # Rust Companion API
2
+
3
+ Base URL
4
+
5
+ - https://companion-rust.facepunch.com
6
+
7
+ ## App Endpoints
8
+
9
+ These endpoints are used by the Rust+ Companion App.
10
+
11
+ ### `/api/avatar/{steamId}`
12
+
13
+ - Method: `GET`
14
+
15
+ Redirects to the Profile Image for the SteamId.
16
+
17
+ ### `/api/history/read`
18
+
19
+ - Method: `POST`
20
+ - Headers:
21
+ - `Content-Type`: `application/json`
22
+ - Body: `AuthToken`
23
+
24
+ Response contains event history, such as Player Deaths and Server Pair Requests.
25
+
26
+ - Notification ID
27
+ - Notification Date
28
+ - Player SteamId
29
+ - Server ID
30
+ - Title (eg `{name} is online`)
31
+ - Body (server name)
32
+ - Data (event data)
33
+
34
+ ### TODO
35
+
36
+ Endpoints that haven't been documented yet.
37
+
38
+ - POST /api/push/register
39
+ - DELETE /api/push/unregister
40
+ - POST /api/subscriptions/app/add
41
+ - POST /api/subscriptions/app/remove
42
+ - POST /api/subscriptions/app/check
43
+ - POST /api/channel/enable
44
+ - POST /api/channel/disable
45
+ - POST /api/channel/check
46
+
47
+ ## Server Endpoints
48
+
49
+ These endpoints are used by the Rust Server.
50
+
51
+ ### `/api/server/register`
52
+
53
+ - Method: `GET`
54
+
55
+ Registers a new Rust server with the Rust+ Companion API. This is called when the Rust server is initialized and has not registered, or refreshing the existing server token fails.
56
+
57
+ ### `/api/server/refresh`
58
+
59
+ - Method: `POST`
60
+ - Headers:
61
+ - `Content-Type`: `text/plain`
62
+ - Body: `Existing Server Token`
63
+
64
+ Refreshes an existing server token.
65
+
66
+ ### `/api/push/send`
67
+
68
+ - Method: `POST`
69
+ - Headers:
70
+ - `Content-Type`: `application/json`
71
+ - JSON Body:
72
+ - `ServerToken` (string)
73
+ - `SteamIds` (list of unsigned longs)
74
+ - `Channel` (int)
75
+ - `Pairing=1001`
76
+ - `PlayerLoggedIn=1002`
77
+ - `PlayerDied=1003`
78
+ - `SmartAlarm=1004`
79
+ - `Title` (string)
80
+ - `Body` (string)
81
+ - `Data` (dictionary<string, string>)
82
+ - `id` (string)
83
+ - `name` (string)
84
+ - `desc` (string)
85
+ - `img` (string)
86
+ - `logo` (string)
87
+ - `url` (string)
88
+ - `ip` (string)
89
+ - `port` (string)
90
+ - `playerId` (string)
91
+ - `playerToken` (string)
92
+ - `entityId` (string)
93
+ - `entityType` (string)
94
+ - `entityName` (string)
95
+ - `type` (string)
96
+ - `death`
97
+ - `login`
98
+ - `server`
99
+ - `entity`
100
+
101
+ Sends a push notification to the Rust+ Companion App.
@@ -0,0 +1,7 @@
1
+ # Download Rust+ Bundle
2
+
3
+ You can use the following bash snippet to fetch the latest Rust+ bundle URL.
4
+
5
+ ```bash
6
+ curl -s -H 'Exponent-SDK-Version: 44.0.0' -H 'Exponent-Platform: android' -H 'Exponent-Version: 0.0.25' -H 'Accept: application/expo+json,application/json' -H 'Expo-Release-Channel: default' -H 'Expo-Api-Version: 1' -H 'Expo-Client-Environment: STANDALONE' -H 'Exponent-Accept-Signature: true' -H 'Expo-JSON-Error: true' -H 'Host: exp.host' -H 'User-Agent: okhttp/3.12.1' --compressed 'https://exp.host/@facepunch/RustCompanion' | python -c 'import sys, json; print(json.loads(json.load(sys.stdin)["manifestString"])["bundleUrl"])'
7
+ ```
@@ -0,0 +1,19 @@
1
+ # Rust+ Pairing Flow
2
+
3
+ The procedure for pairing with a Rust Server and Smart Devices in the official Rust+ app is like so:
4
+
5
+ - Player installs Rust+ mobile app from Apple App Store or Google Play Store.
6
+ - Player logs in to Rust+ mobile app with Steam Account.
7
+ - Player gets redirected back to the Rust+ mobile app with a Steam OpenId Auth Token.
8
+ - Rust+ mobile app sends the `ExponentPushToken` ([expo app](https://expo.io/) notification token) for your device along with your Steam Auth Token to the `/api/push/register` endpoint of the Rust Companion API.
9
+ - Rust Companion API returns a refreshed Steam Auth Token which expires after 2 weeks.
10
+ - Player connects to Rust Server in game.
11
+ - Player goes to Rust+ menu in game.
12
+ - Player clicks "Pair with Server".
13
+ - Rust game server communicates with Rust Companion API with `serverToken` from `companion.id` file in Rust game server folder. (I haven't checked this, but assume that's how it works)
14
+ - Rust Companion API sends a notification to the registered device via the `ExponentPushToken`.
15
+ - The received Pairing Notification contains the Server Information required for the Rust+ app to connect to the WebSocket running on `app.port` configured in `server.cfg` while also authenticating as the Steam Account associated with the Steam OpenId token sent in previous steps.
16
+ - Player clicks "Pair" on "Smart Alarms" and "Smart Switches" in game.
17
+ - Rust game server communicates with Rust Companion API. (like above, I haven't checked this, but assume so)
18
+ - Rust Companion API sends another notification to the registered device.
19
+ - The received Pairing Notification contains the Entity Id and Entity Type (such as Smart Alarm or Smart Switch) as well as the Server Information you get from the normal Server Pairing process.
package/donate.md ADDED
@@ -0,0 +1,10 @@
1
+ # Donate
2
+
3
+ Thank you for considering donating, this helps support my work on this project 😁
4
+
5
+ ## How can I donate?
6
+
7
+ - Bitcoin: bc1qy22smke8n4c54evdxmp7lpy9p0e6m9tavtlg2q
8
+ - Ethereum: 0xc64CFbA5D0BF7664158c5671F64d446395b3bF3D
9
+ - Buy me a Coffee: [https://ko-fi.com/liamcottle](https://ko-fi.com/liamcottle)
10
+ - Sponsor on GitHub: [https://github.com/sponsors/liamcottle](https://github.com/sponsors/liamcottle)
@@ -0,0 +1,100 @@
1
+ const RustPlus = require('../rustplus');
2
+ const Camera = require("../camera");
3
+ var rustplus = new RustPlus('ip', 'port', 'playerId', 'playerToken');
4
+
5
+ function delay(time) {
6
+ return new Promise(resolve => setTimeout(resolve, time));
7
+ }
8
+
9
+ rustplus.on('connected', async () => {
10
+
11
+ console.log("connected");
12
+
13
+ // get a camera (should be an autoturret for this example)
14
+ const turret = rustplus.getCamera("TURRET1");
15
+
16
+ // wait until subscribed to autoturret camera
17
+ turret.on('subscribed', async () => {
18
+
19
+ // check if camera is an auto turret
20
+ if(!turret.isAutoTurret()){
21
+ console.log("Camera is not an auto turret!");
22
+ await rustplus.disconnect();
23
+ return;
24
+ }
25
+
26
+ console.log("subscribed to autoturret camera");
27
+ await delay(500);
28
+
29
+ const shootCount = 3;
30
+ const shootDelay = 250;
31
+ const moveDelay = 500;
32
+ const moveAmount = 5;
33
+
34
+ // shoot autoturret
35
+ console.log("shooting");
36
+ for(let i = 0; i < shootCount; i++){
37
+ await delay(shootDelay);
38
+ await turret.shoot();
39
+ }
40
+
41
+ // move autoturret left
42
+ console.log("moving left");
43
+ await delay(moveDelay);
44
+ await turret.move(Camera.Buttons.NONE, -moveAmount, 0);
45
+
46
+ // shoot autoturret
47
+ console.log("shooting");
48
+ for(let i = 0; i < shootCount; i++){
49
+ await delay(shootDelay);
50
+ await turret.shoot();
51
+ }
52
+
53
+ // move autoturret up
54
+ console.log("moving up");
55
+ await delay(moveDelay);
56
+ await turret.move(Camera.Buttons.NONE, 0, moveAmount);
57
+
58
+ // shoot autoturret
59
+ console.log("shooting");
60
+ for(let i = 0; i < shootCount; i++){
61
+ await delay(shootDelay);
62
+ await turret.shoot();
63
+ }
64
+
65
+ // move autoturret right
66
+ console.log("moving right");
67
+ await delay(moveDelay);
68
+ await turret.move(Camera.Buttons.NONE, moveAmount, 0);
69
+
70
+ // shoot autoturret
71
+ console.log("shooting");
72
+ for(let i = 0; i < shootCount; i++){
73
+ await delay(shootDelay);
74
+ await turret.shoot();
75
+ }
76
+
77
+ // move autoturret down
78
+ console.log("moving down");
79
+ await delay(moveDelay);
80
+ await turret.move(Camera.Buttons.NONE, 0, -moveAmount);
81
+
82
+ // shoot autoturret
83
+ console.log("shooting");
84
+ for(let i = 0; i < shootCount; i++){
85
+ await delay(shootDelay);
86
+ await turret.shoot();
87
+ }
88
+
89
+ console.log("disconnecting");
90
+ await rustplus.disconnect();
91
+
92
+ });
93
+
94
+ // subscribe to autoturret camera
95
+ await turret.subscribe();
96
+
97
+ });
98
+
99
+ // connect to rust server
100
+ rustplus.connect();
@@ -0,0 +1,16 @@
1
+ const RustPlus = require('@rustwirebot/rustplus.js');
2
+ var rustplus = new RustPlus('ip', 'port', 'playerId', 'playerToken');
3
+
4
+ // wait until connected before sending commands
5
+ rustplus.on('connected', () => {
6
+
7
+ // send message to team chat
8
+ rustplus.sendTeamMessage('Hello from rustplus.js!');
9
+
10
+ // disconnect from rust server
11
+ rustplus.disconnect();
12
+
13
+ });
14
+
15
+ // connect to rust server
16
+ rustplus.connect();
@@ -0,0 +1,21 @@
1
+ const RustPlus = require('@rustwirebot/rustplus.js');
2
+ var rustplus = new RustPlus('ip', 'port', 'playerId', 'playerToken');
3
+
4
+ // wait until connected before sending commands
5
+ rustplus.on('connected', () => {
6
+
7
+ // turn smart switch on by entity id
8
+ rustplus.turnSmartSwitchOn(1234567, (message) => {
9
+
10
+ // log result
11
+ console.log("turnSmartSwitchOn result: " + JSON.stringify(message));
12
+
13
+ // disconnect from rust server
14
+ rustplus.disconnect();
15
+
16
+ });
17
+
18
+ });
19
+
20
+ // connect to rust server
21
+ rustplus.connect();
@@ -0,0 +1,21 @@
1
+ const RustPlus = require('@rustwirebot/rustplus.js');
2
+ var rustplus = new RustPlus('ip', 'port', 'playerId', 'playerToken');
3
+
4
+ // wait until connected before sending commands
5
+ rustplus.on('connected', () => {
6
+
7
+ // turn smart switch off by entity id
8
+ rustplus.turnSmartSwitchOff(1234567, (message) => {
9
+
10
+ // log result
11
+ console.log("turnSmartSwitchOff result: " + JSON.stringify(message));
12
+
13
+ // disconnect from rust server
14
+ rustplus.disconnect();
15
+
16
+ });
17
+
18
+ });
19
+
20
+ // connect to rust server
21
+ rustplus.connect();