@woopsy/mcpanel 2.0.0 → 2.1.1

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.
@@ -33,14 +33,16 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ConfigManager = exports.APP_ROOT = void 0;
36
+ exports.ConfigManager = exports.APP_DATA_DIR = exports.APP_ROOT = void 0;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
39
40
  // Dynamically resolve application root folder
40
41
  exports.APP_ROOT = fs.existsSync(path.join(__dirname, '..', '..', 'package.json'))
41
42
  ? path.resolve(__dirname, '..', '..')
42
43
  : path.resolve(__dirname, '..');
43
- const CONFIG_PATH = path.join(exports.APP_ROOT, 'config.json');
44
+ exports.APP_DATA_DIR = path.join(os.homedir(), '.mcpanel');
45
+ const CONFIG_PATH = path.join(exports.APP_DATA_DIR, 'config.json');
44
46
  const DEFAULT_CONFIG = {
45
47
  defaultJavaPath: 'java',
46
48
  defaultRam: '4G',
@@ -61,9 +63,12 @@ class ConfigManager {
61
63
  * Initializes folders and configuration file
62
64
  */
63
65
  initialize() {
66
+ if (!fs.existsSync(exports.APP_DATA_DIR)) {
67
+ fs.mkdirSync(exports.APP_DATA_DIR, { recursive: true });
68
+ }
64
69
  const requiredDirs = ['backups', 'downloads', 'logs', 'playit'];
65
70
  for (const dir of requiredDirs) {
66
- const dirPath = path.join(exports.APP_ROOT, dir);
71
+ const dirPath = path.join(exports.APP_DATA_DIR, dir);
67
72
  if (!fs.existsSync(dirPath)) {
68
73
  fs.mkdirSync(dirPath, { recursive: true });
69
74
  }
@@ -75,7 +80,8 @@ class ConfigManager {
75
80
  */
76
81
  load() {
77
82
  if (!fs.existsSync(CONFIG_PATH)) {
78
- this.config = { ...DEFAULT_CONFIG };
83
+ this.config = { ...DEFAULT_CONFIG, playitSettings: {} };
84
+ this.migrateLegacyConfig();
79
85
  this.save();
80
86
  return;
81
87
  }
@@ -116,6 +122,9 @@ class ConfigManager {
116
122
  server,
117
123
  externalBackups: parsed.externalBackups || [],
118
124
  };
125
+ // Recover an already-claimed playit secret from the pre-2.0 config
126
+ // location before persisting (no-op once a secret is present here).
127
+ this.migrateLegacyConfig();
119
128
  // Persist the migrated shape so the legacy keys are cleaned up on disk.
120
129
  this.save();
121
130
  }
@@ -126,6 +135,42 @@ class ConfigManager {
126
135
  this.save();
127
136
  }
128
137
  }
138
+ /**
139
+ * Recovers settings written by versions <2.0, which stored config.json next
140
+ * to the app (`APP_ROOT/config.json`) instead of in `~/.mcpanel`. Without
141
+ * this, an already-claimed playit agent secret is invisible to the new
142
+ * location, so the agent gets re-claimed in the browser on every launch.
143
+ *
144
+ * Only runs when the current config has no playit secret, and never
145
+ * overwrites values already present in the new location.
146
+ */
147
+ migrateLegacyConfig() {
148
+ const legacyPath = path.join(exports.APP_ROOT, 'config.json');
149
+ if (legacyPath === CONFIG_PATH)
150
+ return; // same file — nothing to migrate
151
+ if (this.config.playitSettings.secret)
152
+ return; // already linked
153
+ if (!fs.existsSync(legacyPath))
154
+ return;
155
+ try {
156
+ const legacy = JSON.parse(fs.readFileSync(legacyPath, 'utf-8'));
157
+ if (legacy?.playitSettings?.secret) {
158
+ // Bring the secret + last-known tunnel forward so the existing agent
159
+ // and tunnel are reused instead of re-claimed/recreated.
160
+ this.config.playitSettings = {
161
+ ...legacy.playitSettings,
162
+ ...this.config.playitSettings,
163
+ };
164
+ }
165
+ // Adopt the legacy server only if none is synced in the new location.
166
+ if (!this.config.server && legacy.server && typeof legacy.server === 'object') {
167
+ this.config.server = legacy.server;
168
+ }
169
+ }
170
+ catch {
171
+ // Unreadable/corrupt legacy config — ignore and continue with defaults.
172
+ }
173
+ }
129
174
  /**
130
175
  * Saves the current config memory state to disk
131
176
  */
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ const backupManager = new backupManager_1.BackupManager(configManager);
62
62
  const playitManager = new playitManager_1.PlayitManager(configManager);
63
63
  const trayManager = new trayManager_1.TrayManager(configManager, processManager, playitManager);
64
64
  const router = new commandRouter_1.CommandRouter(configManager, processManager, serverManager, backupManager, playitManager);
65
- const HISTORY_PATH = path.join(configManager_1.APP_ROOT, 'logs', '.history');
65
+ const HISTORY_PATH = path.join(configManager_1.APP_DATA_DIR, 'logs', '.history');
66
66
  let currentState = 'COMMAND';
67
67
  const propertiesContext = {
68
68
  properties: {},
@@ -61,7 +61,7 @@ class BackupManager {
61
61
  }
62
62
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
63
63
  const backupFileName = `${server.name}_backup_${timestamp}.zip`;
64
- const backupDestDir = path.join(configManager_1.APP_ROOT, 'backups');
64
+ const backupDestDir = path.join(configManager_1.APP_DATA_DIR, 'backups');
65
65
  if (!fs.existsSync(backupDestDir)) {
66
66
  fs.mkdirSync(backupDestDir, { recursive: true });
67
67
  }
@@ -88,7 +88,7 @@ class BackupManager {
88
88
  listBackups() {
89
89
  const backups = [];
90
90
  const scanDirs = [
91
- path.join(configManager_1.APP_ROOT, 'backups'),
91
+ path.join(configManager_1.APP_DATA_DIR, 'backups'),
92
92
  ...this.configManager.getConfig().externalBackups
93
93
  ];
94
94
  for (const dir of scanDirs) {
@@ -79,7 +79,7 @@ class PlayitManager {
79
79
  getExecutablePath() {
80
80
  const osType = (0, helpers_1.detectOS)();
81
81
  const binName = osType === 'Windows' ? 'playit.exe' : 'playit';
82
- return path.join(configManager_1.APP_ROOT, 'playit', binName);
82
+ return path.join(configManager_1.APP_DATA_DIR, 'playit', binName);
83
83
  }
84
84
  /** Path to the control cli (used for the one-time claim flow). */
85
85
  getCliPath() {
@@ -87,17 +87,17 @@ class PlayitManager {
87
87
  // v1.0.8 only ships a separate cli for Linux; on Windows the main exe is used.
88
88
  if (osType === 'Windows')
89
89
  return this.getExecutablePath();
90
- return path.join(configManager_1.APP_ROOT, 'playit', 'playit-cli');
90
+ return path.join(configManager_1.APP_DATA_DIR, 'playit', 'playit-cli');
91
91
  }
92
92
  /** IPC socket / named pipe the daemon binds to (its default location may not exist). */
93
93
  getSocketPath() {
94
94
  const osType = (0, helpers_1.detectOS)();
95
95
  if (osType === 'Windows')
96
96
  return '\\\\.\\pipe\\mcpanel-playit';
97
- return path.join(configManager_1.APP_ROOT, 'playit', 'agent.sock');
97
+ return path.join(configManager_1.APP_DATA_DIR, 'playit', 'agent.sock');
98
98
  }
99
99
  getVersionSentinel() {
100
- return path.join(configManager_1.APP_ROOT, 'playit', '.version');
100
+ return path.join(configManager_1.APP_DATA_DIR, 'playit', '.version');
101
101
  }
102
102
  downloadUrls() {
103
103
  const base = `https://github.com/playit-cloud/playit-agent/releases/download/v${PLAYIT_VERSION}`;
@@ -40,7 +40,7 @@ const path = __importStar(require("path"));
40
40
  const https = __importStar(require("https"));
41
41
  const configManager_1 = require("../config/configManager");
42
42
  const logger_1 = require("../utils/logger");
43
- const DOWNLOADS_DIR = path.join(configManager_1.APP_ROOT, 'downloads');
43
+ const DOWNLOADS_DIR = path.join(configManager_1.APP_DATA_DIR, 'downloads');
44
44
  /**
45
45
  * Downloads a file from a URL with redirection support and reports progress.
46
46
  */
@@ -48,7 +48,7 @@ const configManager_1 = require("../config/configManager");
48
48
  * every few hours, keeping startup fast.
49
49
  * - Fully fail-silent: no network / offline / parse error => returns null.
50
50
  */
51
- const CACHE_FILE = path.join(configManager_1.APP_ROOT, 'logs', '.update-check.json');
51
+ const CACHE_FILE = path.join(configManager_1.APP_DATA_DIR, 'logs', '.update-check.json');
52
52
  const CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000; // re-check at most every 6h
53
53
  const FETCH_TIMEOUT_MS = 2500;
54
54
  function readPkg() {
@@ -37,7 +37,7 @@ exports.logger = void 0;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const configManager_1 = require("../config/configManager");
40
- const LOGS_DIR = path.join(configManager_1.APP_ROOT, 'logs');
40
+ const LOGS_DIR = path.join(configManager_1.APP_DATA_DIR, 'logs');
41
41
  function ensureLogsDirExists() {
42
42
  if (!fs.existsSync(LOGS_DIR)) {
43
43
  fs.mkdirSync(LOGS_DIR, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@woopsy/mcpanel",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "MCPANEL — a terminal-based, single-server Minecraft server manager with an Arch/neofetch-style UI, live logs, backups, plugins and Playit.gg tunnels.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {