ropilot 0.1.3 → 0.1.5
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/lib/setup.js +123 -7
- package/package.json +1 -1
package/lib/setup.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Installing Studio plugin
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { existsSync, writeFileSync, mkdirSync, readFileSync } from 'fs';
|
|
11
|
+
import { existsSync, writeFileSync, mkdirSync, readFileSync, readdirSync } from 'fs';
|
|
12
12
|
import { join, dirname } from 'path';
|
|
13
13
|
import { homedir, platform } from 'os';
|
|
14
14
|
import { createInterface } from 'readline';
|
|
@@ -28,17 +28,94 @@ const PLUGIN_VERSION_URL = 'https://ropilot.ai/plugin/version';
|
|
|
28
28
|
const PLUGIN_DOWNLOAD_URL = 'https://ropilot.ai/plugin/StudioPlugin.lua';
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Check if running in WSL
|
|
32
|
+
*/
|
|
33
|
+
function isWSL() {
|
|
34
|
+
try {
|
|
35
|
+
const release = readFileSync('/proc/version', 'utf-8').toLowerCase();
|
|
36
|
+
return release.includes('microsoft') || release.includes('wsl');
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get Windows username when running in WSL (tries multiple methods)
|
|
44
|
+
*/
|
|
45
|
+
function getWindowsUsername() {
|
|
46
|
+
const { execSync } = require('child_process');
|
|
47
|
+
|
|
48
|
+
// Method 1: cmd.exe
|
|
49
|
+
try {
|
|
50
|
+
const result = execSync('cmd.exe /c echo %USERNAME%', { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
51
|
+
if (result && !result.includes('%')) return result;
|
|
52
|
+
} catch {}
|
|
53
|
+
|
|
54
|
+
// Method 2: whoami.exe (returns DOMAIN\user)
|
|
55
|
+
try {
|
|
56
|
+
const result = execSync('/mnt/c/Windows/System32/whoami.exe', { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
57
|
+
if (result && result.includes('\\')) {
|
|
58
|
+
return result.split('\\').pop();
|
|
59
|
+
}
|
|
60
|
+
} catch {}
|
|
61
|
+
|
|
62
|
+
// Method 3: powershell
|
|
63
|
+
try {
|
|
64
|
+
const result = execSync('powershell.exe -NoProfile -Command "$env:USERNAME"', { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
65
|
+
if (result) return result;
|
|
66
|
+
} catch {}
|
|
67
|
+
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get valid Windows users from /mnt/c/Users
|
|
73
|
+
*/
|
|
74
|
+
function getValidWindowsUsers() {
|
|
75
|
+
const usersDir = '/mnt/c/Users';
|
|
76
|
+
try {
|
|
77
|
+
return readdirSync(usersDir).filter(u =>
|
|
78
|
+
!['Public', 'Default', 'Default User', 'All Users', 'desktop.ini'].includes(u) &&
|
|
79
|
+
existsSync(join(usersDir, u, 'AppData'))
|
|
80
|
+
);
|
|
81
|
+
} catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get Roblox plugins folder path based on OS (with WSL detection)
|
|
88
|
+
* Returns { path, needsPrompt, users } - needsPrompt true if user selection needed
|
|
32
89
|
*/
|
|
33
90
|
function getPluginsFolder() {
|
|
34
91
|
const os = platform();
|
|
92
|
+
|
|
93
|
+
// Check for WSL first - need to use Windows path
|
|
94
|
+
if (os === 'linux' && isWSL()) {
|
|
95
|
+
// Try to auto-detect Windows username
|
|
96
|
+
const windowsUser = getWindowsUsername();
|
|
97
|
+
if (windowsUser && existsSync(join('/mnt/c/Users', windowsUser))) {
|
|
98
|
+
return { path: join('/mnt/c/Users', windowsUser, 'AppData', 'Local', 'Roblox', 'Plugins') };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Fallback: scan /mnt/c/Users
|
|
102
|
+
const validUsers = getValidWindowsUsers();
|
|
103
|
+
if (validUsers.length === 1) {
|
|
104
|
+
return { path: join('/mnt/c/Users', validUsers[0], 'AppData', 'Local', 'Roblox', 'Plugins') };
|
|
105
|
+
} else if (validUsers.length > 1) {
|
|
106
|
+
return { path: null, needsPrompt: true, users: validUsers };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { path: null };
|
|
110
|
+
}
|
|
111
|
+
|
|
35
112
|
if (os === 'win32') {
|
|
36
|
-
return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Roblox', 'Plugins');
|
|
113
|
+
return { path: join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Roblox', 'Plugins') };
|
|
37
114
|
} else if (os === 'darwin') {
|
|
38
|
-
return join(homedir(), 'Documents', 'Roblox', 'Plugins');
|
|
115
|
+
return { path: join(homedir(), 'Documents', 'Roblox', 'Plugins') };
|
|
39
116
|
} else {
|
|
40
|
-
// Linux - Roblox doesn't officially support Linux
|
|
41
|
-
return
|
|
117
|
+
// Linux without WSL - Roblox doesn't officially support Linux
|
|
118
|
+
return { path: null };
|
|
42
119
|
}
|
|
43
120
|
}
|
|
44
121
|
|
|
@@ -82,7 +159,46 @@ async function installPlugin() {
|
|
|
82
159
|
const pluginSource = await pluginResponse.text();
|
|
83
160
|
|
|
84
161
|
// Get plugins folder
|
|
85
|
-
|
|
162
|
+
let folderResult = getPluginsFolder();
|
|
163
|
+
let pluginsFolder = folderResult.path;
|
|
164
|
+
|
|
165
|
+
// If WSL detected multiple users, prompt for selection
|
|
166
|
+
if (folderResult.needsPrompt && folderResult.users) {
|
|
167
|
+
console.log(' Multiple Windows users detected:');
|
|
168
|
+
folderResult.users.forEach((u, i) => console.log(` ${i + 1}. ${u}`));
|
|
169
|
+
const choice = await prompt(` Enter number (1-${folderResult.users.length}) or username: `);
|
|
170
|
+
|
|
171
|
+
let selectedUser;
|
|
172
|
+
const num = parseInt(choice);
|
|
173
|
+
if (num >= 1 && num <= folderResult.users.length) {
|
|
174
|
+
selectedUser = folderResult.users[num - 1];
|
|
175
|
+
} else if (folderResult.users.includes(choice)) {
|
|
176
|
+
selectedUser = choice;
|
|
177
|
+
} else if (existsSync(join('/mnt/c/Users', choice, 'AppData'))) {
|
|
178
|
+
selectedUser = choice;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (selectedUser) {
|
|
182
|
+
pluginsFolder = join('/mnt/c/Users', selectedUser, 'AppData', 'Local', 'Roblox', 'Plugins');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// If still no folder and running in WSL, prompt for username directly
|
|
187
|
+
if (!pluginsFolder && isWSL()) {
|
|
188
|
+
const username = await prompt(' Enter your Windows username: ');
|
|
189
|
+
if (username && existsSync(join('/mnt/c/Users', username))) {
|
|
190
|
+
pluginsFolder = join('/mnt/c/Users', username, 'AppData', 'Local', 'Roblox', 'Plugins');
|
|
191
|
+
} else if (username) {
|
|
192
|
+
// Trust user input even if path doesn't exist yet
|
|
193
|
+
pluginsFolder = join('/mnt/c/Users', username, 'AppData', 'Local', 'Roblox', 'Plugins');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!pluginsFolder) {
|
|
198
|
+
console.log(' Could not determine Roblox plugins folder');
|
|
199
|
+
console.log(' Manual install: Download from https://ropilot.ai/plugin/StudioPlugin.lua');
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
86
202
|
|
|
87
203
|
// Create plugins folder if it doesn't exist
|
|
88
204
|
mkdirSync(pluginsFolder, { recursive: true });
|