dankgrinder 8.75.0 → 8.77.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 (2) hide show
  1. package/lib/ui.js +76 -69
  2. package/package.json +4 -1
package/lib/ui.js CHANGED
@@ -53,11 +53,7 @@ function init({ workers }) { _workers = workers; _startTime = Date.now(); _event
53
53
 
54
54
  function drawBanner(version) {
55
55
  _version = version || '0.0.0';
56
- console.clear();
57
- const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
58
- console.log(chalk.bold(applyGradient(titleStr)));
59
- console.log(chalk.bold.magenta(`v${_version} — ${getLoader()} Booting... `));
60
- console.log();
56
+ // Do not console.log here, let render() handle the banner to prevent log-update resize duplication
61
57
  }
62
58
 
63
59
  function fmtUptime() {
@@ -92,35 +88,55 @@ function log(accountIdx, msg) { if (!_live && accountIdx === -1) console.log(cha
92
88
  function updateAccountRow() { }
93
89
 
94
90
  // Precision width padding
95
- function padFixed(str, len, isAnsiPrepared = false) {
96
- if (!isAnsiPrepared) {
97
- if (str.length > len) return str.substring(0, len - 1) + '…';
98
- return str.padEnd(len, ' ');
99
- } else {
100
- const rawLen = str.replace(/\x1b\[[0-9;]*m/g, '').length;
101
- if (rawLen < len) return str + ' '.repeat(len - rawLen);
102
- return str; // Assume caller pre-truncated the inner text
103
- }
91
+ function trunc(str, max) {
92
+ return str.length > max ? str.substring(0, max - 1) + '…' : str;
93
+ }
94
+ function pad(str, len) {
95
+ const vLen = str.replace(/\x1b\[[0-9;]*m/g, '').length;
96
+ return str + ' '.repeat(Math.max(0, len - vLen));
97
+ }
98
+ function makeRow(c1, c2, c3, c4, c5, c6, wCols, logW) {
99
+ return `│ ${pad(c1, wCols.num)} │ ${pad(c2, wCols.name)} │ ${pad(c3, wCols.bal)} │ ${pad(c4, wCols.ls)} │ ${pad(c5, wCols.lv)} │ ${pad(c6, logW)} │`;
104
100
  }
105
101
 
106
102
  function render() {
107
103
  if (!_live) return;
108
- const cols = process.stdout.columns || 110;
109
- const rows = process.stdout.rows || 30;
110
-
104
+ const C = process.stdout.columns || 110;
105
+
106
+ let out = '';
107
+ // Banner
111
108
  const titleStr = figlet.textSync('DANK GRINDER', { font: 'ANSI Shadow' });
112
- let out = chalk.bold(applyGradient(titleStr));
109
+ out += chalk.bold(applyGradient(titleStr));
110
+ out += chalk.bold.magenta(`v${_version} — ${getLoader()} Running... `) + '\n\n';
111
+
112
+ const wCols = { num: 4, name: 18, bal: 14, ls: 5, lv: 5 };
113
113
 
114
- const sep = chalk.hex('#4dd4ee').bold('━'.repeat(cols));
115
- out += sep + '\n';
114
+ const overhead = 19 + wCols.num + wCols.name + wCols.bal + wCols.ls + wCols.lv;
115
+ const logW = Math.max(10, C - overhead);
116
+ const actualC = logW + overhead;
117
+
118
+ const summaryW = actualC - 4;
116
119
 
117
- const wCols = { num: 4, name: 18, bal: 14, ls: 6, lv: 6 };
118
- let logW = Math.max(15, cols - (wCols.num + wCols.name + wCols.bal + wCols.ls + wCols.lv + 12));
120
+ out += '╭' + '─'.repeat(wCols.num + 2) + '┬'
121
+ + '─'.repeat(wCols.name + 2) + '┬'
122
+ + '─'.repeat(wCols.bal + 2) + '┬'
123
+ + '─'.repeat(wCols.ls + 2) + '┬'
124
+ + '─'.repeat(wCols.lv + 2) + '┬'
125
+ + '─'.repeat(logW + 2) + '╮\n';
126
+
127
+ out += makeRow(
128
+ chalk.bold('#'), chalk.bold('ACCOUNT'), chalk.bold('BAL'),
129
+ chalk.bold('LS'), chalk.bold('LV'), chalk.bold('LOGS'),
130
+ wCols, logW
131
+ ) + '\n';
119
132
 
120
- out += `${chalk.bold(' #').padEnd(wCols.num)} ${chalk.bold('ACCOUNT').padEnd(wCols.name)} ${chalk.bold('BAL').padEnd(wCols.bal)} ${chalk.bold('LS').padEnd(wCols.ls)} ${chalk.bold('LV').padEnd(wCols.lv)} ${chalk.bold('LOGS')} \n`;
121
- out += sep + '\n';
133
+ out += '' + ''.repeat(wCols.num + 2) + ''
134
+ + '─'.repeat(wCols.name + 2) + ''
135
+ + '─'.repeat(wCols.bal + 2) + '┼'
136
+ + '─'.repeat(wCols.ls + 2) + '┼'
137
+ + '─'.repeat(wCols.lv + 2) + '┼'
138
+ + '─'.repeat(logW + 2) + '┤\n';
122
139
 
123
- const maxShown = Math.max(3, rows - 24);
124
140
  const sorted = [..._workers].sort((a, b) => {
125
141
  if (!a.channel !== !b.channel) return a.channel ? -1 : 1;
126
142
  const aA = a.channel && !a.paused && !a.dashboardPaused;
@@ -130,17 +146,11 @@ function render() {
130
146
  });
131
147
 
132
148
  let totalCoins = 0, totalBal = 0, onlineCount = 0;
133
- for (let i = 0; i < _workers.length; i++) {
134
- const w = _workers[i];
149
+ for (let i = 0; i < sorted.length; i++) {
150
+ const w = sorted[i];
135
151
  totalCoins += w.stats.coins || 0;
136
152
  totalBal += w.stats.balance || 0;
137
153
  if (w.channel && !w.paused && !w.dashboardPaused) onlineCount++;
138
- }
139
-
140
- const shown = sorted.slice(0, maxShown);
141
- for (let i = 0; i < shown.length; i++) {
142
- const w = shown[i];
143
- const rawIdx = String(_workers.indexOf(w) + 1);
144
154
 
145
155
  let logText = w.lastStatus || 'idle';
146
156
  let activity = '';
@@ -156,54 +166,51 @@ function render() {
156
166
  activity = chalk.gray(getLoader());
157
167
  }
158
168
 
159
- // Fixed widths construction
160
- const numPart = padFixed(` ${rawIdx}`, wCols.num);
161
-
162
- // Name Part
169
+ const numStr = trunc(String(i + 1), wCols.num);
163
170
  const dot = getDot(w);
164
- let uName = w.username || '?';
165
- // dot + space + name -> subtract 2 from allowed length
166
- if (uName.length > wCols.name - 2) uName = uName.substring(0, wCols.name - 3) + '…';
167
- const cName = `${dot.color(dot.dot)} ${getAccountColor(uName)(chalk.bold(uName))}`;
168
- const namePart = padFixed(cName, wCols.name, true);
169
171
 
170
- // Bal Part
172
+ const nameRaw = trunc(w.username || '?', wCols.name - 2);
173
+ const nameStr = dot.color(dot.dot) + ' ' + getAccountColor(nameRaw)(chalk.bold(nameRaw));
174
+
171
175
  let bVal = w.stats.balance !== undefined ? (w.stats.balance >= 1000 ? w.stats.balance.toLocaleString() : String(w.stats.balance)) : '—';
172
- bVal = bVal.length > wCols.bal - 2 ? bVal.substring(0, wCols.bal - 3) + '…' : bVal;
173
- const cBal = bVal === '—' ? chalk.dim('—') : chalk.bold.green(`⏣${bVal}`);
174
- const balPart = padFixed(cBal, wCols.bal, true);
176
+ const balRaw = trunc(bVal === '—' ? '—' : '⏣' + bVal, wCols.bal);
177
+ const balStr = balRaw === '—' ? chalk.dim('—') : chalk.bold.green(balRaw);
175
178
 
176
- // LS Part
177
- let lVal = w._lifesavers !== undefined ? String(w._lifesavers) : '—';
178
- const lColor = lVal === '—' ? chalk.dim : (w._lifesavers === 0 ? chalk.bold.red : (w._lifesavers <= 2 ? chalk.bold.yellow : chalk.bold.cyan));
179
- const lsPart = padFixed(lColor(lVal.substring(0, wCols.ls)), wCols.ls, true);
179
+ const lsRaw = trunc(w._lifesavers !== undefined ? String(w._lifesavers) : '—', wCols.ls);
180
+ const lColor = lsRaw === '—' ? chalk.dim : (w._lifesavers === 0 ? chalk.bold.red : (w._lifesavers <= 2 ? chalk.bold.yellow : chalk.bold.cyan));
181
+ const lsStr = lColor(lsRaw);
180
182
 
181
- // LV Part
182
- let lvVal = w._level !== undefined ? String(w._level) : '—';
183
- const lvPart = padFixed(chalk.bold.magenta(lvVal.substring(0, wCols.lv)), wCols.lv, true);
183
+ const lvRaw = trunc(w._level !== undefined ? String(w._level) : '—', wCols.lv);
184
+ const lvStr = chalk.bold.magenta(lvRaw);
184
185
 
185
- // Log Part
186
- let lStr = logText;
187
- if (lStr.length > logW - 3) lStr = lStr.substring(0, logW - 4) + '…';
188
- const cLog = `${activity} ${chalk.dim.bold(lStr)}`;
189
- const logPart = padFixed(cLog, logW, true);
186
+ const logRaw = trunc(logText, logW - 2);
187
+ const logStr = activity + ' ' + chalk.dim.bold(logRaw);
190
188
 
191
- out += `${chalk.dim(numPart)} ${namePart} ${balPart} ${lsPart} ${lvPart} ${logPart}\n`;
189
+ out += makeRow(numStr, nameStr, balStr, lsStr, lvStr, logStr, wCols, logW) + '\n';
192
190
  }
193
191
 
194
- if (_workers.length > maxShown) {
195
- out += chalk.bold.dim(` ... and ${(_workers.length - maxShown).toLocaleString()} more accounts running ${getSpinner()}\n`);
196
- }
192
+ out += '├' + '─'.repeat(wCols.num + 2) + '┴'
193
+ + '─'.repeat(wCols.name + 2) + '┴'
194
+ + '─'.repeat(wCols.bal + 2) + '┴'
195
+ + '─'.repeat(wCols.ls + 2) + '┴'
196
+ + '─'.repeat(wCols.lv + 2) + '┴'
197
+ + '─'.repeat(logW + 2) + '┤\n';
197
198
 
198
- out += sep + '\n';
199
199
  const totC = totalCoins >= 1000000 ? (totalCoins/1000000).toFixed(1)+'M' : (totalCoins >= 1000 ? (totalCoins/1000).toFixed(1)+'k' : totalCoins);
200
- out += ` ${chalk.bold('Σ ACCOUNTS:')} ${chalk.bold.magenta(_workers.length)} │ ${chalk.bold('⚡ ONLINE:')} ${chalk.bold.cyan(onlineCount)} │ ${chalk.bold('💰 TOTAL:')} ${chalk.bold.green('⏣' + totalBal.toLocaleString())} ${chalk.bold('📈 GAINED:')} ${chalk.bold.yellow('+' + totC)} │ ${chalk.bold('⏱ UP:')} ${chalk.bold.dim(fmtUptime())}\n`;
201
- out += sep + '\n';
200
+ const summLine = chalk.bold('Σ ACT: ') + chalk.bold.magenta(_workers.length) + chalk.dim(' │ ') +
201
+ chalk.bold('⚡ ON: ') + chalk.bold.cyan(onlineCount) + chalk.dim('') +
202
+ chalk.bold('💰 TR/BAL: ') + chalk.bold.green('⏣' + totalBal.toLocaleString()) + chalk.dim(' │ ') +
203
+ chalk.bold('📈 GAINED: ') + chalk.bold.yellow('+' + totC) + chalk.dim(' │ ') +
204
+ chalk.bold('⏱ UP: ') + chalk.bold.dim(fmtUptime());
205
+
206
+ out += `│ ${pad(summLine, summaryW)} │\n`;
207
+ out += '├' + '─'.repeat(actualC - 2) + '┤\n';
208
+ out += `│ ${pad(chalk.bold.cyan('📻 LATEST EVENTS'), summaryW)} │\n`;
209
+
210
+ if (_events.length === 0) out += `│ ${pad(chalk.dim(' Quiet here...'), summaryW)} │\n`;
211
+ _events.forEach(ev => { out += `│ ${pad(chalk.dim(`[${ev.ts}] `) + ev.icon + ' ' + ev.msg, summaryW)} │\n`; });
202
212
 
203
- out += chalk.bold.cyan(` 📻 LATEST EVENTS \n`) + chalk.dim.bold('─'.repeat(cols)) + '\n';
204
- if (_events.length === 0) out += chalk.dim(' Quiet here...\n');
205
- _events.forEach(ev => { out += chalk.dim(` [${ev.ts}] `) + `${ev.icon} ${ev.msg}\n`; });
206
- out += chalk.dim.bold('─'.repeat(cols)) + '\n';
213
+ out += '╰' + '─'.repeat(actualC - 2) + '╯\n';
207
214
 
208
215
  logUpdate(out);
209
216
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dankgrinder",
3
- "version": "8.75.0",
3
+ "version": "8.77.0",
4
4
  "description": "Dank Memer automation engine — grind coins while you sleep",
5
5
  "bin": {
6
6
  "dankgrinder": "bin/dankgrinder.js"
@@ -24,9 +24,12 @@
24
24
  "test": "node --test test/**/*.test.js"
25
25
  },
26
26
  "dependencies": {
27
+ "chalk": "^4.1.2",
27
28
  "debug": "^4.4.0",
28
29
  "discord.js-selfbot-v13": "3.5.0",
30
+ "figlet": "^1.8.0",
29
31
  "ioredis": "^5.10.1",
32
+ "log-update": "^4.0.0",
30
33
  "sharp": "^0.34.5",
31
34
  "zlib-sync": "^0.1.10"
32
35
  },