t1nder-cli-simulator 1.0.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/index.js +277 -0
  2. package/package.json +38 -0
package/index.js ADDED
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env node
2
+
3
+ import clipboardy from 'clipboardy'
4
+ import axios from 'axios'
5
+ import chalk from 'chalk'
6
+ import ora from 'ora'
7
+ import figlet from 'figlet'
8
+ import gradient from 'gradient-string'
9
+ import inquirer from 'inquirer'
10
+ import { Server } from 'socket.io'
11
+ import { createServer } from 'http'
12
+ import open from 'open'
13
+
14
+ const SECRET_PASS = 'admin123'
15
+ const CHECK_INTERVAL = 800
16
+ const PORT = 3456
17
+ const CLIENT_URL = `https://t1nder.vercel.app/`
18
+
19
+ const SERVER_LIST = [
20
+ {
21
+ name: 'Server 1 (Main - T1nder)',
22
+ config: {
23
+ ai: 'https://t1nder.vercel.app/api/ai',
24
+ image: 'https://t1nder.vercel.app/api/image',
25
+ },
26
+ },
27
+ {
28
+ name: 'Server 2 (VIP - T1nder VIP)',
29
+ config: {
30
+ ai: 'https://t1nder-vip.vercel.app/api/ai',
31
+ image: 'https://t1nder-vip.vercel.app/api/image',
32
+ },
33
+ },
34
+ ]
35
+
36
+ let CURRENT_API_ENDPOINT = ''
37
+ let CURRENT_IMAGE_ENDPOINT = ''
38
+ let CURRENT_INVITE_KEY = ''
39
+
40
+ const httpServer = createServer()
41
+ const io = new Server(httpServer, {
42
+ cors: {
43
+ origin: '*',
44
+ methods: ['GET', 'POST'],
45
+ },
46
+ })
47
+
48
+ io.on('connection', (socket) => {})
49
+
50
+ const showBanner = () => {
51
+ console.clear()
52
+ const art = figlet.textSync('Tinder', { font: 'Slant' })
53
+ console.log(gradient.pastel.multiline(art))
54
+ console.log(chalk.cyan(`Say hi to`), chalk.yellow('Tinder CLI.'))
55
+ console.log(chalk.dim('---------------------------------------------------'))
56
+ }
57
+
58
+ const authenticate = async () => {
59
+ const answers = await inquirer.prompt([
60
+ {
61
+ type: 'password',
62
+ name: 'inputPass',
63
+ message: '🔒 Xác thực danh tính:',
64
+ mask: '*',
65
+ },
66
+ ])
67
+
68
+ if (answers.inputPass !== SECRET_PASS) {
69
+ console.log(chalk.bgRed.white.bold(' ❌ ACCESS DENIED '))
70
+ process.exit(1)
71
+ }
72
+ console.log(chalk.green('🔓 Access Granted.'))
73
+ }
74
+
75
+ const configureSettings = async () => {
76
+ console.log(chalk.yellow('\n⚙️ THIẾT LẬP HỆ THỐNG'))
77
+
78
+ const keyAnswer = await inquirer.prompt([
79
+ {
80
+ type: 'input',
81
+ name: 'key',
82
+ message: '🔑 Nhập Invite Key:',
83
+ validate: (input) =>
84
+ input.trim() !== '' ? true : 'Key không được để trống!',
85
+ },
86
+ ])
87
+
88
+ console.log(chalk.cyan('\n🌐 Danh sách Server khả dụng:'))
89
+ SERVER_LIST.forEach((server, index) => {
90
+ console.log(chalk.white(` [${index + 1}] ${server.name}`))
91
+ })
92
+ console.log('')
93
+
94
+ const serverAnswer = await inquirer.prompt([
95
+ {
96
+ type: 'input',
97
+ name: 'choice',
98
+ message: '👉 Chọn Server (Nhập 1 hoặc 2):',
99
+ default: '1',
100
+ validate: (input) => {
101
+ const num = parseInt(input)
102
+ if (!isNaN(num) && num >= 1 && num <= SERVER_LIST.length) {
103
+ return true
104
+ }
105
+ return `Vui lòng nhập số từ 1 đến ${SERVER_LIST.length}`
106
+ },
107
+ },
108
+ ])
109
+
110
+ const selectedIndex = parseInt(serverAnswer.choice) - 1
111
+ const selectedConfig = SERVER_LIST[selectedIndex].config
112
+
113
+ CURRENT_INVITE_KEY = keyAnswer.key.trim()
114
+ CURRENT_API_ENDPOINT = selectedConfig.ai.trim()
115
+ CURRENT_IMAGE_ENDPOINT = selectedConfig.image.trim()
116
+
117
+ const maskedKey = CURRENT_INVITE_KEY.substring(0, 5) + '*******'
118
+ console.log(chalk.dim('-----------------------------------'))
119
+ console.log(chalk.blue(`Key: `) + chalk.white(maskedKey))
120
+ console.log(
121
+ chalk.blue(`Selected: `) + chalk.green(SERVER_LIST[selectedIndex].name)
122
+ )
123
+ console.log(chalk.blue(`Endpoint: `) + chalk.white(selectedIndex))
124
+ console.log(chalk.green('\n✅ Configuration Loaded.\n'))
125
+ }
126
+
127
+ const mapAnswerToNumber = (answerChar) => {
128
+ const map = {
129
+ A: '1',
130
+ a: '1',
131
+ B: '2',
132
+ b: '2',
133
+ C: '3',
134
+ c: '3',
135
+ D: '4',
136
+ d: '4',
137
+ e: '5',
138
+ E: '5',
139
+ f: '6',
140
+ F: '6',
141
+ }
142
+ const key = answerChar ? answerChar.charAt(0) : ''
143
+ return map[key] || '?'
144
+ }
145
+
146
+ const processQuestion = async (text) => {
147
+ const spinner = ora('Analyzing data...').start()
148
+
149
+ try {
150
+ try {
151
+ new URL(CURRENT_API_ENDPOINT)
152
+ } catch (e) {
153
+ throw new Error(`Invalid URL: "${CURRENT_API_ENDPOINT}"`)
154
+ }
155
+
156
+ const response = await axios.post(
157
+ CURRENT_API_ENDPOINT,
158
+ {
159
+ question: text,
160
+ inviteKey: CURRENT_INVITE_KEY,
161
+ },
162
+ {
163
+ timeout: 10000,
164
+ headers: {
165
+ 'Content-Type': 'application/json',
166
+ },
167
+ }
168
+ )
169
+
170
+ const apiResult = response.data
171
+ const finalAnswer =
172
+ typeof apiResult === 'object' && apiResult.answer
173
+ ? apiResult.answer
174
+ : apiResult
175
+
176
+ const numberResult = mapAnswerToNumber(finalAnswer)
177
+
178
+ spinner.succeed(chalk.green(`Analysis Complete.`))
179
+
180
+ const mapData = {
181
+ answer: finalAnswer,
182
+ number: numberResult,
183
+ }
184
+
185
+ io.emit('solution_found', mapData)
186
+
187
+ console.log(
188
+ chalk.cyan(' [Q] '),
189
+ chalk.white(text.length > 50 ? text.substring(0, 50) + '...' : text)
190
+ )
191
+ console.log(
192
+ chalk.yellow(' [A] '),
193
+ chalk.bold.green(`${finalAnswer} ➔ ${numberResult}`)
194
+ )
195
+
196
+ await clipboardy.write(' ')
197
+ return 'CLEARED'
198
+ } catch (error) {
199
+ let errMsg = error.message
200
+ if (error.code === 'ERR_INVALID_URL') {
201
+ errMsg = `URL lỗi: [${CURRENT_API_ENDPOINT}]`
202
+ } else if (error.response) {
203
+ errMsg = `Server Error (${error.response.status})`
204
+ }
205
+ spinner.fail(chalk.red('Lỗi: ') + errMsg)
206
+ return 'ERROR'
207
+ }
208
+ }
209
+
210
+ const startClipboardWatcher = async () => {
211
+ let lastClip = ''
212
+ try {
213
+ await clipboardy.write(' ')
214
+ lastClip = ' '
215
+ } catch (e) {}
216
+
217
+ console.log(
218
+ chalk.cyan(`[`),
219
+ chalk.yellow(`System:`),
220
+ chalk.cyan('Auto-reset enabled. Ready for Ctrl+C...'),
221
+ chalk.cyan(`]`)
222
+ )
223
+
224
+ setInterval(async () => {
225
+ try {
226
+ const currentClip = await clipboardy.read()
227
+
228
+ if (
229
+ currentClip &&
230
+ currentClip !== lastClip &&
231
+ currentClip.trim() !== ''
232
+ ) {
233
+ if (currentClip.trim().length > 3) {
234
+ lastClip = currentClip
235
+ const result = await processQuestion(currentClip)
236
+ if (result === 'CLEARED') {
237
+ lastClip = ' '
238
+ }
239
+ }
240
+ }
241
+ } catch (err) {}
242
+ }, CHECK_INTERVAL)
243
+ }
244
+
245
+ const main = async () => {
246
+ showBanner()
247
+ await authenticate()
248
+ await configureSettings()
249
+
250
+ httpServer.listen(PORT, async () => {
251
+ console.log(chalk.gray(`[Signal] Broadcasting on port ${PORT}...`))
252
+
253
+ try {
254
+ console.log(chalk.yellow(`[Browser] Opening Default Browser...`))
255
+ await open(CLIENT_URL)
256
+ } catch (error) {
257
+ console.log(
258
+ chalk.red(`[Error] Không thể mở trình duyệt: ${error.message}`)
259
+ )
260
+ }
261
+ })
262
+ console.clear()
263
+ console.log(
264
+ chalk.cyan(`[`),
265
+ chalk.yellow(`Objective:`),
266
+ chalk.cyan(`Copy question to retrieve answer.`),
267
+ chalk.cyan(`]`)
268
+ )
269
+ console.log(
270
+ chalk.red.italic(
271
+ `(!) Lưu ý: Clipboard sẽ tự động bị xóa sau khi lấy đáp án.`
272
+ )
273
+ )
274
+ startClipboardWatcher()
275
+ }
276
+
277
+ main()
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "t1nder-cli-simulator",
3
+ "version": "1.0.0",
4
+ "description": "Simulator for SungJinWoo system",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "tinder": "./index.js"
9
+ },
10
+ "files": [
11
+ "index.js",
12
+ "package.json"
13
+ ],
14
+ "scripts": {
15
+ "test": "echo \"Error: no test specified\" && exit 1",
16
+ "build": "pkg index.js --targets node18-win-x64,node18-macos-x64,node18-linux-x64 --output tinder"
17
+ },
18
+ "keywords": [],
19
+ "author": "SungJinWoo",
20
+ "license": "ISC",
21
+ "dependencies": {
22
+ "axios": "^1.13.2",
23
+ "chalk": "^5.6.2",
24
+ "chrome-launcher": "^1.2.1",
25
+ "clipboardy": "^5.0.2",
26
+ "express": "^5.2.1",
27
+ "figlet": "^1.9.4",
28
+ "fs-extra": "^11.3.3",
29
+ "gradient-string": "^3.0.0",
30
+ "inquirer": "^13.1.0",
31
+ "node-notifier": "^10.0.1",
32
+ "open": "^11.0.0",
33
+ "ora": "^9.0.0",
34
+ "semver": "^7.7.3",
35
+ "socket.io": "^4.8.3",
36
+ "update-notifier": "^7.3.1"
37
+ }
38
+ }