Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- Dockerfile +39 -0
- Procfile +1 -0
- README.md +6 -8
- config.js +45 -0
- database.json +1734 -0
- docker-compose.yml +15 -0
- handler.js +1261 -0
- heroku.yml +3 -0
- index.js +121 -0
- lib/cloudDBAdapter.js +58 -0
- lib/cluster.js +36 -0
- lib/color.js +14 -0
- lib/converter.js +84 -0
- lib/database.js +71 -0
- lib/exif.js +116 -0
- lib/functions.js +149 -0
- lib/gdrive.js +75 -0
- lib/levelling.js +50 -0
- lib/logs.js +19 -0
- lib/lowdb/Low.d.ts +11 -0
- lib/lowdb/Low.js +21 -0
- lib/lowdb/LowSync.d.ts +11 -0
- lib/lowdb/LowSync.js +21 -0
- lib/lowdb/MissingAdapterError.d.ts +3 -0
- lib/lowdb/MissingAdapterError.js +7 -0
- lib/lowdb/adapters/JSONFile.d.ts +7 -0
- lib/lowdb/adapters/JSONFile.js +19 -0
- lib/lowdb/adapters/JSONFileSync.d.ts +7 -0
- lib/lowdb/adapters/JSONFileSync.js +19 -0
- lib/lowdb/adapters/LocalStorage.d.ts +7 -0
- lib/lowdb/adapters/LocalStorage.js +16 -0
- lib/lowdb/adapters/Memory.d.ts +6 -0
- lib/lowdb/adapters/Memory.js +13 -0
- lib/lowdb/adapters/MemorySync.d.ts +6 -0
- lib/lowdb/adapters/MemorySync.js +12 -0
- lib/lowdb/adapters/TextFile.d.ts +8 -0
- lib/lowdb/adapters/TextFile.js +25 -0
- lib/lowdb/adapters/TextFileSync.d.ts +8 -0
- lib/lowdb/adapters/TextFileSync.js +26 -0
- lib/lowdb/index.d.ts +9 -0
- lib/lowdb/index.js +11 -0
- lib/mongoDB.js +44 -0
- lib/myfunc.js +307 -0
- lib/print.js +93 -0
- lib/scrape.js +254 -0
- lib/simple.js +1638 -0
- lib/sticker.js +209 -0
- lib/tictactoe.d.ts +15 -0
- lib/tictactoe.js +93 -0
- lib/ular_tangga.js +50 -0
Dockerfile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Menggunakan Node.js versi 18 sebagai base image
|
| 2 |
+
FROM node:18
|
| 3 |
+
|
| 4 |
+
# Menginstal git, ffmpeg, imagemagick, dan webp
|
| 5 |
+
RUN apt-get update && \
|
| 6 |
+
apt-get install -y \
|
| 7 |
+
git \
|
| 8 |
+
ffmpeg \
|
| 9 |
+
imagemagick \
|
| 10 |
+
webp && \
|
| 11 |
+
apt-get clean && \
|
| 12 |
+
rm -rf /var/lib/apt/lists/*
|
| 13 |
+
|
| 14 |
+
# Menetapkan direktori kerja
|
| 15 |
+
WORKDIR /app
|
| 16 |
+
|
| 17 |
+
# Membuat direktori sessions
|
| 18 |
+
RUN mkdir -p /app/sessions
|
| 19 |
+
|
| 20 |
+
# Menyalin file package.json dan package-lock.json
|
| 21 |
+
COPY package.json ./
|
| 22 |
+
|
| 23 |
+
# Menginstal dependensi Node.js
|
| 24 |
+
RUN npm install
|
| 25 |
+
|
| 26 |
+
# Menyalin semua file aplikasi ke dalam container
|
| 27 |
+
COPY . .
|
| 28 |
+
|
| 29 |
+
# Mengubah kepemilikan direktori /app
|
| 30 |
+
RUN chown -R node:node /app
|
| 31 |
+
|
| 32 |
+
# Beralih ke pengguna non-root
|
| 33 |
+
USER node
|
| 34 |
+
|
| 35 |
+
# Mengekspos port 7860
|
| 36 |
+
EXPOSE 7860
|
| 37 |
+
|
| 38 |
+
# Menjalankan aplikasi
|
| 39 |
+
CMD ["npm", "start"]
|
Procfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
worker: node index.js --autocleartmp --autoread
|
README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
-
sdk:
|
| 7 |
-
sdk_version: 5.8.0
|
| 8 |
-
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
| 12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
---
|
| 2 |
+
title: veila
|
| 3 |
+
emoji: 😻
|
| 4 |
+
colorFrom: red
|
| 5 |
+
colorTo: indigo
|
| 6 |
+
sdk: docker
|
|
|
|
|
|
|
| 7 |
pinned: false
|
| 8 |
---
|
| 9 |
|
| 10 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
config.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
global.owner = ['6285878836361']
|
| 2 |
+
global.mods = ['6285878836361']
|
| 3 |
+
global.prems = ['6285878836361']
|
| 4 |
+
global.nameowner = 'rizki'
|
| 5 |
+
global.numberowner = '6285878836361'
|
| 6 |
+
global.mail = 'irfanwibu88@gmail.com'
|
| 7 |
+
global.gc = 'https://chat.whatsapp.com/KIcqnzY4NJMHXPTz8Xopvd'
|
| 8 |
+
global.instagram = 'https://instagram.com/ikykunnnn'
|
| 9 |
+
global.wm = '© ikyyBot Whatsapp Multi device'
|
| 10 |
+
global.wait = '_*Tunggu sedang di proses...*_'
|
| 11 |
+
global.eror = '_*Server Error*_'
|
| 12 |
+
global.stiker_wait = '*⫹⫺ Stiker sedang dibuat...*'
|
| 13 |
+
global.packname = 'Made With'
|
| 14 |
+
global.author = 'Bot WhatsApp'
|
| 15 |
+
global.autobio = true // Set true untuk mengaktifkan autobio
|
| 16 |
+
global.maxwarn = '3' // Peringatan maksimum
|
| 17 |
+
global.antiporn = true // Auto delete pesan porno (bot harus admin)
|
| 18 |
+
|
| 19 |
+
//INI WAJIB DI ISI!//
|
| 20 |
+
global.btc = 'BohqrvbJ'
|
| 21 |
+
//Daftar terlebih dahulu https://api.botcahx.eu.org
|
| 22 |
+
|
| 23 |
+
//INI OPTIONAL BOLEH DI ISI BOLEH JUGA ENGGA//
|
| 24 |
+
global.lann = 'YOUR_APIKEY_HERE'
|
| 25 |
+
//Daftar https://api.betabotz.eu.org
|
| 26 |
+
|
| 27 |
+
//jangan diganti!
|
| 28 |
+
global.APIs = {
|
| 29 |
+
btc: 'https://api.botcahx.eu.org'
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
//ini tidak di isi juga tidak apa-apa
|
| 33 |
+
global.APIKeys = {
|
| 34 |
+
'https://api.botcahx.eu.org': 'BohqrvbJ'
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
let fs = require('fs')
|
| 38 |
+
let chalk = require('chalk')
|
| 39 |
+
let file = require.resolve(__filename)
|
| 40 |
+
fs.watchFile(file, () => {
|
| 41 |
+
fs.unwatchFile(file)
|
| 42 |
+
console.log(chalk.redBright("Update 'config.js'"))
|
| 43 |
+
delete require.cache[file]
|
| 44 |
+
require(file)
|
| 45 |
+
})
|
database.json
ADDED
|
@@ -0,0 +1,1734 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"users": {
|
| 3 |
+
"6285878836361@s.whatsapp.net": {
|
| 4 |
+
"taxi": 0,
|
| 5 |
+
"lasttaxi": 0,
|
| 6 |
+
"lastyoutuber": 0,
|
| 7 |
+
"subscribers": 0,
|
| 8 |
+
"viewers": 0,
|
| 9 |
+
"like": 0,
|
| 10 |
+
"playButton": 0,
|
| 11 |
+
"saldo": 0,
|
| 12 |
+
"pengeluaran": 0,
|
| 13 |
+
"healt": 100,
|
| 14 |
+
"health": 100,
|
| 15 |
+
"energi": 100,
|
| 16 |
+
"power": 100,
|
| 17 |
+
"title": 0,
|
| 18 |
+
"haus": 100,
|
| 19 |
+
"laper": 100,
|
| 20 |
+
"tprem": 0,
|
| 21 |
+
"stamina": 100,
|
| 22 |
+
"level": 0,
|
| 23 |
+
"follow": 0,
|
| 24 |
+
"lastfollow": 0,
|
| 25 |
+
"followers": 0,
|
| 26 |
+
"pasangan": "",
|
| 27 |
+
"sahabat": "",
|
| 28 |
+
"location": "Gubuk",
|
| 29 |
+
"titlein": "Belum Ada",
|
| 30 |
+
"ultah": "",
|
| 31 |
+
"waifu": "Belum Di Set",
|
| 32 |
+
"husbu": "Belum Di Set",
|
| 33 |
+
"pc": 0,
|
| 34 |
+
"exp": 116,
|
| 35 |
+
"coin": 0,
|
| 36 |
+
"atm": 0,
|
| 37 |
+
"limit": 100,
|
| 38 |
+
"skata": 0,
|
| 39 |
+
"tigame": 999,
|
| 40 |
+
"lastclaim": 0,
|
| 41 |
+
"judilast": 0,
|
| 42 |
+
"lastnambang": 0,
|
| 43 |
+
"lastnebang": 0,
|
| 44 |
+
"lastmulung": 0,
|
| 45 |
+
"lastkerja": 0,
|
| 46 |
+
"lastmaling": 0,
|
| 47 |
+
"lastbunuhi": 0,
|
| 48 |
+
"lastbisnis": 0,
|
| 49 |
+
"lastberbisnis": 0,
|
| 50 |
+
"bisnis": 0,
|
| 51 |
+
"berbisnis": 0,
|
| 52 |
+
"lastmancing": 0,
|
| 53 |
+
"pancing": 0,
|
| 54 |
+
"pancingan": 0,
|
| 55 |
+
"totalPancingan": 0,
|
| 56 |
+
"kardus": 0,
|
| 57 |
+
"botol": 0,
|
| 58 |
+
"kaleng": 0,
|
| 59 |
+
"money": 0,
|
| 60 |
+
"litecoin": 0,
|
| 61 |
+
"chip": 0,
|
| 62 |
+
"tiketcoin": 0,
|
| 63 |
+
"poin": 0,
|
| 64 |
+
"bank": 0,
|
| 65 |
+
"balance": 0,
|
| 66 |
+
"diamond": 0,
|
| 67 |
+
"emerald": 0,
|
| 68 |
+
"rock": 0,
|
| 69 |
+
"wood": 0,
|
| 70 |
+
"berlian": 0,
|
| 71 |
+
"iron": 0,
|
| 72 |
+
"emas": 0,
|
| 73 |
+
"common": 0,
|
| 74 |
+
"uncommon": 0,
|
| 75 |
+
"mythic": 0,
|
| 76 |
+
"legendary": 0,
|
| 77 |
+
"rumahsakit": 0,
|
| 78 |
+
"tambang": 0,
|
| 79 |
+
"camptroops": 0,
|
| 80 |
+
"pertanian": 0,
|
| 81 |
+
"fortress": 0,
|
| 82 |
+
"trofi": 0,
|
| 83 |
+
"rtrofi": "perunggu",
|
| 84 |
+
"makanan": 0,
|
| 85 |
+
"troopcamp": 0,
|
| 86 |
+
"shield": 0,
|
| 87 |
+
"arlok": 0,
|
| 88 |
+
"ojekk": 0,
|
| 89 |
+
"ojek": 0,
|
| 90 |
+
"lastngewe": 0,
|
| 91 |
+
"ngewe": 0,
|
| 92 |
+
"polisi": 0,
|
| 93 |
+
"pedagang": 0,
|
| 94 |
+
"dokter": 0,
|
| 95 |
+
"petani": 0,
|
| 96 |
+
"montir": 0,
|
| 97 |
+
"kuli": 0,
|
| 98 |
+
"korbanngocok": 0,
|
| 99 |
+
"coal": 0,
|
| 100 |
+
"korekapi": 0,
|
| 101 |
+
"ayambakar": 0,
|
| 102 |
+
"gulai": 0,
|
| 103 |
+
"rendang": 0,
|
| 104 |
+
"ayamgoreng": 0,
|
| 105 |
+
"oporayam": 0,
|
| 106 |
+
"steak": 0,
|
| 107 |
+
"babipanggang": 0,
|
| 108 |
+
"ikanbakar": 0,
|
| 109 |
+
"lelebakar": 0,
|
| 110 |
+
"nilabakar": 0,
|
| 111 |
+
"bawalbakar": 0,
|
| 112 |
+
"udangbakar": 0,
|
| 113 |
+
"pausbakar": 0,
|
| 114 |
+
"kepitingbakar": 0,
|
| 115 |
+
"soda": 0,
|
| 116 |
+
"vodka": 0,
|
| 117 |
+
"ganja": 0,
|
| 118 |
+
"bandage": 0,
|
| 119 |
+
"sushi": 0,
|
| 120 |
+
"roti": 0,
|
| 121 |
+
"ramuan": 0,
|
| 122 |
+
"lastramuanclaim": 0,
|
| 123 |
+
"gems": 0,
|
| 124 |
+
"cupon": 0,
|
| 125 |
+
"lastgemsclaim": 0,
|
| 126 |
+
"eleksirb": 0,
|
| 127 |
+
"penduduk": 0,
|
| 128 |
+
"archer": 0,
|
| 129 |
+
"shadow": 0,
|
| 130 |
+
"laststringclaim": 0,
|
| 131 |
+
"lastpotionclaim": 0,
|
| 132 |
+
"lastswordclaim": 0,
|
| 133 |
+
"lastweaponclaim": 0,
|
| 134 |
+
"lastironclaim": 0,
|
| 135 |
+
"lastmancingclaim": 0,
|
| 136 |
+
"anakpancingan": 0,
|
| 137 |
+
"as": 0,
|
| 138 |
+
"paus": 0,
|
| 139 |
+
"kepiting": 0,
|
| 140 |
+
"gurita": 0,
|
| 141 |
+
"cumi": 0,
|
| 142 |
+
"buntal": 0,
|
| 143 |
+
"dory": 0,
|
| 144 |
+
"lumba": 0,
|
| 145 |
+
"lobster": 0,
|
| 146 |
+
"hiu": 0,
|
| 147 |
+
"lele": 0,
|
| 148 |
+
"nila": 0,
|
| 149 |
+
"bawal": 0,
|
| 150 |
+
"udang": 0,
|
| 151 |
+
"ikan": 0,
|
| 152 |
+
"orca": 0,
|
| 153 |
+
"banteng": 0,
|
| 154 |
+
"harimau": 0,
|
| 155 |
+
"gajah": 0,
|
| 156 |
+
"kambing": 0,
|
| 157 |
+
"panda": 0,
|
| 158 |
+
"buaya": 0,
|
| 159 |
+
"kerbau": 0,
|
| 160 |
+
"sapi": 0,
|
| 161 |
+
"monyet": 0,
|
| 162 |
+
"babihutan": 0,
|
| 163 |
+
"babi": 0,
|
| 164 |
+
"ayam": 0,
|
| 165 |
+
"apel": 20,
|
| 166 |
+
"ayamb": 0,
|
| 167 |
+
"ayamg": 0,
|
| 168 |
+
"ssapi": 0,
|
| 169 |
+
"sapir": 0,
|
| 170 |
+
"leleb": 0,
|
| 171 |
+
"leleg": 0,
|
| 172 |
+
"esteh": 0,
|
| 173 |
+
"pet": 0,
|
| 174 |
+
"potion": 0,
|
| 175 |
+
"sampah": 0,
|
| 176 |
+
"kucing": 0,
|
| 177 |
+
"kucinglastclaim": 0,
|
| 178 |
+
"kucingexp": 0,
|
| 179 |
+
"kuda": 0,
|
| 180 |
+
"kudalastclaim": 0,
|
| 181 |
+
"rubah": 0,
|
| 182 |
+
"rubahlastclaim": 0,
|
| 183 |
+
"rubahexp": 0,
|
| 184 |
+
"anjing": 0,
|
| 185 |
+
"anjinglastclaim": 0,
|
| 186 |
+
"anjingexp": 0,
|
| 187 |
+
"naga": 0,
|
| 188 |
+
"nagalastclaim": 0,
|
| 189 |
+
"griffin": 0,
|
| 190 |
+
"griffinlastclaim": 0,
|
| 191 |
+
"centaur": 0,
|
| 192 |
+
"fightnaga": 0,
|
| 193 |
+
"centaurlastclaim": 0,
|
| 194 |
+
"serigala": 0,
|
| 195 |
+
"serigalalastclaim": 0,
|
| 196 |
+
"serigalaexp": 0,
|
| 197 |
+
"phonix": 0,
|
| 198 |
+
"phonixlastclaim": 0,
|
| 199 |
+
"phonixexp": 0,
|
| 200 |
+
"makanannaga": 0,
|
| 201 |
+
"makananphonix": 0,
|
| 202 |
+
"makanancentaur": 0,
|
| 203 |
+
"makananserigala": 0,
|
| 204 |
+
"Banneduser": false,
|
| 205 |
+
"BannedReason": "",
|
| 206 |
+
"banned": false,
|
| 207 |
+
"bannedTime": 0,
|
| 208 |
+
"warn": 0,
|
| 209 |
+
"afk": -1,
|
| 210 |
+
"afkReason": "",
|
| 211 |
+
"anakkucing": 0,
|
| 212 |
+
"anakkuda": 0,
|
| 213 |
+
"anakrubah": 0,
|
| 214 |
+
"anakanjing": 0,
|
| 215 |
+
"makananpet": 0,
|
| 216 |
+
"makananPet": 0,
|
| 217 |
+
"antispam": 0,
|
| 218 |
+
"antispamlastclaim": 0,
|
| 219 |
+
"kayu": 0,
|
| 220 |
+
"batu": 0,
|
| 221 |
+
"string": 0,
|
| 222 |
+
"umpan": 0,
|
| 223 |
+
"armor": 0,
|
| 224 |
+
"armordurability": 0,
|
| 225 |
+
"weapon": 0,
|
| 226 |
+
"weapondurability": 0,
|
| 227 |
+
"sword": 0,
|
| 228 |
+
"sworddurability": 0,
|
| 229 |
+
"pickaxe": 0,
|
| 230 |
+
"pickaxedurability": 0,
|
| 231 |
+
"fishingrod": 0,
|
| 232 |
+
"fishingroddurability": 0,
|
| 233 |
+
"katana": 0,
|
| 234 |
+
"katanadurability": 0,
|
| 235 |
+
"bow": 0,
|
| 236 |
+
"bowdurability": 0,
|
| 237 |
+
"kapak": 0,
|
| 238 |
+
"kapakdurability": 0,
|
| 239 |
+
"axe": 0,
|
| 240 |
+
"axedurability": 0,
|
| 241 |
+
"pisau": 0,
|
| 242 |
+
"pisaudurability": 0,
|
| 243 |
+
"kerjasatu": 0,
|
| 244 |
+
"kerjadua": 0,
|
| 245 |
+
"kerjatiga": 0,
|
| 246 |
+
"kerjaempat": 0,
|
| 247 |
+
"kerjalima": 0,
|
| 248 |
+
"kerjaenam": 0,
|
| 249 |
+
"kerjatujuh": 0,
|
| 250 |
+
"kerjadelapan": 0,
|
| 251 |
+
"kerjasembilan": 0,
|
| 252 |
+
"kerjasepuluh": 0,
|
| 253 |
+
"kerjasebelas": 0,
|
| 254 |
+
"kerjaduabelas": 0,
|
| 255 |
+
"kerjatigabelas": 0,
|
| 256 |
+
"kerjaempatbelas": 0,
|
| 257 |
+
"kerjalimabelas": 0,
|
| 258 |
+
"pekerjaansatu": 0,
|
| 259 |
+
"pekerjaandua": 0,
|
| 260 |
+
"pekerjaantiga": 0,
|
| 261 |
+
"pekerjaanempat": 0,
|
| 262 |
+
"pekerjaanlima": 0,
|
| 263 |
+
"pekerjaanenam": 0,
|
| 264 |
+
"pekerjaantujuh": 0,
|
| 265 |
+
"pekerjaandelapan": 0,
|
| 266 |
+
"pekerjaansembilan": 0,
|
| 267 |
+
"pekerjaansepuluh": 0,
|
| 268 |
+
"pekerjaansebelas": 0,
|
| 269 |
+
"pekerjaanduabelas": 0,
|
| 270 |
+
"pekerjaantigabelas": 0,
|
| 271 |
+
"pekerjaanempatbelas": 0,
|
| 272 |
+
"pekerjaanlimabelas": 0,
|
| 273 |
+
"lastadventure": 0,
|
| 274 |
+
"lastwar": 0,
|
| 275 |
+
"lastberkebon": 0,
|
| 276 |
+
"lastberburu": 0,
|
| 277 |
+
"lastbansos": 0,
|
| 278 |
+
"lastrampok": 0,
|
| 279 |
+
"lastkill": 0,
|
| 280 |
+
"lastfishing": 0,
|
| 281 |
+
"lastdungeon": 0,
|
| 282 |
+
"lastduel": 0,
|
| 283 |
+
"lastmining": 0,
|
| 284 |
+
"lasthourly": 0,
|
| 285 |
+
"lastdagang": 0,
|
| 286 |
+
"lasthunt": 0,
|
| 287 |
+
"lasthun": 0,
|
| 288 |
+
"lastweekly": 0,
|
| 289 |
+
"lastmonthly": 0,
|
| 290 |
+
"lastyearly": 0,
|
| 291 |
+
"lastjb": 0,
|
| 292 |
+
"lastrob": 0,
|
| 293 |
+
"lastdaang": 0,
|
| 294 |
+
"lastngojek": 0,
|
| 295 |
+
"lastgrab": 0,
|
| 296 |
+
"lastngocok": 0,
|
| 297 |
+
"lastturu": 0,
|
| 298 |
+
"lastseen": 0,
|
| 299 |
+
"lastSetStatus": 0,
|
| 300 |
+
"registered": false,
|
| 301 |
+
"mangga": 0,
|
| 302 |
+
"stroberi": 0,
|
| 303 |
+
"semangka": 0,
|
| 304 |
+
"jeruk": 0,
|
| 305 |
+
"name": "+62 858-7883-6361",
|
| 306 |
+
"age": -1,
|
| 307 |
+
"regTime": -1,
|
| 308 |
+
"premiumDate": -1,
|
| 309 |
+
"premium": false,
|
| 310 |
+
"premiumTime": 0,
|
| 311 |
+
"vip": "tidak",
|
| 312 |
+
"vipPoin": 0,
|
| 313 |
+
"job": "Pengangguran",
|
| 314 |
+
"jobexp": 0,
|
| 315 |
+
"jail": false,
|
| 316 |
+
"penjara": false,
|
| 317 |
+
"antarpaket": 0,
|
| 318 |
+
"dirawat": false,
|
| 319 |
+
"lbars": "[▒▒▒▒▒▒▒▒▒]",
|
| 320 |
+
"role": "Newbie ㋡",
|
| 321 |
+
"autolevelup": true,
|
| 322 |
+
"lastIstigfar": 0,
|
| 323 |
+
"skill": "",
|
| 324 |
+
"korps": "",
|
| 325 |
+
"korpsgrade": "",
|
| 326 |
+
"demon": "",
|
| 327 |
+
"breaths": "",
|
| 328 |
+
"magic": "",
|
| 329 |
+
"darahiblis": 0,
|
| 330 |
+
"demonblood": 0,
|
| 331 |
+
"demonkill": 0,
|
| 332 |
+
"hashirakill": 0,
|
| 333 |
+
"alldemonkill": 0,
|
| 334 |
+
"allhashirakill": 0,
|
| 335 |
+
"attack": 0,
|
| 336 |
+
"speed": 0,
|
| 337 |
+
"strenght": 0,
|
| 338 |
+
"defense": 0,
|
| 339 |
+
"regeneration": 0,
|
| 340 |
+
"ovo": 0,
|
| 341 |
+
"dana": 0,
|
| 342 |
+
"gopay": 0,
|
| 343 |
+
"lastngaji": 0,
|
| 344 |
+
"lastlonte": 0,
|
| 345 |
+
"lastkoboy": 0,
|
| 346 |
+
"lastdate": 0,
|
| 347 |
+
"lasttambang": 0,
|
| 348 |
+
"lastngepet": 0,
|
| 349 |
+
"command": 2,
|
| 350 |
+
"commandTotal": 2,
|
| 351 |
+
"lastCmd": 1733916892180,
|
| 352 |
+
"glimit": 10,
|
| 353 |
+
"pertambangan": 0,
|
| 354 |
+
"lastbossbattle": 0,
|
| 355 |
+
"aqua": 0,
|
| 356 |
+
"glory": 0,
|
| 357 |
+
"enchant": 0,
|
| 358 |
+
"psepick": 0,
|
| 359 |
+
"psenjata": 0,
|
| 360 |
+
"lastgemclaim": 0,
|
| 361 |
+
"makanangriffin": 0,
|
| 362 |
+
"healthmonster": 0,
|
| 363 |
+
"anakserigala": 0,
|
| 364 |
+
"anaknaga": 0,
|
| 365 |
+
"anakphonix": 0,
|
| 366 |
+
"anakgriffin": 0,
|
| 367 |
+
"kyubi": 0,
|
| 368 |
+
"anakkyubi": 0,
|
| 369 |
+
"anakcentaur": 0,
|
| 370 |
+
"kingdom": false,
|
| 371 |
+
"lastsda": 0,
|
| 372 |
+
"lastberbru": 0,
|
| 373 |
+
"lastgift": 0,
|
| 374 |
+
"jualan": 0,
|
| 375 |
+
"lastjualan": 0,
|
| 376 |
+
"ngocokk": 0,
|
| 377 |
+
"lastngocokk": 0,
|
| 378 |
+
"lastcodereg": 0,
|
| 379 |
+
"anggur": 0,
|
| 380 |
+
"pisang": 0,
|
| 381 |
+
"bibitanggur": 0,
|
| 382 |
+
"bibitpisang": 0,
|
| 383 |
+
"bibitapel": 0,
|
| 384 |
+
"bibitmangga": 0,
|
| 385 |
+
"bibitjeruk": 0
|
| 386 |
+
},
|
| 387 |
+
"6283121935164@s.whatsapp.net": {
|
| 388 |
+
"taxi": 0,
|
| 389 |
+
"lasttaxi": 0,
|
| 390 |
+
"lastyoutuber": 0,
|
| 391 |
+
"subscribers": 0,
|
| 392 |
+
"viewers": 0,
|
| 393 |
+
"like": 0,
|
| 394 |
+
"playButton": 0,
|
| 395 |
+
"saldo": 0,
|
| 396 |
+
"pengeluaran": 0,
|
| 397 |
+
"healt": 100,
|
| 398 |
+
"health": 100,
|
| 399 |
+
"energi": 100,
|
| 400 |
+
"power": 100,
|
| 401 |
+
"title": 0,
|
| 402 |
+
"haus": 100,
|
| 403 |
+
"laper": 100,
|
| 404 |
+
"tprem": 0,
|
| 405 |
+
"stamina": 100,
|
| 406 |
+
"level": 0,
|
| 407 |
+
"follow": 0,
|
| 408 |
+
"lastfollow": 0,
|
| 409 |
+
"followers": 0,
|
| 410 |
+
"pasangan": "",
|
| 411 |
+
"sahabat": "",
|
| 412 |
+
"location": "Gubuk",
|
| 413 |
+
"titlein": "Belum Ada",
|
| 414 |
+
"ultah": "",
|
| 415 |
+
"waifu": "Belum Di Set",
|
| 416 |
+
"husbu": "Belum Di Set",
|
| 417 |
+
"pc": 0,
|
| 418 |
+
"exp": 0,
|
| 419 |
+
"coin": 0,
|
| 420 |
+
"atm": 0,
|
| 421 |
+
"limit": 100,
|
| 422 |
+
"skata": 0,
|
| 423 |
+
"tigame": 999,
|
| 424 |
+
"lastclaim": 0,
|
| 425 |
+
"judilast": 0,
|
| 426 |
+
"lastnambang": 0,
|
| 427 |
+
"lastnebang": 0,
|
| 428 |
+
"lastmulung": 0,
|
| 429 |
+
"lastkerja": 0,
|
| 430 |
+
"lastmaling": 0,
|
| 431 |
+
"lastbunuhi": 0,
|
| 432 |
+
"lastbisnis": 0,
|
| 433 |
+
"lastberbisnis": 0,
|
| 434 |
+
"bisnis": 0,
|
| 435 |
+
"berbisnis": 0,
|
| 436 |
+
"lastmancing": 0,
|
| 437 |
+
"pancing": 0,
|
| 438 |
+
"pancingan": 0,
|
| 439 |
+
"totalPancingan": 0,
|
| 440 |
+
"kardus": 0,
|
| 441 |
+
"botol": 0,
|
| 442 |
+
"kaleng": 0,
|
| 443 |
+
"money": 0,
|
| 444 |
+
"litecoin": 0,
|
| 445 |
+
"chip": 0,
|
| 446 |
+
"tiketcoin": 0,
|
| 447 |
+
"poin": 0,
|
| 448 |
+
"bank": 0,
|
| 449 |
+
"balance": 0,
|
| 450 |
+
"diamond": 0,
|
| 451 |
+
"emerald": 0,
|
| 452 |
+
"rock": 0,
|
| 453 |
+
"wood": 0,
|
| 454 |
+
"berlian": 0,
|
| 455 |
+
"iron": 0,
|
| 456 |
+
"emas": 0,
|
| 457 |
+
"common": 0,
|
| 458 |
+
"uncommon": 0,
|
| 459 |
+
"mythic": 0,
|
| 460 |
+
"legendary": 0,
|
| 461 |
+
"rumahsakit": 0,
|
| 462 |
+
"tambang": 0,
|
| 463 |
+
"camptroops": 0,
|
| 464 |
+
"pertanian": 0,
|
| 465 |
+
"fortress": 0,
|
| 466 |
+
"trofi": 0,
|
| 467 |
+
"rtrofi": "perunggu",
|
| 468 |
+
"makanan": 0,
|
| 469 |
+
"troopcamp": 0,
|
| 470 |
+
"shield": 0,
|
| 471 |
+
"arlok": 0,
|
| 472 |
+
"ojekk": 0,
|
| 473 |
+
"ojek": 0,
|
| 474 |
+
"lastngewe": 0,
|
| 475 |
+
"ngewe": 0,
|
| 476 |
+
"polisi": 0,
|
| 477 |
+
"pedagang": 0,
|
| 478 |
+
"dokter": 0,
|
| 479 |
+
"petani": 0,
|
| 480 |
+
"montir": 0,
|
| 481 |
+
"kuli": 0,
|
| 482 |
+
"korbanngocok": 0,
|
| 483 |
+
"coal": 0,
|
| 484 |
+
"korekapi": 0,
|
| 485 |
+
"ayambakar": 0,
|
| 486 |
+
"gulai": 0,
|
| 487 |
+
"rendang": 0,
|
| 488 |
+
"ayamgoreng": 0,
|
| 489 |
+
"oporayam": 0,
|
| 490 |
+
"steak": 0,
|
| 491 |
+
"babipanggang": 0,
|
| 492 |
+
"ikanbakar": 0,
|
| 493 |
+
"lelebakar": 0,
|
| 494 |
+
"nilabakar": 0,
|
| 495 |
+
"bawalbakar": 0,
|
| 496 |
+
"udangbakar": 0,
|
| 497 |
+
"pausbakar": 0,
|
| 498 |
+
"kepitingbakar": 0,
|
| 499 |
+
"soda": 0,
|
| 500 |
+
"vodka": 0,
|
| 501 |
+
"ganja": 0,
|
| 502 |
+
"bandage": 0,
|
| 503 |
+
"sushi": 0,
|
| 504 |
+
"roti": 0,
|
| 505 |
+
"ramuan": 0,
|
| 506 |
+
"lastramuanclaim": 0,
|
| 507 |
+
"gems": 0,
|
| 508 |
+
"cupon": 0,
|
| 509 |
+
"lastgemsclaim": 0,
|
| 510 |
+
"eleksirb": 0,
|
| 511 |
+
"penduduk": 0,
|
| 512 |
+
"archer": 0,
|
| 513 |
+
"shadow": 0,
|
| 514 |
+
"laststringclaim": 0,
|
| 515 |
+
"lastpotionclaim": 0,
|
| 516 |
+
"lastswordclaim": 0,
|
| 517 |
+
"lastweaponclaim": 0,
|
| 518 |
+
"lastironclaim": 0,
|
| 519 |
+
"lastmancingclaim": 0,
|
| 520 |
+
"anakpancingan": 0,
|
| 521 |
+
"as": 0,
|
| 522 |
+
"paus": 0,
|
| 523 |
+
"kepiting": 0,
|
| 524 |
+
"gurita": 0,
|
| 525 |
+
"cumi": 0,
|
| 526 |
+
"buntal": 0,
|
| 527 |
+
"dory": 0,
|
| 528 |
+
"lumba": 0,
|
| 529 |
+
"lobster": 0,
|
| 530 |
+
"hiu": 0,
|
| 531 |
+
"lele": 0,
|
| 532 |
+
"nila": 0,
|
| 533 |
+
"bawal": 0,
|
| 534 |
+
"udang": 0,
|
| 535 |
+
"ikan": 0,
|
| 536 |
+
"orca": 0,
|
| 537 |
+
"banteng": 0,
|
| 538 |
+
"harimau": 0,
|
| 539 |
+
"gajah": 0,
|
| 540 |
+
"kambing": 0,
|
| 541 |
+
"panda": 0,
|
| 542 |
+
"buaya": 0,
|
| 543 |
+
"kerbau": 0,
|
| 544 |
+
"sapi": 0,
|
| 545 |
+
"monyet": 0,
|
| 546 |
+
"babihutan": 0,
|
| 547 |
+
"babi": 0,
|
| 548 |
+
"ayam": 0,
|
| 549 |
+
"apel": 20,
|
| 550 |
+
"ayamb": 0,
|
| 551 |
+
"ayamg": 0,
|
| 552 |
+
"ssapi": 0,
|
| 553 |
+
"sapir": 0,
|
| 554 |
+
"leleb": 0,
|
| 555 |
+
"leleg": 0,
|
| 556 |
+
"esteh": 0,
|
| 557 |
+
"pet": 0,
|
| 558 |
+
"potion": 0,
|
| 559 |
+
"sampah": 0,
|
| 560 |
+
"kucing": 0,
|
| 561 |
+
"kucinglastclaim": 0,
|
| 562 |
+
"kucingexp": 0,
|
| 563 |
+
"kuda": 0,
|
| 564 |
+
"kudalastclaim": 0,
|
| 565 |
+
"rubah": 0,
|
| 566 |
+
"rubahlastclaim": 0,
|
| 567 |
+
"rubahexp": 0,
|
| 568 |
+
"anjing": 0,
|
| 569 |
+
"anjinglastclaim": 0,
|
| 570 |
+
"anjingexp": 0,
|
| 571 |
+
"naga": 0,
|
| 572 |
+
"nagalastclaim": 0,
|
| 573 |
+
"griffin": 0,
|
| 574 |
+
"griffinlastclaim": 0,
|
| 575 |
+
"centaur": 0,
|
| 576 |
+
"fightnaga": 0,
|
| 577 |
+
"centaurlastclaim": 0,
|
| 578 |
+
"serigala": 0,
|
| 579 |
+
"serigalalastclaim": 0,
|
| 580 |
+
"serigalaexp": 0,
|
| 581 |
+
"phonix": 0,
|
| 582 |
+
"phonixlastclaim": 0,
|
| 583 |
+
"phonixexp": 0,
|
| 584 |
+
"makanannaga": 0,
|
| 585 |
+
"makananphonix": 0,
|
| 586 |
+
"makanancentaur": 0,
|
| 587 |
+
"makananserigala": 0,
|
| 588 |
+
"Banneduser": false,
|
| 589 |
+
"BannedReason": "",
|
| 590 |
+
"banned": false,
|
| 591 |
+
"bannedTime": 0,
|
| 592 |
+
"warn": 0,
|
| 593 |
+
"afk": -1,
|
| 594 |
+
"afkReason": "",
|
| 595 |
+
"anakkucing": 0,
|
| 596 |
+
"anakkuda": 0,
|
| 597 |
+
"anakrubah": 0,
|
| 598 |
+
"anakanjing": 0,
|
| 599 |
+
"makananpet": 0,
|
| 600 |
+
"makananPet": 0,
|
| 601 |
+
"antispam": 0,
|
| 602 |
+
"antispamlastclaim": 0,
|
| 603 |
+
"kayu": 0,
|
| 604 |
+
"batu": 0,
|
| 605 |
+
"string": 0,
|
| 606 |
+
"umpan": 0,
|
| 607 |
+
"armor": 0,
|
| 608 |
+
"armordurability": 0,
|
| 609 |
+
"weapon": 0,
|
| 610 |
+
"weapondurability": 0,
|
| 611 |
+
"sword": 0,
|
| 612 |
+
"sworddurability": 0,
|
| 613 |
+
"pickaxe": 0,
|
| 614 |
+
"pickaxedurability": 0,
|
| 615 |
+
"fishingrod": 0,
|
| 616 |
+
"fishingroddurability": 0,
|
| 617 |
+
"katana": 0,
|
| 618 |
+
"katanadurability": 0,
|
| 619 |
+
"bow": 0,
|
| 620 |
+
"bowdurability": 0,
|
| 621 |
+
"kapak": 0,
|
| 622 |
+
"kapakdurability": 0,
|
| 623 |
+
"axe": 0,
|
| 624 |
+
"axedurability": 0,
|
| 625 |
+
"pisau": 0,
|
| 626 |
+
"pisaudurability": 0,
|
| 627 |
+
"kerjasatu": 0,
|
| 628 |
+
"kerjadua": 0,
|
| 629 |
+
"kerjatiga": 0,
|
| 630 |
+
"kerjaempat": 0,
|
| 631 |
+
"kerjalima": 0,
|
| 632 |
+
"kerjaenam": 0,
|
| 633 |
+
"kerjatujuh": 0,
|
| 634 |
+
"kerjadelapan": 0,
|
| 635 |
+
"kerjasembilan": 0,
|
| 636 |
+
"kerjasepuluh": 0,
|
| 637 |
+
"kerjasebelas": 0,
|
| 638 |
+
"kerjaduabelas": 0,
|
| 639 |
+
"kerjatigabelas": 0,
|
| 640 |
+
"kerjaempatbelas": 0,
|
| 641 |
+
"kerjalimabelas": 0,
|
| 642 |
+
"pekerjaansatu": 0,
|
| 643 |
+
"pekerjaandua": 0,
|
| 644 |
+
"pekerjaantiga": 0,
|
| 645 |
+
"pekerjaanempat": 0,
|
| 646 |
+
"pekerjaanlima": 0,
|
| 647 |
+
"pekerjaanenam": 0,
|
| 648 |
+
"pekerjaantujuh": 0,
|
| 649 |
+
"pekerjaandelapan": 0,
|
| 650 |
+
"pekerjaansembilan": 0,
|
| 651 |
+
"pekerjaansepuluh": 0,
|
| 652 |
+
"pekerjaansebelas": 0,
|
| 653 |
+
"pekerjaanduabelas": 0,
|
| 654 |
+
"pekerjaantigabelas": 0,
|
| 655 |
+
"pekerjaanempatbelas": 0,
|
| 656 |
+
"pekerjaanlimabelas": 0,
|
| 657 |
+
"lastadventure": 0,
|
| 658 |
+
"lastwar": 0,
|
| 659 |
+
"lastberkebon": 0,
|
| 660 |
+
"lastberburu": 0,
|
| 661 |
+
"lastbansos": 0,
|
| 662 |
+
"lastrampok": 0,
|
| 663 |
+
"lastkill": 0,
|
| 664 |
+
"lastfishing": 0,
|
| 665 |
+
"lastdungeon": 0,
|
| 666 |
+
"lastduel": 0,
|
| 667 |
+
"lastmining": 0,
|
| 668 |
+
"lasthourly": 0,
|
| 669 |
+
"lastdagang": 0,
|
| 670 |
+
"lasthunt": 0,
|
| 671 |
+
"lasthun": 0,
|
| 672 |
+
"lastweekly": 0,
|
| 673 |
+
"lastmonthly": 0,
|
| 674 |
+
"lastyearly": 0,
|
| 675 |
+
"lastjb": 0,
|
| 676 |
+
"lastrob": 0,
|
| 677 |
+
"lastdaang": 0,
|
| 678 |
+
"lastngojek": 0,
|
| 679 |
+
"lastgrab": 0,
|
| 680 |
+
"lastngocok": 0,
|
| 681 |
+
"lastturu": 0,
|
| 682 |
+
"lastseen": 0,
|
| 683 |
+
"lastSetStatus": 0,
|
| 684 |
+
"registered": false,
|
| 685 |
+
"mangga": 0,
|
| 686 |
+
"stroberi": 0,
|
| 687 |
+
"semangka": 0,
|
| 688 |
+
"jeruk": 0,
|
| 689 |
+
"name": "irfan",
|
| 690 |
+
"age": -1,
|
| 691 |
+
"regTime": -1,
|
| 692 |
+
"premiumDate": -1,
|
| 693 |
+
"premium": false,
|
| 694 |
+
"premiumTime": 0,
|
| 695 |
+
"vip": "tidak",
|
| 696 |
+
"vipPoin": 0,
|
| 697 |
+
"job": "Pengangguran",
|
| 698 |
+
"jobexp": 0,
|
| 699 |
+
"jail": false,
|
| 700 |
+
"penjara": false,
|
| 701 |
+
"antarpaket": 0,
|
| 702 |
+
"dirawat": false,
|
| 703 |
+
"lbars": "[▒▒▒▒▒▒▒▒▒]",
|
| 704 |
+
"role": "Newbie ㋡",
|
| 705 |
+
"autolevelup": true,
|
| 706 |
+
"lastIstigfar": 0,
|
| 707 |
+
"skill": "",
|
| 708 |
+
"korps": "",
|
| 709 |
+
"korpsgrade": "",
|
| 710 |
+
"demon": "",
|
| 711 |
+
"breaths": "",
|
| 712 |
+
"magic": "",
|
| 713 |
+
"darahiblis": 0,
|
| 714 |
+
"demonblood": 0,
|
| 715 |
+
"demonkill": 0,
|
| 716 |
+
"hashirakill": 0,
|
| 717 |
+
"alldemonkill": 0,
|
| 718 |
+
"allhashirakill": 0,
|
| 719 |
+
"attack": 0,
|
| 720 |
+
"speed": 0,
|
| 721 |
+
"strenght": 0,
|
| 722 |
+
"defense": 0,
|
| 723 |
+
"regeneration": 0,
|
| 724 |
+
"ovo": 0,
|
| 725 |
+
"dana": 0,
|
| 726 |
+
"gopay": 0,
|
| 727 |
+
"lastngaji": 0,
|
| 728 |
+
"lastlonte": 0,
|
| 729 |
+
"lastkoboy": 0,
|
| 730 |
+
"lastdate": 0,
|
| 731 |
+
"lasttambang": 0,
|
| 732 |
+
"lastngepet": 0,
|
| 733 |
+
"glimit": 10,
|
| 734 |
+
"pertambangan": 0,
|
| 735 |
+
"lastbossbattle": 0,
|
| 736 |
+
"aqua": 0,
|
| 737 |
+
"glory": 0,
|
| 738 |
+
"enchant": 0,
|
| 739 |
+
"psepick": 0,
|
| 740 |
+
"psenjata": 0,
|
| 741 |
+
"lastgemclaim": 0,
|
| 742 |
+
"makanangriffin": 0,
|
| 743 |
+
"healthmonster": 0,
|
| 744 |
+
"anakserigala": 0,
|
| 745 |
+
"anaknaga": 0,
|
| 746 |
+
"anakphonix": 0,
|
| 747 |
+
"anakgriffin": 0,
|
| 748 |
+
"kyubi": 0,
|
| 749 |
+
"anakkyubi": 0,
|
| 750 |
+
"anakcentaur": 0,
|
| 751 |
+
"kingdom": false,
|
| 752 |
+
"lastsda": 0,
|
| 753 |
+
"lastberbru": 0,
|
| 754 |
+
"lastgift": 0,
|
| 755 |
+
"jualan": 0,
|
| 756 |
+
"lastjualan": 0,
|
| 757 |
+
"ngocokk": 0,
|
| 758 |
+
"lastngocokk": 0,
|
| 759 |
+
"lastcodereg": 0,
|
| 760 |
+
"anggur": 0,
|
| 761 |
+
"pisang": 0,
|
| 762 |
+
"bibitanggur": 0,
|
| 763 |
+
"bibitpisang": 0,
|
| 764 |
+
"bibitapel": 0,
|
| 765 |
+
"bibitmangga": 0,
|
| 766 |
+
"bibitjeruk": 0
|
| 767 |
+
},
|
| 768 |
+
"6281212181641@s.whatsapp.net": {
|
| 769 |
+
"taxi": 0,
|
| 770 |
+
"lasttaxi": 0,
|
| 771 |
+
"lastyoutuber": 0,
|
| 772 |
+
"subscribers": 0,
|
| 773 |
+
"viewers": 0,
|
| 774 |
+
"like": 0,
|
| 775 |
+
"playButton": 0,
|
| 776 |
+
"saldo": 0,
|
| 777 |
+
"pengeluaran": 0,
|
| 778 |
+
"healt": 100,
|
| 779 |
+
"health": 100,
|
| 780 |
+
"energi": 100,
|
| 781 |
+
"power": 100,
|
| 782 |
+
"title": 0,
|
| 783 |
+
"haus": 100,
|
| 784 |
+
"laper": 100,
|
| 785 |
+
"tprem": 0,
|
| 786 |
+
"stamina": 100,
|
| 787 |
+
"level": 0,
|
| 788 |
+
"follow": 0,
|
| 789 |
+
"lastfollow": 0,
|
| 790 |
+
"followers": 0,
|
| 791 |
+
"pasangan": "",
|
| 792 |
+
"sahabat": "",
|
| 793 |
+
"location": "Gubuk",
|
| 794 |
+
"titlein": "Belum Ada",
|
| 795 |
+
"ultah": "",
|
| 796 |
+
"waifu": "Belum Di Set",
|
| 797 |
+
"husbu": "Belum Di Set",
|
| 798 |
+
"pc": 0,
|
| 799 |
+
"exp": 13,
|
| 800 |
+
"coin": 0,
|
| 801 |
+
"atm": 0,
|
| 802 |
+
"limit": 100,
|
| 803 |
+
"skata": 0,
|
| 804 |
+
"tigame": 999,
|
| 805 |
+
"lastclaim": 0,
|
| 806 |
+
"judilast": 0,
|
| 807 |
+
"lastnambang": 0,
|
| 808 |
+
"lastnebang": 0,
|
| 809 |
+
"lastmulung": 0,
|
| 810 |
+
"lastkerja": 0,
|
| 811 |
+
"lastmaling": 0,
|
| 812 |
+
"lastbunuhi": 0,
|
| 813 |
+
"lastbisnis": 0,
|
| 814 |
+
"lastberbisnis": 0,
|
| 815 |
+
"bisnis": 0,
|
| 816 |
+
"berbisnis": 0,
|
| 817 |
+
"lastmancing": 0,
|
| 818 |
+
"pancing": 0,
|
| 819 |
+
"pancingan": 0,
|
| 820 |
+
"totalPancingan": 0,
|
| 821 |
+
"kardus": 0,
|
| 822 |
+
"botol": 0,
|
| 823 |
+
"kaleng": 0,
|
| 824 |
+
"money": 0,
|
| 825 |
+
"litecoin": 0,
|
| 826 |
+
"chip": 0,
|
| 827 |
+
"tiketcoin": 0,
|
| 828 |
+
"poin": 0,
|
| 829 |
+
"bank": 0,
|
| 830 |
+
"balance": 0,
|
| 831 |
+
"diamond": 0,
|
| 832 |
+
"emerald": 0,
|
| 833 |
+
"rock": 0,
|
| 834 |
+
"wood": 0,
|
| 835 |
+
"berlian": 0,
|
| 836 |
+
"iron": 0,
|
| 837 |
+
"emas": 0,
|
| 838 |
+
"common": 0,
|
| 839 |
+
"uncommon": 0,
|
| 840 |
+
"mythic": 0,
|
| 841 |
+
"legendary": 0,
|
| 842 |
+
"rumahsakit": 0,
|
| 843 |
+
"tambang": 0,
|
| 844 |
+
"camptroops": 0,
|
| 845 |
+
"pertanian": 0,
|
| 846 |
+
"fortress": 0,
|
| 847 |
+
"trofi": 0,
|
| 848 |
+
"rtrofi": "perunggu",
|
| 849 |
+
"makanan": 0,
|
| 850 |
+
"troopcamp": 0,
|
| 851 |
+
"shield": 0,
|
| 852 |
+
"arlok": 0,
|
| 853 |
+
"ojekk": 0,
|
| 854 |
+
"ojek": 0,
|
| 855 |
+
"lastngewe": 0,
|
| 856 |
+
"ngewe": 0,
|
| 857 |
+
"polisi": 0,
|
| 858 |
+
"pedagang": 0,
|
| 859 |
+
"dokter": 0,
|
| 860 |
+
"petani": 0,
|
| 861 |
+
"montir": 0,
|
| 862 |
+
"kuli": 0,
|
| 863 |
+
"korbanngocok": 0,
|
| 864 |
+
"coal": 0,
|
| 865 |
+
"korekapi": 0,
|
| 866 |
+
"ayambakar": 0,
|
| 867 |
+
"gulai": 0,
|
| 868 |
+
"rendang": 0,
|
| 869 |
+
"ayamgoreng": 0,
|
| 870 |
+
"oporayam": 0,
|
| 871 |
+
"steak": 0,
|
| 872 |
+
"babipanggang": 0,
|
| 873 |
+
"ikanbakar": 0,
|
| 874 |
+
"lelebakar": 0,
|
| 875 |
+
"nilabakar": 0,
|
| 876 |
+
"bawalbakar": 0,
|
| 877 |
+
"udangbakar": 0,
|
| 878 |
+
"pausbakar": 0,
|
| 879 |
+
"kepitingbakar": 0,
|
| 880 |
+
"soda": 0,
|
| 881 |
+
"vodka": 0,
|
| 882 |
+
"ganja": 0,
|
| 883 |
+
"bandage": 0,
|
| 884 |
+
"sushi": 0,
|
| 885 |
+
"roti": 0,
|
| 886 |
+
"ramuan": 0,
|
| 887 |
+
"lastramuanclaim": 0,
|
| 888 |
+
"gems": 0,
|
| 889 |
+
"cupon": 0,
|
| 890 |
+
"lastgemsclaim": 0,
|
| 891 |
+
"eleksirb": 0,
|
| 892 |
+
"penduduk": 0,
|
| 893 |
+
"archer": 0,
|
| 894 |
+
"shadow": 0,
|
| 895 |
+
"laststringclaim": 0,
|
| 896 |
+
"lastpotionclaim": 0,
|
| 897 |
+
"lastswordclaim": 0,
|
| 898 |
+
"lastweaponclaim": 0,
|
| 899 |
+
"lastironclaim": 0,
|
| 900 |
+
"lastmancingclaim": 0,
|
| 901 |
+
"anakpancingan": 0,
|
| 902 |
+
"as": 0,
|
| 903 |
+
"paus": 0,
|
| 904 |
+
"kepiting": 0,
|
| 905 |
+
"gurita": 0,
|
| 906 |
+
"cumi": 0,
|
| 907 |
+
"buntal": 0,
|
| 908 |
+
"dory": 0,
|
| 909 |
+
"lumba": 0,
|
| 910 |
+
"lobster": 0,
|
| 911 |
+
"hiu": 0,
|
| 912 |
+
"lele": 0,
|
| 913 |
+
"nila": 0,
|
| 914 |
+
"bawal": 0,
|
| 915 |
+
"udang": 0,
|
| 916 |
+
"ikan": 0,
|
| 917 |
+
"orca": 0,
|
| 918 |
+
"banteng": 0,
|
| 919 |
+
"harimau": 0,
|
| 920 |
+
"gajah": 0,
|
| 921 |
+
"kambing": 0,
|
| 922 |
+
"panda": 0,
|
| 923 |
+
"buaya": 0,
|
| 924 |
+
"kerbau": 0,
|
| 925 |
+
"sapi": 0,
|
| 926 |
+
"monyet": 0,
|
| 927 |
+
"babihutan": 0,
|
| 928 |
+
"babi": 0,
|
| 929 |
+
"ayam": 0,
|
| 930 |
+
"apel": 20,
|
| 931 |
+
"ayamb": 0,
|
| 932 |
+
"ayamg": 0,
|
| 933 |
+
"ssapi": 0,
|
| 934 |
+
"sapir": 0,
|
| 935 |
+
"leleb": 0,
|
| 936 |
+
"leleg": 0,
|
| 937 |
+
"esteh": 0,
|
| 938 |
+
"pet": 0,
|
| 939 |
+
"potion": 0,
|
| 940 |
+
"sampah": 0,
|
| 941 |
+
"kucing": 0,
|
| 942 |
+
"kucinglastclaim": 0,
|
| 943 |
+
"kucingexp": 0,
|
| 944 |
+
"kuda": 0,
|
| 945 |
+
"kudalastclaim": 0,
|
| 946 |
+
"rubah": 0,
|
| 947 |
+
"rubahlastclaim": 0,
|
| 948 |
+
"rubahexp": 0,
|
| 949 |
+
"anjing": 0,
|
| 950 |
+
"anjinglastclaim": 0,
|
| 951 |
+
"anjingexp": 0,
|
| 952 |
+
"naga": 0,
|
| 953 |
+
"nagalastclaim": 0,
|
| 954 |
+
"griffin": 0,
|
| 955 |
+
"griffinlastclaim": 0,
|
| 956 |
+
"centaur": 0,
|
| 957 |
+
"fightnaga": 0,
|
| 958 |
+
"centaurlastclaim": 0,
|
| 959 |
+
"serigala": 0,
|
| 960 |
+
"serigalalastclaim": 0,
|
| 961 |
+
"serigalaexp": 0,
|
| 962 |
+
"phonix": 0,
|
| 963 |
+
"phonixlastclaim": 0,
|
| 964 |
+
"phonixexp": 0,
|
| 965 |
+
"makanannaga": 0,
|
| 966 |
+
"makananphonix": 0,
|
| 967 |
+
"makanancentaur": 0,
|
| 968 |
+
"makananserigala": 0,
|
| 969 |
+
"Banneduser": false,
|
| 970 |
+
"BannedReason": "",
|
| 971 |
+
"banned": false,
|
| 972 |
+
"bannedTime": 0,
|
| 973 |
+
"warn": 0,
|
| 974 |
+
"afk": -1,
|
| 975 |
+
"afkReason": "",
|
| 976 |
+
"anakkucing": 0,
|
| 977 |
+
"anakkuda": 0,
|
| 978 |
+
"anakrubah": 0,
|
| 979 |
+
"anakanjing": 0,
|
| 980 |
+
"makananpet": 0,
|
| 981 |
+
"makananPet": 0,
|
| 982 |
+
"antispam": 0,
|
| 983 |
+
"antispamlastclaim": 0,
|
| 984 |
+
"kayu": 0,
|
| 985 |
+
"batu": 0,
|
| 986 |
+
"string": 0,
|
| 987 |
+
"umpan": 0,
|
| 988 |
+
"armor": 0,
|
| 989 |
+
"armordurability": 0,
|
| 990 |
+
"weapon": 0,
|
| 991 |
+
"weapondurability": 0,
|
| 992 |
+
"sword": 0,
|
| 993 |
+
"sworddurability": 0,
|
| 994 |
+
"pickaxe": 0,
|
| 995 |
+
"pickaxedurability": 0,
|
| 996 |
+
"fishingrod": 0,
|
| 997 |
+
"fishingroddurability": 0,
|
| 998 |
+
"katana": 0,
|
| 999 |
+
"katanadurability": 0,
|
| 1000 |
+
"bow": 0,
|
| 1001 |
+
"bowdurability": 0,
|
| 1002 |
+
"kapak": 0,
|
| 1003 |
+
"kapakdurability": 0,
|
| 1004 |
+
"axe": 0,
|
| 1005 |
+
"axedurability": 0,
|
| 1006 |
+
"pisau": 0,
|
| 1007 |
+
"pisaudurability": 0,
|
| 1008 |
+
"kerjasatu": 0,
|
| 1009 |
+
"kerjadua": 0,
|
| 1010 |
+
"kerjatiga": 0,
|
| 1011 |
+
"kerjaempat": 0,
|
| 1012 |
+
"kerjalima": 0,
|
| 1013 |
+
"kerjaenam": 0,
|
| 1014 |
+
"kerjatujuh": 0,
|
| 1015 |
+
"kerjadelapan": 0,
|
| 1016 |
+
"kerjasembilan": 0,
|
| 1017 |
+
"kerjasepuluh": 0,
|
| 1018 |
+
"kerjasebelas": 0,
|
| 1019 |
+
"kerjaduabelas": 0,
|
| 1020 |
+
"kerjatigabelas": 0,
|
| 1021 |
+
"kerjaempatbelas": 0,
|
| 1022 |
+
"kerjalimabelas": 0,
|
| 1023 |
+
"pekerjaansatu": 0,
|
| 1024 |
+
"pekerjaandua": 0,
|
| 1025 |
+
"pekerjaantiga": 0,
|
| 1026 |
+
"pekerjaanempat": 0,
|
| 1027 |
+
"pekerjaanlima": 0,
|
| 1028 |
+
"pekerjaanenam": 0,
|
| 1029 |
+
"pekerjaantujuh": 0,
|
| 1030 |
+
"pekerjaandelapan": 0,
|
| 1031 |
+
"pekerjaansembilan": 0,
|
| 1032 |
+
"pekerjaansepuluh": 0,
|
| 1033 |
+
"pekerjaansebelas": 0,
|
| 1034 |
+
"pekerjaanduabelas": 0,
|
| 1035 |
+
"pekerjaantigabelas": 0,
|
| 1036 |
+
"pekerjaanempatbelas": 0,
|
| 1037 |
+
"pekerjaanlimabelas": 0,
|
| 1038 |
+
"lastadventure": 0,
|
| 1039 |
+
"lastwar": 0,
|
| 1040 |
+
"lastberkebon": 0,
|
| 1041 |
+
"lastberburu": 0,
|
| 1042 |
+
"lastbansos": 0,
|
| 1043 |
+
"lastrampok": 0,
|
| 1044 |
+
"lastkill": 0,
|
| 1045 |
+
"lastfishing": 0,
|
| 1046 |
+
"lastdungeon": 0,
|
| 1047 |
+
"lastduel": 0,
|
| 1048 |
+
"lastmining": 0,
|
| 1049 |
+
"lasthourly": 0,
|
| 1050 |
+
"lastdagang": 0,
|
| 1051 |
+
"lasthunt": 0,
|
| 1052 |
+
"lasthun": 0,
|
| 1053 |
+
"lastweekly": 0,
|
| 1054 |
+
"lastmonthly": 0,
|
| 1055 |
+
"lastyearly": 0,
|
| 1056 |
+
"lastjb": 0,
|
| 1057 |
+
"lastrob": 0,
|
| 1058 |
+
"lastdaang": 0,
|
| 1059 |
+
"lastngojek": 0,
|
| 1060 |
+
"lastgrab": 0,
|
| 1061 |
+
"lastngocok": 0,
|
| 1062 |
+
"lastturu": 0,
|
| 1063 |
+
"lastseen": 0,
|
| 1064 |
+
"lastSetStatus": 0,
|
| 1065 |
+
"registered": false,
|
| 1066 |
+
"mangga": 0,
|
| 1067 |
+
"stroberi": 0,
|
| 1068 |
+
"semangka": 0,
|
| 1069 |
+
"jeruk": 0,
|
| 1070 |
+
"name": "IKYBOT AUTOAI",
|
| 1071 |
+
"age": -1,
|
| 1072 |
+
"regTime": -1,
|
| 1073 |
+
"premiumDate": -1,
|
| 1074 |
+
"premium": false,
|
| 1075 |
+
"premiumTime": 0,
|
| 1076 |
+
"vip": "tidak",
|
| 1077 |
+
"vipPoin": 0,
|
| 1078 |
+
"job": "Pengangguran",
|
| 1079 |
+
"jobexp": 0,
|
| 1080 |
+
"jail": false,
|
| 1081 |
+
"penjara": false,
|
| 1082 |
+
"antarpaket": 0,
|
| 1083 |
+
"dirawat": false,
|
| 1084 |
+
"lbars": "[▒▒▒▒▒▒▒▒▒]",
|
| 1085 |
+
"role": "Newbie ㋡",
|
| 1086 |
+
"autolevelup": true,
|
| 1087 |
+
"lastIstigfar": 0,
|
| 1088 |
+
"skill": "",
|
| 1089 |
+
"korps": "",
|
| 1090 |
+
"korpsgrade": "",
|
| 1091 |
+
"demon": "",
|
| 1092 |
+
"breaths": "",
|
| 1093 |
+
"magic": "",
|
| 1094 |
+
"darahiblis": 0,
|
| 1095 |
+
"demonblood": 0,
|
| 1096 |
+
"demonkill": 0,
|
| 1097 |
+
"hashirakill": 0,
|
| 1098 |
+
"alldemonkill": 0,
|
| 1099 |
+
"allhashirakill": 0,
|
| 1100 |
+
"attack": 0,
|
| 1101 |
+
"speed": 0,
|
| 1102 |
+
"strenght": 0,
|
| 1103 |
+
"defense": 0,
|
| 1104 |
+
"regeneration": 0,
|
| 1105 |
+
"ovo": 0,
|
| 1106 |
+
"dana": 0,
|
| 1107 |
+
"gopay": 0,
|
| 1108 |
+
"lastngaji": 0,
|
| 1109 |
+
"lastlonte": 0,
|
| 1110 |
+
"lastkoboy": 0,
|
| 1111 |
+
"lastdate": 0,
|
| 1112 |
+
"lasttambang": 0,
|
| 1113 |
+
"lastngepet": 0,
|
| 1114 |
+
"glimit": 10,
|
| 1115 |
+
"pertambangan": 0,
|
| 1116 |
+
"lastbossbattle": 0,
|
| 1117 |
+
"aqua": 0,
|
| 1118 |
+
"glory": 0,
|
| 1119 |
+
"enchant": 0,
|
| 1120 |
+
"psepick": 0,
|
| 1121 |
+
"psenjata": 0,
|
| 1122 |
+
"lastgemclaim": 0,
|
| 1123 |
+
"makanangriffin": 0,
|
| 1124 |
+
"healthmonster": 0,
|
| 1125 |
+
"anakserigala": 0,
|
| 1126 |
+
"anaknaga": 0,
|
| 1127 |
+
"anakphonix": 0,
|
| 1128 |
+
"anakgriffin": 0,
|
| 1129 |
+
"kyubi": 0,
|
| 1130 |
+
"anakkyubi": 0,
|
| 1131 |
+
"anakcentaur": 0,
|
| 1132 |
+
"kingdom": false,
|
| 1133 |
+
"lastsda": 0,
|
| 1134 |
+
"lastberbru": 0,
|
| 1135 |
+
"lastgift": 0,
|
| 1136 |
+
"jualan": 0,
|
| 1137 |
+
"lastjualan": 0,
|
| 1138 |
+
"ngocokk": 0,
|
| 1139 |
+
"lastngocokk": 0,
|
| 1140 |
+
"lastcodereg": 0,
|
| 1141 |
+
"anggur": 0,
|
| 1142 |
+
"pisang": 0,
|
| 1143 |
+
"bibitanggur": 0,
|
| 1144 |
+
"bibitpisang": 0,
|
| 1145 |
+
"bibitapel": 0,
|
| 1146 |
+
"bibitmangga": 0,
|
| 1147 |
+
"bibitjeruk": 0
|
| 1148 |
+
},
|
| 1149 |
+
"6287821561429@s.whatsapp.net": {
|
| 1150 |
+
"taxi": 0,
|
| 1151 |
+
"lasttaxi": 0,
|
| 1152 |
+
"lastyoutuber": 0,
|
| 1153 |
+
"subscribers": 0,
|
| 1154 |
+
"viewers": 0,
|
| 1155 |
+
"like": 0,
|
| 1156 |
+
"playButton": 0,
|
| 1157 |
+
"saldo": 0,
|
| 1158 |
+
"pengeluaran": 0,
|
| 1159 |
+
"healt": 100,
|
| 1160 |
+
"health": 100,
|
| 1161 |
+
"energi": 100,
|
| 1162 |
+
"power": 100,
|
| 1163 |
+
"title": 0,
|
| 1164 |
+
"haus": 100,
|
| 1165 |
+
"laper": 100,
|
| 1166 |
+
"tprem": 0,
|
| 1167 |
+
"stamina": 100,
|
| 1168 |
+
"level": 0,
|
| 1169 |
+
"follow": 0,
|
| 1170 |
+
"lastfollow": 0,
|
| 1171 |
+
"followers": 0,
|
| 1172 |
+
"pasangan": "",
|
| 1173 |
+
"sahabat": "",
|
| 1174 |
+
"location": "Gubuk",
|
| 1175 |
+
"titlein": "Belum Ada",
|
| 1176 |
+
"ultah": "",
|
| 1177 |
+
"waifu": "Belum Di Set",
|
| 1178 |
+
"husbu": "Belum Di Set",
|
| 1179 |
+
"pc": 0,
|
| 1180 |
+
"exp": 18,
|
| 1181 |
+
"coin": 0,
|
| 1182 |
+
"atm": 0,
|
| 1183 |
+
"limit": 100,
|
| 1184 |
+
"skata": 0,
|
| 1185 |
+
"tigame": 999,
|
| 1186 |
+
"lastclaim": 0,
|
| 1187 |
+
"judilast": 0,
|
| 1188 |
+
"lastnambang": 0,
|
| 1189 |
+
"lastnebang": 0,
|
| 1190 |
+
"lastmulung": 0,
|
| 1191 |
+
"lastkerja": 0,
|
| 1192 |
+
"lastmaling": 0,
|
| 1193 |
+
"lastbunuhi": 0,
|
| 1194 |
+
"lastbisnis": 0,
|
| 1195 |
+
"lastberbisnis": 0,
|
| 1196 |
+
"bisnis": 0,
|
| 1197 |
+
"berbisnis": 0,
|
| 1198 |
+
"lastmancing": 0,
|
| 1199 |
+
"pancing": 0,
|
| 1200 |
+
"pancingan": 0,
|
| 1201 |
+
"totalPancingan": 0,
|
| 1202 |
+
"kardus": 0,
|
| 1203 |
+
"botol": 0,
|
| 1204 |
+
"kaleng": 0,
|
| 1205 |
+
"money": 0,
|
| 1206 |
+
"litecoin": 0,
|
| 1207 |
+
"chip": 0,
|
| 1208 |
+
"tiketcoin": 0,
|
| 1209 |
+
"poin": 0,
|
| 1210 |
+
"bank": 0,
|
| 1211 |
+
"balance": 0,
|
| 1212 |
+
"diamond": 0,
|
| 1213 |
+
"emerald": 0,
|
| 1214 |
+
"rock": 0,
|
| 1215 |
+
"wood": 0,
|
| 1216 |
+
"berlian": 0,
|
| 1217 |
+
"iron": 0,
|
| 1218 |
+
"emas": 0,
|
| 1219 |
+
"common": 0,
|
| 1220 |
+
"uncommon": 0,
|
| 1221 |
+
"mythic": 0,
|
| 1222 |
+
"legendary": 0,
|
| 1223 |
+
"rumahsakit": 0,
|
| 1224 |
+
"tambang": 0,
|
| 1225 |
+
"camptroops": 0,
|
| 1226 |
+
"pertanian": 0,
|
| 1227 |
+
"fortress": 0,
|
| 1228 |
+
"trofi": 0,
|
| 1229 |
+
"rtrofi": "perunggu",
|
| 1230 |
+
"makanan": 0,
|
| 1231 |
+
"troopcamp": 0,
|
| 1232 |
+
"shield": 0,
|
| 1233 |
+
"arlok": 0,
|
| 1234 |
+
"ojekk": 0,
|
| 1235 |
+
"ojek": 0,
|
| 1236 |
+
"lastngewe": 0,
|
| 1237 |
+
"ngewe": 0,
|
| 1238 |
+
"polisi": 0,
|
| 1239 |
+
"pedagang": 0,
|
| 1240 |
+
"dokter": 0,
|
| 1241 |
+
"petani": 0,
|
| 1242 |
+
"montir": 0,
|
| 1243 |
+
"kuli": 0,
|
| 1244 |
+
"korbanngocok": 0,
|
| 1245 |
+
"coal": 0,
|
| 1246 |
+
"korekapi": 0,
|
| 1247 |
+
"ayambakar": 0,
|
| 1248 |
+
"gulai": 0,
|
| 1249 |
+
"rendang": 0,
|
| 1250 |
+
"ayamgoreng": 0,
|
| 1251 |
+
"oporayam": 0,
|
| 1252 |
+
"steak": 0,
|
| 1253 |
+
"babipanggang": 0,
|
| 1254 |
+
"ikanbakar": 0,
|
| 1255 |
+
"lelebakar": 0,
|
| 1256 |
+
"nilabakar": 0,
|
| 1257 |
+
"bawalbakar": 0,
|
| 1258 |
+
"udangbakar": 0,
|
| 1259 |
+
"pausbakar": 0,
|
| 1260 |
+
"kepitingbakar": 0,
|
| 1261 |
+
"soda": 0,
|
| 1262 |
+
"vodka": 0,
|
| 1263 |
+
"ganja": 0,
|
| 1264 |
+
"bandage": 0,
|
| 1265 |
+
"sushi": 0,
|
| 1266 |
+
"roti": 0,
|
| 1267 |
+
"ramuan": 0,
|
| 1268 |
+
"lastramuanclaim": 0,
|
| 1269 |
+
"gems": 0,
|
| 1270 |
+
"cupon": 0,
|
| 1271 |
+
"lastgemsclaim": 0,
|
| 1272 |
+
"eleksirb": 0,
|
| 1273 |
+
"penduduk": 0,
|
| 1274 |
+
"archer": 0,
|
| 1275 |
+
"shadow": 0,
|
| 1276 |
+
"laststringclaim": 0,
|
| 1277 |
+
"lastpotionclaim": 0,
|
| 1278 |
+
"lastswordclaim": 0,
|
| 1279 |
+
"lastweaponclaim": 0,
|
| 1280 |
+
"lastironclaim": 0,
|
| 1281 |
+
"lastmancingclaim": 0,
|
| 1282 |
+
"anakpancingan": 0,
|
| 1283 |
+
"as": 0,
|
| 1284 |
+
"paus": 0,
|
| 1285 |
+
"kepiting": 0,
|
| 1286 |
+
"gurita": 0,
|
| 1287 |
+
"cumi": 0,
|
| 1288 |
+
"buntal": 0,
|
| 1289 |
+
"dory": 0,
|
| 1290 |
+
"lumba": 0,
|
| 1291 |
+
"lobster": 0,
|
| 1292 |
+
"hiu": 0,
|
| 1293 |
+
"lele": 0,
|
| 1294 |
+
"nila": 0,
|
| 1295 |
+
"bawal": 0,
|
| 1296 |
+
"udang": 0,
|
| 1297 |
+
"ikan": 0,
|
| 1298 |
+
"orca": 0,
|
| 1299 |
+
"banteng": 0,
|
| 1300 |
+
"harimau": 0,
|
| 1301 |
+
"gajah": 0,
|
| 1302 |
+
"kambing": 0,
|
| 1303 |
+
"panda": 0,
|
| 1304 |
+
"buaya": 0,
|
| 1305 |
+
"kerbau": 0,
|
| 1306 |
+
"sapi": 0,
|
| 1307 |
+
"monyet": 0,
|
| 1308 |
+
"babihutan": 0,
|
| 1309 |
+
"babi": 0,
|
| 1310 |
+
"ayam": 0,
|
| 1311 |
+
"apel": 20,
|
| 1312 |
+
"ayamb": 0,
|
| 1313 |
+
"ayamg": 0,
|
| 1314 |
+
"ssapi": 0,
|
| 1315 |
+
"sapir": 0,
|
| 1316 |
+
"leleb": 0,
|
| 1317 |
+
"leleg": 0,
|
| 1318 |
+
"esteh": 0,
|
| 1319 |
+
"pet": 0,
|
| 1320 |
+
"potion": 0,
|
| 1321 |
+
"sampah": 0,
|
| 1322 |
+
"kucing": 0,
|
| 1323 |
+
"kucinglastclaim": 0,
|
| 1324 |
+
"kucingexp": 0,
|
| 1325 |
+
"kuda": 0,
|
| 1326 |
+
"kudalastclaim": 0,
|
| 1327 |
+
"rubah": 0,
|
| 1328 |
+
"rubahlastclaim": 0,
|
| 1329 |
+
"rubahexp": 0,
|
| 1330 |
+
"anjing": 0,
|
| 1331 |
+
"anjinglastclaim": 0,
|
| 1332 |
+
"anjingexp": 0,
|
| 1333 |
+
"naga": 0,
|
| 1334 |
+
"nagalastclaim": 0,
|
| 1335 |
+
"griffin": 0,
|
| 1336 |
+
"griffinlastclaim": 0,
|
| 1337 |
+
"centaur": 0,
|
| 1338 |
+
"fightnaga": 0,
|
| 1339 |
+
"centaurlastclaim": 0,
|
| 1340 |
+
"serigala": 0,
|
| 1341 |
+
"serigalalastclaim": 0,
|
| 1342 |
+
"serigalaexp": 0,
|
| 1343 |
+
"phonix": 0,
|
| 1344 |
+
"phonixlastclaim": 0,
|
| 1345 |
+
"phonixexp": 0,
|
| 1346 |
+
"makanannaga": 0,
|
| 1347 |
+
"makananphonix": 0,
|
| 1348 |
+
"makanancentaur": 0,
|
| 1349 |
+
"makananserigala": 0,
|
| 1350 |
+
"Banneduser": false,
|
| 1351 |
+
"BannedReason": "",
|
| 1352 |
+
"banned": false,
|
| 1353 |
+
"bannedTime": 0,
|
| 1354 |
+
"warn": 0,
|
| 1355 |
+
"afk": -1,
|
| 1356 |
+
"afkReason": "",
|
| 1357 |
+
"anakkucing": 0,
|
| 1358 |
+
"anakkuda": 0,
|
| 1359 |
+
"anakrubah": 0,
|
| 1360 |
+
"anakanjing": 0,
|
| 1361 |
+
"makananpet": 0,
|
| 1362 |
+
"makananPet": 0,
|
| 1363 |
+
"antispam": 0,
|
| 1364 |
+
"antispamlastclaim": 0,
|
| 1365 |
+
"kayu": 0,
|
| 1366 |
+
"batu": 0,
|
| 1367 |
+
"string": 0,
|
| 1368 |
+
"umpan": 0,
|
| 1369 |
+
"armor": 0,
|
| 1370 |
+
"armordurability": 0,
|
| 1371 |
+
"weapon": 0,
|
| 1372 |
+
"weapondurability": 0,
|
| 1373 |
+
"sword": 0,
|
| 1374 |
+
"sworddurability": 0,
|
| 1375 |
+
"pickaxe": 0,
|
| 1376 |
+
"pickaxedurability": 0,
|
| 1377 |
+
"fishingrod": 0,
|
| 1378 |
+
"fishingroddurability": 0,
|
| 1379 |
+
"katana": 0,
|
| 1380 |
+
"katanadurability": 0,
|
| 1381 |
+
"bow": 0,
|
| 1382 |
+
"bowdurability": 0,
|
| 1383 |
+
"kapak": 0,
|
| 1384 |
+
"kapakdurability": 0,
|
| 1385 |
+
"axe": 0,
|
| 1386 |
+
"axedurability": 0,
|
| 1387 |
+
"pisau": 0,
|
| 1388 |
+
"pisaudurability": 0,
|
| 1389 |
+
"kerjasatu": 0,
|
| 1390 |
+
"kerjadua": 0,
|
| 1391 |
+
"kerjatiga": 0,
|
| 1392 |
+
"kerjaempat": 0,
|
| 1393 |
+
"kerjalima": 0,
|
| 1394 |
+
"kerjaenam": 0,
|
| 1395 |
+
"kerjatujuh": 0,
|
| 1396 |
+
"kerjadelapan": 0,
|
| 1397 |
+
"kerjasembilan": 0,
|
| 1398 |
+
"kerjasepuluh": 0,
|
| 1399 |
+
"kerjasebelas": 0,
|
| 1400 |
+
"kerjaduabelas": 0,
|
| 1401 |
+
"kerjatigabelas": 0,
|
| 1402 |
+
"kerjaempatbelas": 0,
|
| 1403 |
+
"kerjalimabelas": 0,
|
| 1404 |
+
"pekerjaansatu": 0,
|
| 1405 |
+
"pekerjaandua": 0,
|
| 1406 |
+
"pekerjaantiga": 0,
|
| 1407 |
+
"pekerjaanempat": 0,
|
| 1408 |
+
"pekerjaanlima": 0,
|
| 1409 |
+
"pekerjaanenam": 0,
|
| 1410 |
+
"pekerjaantujuh": 0,
|
| 1411 |
+
"pekerjaandelapan": 0,
|
| 1412 |
+
"pekerjaansembilan": 0,
|
| 1413 |
+
"pekerjaansepuluh": 0,
|
| 1414 |
+
"pekerjaansebelas": 0,
|
| 1415 |
+
"pekerjaanduabelas": 0,
|
| 1416 |
+
"pekerjaantigabelas": 0,
|
| 1417 |
+
"pekerjaanempatbelas": 0,
|
| 1418 |
+
"pekerjaanlimabelas": 0,
|
| 1419 |
+
"lastadventure": 0,
|
| 1420 |
+
"lastwar": 0,
|
| 1421 |
+
"lastberkebon": 0,
|
| 1422 |
+
"lastberburu": 0,
|
| 1423 |
+
"lastbansos": 0,
|
| 1424 |
+
"lastrampok": 0,
|
| 1425 |
+
"lastkill": 0,
|
| 1426 |
+
"lastfishing": 0,
|
| 1427 |
+
"lastdungeon": 0,
|
| 1428 |
+
"lastduel": 0,
|
| 1429 |
+
"lastmining": 0,
|
| 1430 |
+
"lasthourly": 0,
|
| 1431 |
+
"lastdagang": 0,
|
| 1432 |
+
"lasthunt": 0,
|
| 1433 |
+
"lasthun": 0,
|
| 1434 |
+
"lastweekly": 0,
|
| 1435 |
+
"lastmonthly": 0,
|
| 1436 |
+
"lastyearly": 0,
|
| 1437 |
+
"lastjb": 0,
|
| 1438 |
+
"lastrob": 0,
|
| 1439 |
+
"lastdaang": 0,
|
| 1440 |
+
"lastngojek": 0,
|
| 1441 |
+
"lastgrab": 0,
|
| 1442 |
+
"lastngocok": 0,
|
| 1443 |
+
"lastturu": 0,
|
| 1444 |
+
"lastseen": 0,
|
| 1445 |
+
"lastSetStatus": 0,
|
| 1446 |
+
"registered": false,
|
| 1447 |
+
"mangga": 0,
|
| 1448 |
+
"stroberi": 0,
|
| 1449 |
+
"semangka": 0,
|
| 1450 |
+
"jeruk": 0,
|
| 1451 |
+
"name": "+62 878-2156-1429",
|
| 1452 |
+
"age": -1,
|
| 1453 |
+
"regTime": -1,
|
| 1454 |
+
"premiumDate": -1,
|
| 1455 |
+
"premium": false,
|
| 1456 |
+
"premiumTime": 0,
|
| 1457 |
+
"vip": "tidak",
|
| 1458 |
+
"vipPoin": 0,
|
| 1459 |
+
"job": "Pengangguran",
|
| 1460 |
+
"jobexp": 0,
|
| 1461 |
+
"jail": false,
|
| 1462 |
+
"penjara": false,
|
| 1463 |
+
"antarpaket": 0,
|
| 1464 |
+
"dirawat": false,
|
| 1465 |
+
"lbars": "[▒▒▒▒▒▒▒▒▒]",
|
| 1466 |
+
"role": "Newbie ㋡",
|
| 1467 |
+
"autolevelup": true,
|
| 1468 |
+
"lastIstigfar": 0,
|
| 1469 |
+
"skill": "",
|
| 1470 |
+
"korps": "",
|
| 1471 |
+
"korpsgrade": "",
|
| 1472 |
+
"demon": "",
|
| 1473 |
+
"breaths": "",
|
| 1474 |
+
"magic": "",
|
| 1475 |
+
"darahiblis": 0,
|
| 1476 |
+
"demonblood": 0,
|
| 1477 |
+
"demonkill": 0,
|
| 1478 |
+
"hashirakill": 0,
|
| 1479 |
+
"alldemonkill": 0,
|
| 1480 |
+
"allhashirakill": 0,
|
| 1481 |
+
"attack": 0,
|
| 1482 |
+
"speed": 0,
|
| 1483 |
+
"strenght": 0,
|
| 1484 |
+
"defense": 0,
|
| 1485 |
+
"regeneration": 0,
|
| 1486 |
+
"ovo": 0,
|
| 1487 |
+
"dana": 0,
|
| 1488 |
+
"gopay": 0,
|
| 1489 |
+
"lastngaji": 0,
|
| 1490 |
+
"lastlonte": 0,
|
| 1491 |
+
"lastkoboy": 0,
|
| 1492 |
+
"lastdate": 0,
|
| 1493 |
+
"lasttambang": 0,
|
| 1494 |
+
"lastngepet": 0,
|
| 1495 |
+
"glimit": 10,
|
| 1496 |
+
"pertambangan": 0,
|
| 1497 |
+
"lastbossbattle": 0,
|
| 1498 |
+
"aqua": 0,
|
| 1499 |
+
"glory": 0,
|
| 1500 |
+
"enchant": 0,
|
| 1501 |
+
"psepick": 0,
|
| 1502 |
+
"psenjata": 0,
|
| 1503 |
+
"lastgemclaim": 0,
|
| 1504 |
+
"makanangriffin": 0,
|
| 1505 |
+
"healthmonster": 0,
|
| 1506 |
+
"anakserigala": 0,
|
| 1507 |
+
"anaknaga": 0,
|
| 1508 |
+
"anakphonix": 0,
|
| 1509 |
+
"anakgriffin": 0,
|
| 1510 |
+
"kyubi": 0,
|
| 1511 |
+
"anakkyubi": 0,
|
| 1512 |
+
"anakcentaur": 0,
|
| 1513 |
+
"kingdom": false,
|
| 1514 |
+
"lastsda": 0,
|
| 1515 |
+
"lastberbru": 0,
|
| 1516 |
+
"lastgift": 0,
|
| 1517 |
+
"jualan": 0,
|
| 1518 |
+
"lastjualan": 0,
|
| 1519 |
+
"ngocokk": 0,
|
| 1520 |
+
"lastngocokk": 0,
|
| 1521 |
+
"lastcodereg": 0,
|
| 1522 |
+
"anggur": 0,
|
| 1523 |
+
"pisang": 0,
|
| 1524 |
+
"bibitanggur": 0,
|
| 1525 |
+
"bibitpisang": 0,
|
| 1526 |
+
"bibitapel": 0,
|
| 1527 |
+
"bibitmangga": 0,
|
| 1528 |
+
"bibitjeruk": 0
|
| 1529 |
+
}
|
| 1530 |
+
},
|
| 1531 |
+
"chats": {
|
| 1532 |
+
"6285878836361@s.whatsapp.net": {
|
| 1533 |
+
"isBanned": false,
|
| 1534 |
+
"welcome": true,
|
| 1535 |
+
"welcometype": 1,
|
| 1536 |
+
"detect": false,
|
| 1537 |
+
"isBannedTime": false,
|
| 1538 |
+
"mute": false,
|
| 1539 |
+
"listStr": {},
|
| 1540 |
+
"sWelcome": "Hai, @user!\nSelamat datang di grup @subject\n\n@desc",
|
| 1541 |
+
"sBye": "Selamat tinggal @user!",
|
| 1542 |
+
"sPromote": "",
|
| 1543 |
+
"sDemote": "",
|
| 1544 |
+
"delete": false,
|
| 1545 |
+
"antiLink": false,
|
| 1546 |
+
"antiLinknokick": false,
|
| 1547 |
+
"antiSticker": false,
|
| 1548 |
+
"antiStickernokick": false,
|
| 1549 |
+
"viewonce": false,
|
| 1550 |
+
"antiToxic": true,
|
| 1551 |
+
"antilinkig": false,
|
| 1552 |
+
"antilinkignokick": false,
|
| 1553 |
+
"antilinkyt": false,
|
| 1554 |
+
"antilinkytnokick": false,
|
| 1555 |
+
"antilinktwit": false,
|
| 1556 |
+
"antilinktwitnokick": false,
|
| 1557 |
+
"antilinkfb": false,
|
| 1558 |
+
"antilinkfbnokick": false,
|
| 1559 |
+
"antilinkall": false,
|
| 1560 |
+
"antilinkallnokick": false,
|
| 1561 |
+
"antilinkwame": false,
|
| 1562 |
+
"antilinkwamenokick": false,
|
| 1563 |
+
"antilinktele": false,
|
| 1564 |
+
"antilinktelenokick": false,
|
| 1565 |
+
"antilinktt": false,
|
| 1566 |
+
"antilinkttnokick": false,
|
| 1567 |
+
"antibot": false,
|
| 1568 |
+
"rpg": false,
|
| 1569 |
+
"expired": 0,
|
| 1570 |
+
"memgc": {
|
| 1571 |
+
"6285878836361@s.whatsapp.net": {
|
| 1572 |
+
"blacklist": false,
|
| 1573 |
+
"banned": false,
|
| 1574 |
+
"bannedTime": 0,
|
| 1575 |
+
"chat": 0,
|
| 1576 |
+
"chatTotal": 0,
|
| 1577 |
+
"command": 0,
|
| 1578 |
+
"commandTotal": 0,
|
| 1579 |
+
"lastseen": 0
|
| 1580 |
+
},
|
| 1581 |
+
"6283121935164@s.whatsapp.net": {
|
| 1582 |
+
"blacklist": false,
|
| 1583 |
+
"banned": false,
|
| 1584 |
+
"bannedTime": 0,
|
| 1585 |
+
"chat": 0,
|
| 1586 |
+
"chatTotal": 0,
|
| 1587 |
+
"command": 0,
|
| 1588 |
+
"commandTotal": 0,
|
| 1589 |
+
"lastseen": 0
|
| 1590 |
+
},
|
| 1591 |
+
"6287821561429@s.whatsapp.net": {
|
| 1592 |
+
"blacklist": false,
|
| 1593 |
+
"banned": false,
|
| 1594 |
+
"bannedTime": 0,
|
| 1595 |
+
"chat": 0,
|
| 1596 |
+
"chatTotal": 0,
|
| 1597 |
+
"command": 0,
|
| 1598 |
+
"commandTotal": 0,
|
| 1599 |
+
"lastseen": 0
|
| 1600 |
+
}
|
| 1601 |
+
}
|
| 1602 |
+
},
|
| 1603 |
+
"6281212181641@s.whatsapp.net": {
|
| 1604 |
+
"isBanned": false,
|
| 1605 |
+
"welcome": true,
|
| 1606 |
+
"welcometype": 1,
|
| 1607 |
+
"detect": false,
|
| 1608 |
+
"isBannedTime": false,
|
| 1609 |
+
"mute": false,
|
| 1610 |
+
"listStr": {},
|
| 1611 |
+
"sWelcome": "Hai, @user!\nSelamat datang di grup @subject\n\n@desc",
|
| 1612 |
+
"sBye": "Selamat tinggal @user!",
|
| 1613 |
+
"sPromote": "",
|
| 1614 |
+
"sDemote": "",
|
| 1615 |
+
"delete": false,
|
| 1616 |
+
"antiLink": false,
|
| 1617 |
+
"antiLinknokick": false,
|
| 1618 |
+
"antiSticker": false,
|
| 1619 |
+
"antiStickernokick": false,
|
| 1620 |
+
"viewonce": false,
|
| 1621 |
+
"antiToxic": true,
|
| 1622 |
+
"antilinkig": false,
|
| 1623 |
+
"antilinkignokick": false,
|
| 1624 |
+
"antilinkyt": false,
|
| 1625 |
+
"antilinkytnokick": false,
|
| 1626 |
+
"antilinktwit": false,
|
| 1627 |
+
"antilinktwitnokick": false,
|
| 1628 |
+
"antilinkfb": false,
|
| 1629 |
+
"antilinkfbnokick": false,
|
| 1630 |
+
"antilinkall": false,
|
| 1631 |
+
"antilinkallnokick": false,
|
| 1632 |
+
"antilinkwame": false,
|
| 1633 |
+
"antilinkwamenokick": false,
|
| 1634 |
+
"antilinktele": false,
|
| 1635 |
+
"antilinktelenokick": false,
|
| 1636 |
+
"antilinktt": false,
|
| 1637 |
+
"antilinkttnokick": false,
|
| 1638 |
+
"antibot": false,
|
| 1639 |
+
"rpg": false,
|
| 1640 |
+
"expired": 0,
|
| 1641 |
+
"memgc": {
|
| 1642 |
+
"6281212181641@s.whatsapp.net": {
|
| 1643 |
+
"blacklist": false,
|
| 1644 |
+
"banned": false,
|
| 1645 |
+
"bannedTime": 0,
|
| 1646 |
+
"chat": 0,
|
| 1647 |
+
"chatTotal": 0,
|
| 1648 |
+
"command": 0,
|
| 1649 |
+
"commandTotal": 0,
|
| 1650 |
+
"lastseen": 0
|
| 1651 |
+
}
|
| 1652 |
+
}
|
| 1653 |
+
},
|
| 1654 |
+
"6287821561429@s.whatsapp.net": {
|
| 1655 |
+
"isBanned": false,
|
| 1656 |
+
"welcome": true,
|
| 1657 |
+
"welcometype": 1,
|
| 1658 |
+
"detect": false,
|
| 1659 |
+
"isBannedTime": false,
|
| 1660 |
+
"mute": false,
|
| 1661 |
+
"listStr": {},
|
| 1662 |
+
"sWelcome": "Hai, @user!\nSelamat datang di grup @subject\n\n@desc",
|
| 1663 |
+
"sBye": "Selamat tinggal @user!",
|
| 1664 |
+
"sPromote": "",
|
| 1665 |
+
"sDemote": "",
|
| 1666 |
+
"delete": false,
|
| 1667 |
+
"antiLink": false,
|
| 1668 |
+
"antiLinknokick": false,
|
| 1669 |
+
"antiSticker": false,
|
| 1670 |
+
"antiStickernokick": false,
|
| 1671 |
+
"viewonce": false,
|
| 1672 |
+
"antiToxic": true,
|
| 1673 |
+
"antilinkig": false,
|
| 1674 |
+
"antilinkignokick": false,
|
| 1675 |
+
"antilinkyt": false,
|
| 1676 |
+
"antilinkytnokick": false,
|
| 1677 |
+
"antilinktwit": false,
|
| 1678 |
+
"antilinktwitnokick": false,
|
| 1679 |
+
"antilinkfb": false,
|
| 1680 |
+
"antilinkfbnokick": false,
|
| 1681 |
+
"antilinkall": false,
|
| 1682 |
+
"antilinkallnokick": false,
|
| 1683 |
+
"antilinkwame": false,
|
| 1684 |
+
"antilinkwamenokick": false,
|
| 1685 |
+
"antilinktele": false,
|
| 1686 |
+
"antilinktelenokick": false,
|
| 1687 |
+
"antilinktt": false,
|
| 1688 |
+
"antilinkttnokick": false,
|
| 1689 |
+
"antibot": false,
|
| 1690 |
+
"rpg": false,
|
| 1691 |
+
"expired": 0,
|
| 1692 |
+
"memgc": {
|
| 1693 |
+
"6287821561429@s.whatsapp.net": {
|
| 1694 |
+
"blacklist": false,
|
| 1695 |
+
"banned": false,
|
| 1696 |
+
"bannedTime": 0,
|
| 1697 |
+
"chat": 0,
|
| 1698 |
+
"chatTotal": 0,
|
| 1699 |
+
"command": 0,
|
| 1700 |
+
"commandTotal": 0,
|
| 1701 |
+
"lastseen": 0
|
| 1702 |
+
}
|
| 1703 |
+
}
|
| 1704 |
+
}
|
| 1705 |
+
},
|
| 1706 |
+
"stats": {
|
| 1707 |
+
"menu.js": {
|
| 1708 |
+
"total": 2,
|
| 1709 |
+
"success": 2,
|
| 1710 |
+
"last": 1732074269621,
|
| 1711 |
+
"lastSuccess": 1732074269621
|
| 1712 |
+
},
|
| 1713 |
+
"downloader-pindl.js": {
|
| 1714 |
+
"total": 2,
|
| 1715 |
+
"success": 0,
|
| 1716 |
+
"last": 1732074298135,
|
| 1717 |
+
"lastSuccess": 0
|
| 1718 |
+
},
|
| 1719 |
+
"downloader-pinterest.js": {
|
| 1720 |
+
"total": 2,
|
| 1721 |
+
"success": 2,
|
| 1722 |
+
"last": 1732074374075,
|
| 1723 |
+
"lastSuccess": 1732074374075
|
| 1724 |
+
},
|
| 1725 |
+
"server.js": {
|
| 1726 |
+
"total": 3,
|
| 1727 |
+
"success": 3,
|
| 1728 |
+
"last": 1733916896776,
|
| 1729 |
+
"lastSuccess": 1733916896776
|
| 1730 |
+
}
|
| 1731 |
+
},
|
| 1732 |
+
"msgs": {},
|
| 1733 |
+
"sticker": {}
|
| 1734 |
+
}
|
docker-compose.yml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version: "3.9"
|
| 2 |
+
services:
|
| 3 |
+
web:
|
| 4 |
+
build: .
|
| 5 |
+
ports:
|
| 6 |
+
- "8000:5000"
|
| 7 |
+
volumes:
|
| 8 |
+
- .:/code
|
| 9 |
+
- logvolume01:/var/log
|
| 10 |
+
links:
|
| 11 |
+
- redis
|
| 12 |
+
redis:
|
| 13 |
+
image: redis
|
| 14 |
+
volumes:
|
| 15 |
+
logvolume01: {}
|
handler.js
ADDED
|
@@ -0,0 +1,1261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const simple = require('./lib/simple')
|
| 2 |
+
const util = require('util')
|
| 3 |
+
|
| 4 |
+
const isNumber = x => typeof x === 'number' && !isNaN(x)
|
| 5 |
+
const delay = ms => isNumber(ms) && new Promise(resolve => setTimeout(resolve, ms))
|
| 6 |
+
|
| 7 |
+
module.exports = {
|
| 8 |
+
async handler(chatUpdate) {
|
| 9 |
+
if (global.db.data == null) await loadDatabase()
|
| 10 |
+
this.msgqueque = this.msgqueque || []
|
| 11 |
+
// console.log(chatUpdate)
|
| 12 |
+
if (!chatUpdate) return
|
| 13 |
+
// if (chatUpdate.messages.length > 2 || !chatUpdate.messages.length) return
|
| 14 |
+
if (chatUpdate.messages.length > 1) console.log(chatUpdate.messages)
|
| 15 |
+
let m = chatUpdate.messages[chatUpdate.messages.length - 1]
|
| 16 |
+
if (!m) return
|
| 17 |
+
//console.log(JSON.stringify(m, null, 4))
|
| 18 |
+
try {
|
| 19 |
+
m = simple.smsg(this, m) || m
|
| 20 |
+
if (!m) return
|
| 21 |
+
// console.log(m)
|
| 22 |
+
m.exp = 0
|
| 23 |
+
m.limit = false
|
| 24 |
+
try {
|
| 25 |
+
let user = global.db.data.users[m.sender]
|
| 26 |
+
if (typeof user !== 'object') global.db.data.users[m.sender] = {}
|
| 27 |
+
if (user) {
|
| 28 |
+
if (!isNumber(user.saldo)) user.saldo = 0
|
| 29 |
+
if (!isNumber(user.pengeluaran)) user.pengeluaran = 0
|
| 30 |
+
if (!isNumber(user.healt)) user.healt = 100
|
| 31 |
+
if (!isNumber(user.health)) user.health = 100
|
| 32 |
+
if (!isNumber(user.energi)) user.energi = 100
|
| 33 |
+
if (!isNumber(user.power)) user.power = 100
|
| 34 |
+
if (!isNumber(user.title)) user.title = 0
|
| 35 |
+
if (!isNumber(user.stamina)) user.stamina = 100
|
| 36 |
+
if (!isNumber(user.haus)) user.haus = 100
|
| 37 |
+
if (!isNumber(user.laper)) user.laper = 100
|
| 38 |
+
if (!isNumber(user.level)) user.level = 0
|
| 39 |
+
if (!('titlein' in user)) user.titlein = 'Belum Ada'
|
| 40 |
+
if (!("ultah" in user)) user.ultah = ''
|
| 41 |
+
if (!('pasangan' in user)) user.pasangan = ''
|
| 42 |
+
if (!('sahabat' in user)) user.sahabat = ''
|
| 43 |
+
if (!('location' in user)) user.location = 'Gubuk'
|
| 44 |
+
if (!('husbu' in user)) user.husbu = 'Belum Di Set'
|
| 45 |
+
if (!('waifu' in user)) user.waifu = 'Belum Di Set'
|
| 46 |
+
if (!isNumber(user.follow)) user.follow = 0
|
| 47 |
+
if (!isNumber(user.lastfollow)) user.lastfollow = 0
|
| 48 |
+
if (!isNumber(user.followers)) user.followers = 0
|
| 49 |
+
if (!isNumber(user.exp)) user.exp = 0
|
| 50 |
+
if (!isNumber(user.pc)) user.pc = 0
|
| 51 |
+
if (!isNumber(user.korbanngocok)) user.korbanngocok = 0
|
| 52 |
+
if (!isNumber(user.ojekk)) user.ojekk = 0
|
| 53 |
+
if (!isNumber(user.polisi)) user.polisi = 0
|
| 54 |
+
if (!isNumber(user.ojek)) user.ojek = 0
|
| 55 |
+
if (!isNumber(user.pedagang)) user.pedagang = 0
|
| 56 |
+
if (!isNumber(user.dokter)) user.dokter = 0
|
| 57 |
+
if (!isNumber(user.petani)) user.petani = 0
|
| 58 |
+
if (!isNumber(user.montir)) user.montir = 0
|
| 59 |
+
if (!isNumber(user.kuli)) user.kuli = 0
|
| 60 |
+
if (!isNumber(user.trofi)) user.trofi= 0
|
| 61 |
+
if (!user.rtrofi) user.rtrofi = 'Perunggu'
|
| 62 |
+
if (!isNumber(user.troopcamp)) user.troopcamp = 0
|
| 63 |
+
if (!isNumber(user.coin)) user.coin = 0
|
| 64 |
+
if (!isNumber(user.atm)) user.atm = 0
|
| 65 |
+
if (!isNumber(user.limit)) user.limit = 100
|
| 66 |
+
if (!isNumber(user.glimit)) user.glimit = 10
|
| 67 |
+
if (!isNumber(user.tprem)) user.tprem = 0
|
| 68 |
+
if (!isNumber(user.tigame)) user.tigame = 5
|
| 69 |
+
if (!isNumber(user.lastclaim)) user.lastclaim = 0
|
| 70 |
+
if (isNumber(user.lastmulung)) user.lastmulung = 0
|
| 71 |
+
if (!isNumber(user.judilast)) user.judilast = 0
|
| 72 |
+
if (!isNumber(user.lastnambang)) user.lastnambang = 0
|
| 73 |
+
if (!isNumber(user.lastnebang)) user.lastnebang = 0
|
| 74 |
+
if (!isNumber(user.lastkerja)) user.lastkerja = 0
|
| 75 |
+
if (!isNumber(user.lastmaling)) user.lastmaling = 0
|
| 76 |
+
if (!isNumber(user.lastbunuhi)) user.lastbunuhi = 0
|
| 77 |
+
if (!isNumber(user.lastbisnis)) user.lastbisnis = 0
|
| 78 |
+
if (!isNumber(user.lastberbisnis)) user.lastberbisnis = 0
|
| 79 |
+
if (!isNumber(user.berbisnis)) user.berbisnis = 0
|
| 80 |
+
if (!isNumber(user.bisnis)) user.bisnis = 0
|
| 81 |
+
if (!isNumber(user.lastmancing)) user.lastmancing = 0
|
| 82 |
+
if (!isNumber(user.money)) user.money = 0
|
| 83 |
+
if (!isNumber(user.rumahsakit)) user.rumahsakit= 0
|
| 84 |
+
if (!isNumber(user.fortress)) user.fortress = 0
|
| 85 |
+
if (!isNumber(user.shield)) user.shield = false
|
| 86 |
+
if (!isNumber(user.pertanian)) user.pertanian = 0
|
| 87 |
+
if (!isNumber(user.pertambangan)) user.pertambangan = 0
|
| 88 |
+
if (!isNumber(user.camptroops)) user.camptroops = 0
|
| 89 |
+
if (!isNumber(user.tambang)) user.tambang = 0
|
| 90 |
+
|
| 91 |
+
//Tambahan rpg
|
| 92 |
+
if (!isNumber(user.litecoin)) user.litecoin = 0
|
| 93 |
+
if (!isNumber(user.chip)) user.chip = 0
|
| 94 |
+
if (!isNumber(user.tiketcoin)) user.tiketcoin = 0
|
| 95 |
+
if (!isNumber(user.poin)) user.poin = 0
|
| 96 |
+
if (!isNumber (user.lastbossbattle)) user.lastbossbattle = 0
|
| 97 |
+
if (!isNumber (user.bank)) user.bank = 0
|
| 98 |
+
if (!isNumber (user.balance)) user.balance = 0
|
| 99 |
+
|
| 100 |
+
if (!isNumber(user.botol)) user.botol = 0
|
| 101 |
+
if (!isNumber(user.kardus)) user.kardus = 0
|
| 102 |
+
if (!isNumber(user.kaleng)) user.kaleng = 0
|
| 103 |
+
if (!isNumber(user.aqua)) user.aqua = 0
|
| 104 |
+
if (!isNumber(user.diamond)) user.diamond = 0
|
| 105 |
+
if (!isNumber(user.emerald)) user.emerald = 0
|
| 106 |
+
if (!isNumber(user.wood)) user.wood = 0
|
| 107 |
+
if (!isNumber(user.rock)) user.rock = 0
|
| 108 |
+
if (!isNumber(user.berlian)) user.berlian = 0
|
| 109 |
+
if (!isNumber(user.iron)) user.iron = 0
|
| 110 |
+
if (!isNumber(user.emas)) user.emas = 0
|
| 111 |
+
if (!isNumber(user.arlok)) user.arlok = 0
|
| 112 |
+
|
| 113 |
+
if (!isNumber(user.common)) user.common = 0
|
| 114 |
+
if (!isNumber(user.as)) user.as = 0
|
| 115 |
+
if (!isNumber(user.uncommon)) user.uncommon = 0
|
| 116 |
+
if (!isNumber(user.mythic)) user.mythic = 0
|
| 117 |
+
if (!isNumber(user.legendary)) user.legendary = 0
|
| 118 |
+
if (!isNumber(user.glory)) user.glory = 0
|
| 119 |
+
if (!isNumber(user.enchant)) user.enchant = 0
|
| 120 |
+
if (!isNumber(user.pet)) user.pet = 0
|
| 121 |
+
if (!isNumber(user.psepick)) user.psepick = 0
|
| 122 |
+
if (!isNumber(user.psenjata)) user.psenjata = 0
|
| 123 |
+
//rpg meracik
|
| 124 |
+
if (!isNumber(user.lastramuanclaim)) user.lastramuanclaim = 0
|
| 125 |
+
if (!isNumber(user.gems)) user.gems = 0
|
| 126 |
+
if (!isNumber(user.cupon)) user.cupon = 0
|
| 127 |
+
if (!isNumber(user.lastgemclaim)) user.lastgemclaim = 0
|
| 128 |
+
if (!isNumber(user.eleksirb)) user.eleksirb = 0
|
| 129 |
+
if (!isNumber(user.penduduk)) user.penduduk = 0
|
| 130 |
+
if (!isNumber(user.archer)) user.archer = 0
|
| 131 |
+
if (!isNumber(user.shadow)) user.shadow = 0
|
| 132 |
+
if (!isNumber(user.lastpotionclaim)) user.lastpotionclaim = 0
|
| 133 |
+
if (!isNumber(user.laststringclaim)) user.laststringclaim = 0
|
| 134 |
+
if (!isNumber(user.lastswordclaim)) user.lastswordclaim = 0
|
| 135 |
+
if (!isNumber(user.lastweaponclaim)) user.lastweaponclaim = 0
|
| 136 |
+
if (!isNumber(user.lastironclaim)) user.lastironclaim = 0
|
| 137 |
+
if (!isNumber(user.lastmancingclaim)) user.lastmancingclaim = 0
|
| 138 |
+
if (!isNumber(user.anakpancingan)) user.anakpancingan = 0
|
| 139 |
+
|
| 140 |
+
if (!isNumber(user.potion)) user.potion = 0
|
| 141 |
+
if (!isNumber(user.sampah)) user.sampah = 0
|
| 142 |
+
if (!isNumber(user.pancing)) user.pancing = 0
|
| 143 |
+
if (!isNumber(user.pancingan)) user.pancingan = 0
|
| 144 |
+
if (!isNumber(user.totalPancingan)) user.totalPancingan = 0
|
| 145 |
+
//penambah stamina
|
| 146 |
+
if (!isNumber(user.apel)) user.apel = 0
|
| 147 |
+
if (!isNumber(user.ayamb)) user.ayamb = 0
|
| 148 |
+
if (!isNumber(user.ayamg)) user.ayamg = 0
|
| 149 |
+
if (!isNumber(user.sapir)) user.sapir = 0
|
| 150 |
+
if (!isNumber(user.ssapi)) user.ssapi = 0
|
| 151 |
+
if (!isNumber(user.esteh)) user.esteh = 0
|
| 152 |
+
if (!isNumber(user.leleg)) user.leleg = 0
|
| 153 |
+
if (!isNumber(user.leleb)) user.leleb = 0
|
| 154 |
+
|
| 155 |
+
if (!isNumber(user.ayambakar)) user.ayambakar = 0
|
| 156 |
+
if (!isNumber(user.gulai)) user.gulai = 0
|
| 157 |
+
if (!isNumber(user.rendang)) user.rendang = 0
|
| 158 |
+
if (!isNumber(user.ayamgoreng)) user.ayamgoreng = 0
|
| 159 |
+
if (!isNumber(user.oporayam)) user.oporayam = 0
|
| 160 |
+
if (!isNumber(user.steak)) user.steak = 0
|
| 161 |
+
if (!isNumber(user.babipanggang)) user.babipanggang = 0
|
| 162 |
+
if (!isNumber(user.ikanbakar)) user.ikanbakar = 0
|
| 163 |
+
if (!isNumber(user.nilabakar)) user.nilabakar = 0
|
| 164 |
+
if (!isNumber(user.lelebakar)) user.lelebakar = 0
|
| 165 |
+
if (!isNumber(user.bawalbakar)) user.bawalbakar = 0
|
| 166 |
+
if (!isNumber(user.udangbakar)) user.udangbakar = 0
|
| 167 |
+
if (!isNumber(user.pausbakar)) user.pausbakar = 0
|
| 168 |
+
if (!isNumber(user.kepitingbakar)) user.kepitingbakar = 0
|
| 169 |
+
if (!isNumber(user.soda)) user.soda = 0
|
| 170 |
+
if (!isNumber(user.vodka)) user.vodka = 0
|
| 171 |
+
if (!isNumber(user.ganja)) user.ganja = 0
|
| 172 |
+
if (!isNumber(user.bandage)) user.bandage = 0
|
| 173 |
+
if (!isNumber(user.sushi)) user.sushi = 0
|
| 174 |
+
if (!isNumber(user.roti)) user.roti = 0
|
| 175 |
+
//untuk masak
|
| 176 |
+
if (!isNumber(user.coal)) user.coal = 0
|
| 177 |
+
if (!isNumber(user.korekapi)) user.korekapi = 0
|
| 178 |
+
//tools
|
| 179 |
+
if (!isNumber(user.umpan)) user.umpan = 0
|
| 180 |
+
|
| 181 |
+
if (!isNumber(user.armor)) user.armor = 0
|
| 182 |
+
if (!isNumber(user.armordurability)) user.armordurability = 0
|
| 183 |
+
if (!isNumber(user.weapon)) user.weapon = 0
|
| 184 |
+
if (!isNumber(user.weapondurability)) user.weapondurability = 0
|
| 185 |
+
if (!isNumber(user.sword)) user.sword = 0
|
| 186 |
+
if (!isNumber(user.sworddurability)) user.sworddurability = 0
|
| 187 |
+
if (!isNumber(user.pickaxe)) user.pickaxe = 0
|
| 188 |
+
if (!isNumber(user.pickaxedurability)) user.pickaxedurability = 0
|
| 189 |
+
if (!isNumber(user.fishingrod)) user.fishingrod = 0
|
| 190 |
+
if (!isNumber(user.fishingroddurability)) user.fishingroddurability = 0
|
| 191 |
+
if (!isNumber(user.katana)) user.katana = 0
|
| 192 |
+
if (!isNumber(user.katanadurability)) user.katanadurability = 0
|
| 193 |
+
if (!isNumber(user.bow)) user.bow = 0
|
| 194 |
+
if (!isNumber(user.bowdurability)) user.bowdurability = 0
|
| 195 |
+
if (!isNumber(user.kapak)) user.kapak = 0
|
| 196 |
+
if (!isNumber(user.kapakdurability)) user.kapakdurability = 0
|
| 197 |
+
if (!isNumber(user.axe)) user.axe = 0
|
| 198 |
+
if (!isNumber(user.axedurability)) user.axedurability = 0
|
| 199 |
+
if (!isNumber(user.pisau)) user.pisau = 0
|
| 200 |
+
if (!isNumber(user.pisaudurability)) user.pisaudurability = 0
|
| 201 |
+
|
| 202 |
+
if (!isNumber(user.kerjasatu)) user.kerjasatu = 0
|
| 203 |
+
if (!isNumber(user.kerjadua)) user.kerjadua = 0
|
| 204 |
+
if (!isNumber(user.kerjatiga)) user.kerjatiga = 0
|
| 205 |
+
if (!isNumber(user.kerjaempat)) user.kerjaempat = 0
|
| 206 |
+
if (!isNumber(user.kerjalima)) user.kerjalima = 0
|
| 207 |
+
if (!isNumber(user.kerjaenam)) user.kerjaenam = 0
|
| 208 |
+
if (!isNumber(user.kerjatujuh)) user.kerjatujuh = 0
|
| 209 |
+
if (!isNumber(user.kerjadelapan)) user.kerjadelapan = 0
|
| 210 |
+
if (!isNumber(user.kerjasembilan)) user.kerjasembilan = 0
|
| 211 |
+
if (!isNumber(user.kerjasepuluh)) user.kerjasepuluh = 0
|
| 212 |
+
if (!isNumber(user.kerjasebelas)) user.kerjasebelas = 0
|
| 213 |
+
if (!isNumber(user.kerjaduabelas)) user.kerjaduabelas = 0
|
| 214 |
+
if (!isNumber(user.kerjatigabelas)) user.kerjatigabelas = 0
|
| 215 |
+
if (!isNumber(user.kerjaempatbelas)) user.kerjaempatbelas = 0
|
| 216 |
+
if (!isNumber(user.kerjalimabelas)) user.kerjalimabelas = 0
|
| 217 |
+
|
| 218 |
+
if (!isNumber(user.pekerjaansatu)) user.pekerjaansatu = 0
|
| 219 |
+
if (!isNumber(user.pekerjaandua)) user.pekerjaandua = 0
|
| 220 |
+
if (!isNumber(user.pekerjaantiga)) user.pekerjaantiga = 0
|
| 221 |
+
if (!isNumber(user.pekerjaanempat)) user.pekerjaanempat = 0
|
| 222 |
+
if (!isNumber(user.pekerjaanlima)) user.pekerjaanlima = 0
|
| 223 |
+
if (!isNumber(user.pekerjaanenam)) user.pekerjaanenam = 0
|
| 224 |
+
if (!isNumber(user.pekerjaantujuh)) user.pekerjaantujuh = 0
|
| 225 |
+
if (!isNumber(user.pekerjaandelapan)) user.pekerjaandelapan = 0
|
| 226 |
+
if (!isNumber(user.pekerjaansembilan)) user.pekerjaansembilan = 0
|
| 227 |
+
if (!isNumber(user.pekerjaansepuluh)) user.pekerjaansepuluh = 0
|
| 228 |
+
if (!isNumber(user.pekerjaansebelas)) user.pekerjaansebelas = 0
|
| 229 |
+
if (!isNumber(user.pekerjaanduabelas)) user.pekerjaanduabelas = 0
|
| 230 |
+
if (!isNumber(user.pekerjaantigabelas)) user.pekerjaantigabelas = 0
|
| 231 |
+
if (!isNumber(user.pekerjaanempatbelas)) user.pekerjaanempatbelas = 0
|
| 232 |
+
if (!isNumber(user.pekerjaanlimabelas)) user.pekerjaanlimabelas = 0
|
| 233 |
+
|
| 234 |
+
if (!isNumber(user.kucing)) user.kucing = 0
|
| 235 |
+
if (!isNumber(user.kucinglastclaim)) user.kucinglastclaim = 0
|
| 236 |
+
if (!isNumber(user.kucingexp)) user.kucingexp = 0
|
| 237 |
+
if (!isNumber(user.kuda)) user.kuda = 0
|
| 238 |
+
if (!isNumber(user.kudalastclaim)) user.kudalastclaim = 0
|
| 239 |
+
if (!isNumber(user.rubah)) user.rubah = 0
|
| 240 |
+
if (!isNumber(user.rubahlastclaim)) user.rubahlastclaim = 0
|
| 241 |
+
if (!isNumber(user.rubahexp)) user.rubahexp = 0
|
| 242 |
+
if (!isNumber(user.anjing)) user.anjing = 0
|
| 243 |
+
if (!isNumber(user.anjinglastclaim)) user.anjinglastclaim = 0
|
| 244 |
+
if (!isNumber(user.anjingexp)) user.anjingexp = 0
|
| 245 |
+
if (!isNumber(user.serigalalastclaim)) user.serigalalastclaim = 0
|
| 246 |
+
if (!isNumber(user.nagalastclaim)) user.nagalastclaim = 0
|
| 247 |
+
if (!isNumber(user.phonixlastclaim)) user.phonixlastclaim = 0
|
| 248 |
+
if (!isNumber(user.phonixexp)) user.phonixexp = 0
|
| 249 |
+
if (!isNumber(user.griffinlastclaim)) user.griffinlastclaim = 0
|
| 250 |
+
if (!isNumber(user.centaurlastclaim)) user.centaurlastclaim = 0
|
| 251 |
+
|
| 252 |
+
if (!isNumber(user.makananpet)) user.makananpet = 0
|
| 253 |
+
if (!isNumber(user.makanannaga)) user.makanannaga = 0
|
| 254 |
+
if (!isNumber(user.makananphonix)) user.makananphonix = 0
|
| 255 |
+
if (!isNumber(user.makanangriffin)) user.makanangriffin = 0
|
| 256 |
+
if (!isNumber(user.makananserigala)) user.makananserigala = 0
|
| 257 |
+
if (!isNumber(user.makanancentaur)) user.makanancentaur = 0
|
| 258 |
+
|
| 259 |
+
if (!'Banneduser' in user) user.Banneduser = false
|
| 260 |
+
if (!'BannedReason' in user) user.BannedReason = ''
|
| 261 |
+
if (!isNumber(user.warn)) user.warn = 0
|
| 262 |
+
if (!('banned' in user)) user.banned = false
|
| 263 |
+
if (!isNumber(user.bannedTime)) user.bannedTime = 0
|
| 264 |
+
|
| 265 |
+
if (!isNumber(user.afk)) user.afk = -1
|
| 266 |
+
if (!'afkReason' in user) user.afkReason = ''
|
| 267 |
+
|
| 268 |
+
//PET
|
| 269 |
+
if (!isNumber(user.healthmonster)) user.healthmonster = 0
|
| 270 |
+
if (!isNumber(user.anakkucing)) user.anakkucing = 0
|
| 271 |
+
if (!isNumber(user.anakkuda)) user.anakkuda = 0
|
| 272 |
+
if (!isNumber(user.anakrubah)) user.anakrubah = 0
|
| 273 |
+
if (!isNumber(user.anakanjing)) user.anakanjing = 0
|
| 274 |
+
if (!isNumber(user.serigala)) user.serigala = 0
|
| 275 |
+
if (!isNumber(user.serigalaexp)) user.serigalaexp = 0
|
| 276 |
+
if (!isNumber(user.anakserigala)) user.anakserigala = 0
|
| 277 |
+
if (!isNumber(user.naga)) user.naga = 0
|
| 278 |
+
if (!isNumber(user.anaknaga)) user.anaknaga = 0
|
| 279 |
+
if (!isNumber(user.phonix)) user.phonix = 0
|
| 280 |
+
if (!isNumber(user.anakphonix)) user.anakphonix = 0
|
| 281 |
+
if (!isNumber(user.griffin)) user.griffin = 0
|
| 282 |
+
if (!isNumber(user.anakgriffin)) user.anakgriffin = 0
|
| 283 |
+
if (!isNumber(user.kyubi)) user.kyubi = 0
|
| 284 |
+
if (!isNumber(user.anakkyubi)) user.anakkyubi = 0
|
| 285 |
+
if (!isNumber(user.centaur)) user.centaur = 0
|
| 286 |
+
if (!isNumber(user.fightnaga)) user.fightnaga = 0
|
| 287 |
+
if (!isNumber(user.anakcentaur)) user.anakcentaur = 0
|
| 288 |
+
if (!isNumber(user.makananPet)) user.makananPet = 0
|
| 289 |
+
|
| 290 |
+
if (!isNumber(user.antispam)) user.antispam = 0
|
| 291 |
+
if (!isNumber(user.antispamlastclaim)) user.antispamlastclaim = 0
|
| 292 |
+
|
| 293 |
+
if (!isNumber(user.kayu)) user.kayu = 0
|
| 294 |
+
if (!('kingdom' in user)) user.kingdom = false
|
| 295 |
+
if (!isNumber(user.batu)) user.batu = 0
|
| 296 |
+
if (!isNumber(user.ramuan)) user.ramuan = 0
|
| 297 |
+
if (!isNumber(user.string)) user.string = 0
|
| 298 |
+
|
| 299 |
+
//mancing
|
| 300 |
+
if (!isNumber(user.paus)) user.paus = 0
|
| 301 |
+
if (!isNumber(user.kepiting)) user.kepiting = 0
|
| 302 |
+
if (!isNumber(user.gurita)) user.gurita = 0
|
| 303 |
+
if (!isNumber(user.cumi)) user.cumi= 0
|
| 304 |
+
if (!isNumber(user.buntal)) user.buntal = 0
|
| 305 |
+
if (!isNumber(user.dory)) user.dory = 0
|
| 306 |
+
if (!isNumber(user.lumba)) user.lumba = 0
|
| 307 |
+
if (!isNumber(user.lobster)) user.lobster = 0
|
| 308 |
+
if (!isNumber(user.hiu)) user.hiu = 0
|
| 309 |
+
if (!isNumber(user.udang)) user.udang = 0
|
| 310 |
+
if (!isNumber(user.ikan)) user.ikan = 0
|
| 311 |
+
if (!isNumber(user.nila)) user.nila = 0
|
| 312 |
+
if (!isNumber(user.bawal)) user.bawal = 0
|
| 313 |
+
if (!isNumber(user.lele)) user.lele = 0
|
| 314 |
+
if (!isNumber(user.orca)) user.orca = 0
|
| 315 |
+
|
| 316 |
+
if (!isNumber(user.banteng)) user.banteng = 0
|
| 317 |
+
if (!isNumber(user.harimau)) user.harimau = 0
|
| 318 |
+
if (!isNumber(user.gajah)) user.gajah = 0
|
| 319 |
+
if (!isNumber(user.kambing)) user.kambing = 0
|
| 320 |
+
if (!isNumber(user.panda)) user.panda = 0
|
| 321 |
+
if (!isNumber(user.buaya)) user.buaya = 0
|
| 322 |
+
if (!isNumber(user.kerbau)) user.kerbau = 0
|
| 323 |
+
if (!isNumber(user.sapi)) user.sapi = 0
|
| 324 |
+
if (!isNumber(user.monyet)) user.monyet = 0
|
| 325 |
+
if (!isNumber(user.babihutan)) user.babihutan = 0
|
| 326 |
+
if (!isNumber(user.babi)) user.babi = 0
|
| 327 |
+
if (!isNumber(user.ayam)) user.ayam = 0
|
| 328 |
+
|
| 329 |
+
if (!isNumber(user.lastadventure)) user.lastadventure = 0
|
| 330 |
+
if (!isNumber(user.lastberburu)) user.lastberburu = 0
|
| 331 |
+
if (!isNumber(user.lastkill)) user.lastkill = 0
|
| 332 |
+
if (!isNumber(user.lastfishing)) user.lastfishing = 0
|
| 333 |
+
if (!isNumber(user.lastdungeon)) user.lastdungeon = 0
|
| 334 |
+
if (!isNumber(user.lastwar)) user.lastwar = 0
|
| 335 |
+
if (!isNumber(user.lastsda)) user.lastsda = 0
|
| 336 |
+
if (!isNumber(user.lastberbru)) user.lastberbru = 0
|
| 337 |
+
if (!isNumber(user.lastduel)) user.lastduel = 0
|
| 338 |
+
if (!isNumber(user.lastjb)) user.lastjb = 0
|
| 339 |
+
if (!isNumber(user.lastSetStatus)) user.lastSetStatus = 0
|
| 340 |
+
if (!isNumber(user.lastmining)) user.lastmining = 0
|
| 341 |
+
if (!isNumber(user.lasthunt)) user.lasthunt = 0
|
| 342 |
+
if (!isNumber(user.lasthun)) user.lasthun = 0
|
| 343 |
+
if (!isNumber(user.lastngocok)) user.lastngocok = 0
|
| 344 |
+
if (!isNumber(user.lastgift)) user.lastgift = 0
|
| 345 |
+
if (!isNumber(user.lastrob)) user.lastrob = 0
|
| 346 |
+
if (!isNumber(user.lastngojek)) user.lastngojek = 0
|
| 347 |
+
if (!isNumber(user.lastngewe)) user.lastngewe = 0
|
| 348 |
+
if (!isNumber(user.ngewe)) user.ngewe = 0
|
| 349 |
+
if (!isNumber(user.jualan)) user.jualan = 0
|
| 350 |
+
if (!isNumber(user.lastjualan)) user.lastjualan = 0
|
| 351 |
+
if (!isNumber(user.ngocokk)) user.ngocokk = 0
|
| 352 |
+
if (!isNumber(user.lastngocokk)) user.lastngocokk = 0
|
| 353 |
+
if (!isNumber(user.lastgrab)) user.lastgrab = 0
|
| 354 |
+
if (!isNumber(user.lastberkebon)) user.lastberkebon = 0
|
| 355 |
+
if (!isNumber(user.lastcodereg)) user.lastcodereg = 0
|
| 356 |
+
if (!isNumber(user.lastdagang)) user.lastdagang = 0
|
| 357 |
+
if (!isNumber(user.lasthourly)) user.lasthourly = 0
|
| 358 |
+
if (!isNumber(user.lastweekly)) user.lastweekly = 0
|
| 359 |
+
if (!isNumber(user.lastyearly)) user.lastyearly = 0
|
| 360 |
+
if (!isNumber(user.lastmonthly)) user.lastmonthly = 0
|
| 361 |
+
if (!isNumber(user.lastIstigfar)) user.lastIstigfar = 0
|
| 362 |
+
if (!isNumber(user.lastturu)) user.lastturu = 0
|
| 363 |
+
if (!isNumber(user.lastseen)) user.lastseen = 0
|
| 364 |
+
if (!isNumber(user.lastbansos)) user.lastbansos = 0
|
| 365 |
+
if (!isNumber(user.lastrampok)) user.lastrampok = 0
|
| 366 |
+
if (!('registered' in user)) user.registered = false
|
| 367 |
+
if (!user.registered) {
|
| 368 |
+
if (!('name' in user)) user.name = this.getName(m.sender)
|
| 369 |
+
|
| 370 |
+
if (!isNumber(user.apel)) user.apel = 0
|
| 371 |
+
if (!isNumber(user.anggur)) user.anggur = 0
|
| 372 |
+
if (!isNumber(user.jeruk)) user.jeruk = 0
|
| 373 |
+
if (!isNumber(user.semangka)) user.semangka = 0
|
| 374 |
+
if (!isNumber(user.mangga)) user.mangga = 0
|
| 375 |
+
if (!isNumber(user.stroberi)) user.stroberi = 0
|
| 376 |
+
if (!isNumber(user.pisang)) user.pisang = 0
|
| 377 |
+
if (!isNumber(user.kayu)) user.kayu = 0
|
| 378 |
+
if (!isNumber(user.makanan)) user.makanan = 0
|
| 379 |
+
if (!isNumber(user.bibitanggur)) user.bibitanggur = 0
|
| 380 |
+
if (!isNumber(user.bibitpisang)) user.bibitpisang = 0
|
| 381 |
+
if (!isNumber(user.bibitapel)) user.bibitapel = 0
|
| 382 |
+
if (!isNumber(user.bibitmangga)) user.bibitmangga = 0
|
| 383 |
+
if (!isNumber(user.bibitjeruk)) user.bibitjeruk = 0
|
| 384 |
+
|
| 385 |
+
//sambung kata
|
| 386 |
+
if (!isNumber(user.skata)) user.skata = 0
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
if (!isNumber(user.age)) user.age = -1
|
| 390 |
+
if (!isNumber(user.premiumDate)) user.premiumDate = -1
|
| 391 |
+
if (!isNumber(user.regTime)) user.regTime = -1
|
| 392 |
+
|
| 393 |
+
}
|
| 394 |
+
if (!isNumber(user.level)) user.level = 0
|
| 395 |
+
if (!user.job) user.job = 'Pengangguran'
|
| 396 |
+
if (!isNumber(user.jobexp)) user.jobexp = 0
|
| 397 |
+
if (!('jail' in user)) user.jail = false
|
| 398 |
+
if (!('penjara' in user)) user.penjara = false
|
| 399 |
+
if (!('dirawat' in user)) user.dirawat = false
|
| 400 |
+
if (!isNumber(user.antarpaket)) user.antarpaket = 0
|
| 401 |
+
if (!user.lbars) user.lbars = '[▒▒▒▒▒▒▒▒▒]'
|
| 402 |
+
if (!user.premium) user.premium = false
|
| 403 |
+
if (!user.premiumTime) user.premiumTime= 0
|
| 404 |
+
if (!user.vip) user.vip = 'tidak'
|
| 405 |
+
if (!isNumber(user.vipPoin)) user.vipPoin = 0
|
| 406 |
+
if (!user.role) user.role = 'Newbie ㋡'
|
| 407 |
+
if (!('autolevelup' in user)) user.autolevelup = true
|
| 408 |
+
if (!('lastIstigfar' in user)) user.lastIstigfar = true
|
| 409 |
+
|
| 410 |
+
//demon slayer dan rpg baru
|
| 411 |
+
if (!("skill" in user)) user.skill = ""
|
| 412 |
+
if (!("korps" in user)) user.korps = ""
|
| 413 |
+
if (!("korpsgrade" in user)) user.korpsgrade = ""
|
| 414 |
+
if (!("breaths" in user)) user.breaths = ""
|
| 415 |
+
if (!("magic" in user)) user.magic = ""
|
| 416 |
+
if (!("demon" in user)) user.demon = ""
|
| 417 |
+
if (!isNumber(user.darahiblis)) user.darahiblis = 0
|
| 418 |
+
if (!isNumber(user.demonblood)) user.demonblood = 0
|
| 419 |
+
if (!isNumber(user.demonkill)) user.demonkill = 0
|
| 420 |
+
if (!isNumber(user.hashirakill)) user.hashirakill = 0
|
| 421 |
+
if (!isNumber(user.alldemonkill)) user.alldemonkill = 0
|
| 422 |
+
if (!isNumber(user.allhashirakill)) user.allhashirakill = 0
|
| 423 |
+
if (!isNumber(user.attack)) user.attack = 0
|
| 424 |
+
if (!isNumber(user.strenght)) user.strenght = 0
|
| 425 |
+
if (!isNumber(user.speed)) user.speed = 0
|
| 426 |
+
if (!isNumber(user.defense)) user.defense = 0
|
| 427 |
+
if (!isNumber(user.regeneration)) user.regeneration = 0
|
| 428 |
+
if (!isNumber(user.dana)) user.dana = 0
|
| 429 |
+
if (!isNumber(user.gopay)) user.gopay = 0
|
| 430 |
+
if (!isNumber(user.ovo)) user.ovo = 0
|
| 431 |
+
if (!isNumber(user.lastngaji)) user.lastngaji = 0
|
| 432 |
+
if (!isNumber(user.lastlonte)) user.lastlonte = 0
|
| 433 |
+
if (!isNumber(user.lastkoboy)) user.lastkoboy = 0
|
| 434 |
+
if (!isNumber(user.lastdate)) user.lastdate = 0
|
| 435 |
+
if (!isNumber(user.lasttambang)) user.lasttambang = 0
|
| 436 |
+
if (!isNumber(user.lastngepet)) user.lastngepet = 0
|
| 437 |
+
if (!isNumber(user.lasttaxi)) user.lasttaxi = 0
|
| 438 |
+
if (!isNumber(user.taxi)) user.taxi = 0
|
| 439 |
+
if (!isNumber(user.lastyoutuber)) user.lastyoutuber = 0
|
| 440 |
+
if (!isNumber(user.subscribers)) user.subscribers = 0
|
| 441 |
+
if (!isNumber(user.viewers)) user.viewers = 0
|
| 442 |
+
if (!isNumber(user.like)) user.like = 0
|
| 443 |
+
if (!isNumber(user.playButton)) user.playButton = 0
|
| 444 |
+
|
| 445 |
+
} else global.db.data.users[m.sender] = {
|
| 446 |
+
taxi: 0,
|
| 447 |
+
lasttaxi: 0,
|
| 448 |
+
lastyoutuber: 0,
|
| 449 |
+
subscribers: 0,
|
| 450 |
+
viewers: 0,
|
| 451 |
+
like: 0,
|
| 452 |
+
playButton: 0,
|
| 453 |
+
saldo: 0,
|
| 454 |
+
pengeluaran: 0,
|
| 455 |
+
healt: 100,
|
| 456 |
+
health: 100,
|
| 457 |
+
energi: 100,
|
| 458 |
+
power: 100,
|
| 459 |
+
title: '',
|
| 460 |
+
haus: 100,
|
| 461 |
+
laper: 100,
|
| 462 |
+
tprem: 0,
|
| 463 |
+
stamina : 100,
|
| 464 |
+
level: 0,
|
| 465 |
+
follow: 0,
|
| 466 |
+
lastfollow: 0,
|
| 467 |
+
followers: 0,
|
| 468 |
+
pasangan: '',
|
| 469 |
+
sahabat: '',
|
| 470 |
+
location: 'Gubuk',
|
| 471 |
+
titlein: 'Belum Ada',
|
| 472 |
+
ultah: '',
|
| 473 |
+
waifu: 'Belum Di Set',
|
| 474 |
+
husbu: 'Belum Di Set',
|
| 475 |
+
pc : 0,
|
| 476 |
+
exp: 0,
|
| 477 |
+
coin: 0,
|
| 478 |
+
atm: 0,
|
| 479 |
+
limit: 100,
|
| 480 |
+
skata: 0,
|
| 481 |
+
tigame: 999,
|
| 482 |
+
lastclaim: 0,
|
| 483 |
+
judilast: 0,
|
| 484 |
+
lastnambang: 0,
|
| 485 |
+
lastnebang: 0,
|
| 486 |
+
lastmulung: 0,
|
| 487 |
+
lastkerja: 0,
|
| 488 |
+
lastmaling: 0,
|
| 489 |
+
lastbunuhi: 0,
|
| 490 |
+
lastbisnis: 0,
|
| 491 |
+
lastberbisnis: 0,
|
| 492 |
+
bisnis: 0,
|
| 493 |
+
berbisnis: 0,
|
| 494 |
+
lastmancing: 0,
|
| 495 |
+
pancing: 0,
|
| 496 |
+
pancingan: 0,
|
| 497 |
+
totalPancingan: 0,
|
| 498 |
+
kardus: 0,
|
| 499 |
+
botol: 0,
|
| 500 |
+
kaleng: 0,
|
| 501 |
+
money: 0,
|
| 502 |
+
litecoin: 0,
|
| 503 |
+
chip: 0,
|
| 504 |
+
tiketcoin: 0,
|
| 505 |
+
poin: 0,
|
| 506 |
+
bank: 0,
|
| 507 |
+
balance: 0,
|
| 508 |
+
diamond: 0,
|
| 509 |
+
emerald: 0,
|
| 510 |
+
rock: 0,
|
| 511 |
+
wood: 0,
|
| 512 |
+
berlian: 0,
|
| 513 |
+
iron: 0,
|
| 514 |
+
emas: 0,
|
| 515 |
+
common: 0,
|
| 516 |
+
uncommon: 0,
|
| 517 |
+
mythic: 0,
|
| 518 |
+
legendary: 0,
|
| 519 |
+
rumahsakit: 0,
|
| 520 |
+
tambang: 0,
|
| 521 |
+
camptroops: 0,
|
| 522 |
+
pertanian: 0,
|
| 523 |
+
fortress: 0,
|
| 524 |
+
trofi: 0,
|
| 525 |
+
rtrofi: 'perunggu',
|
| 526 |
+
makanan: 0,
|
| 527 |
+
troopcamp: 0,
|
| 528 |
+
shield: 0,
|
| 529 |
+
arlok: 0,
|
| 530 |
+
ojekk: 0,
|
| 531 |
+
ojek: 0,
|
| 532 |
+
lastngewe: 0,
|
| 533 |
+
ngewe: 0,
|
| 534 |
+
polisi: 0,
|
| 535 |
+
pedagang: 0,
|
| 536 |
+
dokter: 0,
|
| 537 |
+
petani: 0,
|
| 538 |
+
montir: 0,
|
| 539 |
+
kuli: 0,
|
| 540 |
+
korbanngocok: 0,
|
| 541 |
+
//+ stamina
|
| 542 |
+
coal: 0,
|
| 543 |
+
korekapi: 0,
|
| 544 |
+
ayambakar: 0,
|
| 545 |
+
gulai: 0,
|
| 546 |
+
rendang: 0,
|
| 547 |
+
ayamgoreng: 0,
|
| 548 |
+
oporayam: 0,
|
| 549 |
+
steak: 0,
|
| 550 |
+
babipanggang: 0,
|
| 551 |
+
ikanbakar: 0,
|
| 552 |
+
lelebakar: 0,
|
| 553 |
+
nilabakar: 0,
|
| 554 |
+
bawalbakar: 0,
|
| 555 |
+
udangbakar: 0,
|
| 556 |
+
pausbakar: 0,
|
| 557 |
+
kepitingbakar: 0,
|
| 558 |
+
soda: 0,
|
| 559 |
+
vodka: 0,
|
| 560 |
+
ganja: 0,
|
| 561 |
+
bandage: 0,
|
| 562 |
+
sushi: 0,
|
| 563 |
+
roti: 0,
|
| 564 |
+
//meracik
|
| 565 |
+
ramuan: 0,
|
| 566 |
+
lastramuanclaim: 0,
|
| 567 |
+
gems: 0,
|
| 568 |
+
cupon: 0,
|
| 569 |
+
lastgemsclaim: 0,
|
| 570 |
+
eleksirb: 0,
|
| 571 |
+
penduduk: 0,
|
| 572 |
+
archer: 0,
|
| 573 |
+
shadow: 0,
|
| 574 |
+
laststringclaim: 0,
|
| 575 |
+
lastpotionclaim: 0,
|
| 576 |
+
lastswordclaim: 0,
|
| 577 |
+
lastweaponclaim: 0,
|
| 578 |
+
lastironclaim: 0,
|
| 579 |
+
lastmancingclaim: 0,
|
| 580 |
+
anakpancingan: 0,
|
| 581 |
+
//mancing
|
| 582 |
+
as: 0,
|
| 583 |
+
paus: 0,
|
| 584 |
+
kepiting: 0,
|
| 585 |
+
gurita: 0,
|
| 586 |
+
cumi: 0,
|
| 587 |
+
buntal: 0,
|
| 588 |
+
dory: 0,
|
| 589 |
+
lumba: 0,
|
| 590 |
+
lobster: 0,
|
| 591 |
+
hiu: 0,
|
| 592 |
+
lele: 0,
|
| 593 |
+
nila: 0,
|
| 594 |
+
bawal: 0,
|
| 595 |
+
udang: 0,
|
| 596 |
+
ikan: 0,
|
| 597 |
+
orca: 0,
|
| 598 |
+
banteng: 0,
|
| 599 |
+
harimau: 0,
|
| 600 |
+
gajah: 0,
|
| 601 |
+
kambing: 0,
|
| 602 |
+
panda: 0,
|
| 603 |
+
buaya: 0,
|
| 604 |
+
kerbau : 0,
|
| 605 |
+
sapi: 0,
|
| 606 |
+
monyet : 0,
|
| 607 |
+
babihutan: 0,
|
| 608 |
+
babi: 0,
|
| 609 |
+
ayam: 0,
|
| 610 |
+
apel: 20,
|
| 611 |
+
ayamb: 0,
|
| 612 |
+
ayamg: 0,
|
| 613 |
+
ssapi: 0,
|
| 614 |
+
sapir: 0,
|
| 615 |
+
leleb: 0,
|
| 616 |
+
leleg: 0,
|
| 617 |
+
esteh: 0,
|
| 618 |
+
pet: 0,
|
| 619 |
+
potion: 0,
|
| 620 |
+
sampah: 0,
|
| 621 |
+
kucing: 0,
|
| 622 |
+
kucinglastclaim: 0,
|
| 623 |
+
kucingexp: 0,
|
| 624 |
+
kuda: 0,
|
| 625 |
+
kudalastclaim: 0,
|
| 626 |
+
rubah: 0,
|
| 627 |
+
rubahlastclaim: 0,
|
| 628 |
+
rubahexp: 0,
|
| 629 |
+
anjing: 0,
|
| 630 |
+
anjinglastclaim: 0,
|
| 631 |
+
anjingexp: 0,
|
| 632 |
+
naga: 0,
|
| 633 |
+
nagalastclaim: 0,
|
| 634 |
+
griffin: 0,
|
| 635 |
+
griffinlastclaim: 0,
|
| 636 |
+
centaur: 0,
|
| 637 |
+
fightnaga: 0,
|
| 638 |
+
centaurlastclaim: 0,
|
| 639 |
+
serigala: 0,
|
| 640 |
+
serigalalastclaim: 0,
|
| 641 |
+
serigalaexp: 0,
|
| 642 |
+
phonix: 0,
|
| 643 |
+
phonixlastclaim: 0,
|
| 644 |
+
phonixexp : 0,
|
| 645 |
+
makanannaga: 0,
|
| 646 |
+
makananphonix: 0,
|
| 647 |
+
makanancentaur: 0,
|
| 648 |
+
makananserigala: 0,
|
| 649 |
+
|
| 650 |
+
Banneduser: false,
|
| 651 |
+
BannedReason: '',
|
| 652 |
+
banned: false,
|
| 653 |
+
bannedTime: 0,
|
| 654 |
+
warn: 0,
|
| 655 |
+
afk: -1,
|
| 656 |
+
afkReason: '',
|
| 657 |
+
anakkucing: 0,
|
| 658 |
+
anakkuda: 0,
|
| 659 |
+
anakrubah: 0,
|
| 660 |
+
anakanjing: 0,
|
| 661 |
+
makananpet: 0,
|
| 662 |
+
makananPet: 0,
|
| 663 |
+
antispam: 0,
|
| 664 |
+
antispamlastclaim: 0,
|
| 665 |
+
kayu: 0,
|
| 666 |
+
batu: 0,
|
| 667 |
+
string: 0,
|
| 668 |
+
umpan: 0,
|
| 669 |
+
armor: 0,
|
| 670 |
+
armordurability: 0,
|
| 671 |
+
weapon: 0,
|
| 672 |
+
weapondurability: 0,
|
| 673 |
+
sword: 0,
|
| 674 |
+
sworddurability: 0,
|
| 675 |
+
pickaxe: 0,
|
| 676 |
+
pickaxedurability: 0,
|
| 677 |
+
fishingrod: 0,
|
| 678 |
+
fishingroddurability: 0,
|
| 679 |
+
katana: 0,
|
| 680 |
+
katanadurability: 0,
|
| 681 |
+
bow: 0,
|
| 682 |
+
bowdurability: 0,
|
| 683 |
+
kapak: 0,
|
| 684 |
+
kapakdurability: 0,
|
| 685 |
+
axe: 0,
|
| 686 |
+
axedurability: 0,
|
| 687 |
+
pisau: 0,
|
| 688 |
+
pisaudurability: 0,
|
| 689 |
+
kerjasatu: 0,
|
| 690 |
+
kerjadua: 0,
|
| 691 |
+
kerjatiga: 0,
|
| 692 |
+
kerjaempat: 0,
|
| 693 |
+
kerjalima: 0,
|
| 694 |
+
kerjaenam: 0,
|
| 695 |
+
kerjatujuh: 0,
|
| 696 |
+
kerjadelapan: 0,
|
| 697 |
+
kerjasembilan: 0,
|
| 698 |
+
kerjasepuluh: 0,
|
| 699 |
+
kerjasebelas: 0,
|
| 700 |
+
kerjaduabelas: 0,
|
| 701 |
+
kerjatigabelas: 0,
|
| 702 |
+
kerjaempatbelas: 0,
|
| 703 |
+
kerjalimabelas: 0,
|
| 704 |
+
pekerjaansatu: 0,
|
| 705 |
+
pekerjaandua: 0,
|
| 706 |
+
pekerjaantiga: 0,
|
| 707 |
+
pekerjaanempat: 0,
|
| 708 |
+
pekerjaanlima: 0,
|
| 709 |
+
pekerjaanenam: 0,
|
| 710 |
+
pekerjaantujuh: 0,
|
| 711 |
+
pekerjaandelapan: 0,
|
| 712 |
+
pekerjaansembilan: 0,
|
| 713 |
+
pekerjaansepuluh: 0,
|
| 714 |
+
pekerjaansebelas: 0,
|
| 715 |
+
pekerjaanduabelas: 0,
|
| 716 |
+
pekerjaantigabelas: 0,
|
| 717 |
+
pekerjaanempatbelas: 0,
|
| 718 |
+
pekerjaanlimabelas: 0,
|
| 719 |
+
lastadventure: 0,
|
| 720 |
+
lastwar: 0,
|
| 721 |
+
lastberkebon: 0,
|
| 722 |
+
lastberburu: 0,
|
| 723 |
+
lastbansos: 0,
|
| 724 |
+
lastrampok: 0,
|
| 725 |
+
lastkill: 0,
|
| 726 |
+
lastfishing: 0,
|
| 727 |
+
lastdungeon: 0,
|
| 728 |
+
lastduel: 0,
|
| 729 |
+
lastmining: 0,
|
| 730 |
+
lasthourly: 0,
|
| 731 |
+
lastdagang: 0,
|
| 732 |
+
lasthunt: 0,
|
| 733 |
+
lasthun : 0,
|
| 734 |
+
lastweekly: 0,
|
| 735 |
+
lastmonthly: 0,
|
| 736 |
+
lastyearly: 0,
|
| 737 |
+
lastjb: 0,
|
| 738 |
+
lastrob: 0,
|
| 739 |
+
lastdaang: 0,
|
| 740 |
+
lastngojek: 0,
|
| 741 |
+
lastgrab: 0,
|
| 742 |
+
lastngocok: 0,
|
| 743 |
+
lastturu: 0,
|
| 744 |
+
lastseen: 0,
|
| 745 |
+
lastSetStatus: 0,
|
| 746 |
+
registered: false,
|
| 747 |
+
apel: 20,
|
| 748 |
+
mangga: 0,
|
| 749 |
+
stroberi: 0,
|
| 750 |
+
semangka: 0,
|
| 751 |
+
jeruk: 0,
|
| 752 |
+
semangka: 0,
|
| 753 |
+
name: this.getName(m.sender),
|
| 754 |
+
age: -1,
|
| 755 |
+
regTime: -1,
|
| 756 |
+
premiumDate: -1,
|
| 757 |
+
premium: false,
|
| 758 |
+
premiumTime: 0,
|
| 759 |
+
vip: 'tidak',
|
| 760 |
+
vipPoin: 0,
|
| 761 |
+
job: 'Pengangguran',
|
| 762 |
+
jobexp: 0,
|
| 763 |
+
jail: false,
|
| 764 |
+
penjara: false,
|
| 765 |
+
antarpaket: 0,
|
| 766 |
+
dirawat: false,
|
| 767 |
+
lbars: '[▒▒▒▒▒▒▒▒▒]',
|
| 768 |
+
role: 'Newbie ㋡',
|
| 769 |
+
registered: false,
|
| 770 |
+
name: this.getName(m.sender),
|
| 771 |
+
age: -1,
|
| 772 |
+
regTime: -1,
|
| 773 |
+
autolevelup: true,
|
| 774 |
+
lastIstigfar: 0,
|
| 775 |
+
|
| 776 |
+
skill: "",
|
| 777 |
+
korps: "",
|
| 778 |
+
korpsgrade: "",
|
| 779 |
+
demon: "",
|
| 780 |
+
breaths: "",
|
| 781 |
+
magic: "",
|
| 782 |
+
darahiblis: 0,
|
| 783 |
+
demonblood: 0,
|
| 784 |
+
demonkill: 0,
|
| 785 |
+
hashirakill: 0,
|
| 786 |
+
alldemonkill: 0,
|
| 787 |
+
allhashirakill: 0,
|
| 788 |
+
attack: 0,
|
| 789 |
+
speed: 0,
|
| 790 |
+
strenght: 0,
|
| 791 |
+
defense: 0,
|
| 792 |
+
regeneration: 0,
|
| 793 |
+
ovo: 0,
|
| 794 |
+
dana: 0,
|
| 795 |
+
gopay: 0,
|
| 796 |
+
lastngaji: 0,
|
| 797 |
+
lastlonte: 0,
|
| 798 |
+
lastkoboy: 0,
|
| 799 |
+
lastdate: 0,
|
| 800 |
+
lasttambang: 0,
|
| 801 |
+
lastngepet: 0,
|
| 802 |
+
}
|
| 803 |
+
let chat = global.db.data.chats[m.chat]
|
| 804 |
+
if (typeof chat !== 'object') global.db.data.chats[m.chat] = {}
|
| 805 |
+
if (chat) {
|
| 806 |
+
if (!('isBanned' in chat)) chat.isBanned = false
|
| 807 |
+
if (!('welcome' in chat)) chat.welcome = true
|
| 808 |
+
if (!isNumber(chat.welcometype)) chat.welcometype = 1
|
| 809 |
+
if (!('detect' in chat)) chat.detect = false
|
| 810 |
+
if (!('isBannedTime' in chat)) chat.isBannedTime = false
|
| 811 |
+
if (!('mute' in chat)) chat.mute = false
|
| 812 |
+
if (!('listStr' in chat)) chat.listStr = {}
|
| 813 |
+
if (!('sWelcome' in chat)) chat.sWelcome = 'Hai, @user!\nSelamat datang di grup @subject\n\n@desc'
|
| 814 |
+
if (!('sBye' in chat)) chat.sBye = 'Selamat tinggal @user!'
|
| 815 |
+
if (!('sPromote' in chat)) chat.sPromote = ''
|
| 816 |
+
if (!('sDemote' in chat)) chat.sDemote = ''
|
| 817 |
+
if (!('delete' in chat)) chat.delete = true
|
| 818 |
+
if (!('antiLink' in chat)) chat.antiLink = true
|
| 819 |
+
if (!('antiLinknokick' in chat)) chat.antiLinknokick = false
|
| 820 |
+
if (!('antiSticker' in chat)) chat.antiSticker = false
|
| 821 |
+
if (!('antiStickernokick' in chat)) chat.antiStickernokick = false
|
| 822 |
+
if (!('viewonce' in chat)) chat.viewonce = false
|
| 823 |
+
if (!('antiToxic' in chat)) chat.antiToxic = false
|
| 824 |
+
if (!isNumber(chat.expired)) chat.expired = 0
|
| 825 |
+
if (!("memgc" in chat)) chat.memgc = {}
|
| 826 |
+
if (!('antilinkig' in chat)) chat.antilinkig = false
|
| 827 |
+
if (!('antilinkignokick' in chat)) chat.antilinkignokick = false
|
| 828 |
+
if (!('antilinkfb' in chat)) chat.antilinkfb = false
|
| 829 |
+
if (!('antilinkfbnokick' in chat)) chat.antilinkfbnokick = false
|
| 830 |
+
if (!('antilinktwit' in chat)) chat.antilinktwit = false
|
| 831 |
+
if (!('antilinktwitnokick' in chat)) chat.antilinktwitnokick = false
|
| 832 |
+
if (!('antilinkyt' in chat)) chat.antilinkyt = false
|
| 833 |
+
if (!('antilinkytnokick' in chat)) chat.antilinkytnokick = false
|
| 834 |
+
if (!('antilinktele' in chat)) chat.antilinktele = false
|
| 835 |
+
if (!('antilinktelenokick' in chat)) chat.antilinktelenokick = false
|
| 836 |
+
if (!('antilinkwame' in chat)) chat.antilinkwame = false
|
| 837 |
+
if (!('antilinkwamenokick' in chat)) chat.antilinkwamenokick = false
|
| 838 |
+
if (!('antilinkall' in chat)) chat.antilinkall = false
|
| 839 |
+
if (!('antilinkallnokick' in chat)) chat.antilinkallnokick = false
|
| 840 |
+
if (!('antilinktt' in chat)) chat.antilinktt = false
|
| 841 |
+
if (!('antilinkttnokick' in chat)) chat.antilinkttnokick = false
|
| 842 |
+
if (!('antibot' in chat)) chat.antibot = false
|
| 843 |
+
} else global.db.data.chats[m.chat] = {
|
| 844 |
+
isBanned: false,
|
| 845 |
+
welcome: true,
|
| 846 |
+
welcometype: 1,
|
| 847 |
+
detect: false,
|
| 848 |
+
isBannedTime: false,
|
| 849 |
+
mute: false,
|
| 850 |
+
listStr: {},
|
| 851 |
+
sWelcome: 'Hai, @user!\nSelamat datang di grup @subject\n\n@desc',
|
| 852 |
+
sBye: 'Selamat tinggal @user!',
|
| 853 |
+
sPromote: '',
|
| 854 |
+
sDemote: '',
|
| 855 |
+
delete: false,
|
| 856 |
+
antiLink: false,
|
| 857 |
+
antiLinknokick: false,
|
| 858 |
+
antiSticker: false,
|
| 859 |
+
antiStickernokick: false,
|
| 860 |
+
viewonce: false,
|
| 861 |
+
antiToxic: true,
|
| 862 |
+
antilinkig: false,
|
| 863 |
+
antilinkignokick: false,
|
| 864 |
+
antilinkyt: false,
|
| 865 |
+
antilinkytnokick: false,
|
| 866 |
+
antilinktwit: false,
|
| 867 |
+
antilinktwitnokick: false,
|
| 868 |
+
antilinkfb: false,
|
| 869 |
+
antilinkfbnokick: false,
|
| 870 |
+
antilinkall: false,
|
| 871 |
+
antilinkallnokick: false,
|
| 872 |
+
antilinkwame: false,
|
| 873 |
+
antilinkwamenokick: false,
|
| 874 |
+
antilinktele: false,
|
| 875 |
+
antilinktelenokick: false,
|
| 876 |
+
antilinktt: false,
|
| 877 |
+
antilinkttnokick: false,
|
| 878 |
+
antibot: false,
|
| 879 |
+
rpg: false,
|
| 880 |
+
}
|
| 881 |
+
let memgc = global.db.data.chats[m.chat].memgc[m.sender]
|
| 882 |
+
if (typeof memgc !== 'object') global.db.data.chats[m.chat].memgc[m.sender] = {}
|
| 883 |
+
if (memgc) {
|
| 884 |
+
if (!('blacklist' in memgc)) memgc.blacklist = false
|
| 885 |
+
if (!('banned' in memgc)) memgc.banned = false
|
| 886 |
+
if (!isNumber(memgc.bannedTime)) memgc.bannedTime = 0
|
| 887 |
+
if (!isNumber(memgc.chat)) memgc.chat = 0
|
| 888 |
+
if (!isNumber(memgc.chatTotal)) memgc.chatTotal = 0
|
| 889 |
+
if (!isNumber(memgc.command)) memgc.command = 0
|
| 890 |
+
if (!isNumber(memgc.commandTotal)) memgc.commandTotal = 0
|
| 891 |
+
if (!isNumber(memgc.lastseen)) memgc.lastseen = 0
|
| 892 |
+
} else global.db.data.chats[m.chat].memgc[m.sender] = {
|
| 893 |
+
blacklist: false,
|
| 894 |
+
banned: false,
|
| 895 |
+
bannedTime: 0,
|
| 896 |
+
chat: 0,
|
| 897 |
+
chatTotal: 0,
|
| 898 |
+
command: 0,
|
| 899 |
+
commandTotal: 0,
|
| 900 |
+
lastseen: 0
|
| 901 |
+
}
|
| 902 |
+
} catch (e) {
|
| 903 |
+
console.error(e)
|
| 904 |
+
}
|
| 905 |
+
if (opts['nyimak']) return
|
| 906 |
+
if (!m.fromMe && opts['self']) return
|
| 907 |
+
if (opts['pconly'] && m.chat.endsWith('g.us')) return
|
| 908 |
+
if (opts['gconly'] && !m.chat.endsWith('g.us')) return
|
| 909 |
+
if (opts['swonly'] && m.chat !== 'status@broadcast') return
|
| 910 |
+
if (typeof m.text !== 'string') m.text = ''
|
| 911 |
+
if (opts['queque'] && m.text) {
|
| 912 |
+
this.msgqueque.push(m.id || m.key.id)
|
| 913 |
+
await delay(this.msgqueque.length * 1000)
|
| 914 |
+
}
|
| 915 |
+
for (let name in global.plugins) {
|
| 916 |
+
let plugin = global.plugins[name]
|
| 917 |
+
if (!plugin) continue
|
| 918 |
+
if (plugin.disabled) continue
|
| 919 |
+
if (!plugin.all) continue
|
| 920 |
+
if (typeof plugin.all !== 'function') continue
|
| 921 |
+
try {
|
| 922 |
+
await plugin.all.call(this, m, chatUpdate)
|
| 923 |
+
} catch (e) {
|
| 924 |
+
if (typeof e === 'string') continue
|
| 925 |
+
console.error(e)
|
| 926 |
+
}
|
| 927 |
+
}
|
| 928 |
+
if (m.id.startsWith('BAE5') && m.id.length === 16 || m.isBaileys && m.fromMe) return
|
| 929 |
+
m.exp += Math.ceil(Math.random() * 10)
|
| 930 |
+
|
| 931 |
+
let usedPrefix
|
| 932 |
+
let _user = global.db.data && global.db.data.users && global.db.data.users[m.sender]
|
| 933 |
+
|
| 934 |
+
let isROwner = [global.conn.user.jid, ...global.owner].map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net').includes(m.sender)
|
| 935 |
+
let isOwner = isROwner || m.fromMe
|
| 936 |
+
let isMods = isOwner || global.mods.map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net').includes(m.sender)
|
| 937 |
+
let isPrems = isROwner || (db.data.users[m.sender].premiumTime > 0 || db.data.users[m.sender].premium)
|
| 938 |
+
let groupMetadata = (m.isGroup ? (conn.chats[m.chat] || {}).metadata : {}) || {}
|
| 939 |
+
let participants = (m.isGroup ? groupMetadata.participants : []) || []
|
| 940 |
+
let user = (m.isGroup ? participants.find(u => conn.decodeJid(u.id) === m.sender) : {}) || {} // User Data
|
| 941 |
+
let bot = (m.isGroup ? participants.find(u => conn.decodeJid(u.id) == this.user.jid) : {}) || {} // Your Data
|
| 942 |
+
let isAdmin = user && user.admin || false // Is User Admin?
|
| 943 |
+
let isBotAdmin = bot && bot.admin || false // Are you Admin?
|
| 944 |
+
for (let name in global.plugins) {
|
| 945 |
+
let plugin = global.plugins[name]
|
| 946 |
+
if (!plugin) continue
|
| 947 |
+
if (plugin.disabled) continue
|
| 948 |
+
if (!opts['restrict']) if (plugin.tags && plugin.tags.includes('admin')) {
|
| 949 |
+
// global.dfail('restrict', m, this)
|
| 950 |
+
continue
|
| 951 |
+
}
|
| 952 |
+
const str2Regex = str => str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
|
| 953 |
+
let _prefix = plugin.customPrefix ? plugin.customPrefix : conn.prefix ? conn.prefix : global.prefix
|
| 954 |
+
let match = (_prefix instanceof RegExp ? // RegExp Mode?
|
| 955 |
+
[[_prefix.exec(m.text), _prefix]] :
|
| 956 |
+
Array.isArray(_prefix) ? // Array?
|
| 957 |
+
_prefix.map(p => {
|
| 958 |
+
let re = p instanceof RegExp ? // RegExp in Array?
|
| 959 |
+
p :
|
| 960 |
+
new RegExp(str2Regex(p))
|
| 961 |
+
return [re.exec(m.text), re]
|
| 962 |
+
}) :
|
| 963 |
+
typeof _prefix === 'string' ? // String?
|
| 964 |
+
[[new RegExp(str2Regex(_prefix)).exec(m.text), new RegExp(str2Regex(_prefix))]] :
|
| 965 |
+
[[[], new RegExp]]
|
| 966 |
+
).find(p => p[1])
|
| 967 |
+
if (typeof plugin.before === 'function') if (await plugin.before.call(this, m, {
|
| 968 |
+
match,
|
| 969 |
+
conn: this,
|
| 970 |
+
participants,
|
| 971 |
+
groupMetadata,
|
| 972 |
+
user,
|
| 973 |
+
bot,
|
| 974 |
+
isROwner,
|
| 975 |
+
isOwner,
|
| 976 |
+
isAdmin,
|
| 977 |
+
isBotAdmin,
|
| 978 |
+
isPrems,
|
| 979 |
+
chatUpdate,
|
| 980 |
+
})) continue
|
| 981 |
+
if (typeof plugin !== 'function') continue
|
| 982 |
+
if ((usedPrefix = (match[0] || '')[0])) {
|
| 983 |
+
let noPrefix = m.text.replace(usedPrefix, '')
|
| 984 |
+
let [command, ...args] = noPrefix.trim().split` `.filter(v => v)
|
| 985 |
+
args = args || []
|
| 986 |
+
let _args = noPrefix.trim().split` `.slice(1)
|
| 987 |
+
let text = _args.join` `
|
| 988 |
+
command = (command || '').toLowerCase()
|
| 989 |
+
let fail = plugin.fail || global.dfail // When failed
|
| 990 |
+
let isAccept = plugin.command instanceof RegExp ? // RegExp Mode?
|
| 991 |
+
plugin.command.test(command) :
|
| 992 |
+
Array.isArray(plugin.command) ? // Array?
|
| 993 |
+
plugin.command.some(cmd => cmd instanceof RegExp ? // RegExp in Array?
|
| 994 |
+
cmd.test(command) :
|
| 995 |
+
cmd === command
|
| 996 |
+
) :
|
| 997 |
+
typeof plugin.command === 'string' ? // String?
|
| 998 |
+
plugin.command === command :
|
| 999 |
+
false
|
| 1000 |
+
|
| 1001 |
+
if (!isAccept) continue
|
| 1002 |
+
m.plugin = name
|
| 1003 |
+
if (m.chat in global.db.data.chats || m.sender in global.db.data.users) {
|
| 1004 |
+
let chat = global.db.data.chats[m.chat]
|
| 1005 |
+
let user = global.db.data.users[m.sender]
|
| 1006 |
+
if (name != 'group-modebot.js' && name != 'owner-unbanchat.js' && name != 'owner-exec.js' && name != 'owner-exec2.js' && name != 'tool-delete.js' && (chat?.isBanned || chat?.mute))
|
| 1007 |
+
return
|
| 1008 |
+
if (name != 'unbanchat.js' && chat && chat.isBanned) return // Except this
|
| 1009 |
+
if (name != 'unbanuser.js' && user && user.banned) return
|
| 1010 |
+
if (m.isGroup) {
|
| 1011 |
+
chat.memgc[m.sender].command++
|
| 1012 |
+
chat.memgc[m.sender].commandTotal++
|
| 1013 |
+
chat.memgc[m.sender].lastCmd = Date.now()
|
| 1014 |
+
}
|
| 1015 |
+
user.command++
|
| 1016 |
+
user.commandTotal++
|
| 1017 |
+
user.lastCmd = Date.now()
|
| 1018 |
+
}
|
| 1019 |
+
|
| 1020 |
+
if (plugin.rowner && plugin.owner && !(isROwner || isOwner)) { // Both Owner
|
| 1021 |
+
fail('owner', m, this)
|
| 1022 |
+
continue
|
| 1023 |
+
}
|
| 1024 |
+
if (plugin.rowner && !isROwner) { // Real Owner
|
| 1025 |
+
fail('rowner', m, this)
|
| 1026 |
+
continue
|
| 1027 |
+
}
|
| 1028 |
+
if (plugin.owner && !isOwner) { // Number Owner
|
| 1029 |
+
fail('owner', m, this)
|
| 1030 |
+
continue
|
| 1031 |
+
}
|
| 1032 |
+
if (plugin.mods && !isMods) { // Moderator
|
| 1033 |
+
fail('mods', m, this)
|
| 1034 |
+
continue
|
| 1035 |
+
}
|
| 1036 |
+
if (plugin.premium && !isPrems) { // Premium
|
| 1037 |
+
fail('premium', m, this)
|
| 1038 |
+
continue
|
| 1039 |
+
}
|
| 1040 |
+
if (plugin.group && !m.isGroup) { // Group Only
|
| 1041 |
+
fail('group', m, this)
|
| 1042 |
+
continue
|
| 1043 |
+
} else if (plugin.botAdmin && !isBotAdmin) { // You Admin
|
| 1044 |
+
fail('botAdmin', m, this)
|
| 1045 |
+
continue
|
| 1046 |
+
} else if (plugin.admin && !isAdmin) { // User Admin
|
| 1047 |
+
fail('admin', m, this)
|
| 1048 |
+
continue
|
| 1049 |
+
}
|
| 1050 |
+
if (plugin.private && m.isGroup) { // Private Chat Only
|
| 1051 |
+
fail('private', m, this)
|
| 1052 |
+
continue
|
| 1053 |
+
}
|
| 1054 |
+
if (plugin.register == true && _user.registered == false) { // Butuh daftar?
|
| 1055 |
+
fail('unreg', m, this)
|
| 1056 |
+
continue
|
| 1057 |
+
}
|
| 1058 |
+
m.isCommand = true
|
| 1059 |
+
let xp = 'exp' in plugin ? parseInt(plugin.exp) : 17 // XP Earning per command
|
| 1060 |
+
if (xp > 200) m.reply('Ngecit -_-') // Hehehe
|
| 1061 |
+
else m.exp += xp
|
| 1062 |
+
if (!isPrems && plugin.limit && global.db.data.users[m.sender].limit < plugin.limit * 1) {
|
| 1063 |
+
this.reply(m.chat, `Limit anda habis, silahkan beli melalui *${usedPrefix}buy* atau beli di *${usedPrefix}shop*`, m)
|
| 1064 |
+
continue // Limit habis
|
| 1065 |
+
}
|
| 1066 |
+
if (plugin.level > _user.level) {
|
| 1067 |
+
this.reply(m.chat, `diperlukan level ${plugin.level} untuk menggunakan perintah ini. Level kamu ${_user.level}\m gunakan .levelup untuk menaikan level!`, m)
|
| 1068 |
+
continue // If the level has not been reached
|
| 1069 |
+
}
|
| 1070 |
+
let extra = {
|
| 1071 |
+
match,
|
| 1072 |
+
usedPrefix,
|
| 1073 |
+
noPrefix,
|
| 1074 |
+
_args,
|
| 1075 |
+
args,
|
| 1076 |
+
command,
|
| 1077 |
+
text,
|
| 1078 |
+
conn: this,
|
| 1079 |
+
participants,
|
| 1080 |
+
groupMetadata,
|
| 1081 |
+
user,
|
| 1082 |
+
bot,
|
| 1083 |
+
isROwner,
|
| 1084 |
+
isOwner,
|
| 1085 |
+
isAdmin,
|
| 1086 |
+
isBotAdmin,
|
| 1087 |
+
isPrems,
|
| 1088 |
+
chatUpdate,
|
| 1089 |
+
}
|
| 1090 |
+
try {
|
| 1091 |
+
await plugin.call(this, m, extra)
|
| 1092 |
+
if (!isPrems) m.limit = m.limit || plugin.limit || false
|
| 1093 |
+
} catch (e) {
|
| 1094 |
+
// Error occured
|
| 1095 |
+
m.error = e
|
| 1096 |
+
console.error(e)
|
| 1097 |
+
if (e) {
|
| 1098 |
+
let text = util.format(e)
|
| 1099 |
+
for (let key of Object.values(APIKeys))
|
| 1100 |
+
text = text.replace(new RegExp(key, 'g'), '#HIDDEN#')
|
| 1101 |
+
if (e.name)
|
| 1102 |
+
for (let jid of owner.map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net').filter(v => v != this.user.jid)) {
|
| 1103 |
+
let data = (await this.onWhatsApp(jid))[0] || {}
|
| 1104 |
+
if (data.exists)
|
| 1105 |
+
m.reply(`*Plugin:* ${m.plugin}\n*Sender:* @${m.sender.split`@`[0]}\n*Chat:* ${m.chat}\n*Chat Name:* ${await this.getName(m.chat)}\n*Command:* ${usedPrefix}${command} ${args.join(' ')}\n\n\`\`\`${text}\`\`\``.trim(), data.jid, { mentions: [m.sender] })
|
| 1106 |
+
}
|
| 1107 |
+
m.reply(text)
|
| 1108 |
+
}
|
| 1109 |
+
} finally {
|
| 1110 |
+
// m.reply(util.format(_user))
|
| 1111 |
+
if (typeof plugin.after === 'function') {
|
| 1112 |
+
try {
|
| 1113 |
+
await plugin.after.call(this, m, extra)
|
| 1114 |
+
} catch (e) {
|
| 1115 |
+
console.error(e)
|
| 1116 |
+
}
|
| 1117 |
+
}
|
| 1118 |
+
if (m.limit) m.reply(+ m.limit + ' Limit terpakai')
|
| 1119 |
+
}
|
| 1120 |
+
break
|
| 1121 |
+
}
|
| 1122 |
+
}
|
| 1123 |
+
} catch (e) {
|
| 1124 |
+
console.error(e)
|
| 1125 |
+
} finally {
|
| 1126 |
+
//conn.sendPresenceUpdate('composing', m.chat) // kalo pengen auto vn hapus // di baris dekat conn
|
| 1127 |
+
//console.log(global.db.data.users[m.sender])
|
| 1128 |
+
let user, stats = global.db.data.stats
|
| 1129 |
+
if (m) {
|
| 1130 |
+
if (m.sender && (user = global.db.data.users[m.sender])) {
|
| 1131 |
+
user.exp += m.exp
|
| 1132 |
+
user.limit -= m.limit * 1
|
| 1133 |
+
}
|
| 1134 |
+
|
| 1135 |
+
let stat
|
| 1136 |
+
if (m.plugin) {
|
| 1137 |
+
let now = + new Date
|
| 1138 |
+
if (m.plugin in stats) {
|
| 1139 |
+
stat = stats[m.plugin]
|
| 1140 |
+
if (!isNumber(stat.total)) stat.total = 1
|
| 1141 |
+
if (!isNumber(stat.success)) stat.success = m.error != null ? 0 : 1
|
| 1142 |
+
if (!isNumber(stat.last)) stat.last = now
|
| 1143 |
+
if (!isNumber(stat.lastSuccess)) stat.lastSuccess = m.error != null ? 0 : now
|
| 1144 |
+
} else stat = stats[m.plugin] = {
|
| 1145 |
+
total: 1,
|
| 1146 |
+
success: m.error != null ? 0 : 1,
|
| 1147 |
+
last: now,
|
| 1148 |
+
lastSuccess: m.error != null ? 0 : now
|
| 1149 |
+
}
|
| 1150 |
+
stat.total += 1
|
| 1151 |
+
stat.last = now
|
| 1152 |
+
if (m.error == null) {
|
| 1153 |
+
stat.success += 1
|
| 1154 |
+
stat.lastSuccess = now
|
| 1155 |
+
}
|
| 1156 |
+
}
|
| 1157 |
+
}
|
| 1158 |
+
|
| 1159 |
+
try {
|
| 1160 |
+
require('./lib/print')(m, this)
|
| 1161 |
+
} catch (e) {
|
| 1162 |
+
console.log(m, m.quoted, e)
|
| 1163 |
+
}
|
| 1164 |
+
if (opts['autoread']) await this.readMessages([m.key])
|
| 1165 |
+
}
|
| 1166 |
+
},
|
| 1167 |
+
|
| 1168 |
+
async participantsUpdate({ id, participants, action }) {
|
| 1169 |
+
if (opts['self']) return
|
| 1170 |
+
// if (id in conn.chats) return // First login will spam
|
| 1171 |
+
if (global.isInit) return
|
| 1172 |
+
let chat = db.data.chats[id] || {}
|
| 1173 |
+
let text = ''
|
| 1174 |
+
switch (action) {
|
| 1175 |
+
case 'add':
|
| 1176 |
+
case 'remove':
|
| 1177 |
+
case 'leave':
|
| 1178 |
+
case 'invite':
|
| 1179 |
+
case 'invite_v4':
|
| 1180 |
+
if (chat.welcome) {
|
| 1181 |
+
let groupMetadata = await this.groupMetadata(id) || (conn.chats[id] || {}).metadata
|
| 1182 |
+
for (let user of participants) {
|
| 1183 |
+
let pp = 'https://btch.pages.dev/file/70e8de9b1879568954f09.jpg'
|
| 1184 |
+
try {
|
| 1185 |
+
pp = await this.profilePictureUrl(user, 'image')
|
| 1186 |
+
} catch (e) {
|
| 1187 |
+
} finally {
|
| 1188 |
+
text = (action === 'add' ? (chat.sWelcome || this.welcome || conn.welcome || 'Welcome, @user!').replace('@subject', await this.getName(id)).replace('@desc', groupMetadata.desc ? groupMetadata.desc.toString() : '') :
|
| 1189 |
+
(chat.sBye || this.bye || conn.bye || 'Bye, @user!')).replace('@user', '@' + user.split('@')[0])
|
| 1190 |
+
this.sendMessage(id, {
|
| 1191 |
+
text: text,
|
| 1192 |
+
contextInfo: {
|
| 1193 |
+
mentionedJid: [user],
|
| 1194 |
+
externalAdReply: {
|
| 1195 |
+
title: global.wm,
|
| 1196 |
+
body: '',
|
| 1197 |
+
thumbnailUrl: pp,
|
| 1198 |
+
sourceUrl: 'https://chat.whatsapp.com/KIcqnzY4NJMHXPTz8Xopvd',
|
| 1199 |
+
mediaType: 1,
|
| 1200 |
+
renderLargerThumbnail: true
|
| 1201 |
+
}}}, { quoted: null })
|
| 1202 |
+
}
|
| 1203 |
+
}
|
| 1204 |
+
}
|
| 1205 |
+
break
|
| 1206 |
+
case 'promote':
|
| 1207 |
+
text = (chat.sPromote || this.spromote || conn.spromote || '@user ```is now Admin```')
|
| 1208 |
+
case 'demote':
|
| 1209 |
+
if (!text) text = (chat.sDemote || this.sdemote || conn.sdemote || '@user ```is no longer Admin```')
|
| 1210 |
+
text = text.replace('@user', '@' + participants[0].split('@')[0])
|
| 1211 |
+
if (chat.detect) this.sendMessage(id, text, {
|
| 1212 |
+
contextInfo: {
|
| 1213 |
+
mentionedJid: this.parseMention(text)
|
| 1214 |
+
}
|
| 1215 |
+
})
|
| 1216 |
+
break
|
| 1217 |
+
}
|
| 1218 |
+
},
|
| 1219 |
+
async delete({ remoteJid, fromMe, id, participant }) {
|
| 1220 |
+
/*if (fromMe) return
|
| 1221 |
+
let chats = Object.entries(conn.chats).find(([user, data]) => data.messages && data.messages[id])
|
| 1222 |
+
if (!chats) return
|
| 1223 |
+
let msg = JSON.parse(chats[1].messages[id])
|
| 1224 |
+
let chat = global.db.data.chats[msg.key.remoteJid] || {}
|
| 1225 |
+
if (chat.delete) return
|
| 1226 |
+
await this.reply(msg.key.remoteJid, `
|
| 1227 |
+
Terdeteksi @${participant.split`@`[0]} telah menghapus pesan
|
| 1228 |
+
Untuk mematikan fitur ini, ketik
|
| 1229 |
+
*.enable delete*
|
| 1230 |
+
`.trim(), msg, {
|
| 1231 |
+
mentions: [participant]
|
| 1232 |
+
})
|
| 1233 |
+
this.copyNForward(msg.key.remoteJid, msg).catch(e => console.log(e, msg))*/
|
| 1234 |
+
}
|
| 1235 |
+
}
|
| 1236 |
+
|
| 1237 |
+
global.dfail = (type, m, conn) => {
|
| 1238 |
+
let msg = {
|
| 1239 |
+
rowner: 'Perintah ini hanya dapat digunakan oleh _*OWWNER!1!1!*_',
|
| 1240 |
+
owner: 'Perintah ini hanya dapat digunakan oleh _*Owner Bot*_!',
|
| 1241 |
+
mods: 'Perintah ini hanya dapat digunakan oleh _*Moderator*_ !',
|
| 1242 |
+
premium: 'Perintah ini hanya untuk member _*Premium*_ !',
|
| 1243 |
+
group: 'Perintah ini hanya dapat digunakan di grup!',
|
| 1244 |
+
private: 'Perintah ini hanya dapat digunakan di Chat Pribadi!',
|
| 1245 |
+
admin: 'Perintah ini hanya untuk *Admin* grup!',
|
| 1246 |
+
botAdmin: 'Jadikan bot sebagai *Admin* untuk menggunakan perintah ini!',
|
| 1247 |
+
unreg: 'Silahkan daftar untuk menggunakan fitur ini dengan cara mengetik:\n\n*#daftar nama.umur*\n\nContoh: *#daftar Mansur.16*',
|
| 1248 |
+
restrict: 'Fitur ini di *disable*!'
|
| 1249 |
+
}[type]
|
| 1250 |
+
if (msg) return m.reply(msg)
|
| 1251 |
+
}
|
| 1252 |
+
|
| 1253 |
+
let fs = require('fs')
|
| 1254 |
+
let chalk = require('chalk')
|
| 1255 |
+
let file = require.resolve(__filename)
|
| 1256 |
+
fs.watchFile(file, () => {
|
| 1257 |
+
fs.unwatchFile(file)
|
| 1258 |
+
console.log(chalk.redBright("Update 'handler.js'"))
|
| 1259 |
+
delete require.cache[file]
|
| 1260 |
+
if (global.reloadHandler) console.log(global.reloadHandler())
|
| 1261 |
+
})
|
heroku.yml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
build:
|
| 2 |
+
docker:
|
| 3 |
+
web: Dockerfile
|
index.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const cluster = require('cluster');
|
| 2 |
+
const { spawn } = require('child_process');
|
| 3 |
+
const path = require('path');
|
| 4 |
+
const fs = require('fs');
|
| 5 |
+
const os = require('os');
|
| 6 |
+
const express = require('express');
|
| 7 |
+
const app = express();
|
| 8 |
+
|
| 9 |
+
// Tetapkan port ke 7860
|
| 10 |
+
const PORT = 7860;
|
| 11 |
+
|
| 12 |
+
app.get('/', (req, res) => {
|
| 13 |
+
res.setHeader('Content-Type', 'application/json');
|
| 14 |
+
const data = {
|
| 15 |
+
status: 'true',
|
| 16 |
+
message: 'Bot Successfully Activated!',
|
| 17 |
+
author: 'rizki'
|
| 18 |
+
};
|
| 19 |
+
const result = {
|
| 20 |
+
response: data
|
| 21 |
+
};
|
| 22 |
+
res.send(JSON.stringify(result, null, 2));
|
| 23 |
+
});
|
| 24 |
+
|
| 25 |
+
// Mulai server pada port 7860
|
| 26 |
+
app.listen(PORT, () => {
|
| 27 |
+
console.log('\x1b[33m%s\x1b[0m', `🌐 Server berjalan di port ${PORT}`);
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
let isRunning = false;
|
| 31 |
+
|
| 32 |
+
function start(file) {
|
| 33 |
+
if (isRunning) return;
|
| 34 |
+
isRunning = true;
|
| 35 |
+
|
| 36 |
+
const args = [path.join(__dirname, file), ...process.argv.slice(2)];
|
| 37 |
+
const p = spawn(process.argv[0], args, {
|
| 38 |
+
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
p.on("message", (data) => {
|
| 42 |
+
console.log('\x1b[36m%s\x1b[0m', `🟢 RECEIVED ${data}`);
|
| 43 |
+
switch (data) {
|
| 44 |
+
case "reset":
|
| 45 |
+
p.kill();
|
| 46 |
+
isRunning = false;
|
| 47 |
+
start.apply(this, arguments);
|
| 48 |
+
break;
|
| 49 |
+
case "uptime":
|
| 50 |
+
p.send(process.uptime());
|
| 51 |
+
break;
|
| 52 |
+
}
|
| 53 |
+
});
|
| 54 |
+
|
| 55 |
+
p.on("exit", (code) => {
|
| 56 |
+
isRunning = false;
|
| 57 |
+
console.error('\x1b[31m%s\x1b[0m', `Exited with code: ${code}`);
|
| 58 |
+
start('main.js');
|
| 59 |
+
|
| 60 |
+
if (code === 0) return;
|
| 61 |
+
|
| 62 |
+
fs.watchFile(args[0], () => {
|
| 63 |
+
fs.unwatchFile(args[0]);
|
| 64 |
+
console.error('\x1b[31m%s\x1b[0m', `File ${args[0]} has been modified. Script will restart...`);
|
| 65 |
+
start("main.js");
|
| 66 |
+
});
|
| 67 |
+
});
|
| 68 |
+
|
| 69 |
+
p.on("error", (err) => {
|
| 70 |
+
console.error('\x1b[31m%s\x1b[0m', `Error: ${err}`);
|
| 71 |
+
p.kill();
|
| 72 |
+
isRunning = false;
|
| 73 |
+
console.error('\x1b[31m%s\x1b[0m', `Error occurred. Script will restart...`);
|
| 74 |
+
start("main.js");
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
const pluginsFolder = path.join(__dirname, "plugins");
|
| 78 |
+
|
| 79 |
+
fs.readdir(pluginsFolder, (err, files) => {
|
| 80 |
+
if (err) {
|
| 81 |
+
console.error('\x1b[31m%s\x1b[0m', `Error reading plugins folder: ${err}`);
|
| 82 |
+
return;
|
| 83 |
+
}
|
| 84 |
+
console.log('\x1b[33m%s\x1b[0m', `🟡 Found ${files.length} plugins in folder ${pluginsFolder}`);
|
| 85 |
+
try {
|
| 86 |
+
require.resolve('@adiwajshing/baileys');
|
| 87 |
+
console.log('\x1b[33m%s\x1b[0m', `🟡 Baileys library version ${require('@adiwajshing/baileys/package.json').version} is installed`);
|
| 88 |
+
} catch (e) {
|
| 89 |
+
console.error('\x1b[31m%s\x1b[0m', `❌ Baileys library is not installed`);
|
| 90 |
+
}
|
| 91 |
+
});
|
| 92 |
+
|
| 93 |
+
console.log(`🖥️ \x1b[33m${os.type()}\x1b[0m, \x1b[33m${os.release()}\x1b[0m - \x1b[33m${os.arch()}\x1b[0m`);
|
| 94 |
+
const ramInGB = os.totalmem() / (1024 * 1024 * 1024);
|
| 95 |
+
console.log(`💾 \x1b[33mTotal RAM: ${ramInGB.toFixed(2)} GB\x1b[0m`);
|
| 96 |
+
const freeRamInGB = os.freemem() / (1024 * 1024 * 1024);
|
| 97 |
+
console.log(`💽 \x1b[33mFree RAM: ${freeRamInGB.toFixed(2)} GB\x1b[0m`);
|
| 98 |
+
console.log('\x1b[33m%s\x1b[0m', `📃 Script by BOTCAHX`);
|
| 99 |
+
|
| 100 |
+
setInterval(() => {}, 1000);
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
start("main.js");
|
| 104 |
+
|
| 105 |
+
const tmpDir = './tmp';
|
| 106 |
+
if (!fs.existsSync(tmpDir)) {
|
| 107 |
+
fs.mkdirSync(tmpDir);
|
| 108 |
+
console.log('\x1b[33m%s\x1b[0m', `📁 Created directory ${tmpDir}`);
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
process.on('unhandledRejection', (reason) => {
|
| 112 |
+
console.error('\x1b[31m%s\x1b[0m', `Unhandled promise rejection: ${reason}`);
|
| 113 |
+
console.error('\x1b[31m%s\x1b[0m', 'Unhandled promise rejection. Script will restart...');
|
| 114 |
+
start('main.js');
|
| 115 |
+
});
|
| 116 |
+
|
| 117 |
+
process.on('exit', (code) => {
|
| 118 |
+
console.error(`Exited with code: ${code}`);
|
| 119 |
+
console.error('Script will restart...');
|
| 120 |
+
start('main.js');
|
| 121 |
+
});
|
lib/cloudDBAdapter.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const got = require('got')
|
| 2 |
+
|
| 3 |
+
const stringify = obj => JSON.stringify(obj, null, 2)
|
| 4 |
+
const parse = str => JSON.parse(str, (_, v) => {
|
| 5 |
+
if (
|
| 6 |
+
v !== null &&
|
| 7 |
+
typeof v === 'object' &&
|
| 8 |
+
'type' in v &&
|
| 9 |
+
v.type === 'Buffer' &&
|
| 10 |
+
'data' in v &&
|
| 11 |
+
Array.isArray(v.data)) {
|
| 12 |
+
return Buffer.from(v.data)
|
| 13 |
+
}
|
| 14 |
+
return v
|
| 15 |
+
})
|
| 16 |
+
class CloudDBAdapter {
|
| 17 |
+
constructor(url, {
|
| 18 |
+
serialize = stringify,
|
| 19 |
+
deserialize = parse,
|
| 20 |
+
fetchOptions = {}
|
| 21 |
+
} = {}) {
|
| 22 |
+
this.url = url
|
| 23 |
+
this.serialize = serialize
|
| 24 |
+
this.deserialize = deserialize
|
| 25 |
+
this.fetchOptions = fetchOptions
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
async read() {
|
| 29 |
+
try {
|
| 30 |
+
let res = await got(this.url, {
|
| 31 |
+
method: 'GET',
|
| 32 |
+
headers: {
|
| 33 |
+
'Accept': 'application/json;q=0.9,text/plain'
|
| 34 |
+
},
|
| 35 |
+
...this.fetchOptions
|
| 36 |
+
})
|
| 37 |
+
if (res.statusCode !== 200) throw res.statusMessage
|
| 38 |
+
return this.deserialize(res.body)
|
| 39 |
+
} catch (e) {
|
| 40 |
+
return null
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
async write(obj) {
|
| 45 |
+
let res = await got(this.url, {
|
| 46 |
+
method: 'POST',
|
| 47 |
+
headers: {
|
| 48 |
+
'Content-Type': 'application/json'
|
| 49 |
+
},
|
| 50 |
+
...this.fetchOptions,
|
| 51 |
+
body: this.serialize(obj)
|
| 52 |
+
})
|
| 53 |
+
if (res.statusCode !== 200) throw res.statusMessage
|
| 54 |
+
return res.body
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
module.exports = CloudDBAdapter
|
lib/cluster.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const cluster = require('cluster')
|
| 2 |
+
const os = require('os')
|
| 3 |
+
const path = require('path')
|
| 4 |
+
const { connectionOptions } = require('../main')
|
| 5 |
+
const { makeWASocket } = require('./simple')
|
| 6 |
+
|
| 7 |
+
var conn
|
| 8 |
+
module.exports = {
|
| 9 |
+
Cluster() {
|
| 10 |
+
if (cluster.isMaster || !cluster.isWorker) {
|
| 11 |
+
if (!os.cpus().length <= 1) throw new Error(`Requires at least 1 cores, but you only have ${os.cpus().length} cores`)
|
| 12 |
+
cluster.setupMaster({
|
| 13 |
+
exec: path.join(__dirname, './cluster.js')
|
| 14 |
+
})
|
| 15 |
+
// for (let i = 0; i < 3; i++)
|
| 16 |
+
cluster.fork()
|
| 17 |
+
console.log(cluster.workers)
|
| 18 |
+
} else {
|
| 19 |
+
// console.log(cluster.workers)
|
| 20 |
+
// if (cluster.worker.id == 1) this.baileys()
|
| 21 |
+
}
|
| 22 |
+
},
|
| 23 |
+
baileys() {
|
| 24 |
+
conn = makeWASocket(connectionOptions)
|
| 25 |
+
for (let event of Object.keys(conn.ev._events)) {
|
| 26 |
+
conn.ev.on(event, (...updates) => {
|
| 27 |
+
event, updates
|
| 28 |
+
})
|
| 29 |
+
}
|
| 30 |
+
},
|
| 31 |
+
convert() {
|
| 32 |
+
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
if (cluster.isWorker) module.exports.Cluster()
|
lib/color.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const chalk = require('chalk')
|
| 2 |
+
|
| 3 |
+
const color = (text, color) => {
|
| 4 |
+
return !color ? chalk.green(text) : chalk.keyword(color)(text)
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
const bgcolor = (text, bgcolor) => {
|
| 8 |
+
return !bgcolor ? chalk.green(text) : chalk.bgKeyword(bgcolor)(text)
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
module.exports = {
|
| 12 |
+
color,
|
| 13 |
+
bgcolor
|
| 14 |
+
}
|
lib/converter.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs')
|
| 2 |
+
const path = require('path')
|
| 3 |
+
const { spawn } = require('child_process')
|
| 4 |
+
|
| 5 |
+
function ffmpeg(buffer, args = [], ext = '', ext2 = '') {
|
| 6 |
+
return new Promise(async (resolve, reject) => {
|
| 7 |
+
try {
|
| 8 |
+
let tmp = path.join(__dirname, '../tmp', + new Date + '.' + ext)
|
| 9 |
+
let out = tmp + '.' + ext2
|
| 10 |
+
await fs.promises.writeFile(tmp, buffer)
|
| 11 |
+
spawn('ffmpeg', [
|
| 12 |
+
'-y',
|
| 13 |
+
'-i', tmp,
|
| 14 |
+
...args,
|
| 15 |
+
out
|
| 16 |
+
])
|
| 17 |
+
.on('error', reject)
|
| 18 |
+
.on('close', async (code) => {
|
| 19 |
+
try {
|
| 20 |
+
await fs.promises.unlink(tmp)
|
| 21 |
+
if (code !== 0) return reject(code)
|
| 22 |
+
resolve({ data: await fs.promises.readFile(out), filename: out })
|
| 23 |
+
// await fs.promises.unlink(out)
|
| 24 |
+
} catch (e) {
|
| 25 |
+
reject(e)
|
| 26 |
+
}
|
| 27 |
+
})
|
| 28 |
+
} catch (e) {
|
| 29 |
+
reject(e)
|
| 30 |
+
}
|
| 31 |
+
})
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* Convert Audio to Playable WhatsApp Audio
|
| 36 |
+
* @param {Buffer} buffer Audio Buffer
|
| 37 |
+
* @param {String} ext File Extension
|
| 38 |
+
*/
|
| 39 |
+
function toPTT(buffer, ext) {
|
| 40 |
+
return ffmpeg(buffer, [
|
| 41 |
+
'-vn',
|
| 42 |
+
'-c:a', 'libopus',
|
| 43 |
+
'-b:a', '128k',
|
| 44 |
+
'-vbr', 'on',
|
| 45 |
+
], ext, 'ogg')
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
/**
|
| 49 |
+
* Convert Audio to Playable WhatsApp PTT
|
| 50 |
+
* @param {Buffer} buffer Audio Buffer
|
| 51 |
+
* @param {String} ext File Extension
|
| 52 |
+
*/
|
| 53 |
+
function toAudio(buffer, ext) {
|
| 54 |
+
return ffmpeg(buffer, [
|
| 55 |
+
'-vn',
|
| 56 |
+
'-c:a', 'libopus',
|
| 57 |
+
'-b:a', '128k',
|
| 58 |
+
'-vbr', 'on',
|
| 59 |
+
'-compression_level', '10'
|
| 60 |
+
], ext, 'opus')
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Convert Audio to Playable WhatsApp Video
|
| 65 |
+
* @param {Buffer} buffer Video Buffer
|
| 66 |
+
* @param {String} ext File Extension
|
| 67 |
+
*/
|
| 68 |
+
function toVideo(buffer, ext) {
|
| 69 |
+
return ffmpeg(buffer, [
|
| 70 |
+
'-c:v', 'libx264',
|
| 71 |
+
'-c:a', 'aac',
|
| 72 |
+
'-ab', '128k',
|
| 73 |
+
'-ar', '44100',
|
| 74 |
+
'-crf', '32',
|
| 75 |
+
'-preset', 'slow'
|
| 76 |
+
], ext, 'mp4')
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
module.exports = {
|
| 80 |
+
toAudio,
|
| 81 |
+
toPTT,
|
| 82 |
+
toVideo,
|
| 83 |
+
ffmpeg,
|
| 84 |
+
}
|
lib/database.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const path = require('path')
|
| 2 |
+
const _fs = require('fs')
|
| 3 |
+
const { promises: fs } = _fs
|
| 4 |
+
|
| 5 |
+
class Database {
|
| 6 |
+
/**
|
| 7 |
+
* Create new Database
|
| 8 |
+
* @param {String} filepath Path to specified json database
|
| 9 |
+
* @param {...any} args JSON.stringify arguments
|
| 10 |
+
*/
|
| 11 |
+
constructor(filepath, ...args) {
|
| 12 |
+
this.file = path.resolve(filepath)
|
| 13 |
+
this.logger = console
|
| 14 |
+
|
| 15 |
+
this._load()
|
| 16 |
+
|
| 17 |
+
this._jsonargs = args
|
| 18 |
+
this._state = false
|
| 19 |
+
this._queue = []
|
| 20 |
+
this._interval = setInterval(async () => {
|
| 21 |
+
if (!this._state && this._queue && this._queue[0]) {
|
| 22 |
+
this._state = true
|
| 23 |
+
await this[this._queue.shift()]().catch(this.logger.error)
|
| 24 |
+
this._state = false
|
| 25 |
+
}
|
| 26 |
+
}, 1000)
|
| 27 |
+
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
get data() {
|
| 31 |
+
return this._data
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
set data(value) {
|
| 35 |
+
this._data = value
|
| 36 |
+
this.save()
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Queue Load
|
| 41 |
+
*/
|
| 42 |
+
load() {
|
| 43 |
+
this._queue.push('_load')
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
/**
|
| 47 |
+
* Queue Save
|
| 48 |
+
*/
|
| 49 |
+
save() {
|
| 50 |
+
this._queue.push('_save')
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
_load() {
|
| 54 |
+
try {
|
| 55 |
+
return this._data = _fs.existsSync(this.file) ? JSON.parse(_fs.readFileSync(this.file)) : {}
|
| 56 |
+
} catch (e) {
|
| 57 |
+
this.logger.error(e)
|
| 58 |
+
return this._data = {}
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
async _save() {
|
| 63 |
+
let dirname = path.dirname(this.file)
|
| 64 |
+
if (!_fs.existsSync(dirname)) await fs.mkdir(dirname, { recursive: true })
|
| 65 |
+
await fs.writeFile(this.file, JSON.stringify(this._data, ...this._jsonargs))
|
| 66 |
+
return this.file
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
module.exports = Database
|
| 71 |
+
|
lib/exif.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs')
|
| 2 |
+
const { tmpdir } = require("os")
|
| 3 |
+
const Crypto = require("crypto")
|
| 4 |
+
const ff = require('fluent-ffmpeg')
|
| 5 |
+
const webp = require("node-webpmux")
|
| 6 |
+
const path = require("path")
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
async function imageToWebp (media) {
|
| 10 |
+
|
| 11 |
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 12 |
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.jpg`)
|
| 13 |
+
|
| 14 |
+
fs.writeFileSync(tmpFileIn, media)
|
| 15 |
+
|
| 16 |
+
await new Promise((resolve, reject) => {
|
| 17 |
+
ff(tmpFileIn)
|
| 18 |
+
.on("error", reject)
|
| 19 |
+
.on("end", () => resolve(true))
|
| 20 |
+
.addOutputOptions([
|
| 21 |
+
"-vcodec",
|
| 22 |
+
"libwebp",
|
| 23 |
+
"-vf",
|
| 24 |
+
"scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse"
|
| 25 |
+
])
|
| 26 |
+
.toFormat("webp")
|
| 27 |
+
.save(tmpFileOut)
|
| 28 |
+
})
|
| 29 |
+
|
| 30 |
+
const buff = fs.readFileSync(tmpFileOut)
|
| 31 |
+
fs.unlinkSync(tmpFileOut)
|
| 32 |
+
fs.unlinkSync(tmpFileIn)
|
| 33 |
+
return buff
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
async function videoToWebp (media) {
|
| 37 |
+
|
| 38 |
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 39 |
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.mp4`)
|
| 40 |
+
|
| 41 |
+
fs.writeFileSync(tmpFileIn, media)
|
| 42 |
+
|
| 43 |
+
await new Promise((resolve, reject) => {
|
| 44 |
+
ff(tmpFileIn)
|
| 45 |
+
.on("error", reject)
|
| 46 |
+
.on("end", () => resolve(true))
|
| 47 |
+
.addOutputOptions([
|
| 48 |
+
"-vcodec",
|
| 49 |
+
"libwebp",
|
| 50 |
+
"-vf",
|
| 51 |
+
"scale='min(320,iw)':min'(320,ih)':force_original_aspect_ratio=decrease,fps=15, pad=320:320:-1:-1:color=white@0.0, split [a][b]; [a] palettegen=reserve_transparent=on:transparency_color=ffffff [p]; [b][p] paletteuse",
|
| 52 |
+
"-loop",
|
| 53 |
+
"0",
|
| 54 |
+
"-ss",
|
| 55 |
+
"00:00:00",
|
| 56 |
+
"-t",
|
| 57 |
+
"00:00:06",
|
| 58 |
+
"-preset",
|
| 59 |
+
"default",
|
| 60 |
+
"-an",
|
| 61 |
+
"-vsync",
|
| 62 |
+
"0"
|
| 63 |
+
])
|
| 64 |
+
.toFormat("webp")
|
| 65 |
+
.save(tmpFileOut)
|
| 66 |
+
})
|
| 67 |
+
|
| 68 |
+
const buff = fs.readFileSync(tmpFileOut)
|
| 69 |
+
fs.unlinkSync(tmpFileOut)
|
| 70 |
+
fs.unlinkSync(tmpFileIn)
|
| 71 |
+
return buff
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
async function writeExifImg (media, metadata) {
|
| 75 |
+
let wMedia = await imageToWebp(media)
|
| 76 |
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 77 |
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 78 |
+
fs.writeFileSync(tmpFileIn, wMedia)
|
| 79 |
+
|
| 80 |
+
if (metadata.packname || metadata.author) {
|
| 81 |
+
const img = new webp.Image()
|
| 82 |
+
const json = { "sticker-pack-id": `https://github.com/BOTCAHX/RTXZY-MD`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] }
|
| 83 |
+
const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00])
|
| 84 |
+
const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8")
|
| 85 |
+
const exif = Buffer.concat([exifAttr, jsonBuff])
|
| 86 |
+
exif.writeUIntLE(jsonBuff.length, 14, 4)
|
| 87 |
+
await img.load(tmpFileIn)
|
| 88 |
+
fs.unlinkSync(tmpFileIn)
|
| 89 |
+
img.exif = exif
|
| 90 |
+
await img.save(tmpFileOut)
|
| 91 |
+
return tmpFileOut
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
async function writeExifVid (media, metadata) {
|
| 96 |
+
let wMedia = await videoToWebp(media)
|
| 97 |
+
const tmpFileIn = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 98 |
+
const tmpFileOut = path.join(tmpdir(), `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`)
|
| 99 |
+
fs.writeFileSync(tmpFileIn, wMedia)
|
| 100 |
+
|
| 101 |
+
if (metadata.packname || metadata.author) {
|
| 102 |
+
const img = new webp.Image()
|
| 103 |
+
const json = { "sticker-pack-id": `https://github.com/BOTCAHX/RTXZY-MD`, "sticker-pack-name": metadata.packname, "sticker-pack-publisher": metadata.author, "emojis": metadata.categories ? metadata.categories : [""] }
|
| 104 |
+
const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00])
|
| 105 |
+
const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8")
|
| 106 |
+
const exif = Buffer.concat([exifAttr, jsonBuff])
|
| 107 |
+
exif.writeUIntLE(jsonBuff.length, 14, 4)
|
| 108 |
+
await img.load(tmpFileIn)
|
| 109 |
+
fs.unlinkSync(tmpFileIn)
|
| 110 |
+
img.exif = exif
|
| 111 |
+
await img.save(tmpFileOut)
|
| 112 |
+
return tmpFileOut
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
module.exports = { imageToWebp, videoToWebp, writeExifImg, writeExifVid }
|
lib/functions.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fetch = require('node-fetch')
|
| 2 |
+
const axios = require('axios')
|
| 3 |
+
const cfonts = require('cfonts')
|
| 4 |
+
const spin = require('spinnies')
|
| 5 |
+
const Crypto = require('crypto')
|
| 6 |
+
|
| 7 |
+
const wait = async (media) => new Promise(async (resolve, reject) => {
|
| 8 |
+
const attachmentData = `data:image/jpeg;base64,${media.toString('base64')}`
|
| 9 |
+
const response = await fetch("https://trace.moe/api/search",{method: "POST",body: JSON.stringify({ image: attachmentData }),headers: { "Content-Type": "application/json" }});
|
| 10 |
+
if (!response.ok) reject(`Gambar tidak ditemukan!`);
|
| 11 |
+
const result = await response.json()
|
| 12 |
+
try {
|
| 13 |
+
const { is_adult, title, title_chinese, title_romaji, title_english, episode, season, similarity, filename, at, tokenthumb, anilist_id } = result.docs[0]
|
| 14 |
+
let belief = () => similarity < 0.89 ? "Saya memiliki keyakinan rendah dalam hal ini : " : ""
|
| 15 |
+
let ecch = () => is_adult ? "Iya" : "Tidak"
|
| 16 |
+
resolve({video: await getBuffer(`https://media.trace.moe/video/${anilist_id}/${encodeURIComponent(filename)}?t=${at}&token=${tokenthumb}`), teks: `${belief()}
|
| 17 |
+
~> Ecchi : *${ecch()}*
|
| 18 |
+
~> Judul Jepang : *${title}*
|
| 19 |
+
~> Ejaan Judul : *${title_romaji}*
|
| 20 |
+
~> Judul Inggris : *${title_english}*
|
| 21 |
+
~> Episode : *${episode}*
|
| 22 |
+
~> Season : *${season}*`});
|
| 23 |
+
} catch (e) {
|
| 24 |
+
console.log(e)
|
| 25 |
+
reject(`Saya tidak tau ini anime apa`)
|
| 26 |
+
}
|
| 27 |
+
})
|
| 28 |
+
|
| 29 |
+
const simih = async (text) => {
|
| 30 |
+
try {
|
| 31 |
+
const sami = await fetch(`https://simsumi.herokuapp.com/api?text=${text}`, {method: 'GET'})
|
| 32 |
+
const res = await sami.json()
|
| 33 |
+
return res.success
|
| 34 |
+
} catch {
|
| 35 |
+
return 'Simi ga tau apa yang anda ngomong, bahasa alien yah kak?'
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
const h2k = (number) => {
|
| 40 |
+
var SI_POSTFIXES = ["", " K", " M", " G", " T", " P", " E"]
|
| 41 |
+
var tier = Math.log10(Math.abs(number)) / 3 | 0
|
| 42 |
+
if(tier == 0) return number
|
| 43 |
+
var postfix = SI_POSTFIXES[tier]
|
| 44 |
+
var scale = Math.pow(10, tier * 3)
|
| 45 |
+
var scaled = number / scale
|
| 46 |
+
var formatted = scaled.toFixed(1) + ''
|
| 47 |
+
if (/\.0$/.test(formatted))
|
| 48 |
+
formatted = formatted.substr(0, formatted.length - 2)
|
| 49 |
+
return formatted + postfix
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
const getBuffer = async (url, options) => {
|
| 53 |
+
try {
|
| 54 |
+
options ? options : {}
|
| 55 |
+
const res = await axios({
|
| 56 |
+
method: "get",
|
| 57 |
+
url,
|
| 58 |
+
headers: {
|
| 59 |
+
'DNT': 1,
|
| 60 |
+
'Upgrade-Insecure-Request': 1
|
| 61 |
+
},
|
| 62 |
+
...options,
|
| 63 |
+
responseType: 'arraybuffer'
|
| 64 |
+
})
|
| 65 |
+
return res.data
|
| 66 |
+
} catch (e) {
|
| 67 |
+
console.log(`Error : ${e}`)
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
const randomBytes = (length) => {
|
| 72 |
+
return Crypto.randomBytes(length)
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
const generateMessageID = () => {
|
| 76 |
+
return randomBytes(10).toString('hex').toUpperCase()
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
const getGroupAdmins = (participants) => {
|
| 80 |
+
admins = []
|
| 81 |
+
for (let i of participants) {
|
| 82 |
+
i.isAdmin ? admins.push(i.jid) : ''
|
| 83 |
+
}
|
| 84 |
+
return admins
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
const getRandom = (ext) => {
|
| 88 |
+
return `${Math.floor(Math.random() * 10000)}${ext}`
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
function pickRandom(list) {
|
| 92 |
+
return list[Math.floor(Math.random() * list.length)]
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
const spinner = {
|
| 96 |
+
"interval": 120,
|
| 97 |
+
"frames": [
|
| 98 |
+
"🕐",
|
| 99 |
+
"🕑",
|
| 100 |
+
"🕒",
|
| 101 |
+
"🕓",
|
| 102 |
+
"🕔",
|
| 103 |
+
"🕕",
|
| 104 |
+
"🕖",
|
| 105 |
+
"🕗",
|
| 106 |
+
"🕘",
|
| 107 |
+
"🕙",
|
| 108 |
+
"🕚",
|
| 109 |
+
"🕛"
|
| 110 |
+
]}
|
| 111 |
+
|
| 112 |
+
let globalSpinner;
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
const getGlobalSpinner = (disableSpins = false) => {
|
| 116 |
+
if(!globalSpinner) globalSpinner = new spin({ color: 'blue', succeedColor: 'green', spinner, disableSpins});
|
| 117 |
+
return globalSpinner;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
spins = getGlobalSpinner(false)
|
| 121 |
+
|
| 122 |
+
const start = (id, text) => {
|
| 123 |
+
spins.add(id, {text: text})
|
| 124 |
+
/*setTimeout(() => {
|
| 125 |
+
spins.succeed('load-spin', {text: 'Suksess'})
|
| 126 |
+
}, Number(wait) * 1000)*/
|
| 127 |
+
}
|
| 128 |
+
const info = (id, text) => {
|
| 129 |
+
spins.update(id, {text: text})
|
| 130 |
+
}
|
| 131 |
+
const success = (id, text) => {
|
| 132 |
+
spins.succeed(id, {text: text})
|
| 133 |
+
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
const close = (id, text) => {
|
| 137 |
+
spins.fail(id, {text: text})
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
const banner = cfonts.render(('LOADING...'), {
|
| 141 |
+
font: 'chrome',
|
| 142 |
+
color: 'candy',
|
| 143 |
+
align: 'center',
|
| 144 |
+
gradient: ["red","yellow"],
|
| 145 |
+
lineHeight: 3
|
| 146 |
+
});
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
module.exports = { wait, simih, getBuffer, h2k, generateMessageID, getGroupAdmins, getRandom, start, info, success, banner, close, pickRandom }
|
lib/gdrive.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
let path = require('path')
|
| 2 |
+
let fs = require('fs').promises
|
| 3 |
+
let { promisify } = require('util')
|
| 4 |
+
let { google } = require('googleapis')
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
// If modifying these scopes, delete token.json.
|
| 8 |
+
const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
|
| 9 |
+
// The file token.json stores the user's access and refresh tokens, and is
|
| 10 |
+
// created automatically when the authorization flow completes for the first
|
| 11 |
+
// time.
|
| 12 |
+
const TOKEN_PATH = path.join(__dirname, '..', 'token.json')
|
| 13 |
+
let
|
| 14 |
+
|
| 15 |
+
class GoogleAuth extends EventEmitter {
|
| 16 |
+
constructor() {
|
| 17 |
+
super()
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
async authorize(credentials) {
|
| 21 |
+
let token
|
| 22 |
+
const { client_secret, client_id } = credentials
|
| 23 |
+
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, `http://localhost:${port}`)
|
| 24 |
+
try {
|
| 25 |
+
token = JSON.parse(await fs.readFile(TOKEN_PATH))
|
| 26 |
+
} catch (e) {
|
| 27 |
+
const authUrl = oAuth2Client.generateAuthUrl({
|
| 28 |
+
access_type: 'offline',
|
| 29 |
+
scope: SCOPES
|
| 30 |
+
})
|
| 31 |
+
this.emit('auth', authUrl)
|
| 32 |
+
let code = await promisify(this.once).bind(this)('token')
|
| 33 |
+
token = await oAuth2Client.getToken(code)
|
| 34 |
+
await fs.writeFile(TOKEN_PATH, JSON.stringify(token))
|
| 35 |
+
} finally {
|
| 36 |
+
await oAuth2Client.setCredentials(token)
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
token(code) {
|
| 41 |
+
this.emit('token', code)
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
class GoogleDrive extends GoogleAuth {
|
| 46 |
+
constructor() {
|
| 47 |
+
super()
|
| 48 |
+
this.path = '/drive/api'
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
async getFolderID(path) {
|
| 52 |
+
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
async infoFile(path) {
|
| 56 |
+
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
async folderList(path) {
|
| 60 |
+
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
async downloadFile(path) {
|
| 64 |
+
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
async uploadFile(path) {
|
| 68 |
+
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
module.exports = {
|
| 73 |
+
GoogleAuth,
|
| 74 |
+
GoogleDrive,
|
| 75 |
+
}
|
lib/levelling.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
/**
|
| 3 |
+
* Growth rate
|
| 4 |
+
* `2.576652002695681`
|
| 5 |
+
*/
|
| 6 |
+
growth: Math.pow(Math.PI / Math.E, 1.618) * Math.E * .75,
|
| 7 |
+
/**
|
| 8 |
+
* get XP range at specified level
|
| 9 |
+
* @param {Number} level
|
| 10 |
+
* @param {Number} multiplier
|
| 11 |
+
*/
|
| 12 |
+
xpRange(level, multiplier = global.multiplier || 1) {
|
| 13 |
+
if (level < 0) throw new TypeError('level cannot be negative value')
|
| 14 |
+
level = Math.floor(level)
|
| 15 |
+
let min = level === 0 ? 0 : Math.round(Math.pow(level, this.growth) * multiplier) + 1
|
| 16 |
+
let max = Math.round(Math.pow(++level, this.growth) * multiplier)
|
| 17 |
+
return {
|
| 18 |
+
min,
|
| 19 |
+
max,
|
| 20 |
+
xp: max - min
|
| 21 |
+
}
|
| 22 |
+
},
|
| 23 |
+
/**
|
| 24 |
+
* get level by xp
|
| 25 |
+
* @param {Number} xp
|
| 26 |
+
* @param {Number} multiplier
|
| 27 |
+
*/
|
| 28 |
+
findLevel(xp, multiplier = global.multiplier || 1) {
|
| 29 |
+
if (xp === Infinity) return Infinity
|
| 30 |
+
if (isNaN(xp)) return NaN
|
| 31 |
+
if (xp <= 0) return -1
|
| 32 |
+
let level = 0
|
| 33 |
+
do level++
|
| 34 |
+
while (this.xpRange(level, multiplier).min <= xp)
|
| 35 |
+
return --level
|
| 36 |
+
},
|
| 37 |
+
/**
|
| 38 |
+
* is able to level up?
|
| 39 |
+
* @param {Number} level
|
| 40 |
+
* @param {Number} xp
|
| 41 |
+
* @param {Number} multiplier
|
| 42 |
+
*/
|
| 43 |
+
canLevelUp(level, xp, multiplier = global.multiplier || 1) {
|
| 44 |
+
if (level < 0) return false
|
| 45 |
+
if (xp === Infinity) return true
|
| 46 |
+
if (isNaN(xp)) return false
|
| 47 |
+
if (xp <= 0) return false
|
| 48 |
+
return level < this.findLevel(xp, multiplier)
|
| 49 |
+
}
|
| 50 |
+
}
|
lib/logs.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
let stdouts = []
|
| 2 |
+
module.exports = (maxLength = 200) => {
|
| 3 |
+
let oldWrite = process.stdout.write.bind(process.stdout)
|
| 4 |
+
module.exports.disable = () => {
|
| 5 |
+
module.exports.isModified = false
|
| 6 |
+
return process.stdout.write = oldWrite
|
| 7 |
+
}
|
| 8 |
+
process.stdout.write = (chunk, encoding, callback) => {
|
| 9 |
+
stdouts.push(Buffer.from(chunk, encoding))
|
| 10 |
+
oldWrite(chunk, encoding, callback)
|
| 11 |
+
if (stdouts.length > maxLength) stdouts.shift()
|
| 12 |
+
}
|
| 13 |
+
module.exports.isModified = true
|
| 14 |
+
return module.exports
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
module.exports.isModified = false
|
| 18 |
+
module.exports.logs = () => Buffer.concat(stdouts)
|
| 19 |
+
|
lib/lowdb/Low.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export interface Adapter<T> {
|
| 2 |
+
read: () => Promise<T | null>;
|
| 3 |
+
write: (data: T) => Promise<void>;
|
| 4 |
+
}
|
| 5 |
+
export declare class Low<T = unknown> {
|
| 6 |
+
adapter: Adapter<T>;
|
| 7 |
+
data: T | null;
|
| 8 |
+
constructor(adapter: Adapter<T>);
|
| 9 |
+
read(): Promise<void>;
|
| 10 |
+
write(): Promise<void>;
|
| 11 |
+
}
|
lib/lowdb/Low.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { MissingAdapterError } = require('./MissingAdapterError.js');
|
| 2 |
+
class Low {
|
| 3 |
+
constructor(adapter) {
|
| 4 |
+
this.data = null;
|
| 5 |
+
if (adapter) {
|
| 6 |
+
this.adapter = adapter;
|
| 7 |
+
}
|
| 8 |
+
else {
|
| 9 |
+
throw new MissingAdapterError();
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
async read() {
|
| 13 |
+
this.data = await this.adapter.read();
|
| 14 |
+
}
|
| 15 |
+
async write() {
|
| 16 |
+
if (this.data) {
|
| 17 |
+
await this.adapter.write(this.data);
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
module.exports = { Low };
|
lib/lowdb/LowSync.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export interface SyncAdapter<T> {
|
| 2 |
+
read: () => T | null;
|
| 3 |
+
write: (data: T) => void;
|
| 4 |
+
}
|
| 5 |
+
export declare class LowSync<T = unknown> {
|
| 6 |
+
adapter: SyncAdapter<T>;
|
| 7 |
+
data: T | null;
|
| 8 |
+
constructor(adapter: SyncAdapter<T>);
|
| 9 |
+
read(): void;
|
| 10 |
+
write(): void;
|
| 11 |
+
}
|
lib/lowdb/LowSync.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { MissingAdapterError } = require('./MissingAdapterError.js');
|
| 2 |
+
class LowSync {
|
| 3 |
+
constructor(adapter) {
|
| 4 |
+
this.data = null;
|
| 5 |
+
if (adapter) {
|
| 6 |
+
this.adapter = adapter;
|
| 7 |
+
}
|
| 8 |
+
else {
|
| 9 |
+
throw new MissingAdapterError();
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
read() {
|
| 13 |
+
this.data = this.adapter.read();
|
| 14 |
+
}
|
| 15 |
+
write() {
|
| 16 |
+
if (this.data !== null) {
|
| 17 |
+
this.adapter.write(this.data);
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
module.exports = { LowSync };
|
lib/lowdb/MissingAdapterError.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export declare class MissingAdapterError extends Error {
|
| 2 |
+
constructor();
|
| 3 |
+
}
|
lib/lowdb/MissingAdapterError.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class MissingAdapterError extends Error {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.message = 'Missing Adapter';
|
| 5 |
+
}
|
| 6 |
+
}
|
| 7 |
+
module.exports = { MissingAdapterError };
|
lib/lowdb/adapters/JSONFile.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Adapter } from '../Low.js';
|
| 2 |
+
export declare class JSONFile<T> implements Adapter<T> {
|
| 3 |
+
private adapter;
|
| 4 |
+
constructor(filename: string);
|
| 5 |
+
read(): Promise<T | null>;
|
| 6 |
+
write(obj: T): Promise<void>;
|
| 7 |
+
}
|
lib/lowdb/adapters/JSONFile.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { TextFile } = require('./TextFile.js');
|
| 2 |
+
class JSONFile {
|
| 3 |
+
constructor(filename) {
|
| 4 |
+
this.adapter = new TextFile(filename);
|
| 5 |
+
}
|
| 6 |
+
async read() {
|
| 7 |
+
const data = await this.adapter.read();
|
| 8 |
+
if (data === null) {
|
| 9 |
+
return null;
|
| 10 |
+
}
|
| 11 |
+
else {
|
| 12 |
+
return JSON.parse(data);
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
write(obj) {
|
| 16 |
+
return this.adapter.write(JSON.stringify(obj, null, 2));
|
| 17 |
+
}
|
| 18 |
+
}
|
| 19 |
+
module.exports = { JSONFile };
|
lib/lowdb/adapters/JSONFileSync.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { SyncAdapter } from '../LowSync.js';
|
| 2 |
+
export declare class JSONFileSync<T> implements SyncAdapter<T> {
|
| 3 |
+
private adapter;
|
| 4 |
+
constructor(filename: string);
|
| 5 |
+
read(): T | null;
|
| 6 |
+
write(obj: T): void;
|
| 7 |
+
}
|
lib/lowdb/adapters/JSONFileSync.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { TextFileSync } = require('./TextFileSync.js');
|
| 2 |
+
class JSONFileSync {
|
| 3 |
+
constructor(filename) {
|
| 4 |
+
this.adapter = new TextFileSync(filename);
|
| 5 |
+
}
|
| 6 |
+
read() {
|
| 7 |
+
const data = this.adapter.read();
|
| 8 |
+
if (data === null) {
|
| 9 |
+
return null;
|
| 10 |
+
}
|
| 11 |
+
else {
|
| 12 |
+
return JSON.parse(data);
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
write(obj) {
|
| 16 |
+
this.adapter.write(JSON.stringify(obj, null, 2));
|
| 17 |
+
}
|
| 18 |
+
}
|
| 19 |
+
module.exports = { JSONFileSync };
|
lib/lowdb/adapters/LocalStorage.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { SyncAdapter } from '../LowSync.js';
|
| 2 |
+
export declare class LocalStorage<T> implements SyncAdapter<T> {
|
| 3 |
+
private key;
|
| 4 |
+
constructor(key: string);
|
| 5 |
+
read(): T | null;
|
| 6 |
+
write(obj: T): void;
|
| 7 |
+
}
|
lib/lowdb/adapters/LocalStorage.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class LocalStorage {
|
| 2 |
+
constructor(key) {
|
| 3 |
+
this.key = key;
|
| 4 |
+
}
|
| 5 |
+
read() {
|
| 6 |
+
const value = localStorage.getItem(this.key);
|
| 7 |
+
if (value === null) {
|
| 8 |
+
return null;
|
| 9 |
+
}
|
| 10 |
+
return JSON.parse(value);
|
| 11 |
+
}
|
| 12 |
+
write(obj) {
|
| 13 |
+
localStorage.setItem(this.key, JSON.stringify(obj));
|
| 14 |
+
}
|
| 15 |
+
}
|
| 16 |
+
module.exports = { LocalStorage };
|
lib/lowdb/adapters/Memory.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Adapter } from '../Low.js';
|
| 2 |
+
export declare class Memory<T> implements Adapter<T> {
|
| 3 |
+
private data;
|
| 4 |
+
read(): Promise<T | null>;
|
| 5 |
+
write(obj: T): Promise<void>;
|
| 6 |
+
}
|
lib/lowdb/adapters/Memory.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class Memory {
|
| 2 |
+
constructor() {
|
| 3 |
+
this.data = null;
|
| 4 |
+
}
|
| 5 |
+
read() {
|
| 6 |
+
return Promise.resolve(this.data);
|
| 7 |
+
}
|
| 8 |
+
write(obj) {
|
| 9 |
+
this.data = obj;
|
| 10 |
+
return Promise.resolve();
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
module.exports = { Memory };
|
lib/lowdb/adapters/MemorySync.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { SyncAdapter } from '../LowSync.js';
|
| 2 |
+
export declare class MemorySync<T> implements SyncAdapter<T> {
|
| 3 |
+
private data;
|
| 4 |
+
read(): T | null;
|
| 5 |
+
write(obj: T): void;
|
| 6 |
+
}
|
lib/lowdb/adapters/MemorySync.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class MemorySync {
|
| 2 |
+
constructor() {
|
| 3 |
+
this.data = null;
|
| 4 |
+
}
|
| 5 |
+
read() {
|
| 6 |
+
return this.data || null;
|
| 7 |
+
}
|
| 8 |
+
write(obj) {
|
| 9 |
+
this.data = obj;
|
| 10 |
+
}
|
| 11 |
+
}
|
| 12 |
+
module.exports = { MemorySync };
|
lib/lowdb/adapters/TextFile.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Adapter } from '../Low.js';
|
| 2 |
+
export declare class TextFile implements Adapter<string> {
|
| 3 |
+
private filename;
|
| 4 |
+
private writer;
|
| 5 |
+
constructor(filename: string);
|
| 6 |
+
read(): Promise<string | null>;
|
| 7 |
+
write(str: string): Promise<void>;
|
| 8 |
+
}
|
lib/lowdb/adapters/TextFile.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs');
|
| 2 |
+
const { Writer } = require('steno');
|
| 3 |
+
class TextFile {
|
| 4 |
+
constructor(filename) {
|
| 5 |
+
this.filename = filename;
|
| 6 |
+
this.writer = new Writer(filename);
|
| 7 |
+
}
|
| 8 |
+
async read() {
|
| 9 |
+
let data;
|
| 10 |
+
try {
|
| 11 |
+
data = await fs.promises.readFile(this.filename, 'utf-8');
|
| 12 |
+
}
|
| 13 |
+
catch (e) {
|
| 14 |
+
if (e.code === 'ENOENT') {
|
| 15 |
+
return null;
|
| 16 |
+
}
|
| 17 |
+
throw e;
|
| 18 |
+
}
|
| 19 |
+
return data;
|
| 20 |
+
}
|
| 21 |
+
write(str) {
|
| 22 |
+
return this.writer.write(str);
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
module.exports = { TextFile };
|
lib/lowdb/adapters/TextFileSync.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { SyncAdapter } from '../LowSync.js';
|
| 2 |
+
export declare class TextFileSync implements SyncAdapter<string> {
|
| 3 |
+
private tempFilename;
|
| 4 |
+
private filename;
|
| 5 |
+
constructor(filename: string);
|
| 6 |
+
read(): string | null;
|
| 7 |
+
write(str: string): void;
|
| 8 |
+
}
|
lib/lowdb/adapters/TextFileSync.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs');
|
| 2 |
+
const path = require('path');
|
| 3 |
+
class TextFileSync {
|
| 4 |
+
constructor(filename) {
|
| 5 |
+
this.filename = filename;
|
| 6 |
+
this.tempFilename = path.join(path.dirname(filename), `.${path.basename(filename)}.tmp`);
|
| 7 |
+
}
|
| 8 |
+
read() {
|
| 9 |
+
let data;
|
| 10 |
+
try {
|
| 11 |
+
data = fs.readFileSync(this.filename, 'utf-8');
|
| 12 |
+
}
|
| 13 |
+
catch (e) {
|
| 14 |
+
if (e.code === 'ENOENT') {
|
| 15 |
+
return null;
|
| 16 |
+
}
|
| 17 |
+
throw e;
|
| 18 |
+
}
|
| 19 |
+
return data;
|
| 20 |
+
}
|
| 21 |
+
write(str) {
|
| 22 |
+
fs.writeFileSync(this.tempFilename, str);
|
| 23 |
+
fs.renameSync(this.tempFilename, this.filename);
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
module.exports = { TextFileSync };
|
lib/lowdb/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export * from './adapters/JSONFile.js';
|
| 2 |
+
export * from './adapters/JSONFileSync.js';
|
| 3 |
+
export * from './adapters/LocalStorage.js';
|
| 4 |
+
export * from './adapters/Memory.js';
|
| 5 |
+
export * from './adapters/MemorySync.js';
|
| 6 |
+
export * from './adapters/TextFile.js';
|
| 7 |
+
export * from './adapters/TextFileSync.js';
|
| 8 |
+
export * from './Low.js';
|
| 9 |
+
export * from './LowSync.js';
|
lib/lowdb/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
...require('./adapters/JSONFile.js'),
|
| 3 |
+
...require('./adapters/JSONFileSync.js'),
|
| 4 |
+
...require('./adapters/LocalStorage.js'),
|
| 5 |
+
...require('./adapters/Memory.js'),
|
| 6 |
+
...require('./adapters/MemorySync.js'),
|
| 7 |
+
...require('./adapters/TextFile.js'),
|
| 8 |
+
...require('./adapters/TextFileSync.js'),
|
| 9 |
+
...require('./Low.js'),
|
| 10 |
+
...require('./LowSync.js'),
|
| 11 |
+
}
|
lib/mongoDB.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const mongoose = require('mongoose')
|
| 2 |
+
const { Schema } = mongoose
|
| 3 |
+
|
| 4 |
+
module.exports = class mongoDB {
|
| 5 |
+
constructor(url, options = { useNewUrlParser: true, useUnifiedTopology: true }) {
|
| 6 |
+
this.url = url
|
| 7 |
+
this.data = this._data = this._schema = this._model = {}
|
| 8 |
+
this.db
|
| 9 |
+
this.options = options
|
| 10 |
+
}
|
| 11 |
+
async read() {
|
| 12 |
+
this.db = await mongoose.connect(this.url, { ...this.options })
|
| 13 |
+
this.connection = mongoose.connection
|
| 14 |
+
let schema = this._schema = new Schema({
|
| 15 |
+
data: {
|
| 16 |
+
type: Object,
|
| 17 |
+
required: true, //depends on whether the field is mandatory or not
|
| 18 |
+
default: {}
|
| 19 |
+
}
|
| 20 |
+
})
|
| 21 |
+
// this._model = mongoose.model('data', schema)
|
| 22 |
+
try { this._model = mongoose.model('data', schema) } catch { this._model = mongoose.model('data') }
|
| 23 |
+
this._data = await this._model.findOne({})
|
| 24 |
+
if (!this._data) {
|
| 25 |
+
this.data = {}
|
| 26 |
+
await this.write(this.data)
|
| 27 |
+
this._data = await this._model.findOne({})
|
| 28 |
+
} else this.data = this._data.data
|
| 29 |
+
return this.data
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
async write(data) {
|
| 34 |
+
if (!data) return data
|
| 35 |
+
if (!this._data) return (new this._model({ data })).save()
|
| 36 |
+
this._model.findById(this._data._id, (err, docs) => {
|
| 37 |
+
if (!err) {
|
| 38 |
+
if (!docs.data) docs.data = {}
|
| 39 |
+
docs.data = data
|
| 40 |
+
return docs.save()
|
| 41 |
+
}
|
| 42 |
+
})
|
| 43 |
+
}
|
| 44 |
+
}
|
lib/myfunc.js
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Create By Dika Ardnt.
|
| 3 |
+
* Contact Me on wa.me/6288292024190
|
| 4 |
+
* Follow https://github.com/DikaArdnt
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
const { proto } = require('@adiwajshing/baileys')
|
| 8 |
+
const chalk = require('chalk')
|
| 9 |
+
const fs = require('fs')
|
| 10 |
+
const Crypto = require('crypto')
|
| 11 |
+
const axios = require('axios')
|
| 12 |
+
const moment = require('moment-timezone')
|
| 13 |
+
const { sizeFormatter } = require('human-readable')
|
| 14 |
+
const util = require('util')
|
| 15 |
+
const jimp = require('jimp')
|
| 16 |
+
const { defaultMaxListeners } = require('stream')
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000)
|
| 20 |
+
|
| 21 |
+
exports.unixTimestampSeconds = unixTimestampSeconds
|
| 22 |
+
|
| 23 |
+
exports.generateMessageTag = (epoch) => {
|
| 24 |
+
let tag = (0, exports.unixTimestampSeconds)().toString();
|
| 25 |
+
if (epoch)
|
| 26 |
+
tag += '.--' + epoch; // attach epoch if provided
|
| 27 |
+
return tag;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
exports.processTime = (timestamp, now) => {
|
| 31 |
+
return moment.duration(now - moment(timestamp * 1000)).asSeconds()
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
exports.getRandom = (ext) => {
|
| 35 |
+
return `${Math.floor(Math.random() * 10000)}${ext}`
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
exports.getBuffer = async (url, options) => {
|
| 39 |
+
try {
|
| 40 |
+
options ? options : {}
|
| 41 |
+
const res = await axios({
|
| 42 |
+
method: "get",
|
| 43 |
+
url,
|
| 44 |
+
headers: {
|
| 45 |
+
'DNT': 1,
|
| 46 |
+
'Upgrade-Insecure-Request': 1
|
| 47 |
+
},
|
| 48 |
+
...options,
|
| 49 |
+
responseType: 'arraybuffer'
|
| 50 |
+
})
|
| 51 |
+
return res.data
|
| 52 |
+
} catch (e) {
|
| 53 |
+
return err
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
exports.fetchJson = async (url, options) => {
|
| 58 |
+
try {
|
| 59 |
+
options ? options : {}
|
| 60 |
+
const res = await axios({
|
| 61 |
+
method: 'GET',
|
| 62 |
+
url: url,
|
| 63 |
+
headers: {
|
| 64 |
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
|
| 65 |
+
},
|
| 66 |
+
...options
|
| 67 |
+
})
|
| 68 |
+
return res.data
|
| 69 |
+
} catch (err) {
|
| 70 |
+
return err
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
exports.runtime = function(seconds) {
|
| 75 |
+
seconds = Number(seconds);
|
| 76 |
+
var d = Math.floor(seconds / (3600 * 24));
|
| 77 |
+
var h = Math.floor(seconds % (3600 * 24) / 3600);
|
| 78 |
+
var m = Math.floor(seconds % 3600 / 60);
|
| 79 |
+
var s = Math.floor(seconds % 60);
|
| 80 |
+
var dDisplay = d > 0 ? d + (d == 1 ? " day, " : " days, ") : "";
|
| 81 |
+
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
|
| 82 |
+
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
|
| 83 |
+
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
|
| 84 |
+
return dDisplay + hDisplay + mDisplay + sDisplay;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
exports.clockString = function(seconds) {
|
| 88 |
+
let h = isNaN(seconds) ? '--' : Math.floor(seconds % (3600 * 24) / 3600)
|
| 89 |
+
let m = isNaN(seconds) ? '--' : Math.floor(seconds % 3600 / 60)
|
| 90 |
+
let s = isNaN(seconds) ? '--' : Math.floor(seconds % 60)
|
| 91 |
+
return [h, m, s].map(v => v.toString().padStart(2, 0)).join(':')
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
exports.sleep = async (ms) => {
|
| 95 |
+
return new Promise(resolve => setTimeout(resolve, ms));
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
exports.isUrl = (url) => {
|
| 99 |
+
return url.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/, 'gi'))
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
exports.getTime = (format, date) => {
|
| 103 |
+
if (date) {
|
| 104 |
+
return moment(date).locale('id').format(format)
|
| 105 |
+
} else {
|
| 106 |
+
return moment.tz('Asia/Jakarta').locale('id').format(format)
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
exports.formatDate = (n, locale = 'id') => {
|
| 111 |
+
let d = new Date(n)
|
| 112 |
+
return d.toLocaleDateString(locale, {
|
| 113 |
+
weekday: 'long',
|
| 114 |
+
day: 'numeric',
|
| 115 |
+
month: 'long',
|
| 116 |
+
year: 'numeric',
|
| 117 |
+
hour: 'numeric',
|
| 118 |
+
minute: 'numeric',
|
| 119 |
+
second: 'numeric'
|
| 120 |
+
})
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
exports.tanggal = (numer) => {
|
| 124 |
+
myMonths = ["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"];
|
| 125 |
+
myDays = ['Minggu','Senin','Selasa','Rabu','Kamis','Jum’at','Sabtu'];
|
| 126 |
+
var tgl = new Date(numer);
|
| 127 |
+
var day = tgl.getDate()
|
| 128 |
+
bulan = tgl.getMonth()
|
| 129 |
+
var thisDay = tgl.getDay(),
|
| 130 |
+
thisDay = myDays[thisDay];
|
| 131 |
+
var yy = tgl.getYear()
|
| 132 |
+
var year = (yy < 1000) ? yy + 1900 : yy;
|
| 133 |
+
const time = moment.tz('Asia/Jakarta').format('DD/MM HH:mm:ss')
|
| 134 |
+
let d = new Date
|
| 135 |
+
let locale = 'id'
|
| 136 |
+
let gmt = new Date(0).getTime() - new Date('1 January 1970').getTime()
|
| 137 |
+
let weton = ['Pahing', 'Pon','Wage','Kliwon','Legi'][Math.floor(((d * 1) + gmt) / 84600000) % 5]
|
| 138 |
+
|
| 139 |
+
return`${thisDay}, ${day} - ${myMonths[bulan]} - ${year}`
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
exports.formatp = sizeFormatter({
|
| 143 |
+
std: 'JEDEC', //'SI' = default | 'IEC' | 'JEDEC'
|
| 144 |
+
decimalPlaces: 2,
|
| 145 |
+
keepTrailingZeroes: false,
|
| 146 |
+
render: (literal, symbol) => `${literal} ${symbol}B`,
|
| 147 |
+
})
|
| 148 |
+
|
| 149 |
+
exports.jsonformat = (string) => {
|
| 150 |
+
return JSON.stringify(string, null, 2)
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
function delay(ms) {
|
| 154 |
+
return new Promise((resolve, reject) => setTimeout(resolve, ms))
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
function format(...args) {
|
| 158 |
+
return util.format(...args)
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
exports.logic = (check, inp, out) => {
|
| 162 |
+
if (inp.length !== out.length) throw new Error('Input and Output must have same length')
|
| 163 |
+
for (let i in inp)
|
| 164 |
+
if (util.isDeepStrictEqual(check, inp[i])) return out[i]
|
| 165 |
+
return null
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
exports.generateProfilePicture = async (buffer) => {
|
| 169 |
+
const jimp = await jimp_1.read(buffer)
|
| 170 |
+
const min = jimp.getWidth()
|
| 171 |
+
const max = jimp.getHeight()
|
| 172 |
+
const cropped = jimp.crop(0, 0, min, max)
|
| 173 |
+
return {
|
| 174 |
+
img: await cropped.scaleToFit(720, 720).getBufferAsync(jimp_1.MIME_JPEG),
|
| 175 |
+
preview: await cropped.scaleToFit(720, 720).getBufferAsync(jimp_1.MIME_JPEG)
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
exports.parseMention = (text = '') => {
|
| 180 |
+
return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net')
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
exports.getGroupAdmins = (participantes) => {
|
| 184 |
+
var admins = []
|
| 185 |
+
for (let i of participantes) {
|
| 186 |
+
i.admin === "admin" ? admins.push(i.id) : ''
|
| 187 |
+
}
|
| 188 |
+
return admins
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
/**
|
| 192 |
+
* Serialize Message
|
| 193 |
+
* @param {WAConnection} conn
|
| 194 |
+
* @param {Object} m
|
| 195 |
+
* @param {store} store
|
| 196 |
+
*/
|
| 197 |
+
exports.smsg = (conn, m, store) => {
|
| 198 |
+
if (!m) return m
|
| 199 |
+
let M = proto.WebMessageInfo
|
| 200 |
+
if (m.key) {
|
| 201 |
+
m.id = m.key.id
|
| 202 |
+
m.isBaileys = m.id.startsWith('BAE5') && m.id.length === 16
|
| 203 |
+
m.chat = m.key.remoteJid
|
| 204 |
+
m.fromMe = m.key.fromMe
|
| 205 |
+
m.isGroup = m.chat.endsWith('@g.us')
|
| 206 |
+
m.sender = m.fromMe ? (conn.user.id.split(":")[0]+'@s.whatsapp.net' || conn.user.id) : (m.key.participant || m.key.remoteJid)
|
| 207 |
+
}
|
| 208 |
+
if (m.message) {
|
| 209 |
+
m.mtype = Object.keys(m.message)[0]
|
| 210 |
+
m.body = m.message.conversation || m.message[m.mtype].caption || m.message[m.mtype].text || (m.mtype == 'listResponseMessage') && m.message[m.mtype].singleSelectReply.selectedRowId || (m.mtype == 'buttonsResponseMessage') && m.message[m.mtype].selectedButtonId || m.mtype
|
| 211 |
+
m.msg = m.message[m.mtype]
|
| 212 |
+
if (m.mtype === 'ephemeralMessage') {
|
| 213 |
+
exports.smsg(hisoka, m.msg)
|
| 214 |
+
m.mtype = m.msg.mtype
|
| 215 |
+
m.msg = m.msg.msg
|
| 216 |
+
}
|
| 217 |
+
let quoted = m.quoted = m.msg.contextInfo ? m.msg.contextInfo.quotedMessage : null
|
| 218 |
+
m.mentionedJid = m.msg.contextInfo ? m.msg.contextInfo.mentionedJid : []
|
| 219 |
+
if (m.quoted) {
|
| 220 |
+
let type = Object.keys(m.quoted)[0]
|
| 221 |
+
m.quoted = m.quoted[type]
|
| 222 |
+
if (['productMessage'].includes(type)) {
|
| 223 |
+
type = Object.keys(m.quoted)[0]
|
| 224 |
+
m.quoted = m.quoted[type]
|
| 225 |
+
}
|
| 226 |
+
if (typeof m.quoted === 'string') m.quoted = {
|
| 227 |
+
text: m.quoted
|
| 228 |
+
}
|
| 229 |
+
m.quoted.mtype = type
|
| 230 |
+
m.quoted.id = m.msg.contextInfo.stanzaId
|
| 231 |
+
m.quoted.chat = m.msg.contextInfo.remoteJid || m.chat
|
| 232 |
+
m.quoted.isBaileys = m.quoted.id ? m.quoted.id.startsWith('BAE5') && m.quoted.id.length === 16 : false
|
| 233 |
+
m.quoted.sender = m.msg.contextInfo.participant.split(":")[0] || m.msg.contextInfo.participant
|
| 234 |
+
m.quoted.fromMe = m.quoted.sender === (conn.user && conn.user.id)
|
| 235 |
+
m.quoted.text = m.quoted.text || m.quoted.caption || ''
|
| 236 |
+
m.quoted.mentionedJid = m.msg.contextInfo ? m.msg.contextInfo.mentionedJid : []
|
| 237 |
+
m.getQuotedObj = m.getQuotedMessage = async () => {
|
| 238 |
+
if (!m.quoted.id) return false
|
| 239 |
+
let q = await store.loadMessage(m.chat, m.quoted.id, conn)
|
| 240 |
+
return exports.smsg(conn, q, store)
|
| 241 |
+
}
|
| 242 |
+
let vM = m.quoted.fakeObj = M.fromObject({
|
| 243 |
+
key: {
|
| 244 |
+
remoteJid: m.quoted.chat,
|
| 245 |
+
fromMe: m.quoted.fromMe,
|
| 246 |
+
id: m.quoted.id
|
| 247 |
+
},
|
| 248 |
+
message: quoted,
|
| 249 |
+
...(m.isGroup ? { participant: m.quoted.sender } : {})
|
| 250 |
+
})
|
| 251 |
+
|
| 252 |
+
/**
|
| 253 |
+
*
|
| 254 |
+
* @returns
|
| 255 |
+
*/
|
| 256 |
+
m.quoted.delete = () => conn.sendMessage(m.quoted.chat, { delete: vM.key })
|
| 257 |
+
|
| 258 |
+
/**
|
| 259 |
+
*
|
| 260 |
+
* @param {*} jid
|
| 261 |
+
* @param {*} forceForward
|
| 262 |
+
* @param {*} options
|
| 263 |
+
* @returns
|
| 264 |
+
*/
|
| 265 |
+
m.quoted.copyNForward = (jid, forceForward = false, options = {}) => conn.copyNForward(jid, vM, forceForward, options)
|
| 266 |
+
|
| 267 |
+
/**
|
| 268 |
+
*
|
| 269 |
+
* @returns
|
| 270 |
+
*/
|
| 271 |
+
m.quoted.download = () => conn.downloadMediaMessage(m.quoted)
|
| 272 |
+
}
|
| 273 |
+
}
|
| 274 |
+
if (m.msg.url) m.download = () => conn.downloadMediaMessage(m.msg)
|
| 275 |
+
m.text = (m.mtype == 'listResponseMessage' ? m.msg.singleSelectReply.selectedRowId : '') || m.msg.text || m.msg.caption || m.msg || ''
|
| 276 |
+
/**
|
| 277 |
+
* Reply to this message
|
| 278 |
+
* @param {String|Object} text
|
| 279 |
+
* @param {String|false} chatId
|
| 280 |
+
* @param {Object} options
|
| 281 |
+
*/
|
| 282 |
+
m.reply = (text, chatId, options) => conn.sendMessage(chatId ? chatId : m.chat, { text: text }, { quoted: m, detectLinks: false, thumbnail: global.thumb, ...options })
|
| 283 |
+
/**
|
| 284 |
+
* Copy this message
|
| 285 |
+
*/
|
| 286 |
+
m.copy = () => exports.smsg(conn, M.fromObject(M.toObject(m)))
|
| 287 |
+
|
| 288 |
+
/**
|
| 289 |
+
*
|
| 290 |
+
* @param {*} jid
|
| 291 |
+
* @param {*} forceForward
|
| 292 |
+
* @param {*} options
|
| 293 |
+
* @returns
|
| 294 |
+
*/
|
| 295 |
+
m.copyNForward = (jid = m.chat, forceForward = false, options = {}) => conn.copyNForward(jid, m, forceForward, options)
|
| 296 |
+
|
| 297 |
+
return m
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
let file = require.resolve(__filename)
|
| 302 |
+
fs.watchFile(file, () => {
|
| 303 |
+
fs.unwatchFile(file)
|
| 304 |
+
console.log(chalk.redBright(`Update ${__filename}`))
|
| 305 |
+
delete require.cache[file]
|
| 306 |
+
require(file)
|
| 307 |
+
})
|
lib/print.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
let { WAMessageStubType } = require('@adiwajshing/baileys')
|
| 2 |
+
let urlRegex = require('url-regex-safe')({ strict: false })
|
| 3 |
+
let PhoneNumber = require('awesome-phonenumber')
|
| 4 |
+
let terminalImage = global.opts['img'] ? require('terminal-image') : ''
|
| 5 |
+
let chalk = require('chalk')
|
| 6 |
+
let fs = require('fs')
|
| 7 |
+
|
| 8 |
+
module.exports = async function (m, conn = { user: {} }) {
|
| 9 |
+
let _name = await conn.getName(m.sender)
|
| 10 |
+
let sender = PhoneNumber('+' + m.sender.replace('@s.whatsapp.net', '')).getNumber('international') + (_name ? ' ~' + _name : '')
|
| 11 |
+
let chat = await conn.getName(m.chat)
|
| 12 |
+
// let ansi = '\x1b['
|
| 13 |
+
let img
|
| 14 |
+
try {
|
| 15 |
+
if (global.opts['img'])
|
| 16 |
+
img = /sticker|image/gi.test(m.mtype) ? await terminalImage.buffer(await m.download()) : false
|
| 17 |
+
} catch (e) {
|
| 18 |
+
console.error(e)
|
| 19 |
+
}
|
| 20 |
+
let filesize = (m.msg ?
|
| 21 |
+
m.msg.vcard ?
|
| 22 |
+
m.msg.vcard.length :
|
| 23 |
+
m.msg.fileLength ?
|
| 24 |
+
m.msg.fileLength.low || m.msg.fileLength :
|
| 25 |
+
m.msg.axolotlSenderKeyDistributionMessage ?
|
| 26 |
+
m.msg.axolotlSenderKeyDistributionMessage.length :
|
| 27 |
+
m.text ?
|
| 28 |
+
m.text.length :
|
| 29 |
+
0
|
| 30 |
+
: m.text ? m.text.length : 0) || 0
|
| 31 |
+
let user = global.DATABASE.data.users[m.sender]
|
| 32 |
+
let me = PhoneNumber('+' + (conn.user && conn.user.jid).replace('@s.whatsapp.net', '')).getNumber('international')
|
| 33 |
+
console.log(`▣────────────···
|
| 34 |
+
│ ${chalk.redBright('%s')}\n│⏰ㅤ${chalk.black(chalk.bgYellow('%s'))}\n│📑ㅤ${chalk.black(chalk.bgGreen('%s'))}\n│📊ㅤ${chalk.magenta('%s [%s %sB]')}
|
| 35 |
+
│📤ㅤ${chalk.green('%s')}\n│📃ㅤ${chalk.yellow('%s%s')}\n│📥ㅤ${chalk.green('%s')}\n│💬ㅤ${chalk.black(chalk.bgYellow('%s'))}
|
| 36 |
+
▣────────────···
|
| 37 |
+
`.trim(),
|
| 38 |
+
me + ' ~' + conn.user.name,
|
| 39 |
+
(m.messageTimestamp ? new Date(1000 * (m.messageTimestamp.low || m.messageTimestamp)) : new Date).toTimeString(),
|
| 40 |
+
m.messageStubType ? WAMessageStubType[m.messageStubType] : '',
|
| 41 |
+
filesize,
|
| 42 |
+
filesize === 0 ? 0 : (filesize / 1009 ** Math.floor(Math.log(filesize) / Math.log(1000))).toFixed(1),
|
| 43 |
+
['', ...'KMGTP'][Math.floor(Math.log(filesize) / Math.log(1000))] || '',
|
| 44 |
+
sender,
|
| 45 |
+
m ? m.exp : '?',
|
| 46 |
+
user ? '|' + user.exp + '|' + user.limit : '' + ('|' + user.level),
|
| 47 |
+
m.chat + (chat ? ' ~' + chat : ''),
|
| 48 |
+
m.mtype ? m.mtype.replace(/message$/i, '').replace('audio', m.msg.ptt ? 'PTT' : 'audio').replace(/^./, v => v.toUpperCase()) : ''
|
| 49 |
+
)
|
| 50 |
+
if (img) console.log(img.trimEnd())
|
| 51 |
+
if (typeof m.text === 'string' && m.text) {
|
| 52 |
+
let log = m.text.replace(/\u200e+/g, '')
|
| 53 |
+
let mdRegex = /(?<=(?:^|[\s\n])\S?)(?:([*_~])(.+?)\1|```((?:.||[\n\r])+?)```)(?=\S?(?:[\s\n]|$))/g
|
| 54 |
+
let mdFormat = (depth = 4) => (_, type, text, monospace) => {
|
| 55 |
+
let types = {
|
| 56 |
+
_: 'italic',
|
| 57 |
+
'*': 'bold',
|
| 58 |
+
'~': 'strikethrough'
|
| 59 |
+
}
|
| 60 |
+
text = text || monospace
|
| 61 |
+
let formatted = !types[type] || depth < 1 ? text : chalk[types[type]](text.replace(mdRegex, mdFormat(depth - 1)))
|
| 62 |
+
// console.log({ depth, type, formatted, text, monospace }, formatted)
|
| 63 |
+
return formatted
|
| 64 |
+
}
|
| 65 |
+
if (log.length < 4096)
|
| 66 |
+
log = log.replace(urlRegex, (url, i, text) => {
|
| 67 |
+
let end = url.length + i
|
| 68 |
+
return i === 0 || end === text.length || (/^\s$/.test(text[end]) && /^\s$/.test(text[i - 1])) ? chalk.blueBright(url) : url
|
| 69 |
+
})
|
| 70 |
+
log = log.replace(mdRegex, mdFormat(4))
|
| 71 |
+
if (m.mentionedJid) for (let user of m.mentionedJid) log = log.replace('@' + user.split`@`[0], chalk.blueBright('@' + await conn.getName(user)))
|
| 72 |
+
console.log(m.error != null ? chalk.red(log) : m.isCommand ? chalk.yellow(log) : log)
|
| 73 |
+
}
|
| 74 |
+
if (m.messageStubParameters) console.log(m.messageStubParameters.map(jid => {
|
| 75 |
+
jid = conn.decodeJid(jid)
|
| 76 |
+
let name = conn.getName(jid)
|
| 77 |
+
return chalk.gray(PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') + (name ? ' ~' + name : ''))
|
| 78 |
+
}).join(', '))
|
| 79 |
+
if (/document/i.test(m.mtype)) console.log(`📄 ${m.msg.filename || m.msg.displayName || 'Document'}`)
|
| 80 |
+
else if (/ContactsArray/i.test(m.mtype)) console.log(`👨👩👧👦 ${' ' || ''}`)
|
| 81 |
+
else if (/contact/i.test(m.mtype)) console.log(`👨 ${m.msg.displayName || ''}`)
|
| 82 |
+
else if (/audio/i.test(m.mtype)) (s = m.msg.seconds, console.log(`${m.msg.ptt ? '🎤 (PTT ' : '🎵 ('}AUDIO) ${Math.floor(s / 60).toString().padStart(2, 0)}:${(s % 60).toString().padStart(2, 0)}`))
|
| 83 |
+
|
| 84 |
+
console.log()
|
| 85 |
+
// if (m.quoted) console.log(m.msg.contextInfo)
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
let file = require.resolve(__filename)
|
| 89 |
+
fs.watchFile(file, () => {
|
| 90 |
+
fs.unwatchFile(file)
|
| 91 |
+
console.log(chalk.redBright("Update 'lib/print.js'"))
|
| 92 |
+
delete require.cache[file]
|
| 93 |
+
})
|
lib/scrape.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const cheerio = require('cheerio')
|
| 2 |
+
const fetch = require('node-fetch')
|
| 3 |
+
const axios = require("axios")
|
| 4 |
+
const qs = require("qs")
|
| 5 |
+
|
| 6 |
+
function quotes(input) {
|
| 7 |
+
return new Promise((resolve, reject) => {
|
| 8 |
+
fetch('https://jagokata.com/kata-bijak/kata-' + input.replace(/\s/g, '_') + '.html?page=1')
|
| 9 |
+
.then(res => res.text())
|
| 10 |
+
.then(res => {
|
| 11 |
+
const $ = cheerio.load(res)
|
| 12 |
+
data = []
|
| 13 |
+
$('div[id="main"]').find('ul[id="citatenrijen"] > li').each(function (index, element) {
|
| 14 |
+
x = $(this).find('div[class="citatenlijst-auteur"] > a').text().trim()
|
| 15 |
+
y = $(this).find('span[class="auteur-beschrijving"]').text().trim()
|
| 16 |
+
z = $(element).find('q[class="fbquote"]').text().trim()
|
| 17 |
+
data.push({ author: x, bio: y, quote: z })
|
| 18 |
+
})
|
| 19 |
+
data.splice(2, 1)
|
| 20 |
+
if (data.length == 0) return resolve({ creator: 'stikerin', status: false })
|
| 21 |
+
resolve({ creator: 'stikerin', status: true, data })
|
| 22 |
+
}).catch(reject)
|
| 23 |
+
})
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
function joox(query) {
|
| 27 |
+
return new Promise((resolve, reject) => {
|
| 28 |
+
const time = Math.floor(new Date() / 1000)
|
| 29 |
+
axios.get('http://api.joox.com/web-fcgi-bin//web_search?lang=id&country=id&type=0&search_input=' + query + '&pn=1&sin=0&ein=29&_=' + time)
|
| 30 |
+
.then(({ data }) => {
|
| 31 |
+
let result = []
|
| 32 |
+
let hasil = []
|
| 33 |
+
let promoses = []
|
| 34 |
+
let ids = []
|
| 35 |
+
data.itemlist.forEach(result => {
|
| 36 |
+
ids.push(result.songid)
|
| 37 |
+
});
|
| 38 |
+
for (let i = 0; i < data.itemlist.length; i++) {
|
| 39 |
+
const get = 'http://api.joox.com/web-fcgi-bin/web_get_songinfo?songid=' + ids[i]
|
| 40 |
+
promoses.push(
|
| 41 |
+
axios.get(get, {
|
| 42 |
+
headers: {
|
| 43 |
+
Cookie: 'wmid=142420656; user_type=1; country=id; session_key=2a5d97d05dc8fe238150184eaf3519ad;'
|
| 44 |
+
}
|
| 45 |
+
})
|
| 46 |
+
.then(({ data }) => {
|
| 47 |
+
const res = JSON.parse(data.replace('MusicInfoCallback(', '').replace('\n)', ''))
|
| 48 |
+
hasil.push({
|
| 49 |
+
lagu: res.msong,
|
| 50 |
+
album: res.malbum,
|
| 51 |
+
penyanyi: res.msinger,
|
| 52 |
+
publish: res.public_time,
|
| 53 |
+
img: res.imgSrc,
|
| 54 |
+
mp3: res.mp3Url
|
| 55 |
+
})
|
| 56 |
+
Promise.all(promoses).then(() => resolve({
|
| 57 |
+
creator: "ariffb",
|
| 58 |
+
status: true,
|
| 59 |
+
data: hasil,
|
| 60 |
+
}))
|
| 61 |
+
}).catch(reject)
|
| 62 |
+
)
|
| 63 |
+
}
|
| 64 |
+
}).catch(reject)
|
| 65 |
+
})
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
function tiktok(url) {
|
| 69 |
+
return new Promise(async (resolve, reject) => {
|
| 70 |
+
axios.get('https://ttdownloader.com/', {
|
| 71 |
+
headers: {
|
| 72 |
+
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
| 73 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 74 |
+
"cookie": "PHPSESSID=9ut8phujrprrmll6oc3bist01t; popCookie=1; _ga=GA1.2.1068750365.1625213061; _gid=GA1.2.842420949.1625213061"
|
| 75 |
+
}
|
| 76 |
+
})
|
| 77 |
+
.then(({ data }) => {
|
| 78 |
+
const $ = cheerio.load(data)
|
| 79 |
+
let token = $('#token').attr('value')
|
| 80 |
+
let config = {
|
| 81 |
+
'url': url,
|
| 82 |
+
'format': '',
|
| 83 |
+
'token': token
|
| 84 |
+
}
|
| 85 |
+
axios('https://ttdownloader.com/req/', {
|
| 86 |
+
method: 'POST',
|
| 87 |
+
data: new URLSearchParams(Object.entries(config)),
|
| 88 |
+
headers: {
|
| 89 |
+
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
| 90 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 91 |
+
"cookie": "PHPSESSID=9ut8phujrprrmll6oc3bist01t; popCookie=1; _ga=GA1.2.1068750365.1625213061; _gid=GA1.2.842420949.1625213061"
|
| 92 |
+
}
|
| 93 |
+
})
|
| 94 |
+
.then(({ data }) => {
|
| 95 |
+
const $ = cheerio.load(data)
|
| 96 |
+
resolve({
|
| 97 |
+
nowm: $('div:nth-child(2) > div.download > a').attr('href'),
|
| 98 |
+
wm: $('div:nth-child(3) > div.download > a').attr('href'),
|
| 99 |
+
audio: $('div:nth-child(4) > div.download > a').attr('href')
|
| 100 |
+
})
|
| 101 |
+
})
|
| 102 |
+
})
|
| 103 |
+
.catch(reject)
|
| 104 |
+
})
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
function twitter(url) {
|
| 108 |
+
return new Promise((resolve, reject) => {
|
| 109 |
+
let params = new URLSearchParams()
|
| 110 |
+
params.append('URL', url)
|
| 111 |
+
fetch('https://twdown.net/download.php', { method: 'POST', body: params })
|
| 112 |
+
.then(res => res.text())
|
| 113 |
+
.then(res => {
|
| 114 |
+
const $ = cheerio.load(res);
|
| 115 |
+
data = []
|
| 116 |
+
$('div.container').find('tbody > tr > td').each(function (index, element) {
|
| 117 |
+
x = $(this).find('a').attr('href')
|
| 118 |
+
if (x !== '#') {
|
| 119 |
+
if (typeof x !== 'undefined') {
|
| 120 |
+
data.push({ url: x })
|
| 121 |
+
}
|
| 122 |
+
}
|
| 123 |
+
})
|
| 124 |
+
if (data.length == 0) return resolve({ status: false })
|
| 125 |
+
resolve({ status: true, data })
|
| 126 |
+
}).catch(reject)
|
| 127 |
+
})
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
function igdl(url) {
|
| 131 |
+
return new Promise(async (resolve, reject) => {
|
| 132 |
+
axios.request({
|
| 133 |
+
url: 'https://www.instagramsave.com/download-instagram-videos.php',
|
| 134 |
+
method: 'GET',
|
| 135 |
+
headers: {
|
| 136 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 137 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg"
|
| 138 |
+
}
|
| 139 |
+
})
|
| 140 |
+
.then(({ data }) => {
|
| 141 |
+
const $ = cheerio.load(data)
|
| 142 |
+
const token = $('#token').attr('value')
|
| 143 |
+
let config = {
|
| 144 |
+
headers: {
|
| 145 |
+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
| 146 |
+
"sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
|
| 147 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg",
|
| 148 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 149 |
+
},
|
| 150 |
+
data: {
|
| 151 |
+
'url': url,
|
| 152 |
+
'action': 'post',
|
| 153 |
+
'token': token
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
axios.post('https://www.instagramsave.com/system/action.php', qs.stringify(config.data), { headers: config.headers })
|
| 157 |
+
.then(({ data }) => {
|
| 158 |
+
resolve(data.medias)
|
| 159 |
+
})
|
| 160 |
+
})
|
| 161 |
+
.catch(reject)
|
| 162 |
+
})
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
function igstory(username) {
|
| 166 |
+
return new Promise(async (resolve, reject) => {
|
| 167 |
+
axios.request({
|
| 168 |
+
url: 'https://www.instagramsave.com/instagram-story-downloader.php',
|
| 169 |
+
method: 'GET',
|
| 170 |
+
headers: {
|
| 171 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 172 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg"
|
| 173 |
+
}
|
| 174 |
+
})
|
| 175 |
+
.then(({ data }) => {
|
| 176 |
+
const $ = cheerio.load(data)
|
| 177 |
+
const token = $('#token').attr('value')
|
| 178 |
+
let config = {
|
| 179 |
+
headers: {
|
| 180 |
+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
| 181 |
+
"sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
|
| 182 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg",
|
| 183 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 184 |
+
},
|
| 185 |
+
data: {
|
| 186 |
+
'url': 'https://www.instagram.com/' + username,
|
| 187 |
+
'action': 'story',
|
| 188 |
+
'token': token
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
axios.post('https://www.instagramsave.com/system/action.php', qs.stringify(config.data), { headers: config.headers })
|
| 192 |
+
.then(({ data }) => {
|
| 193 |
+
resolve(data.medias)
|
| 194 |
+
})
|
| 195 |
+
})
|
| 196 |
+
.catch(reject)
|
| 197 |
+
})
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
function pin(url) {
|
| 201 |
+
return new Promise(async (resolve, reject) => {
|
| 202 |
+
let form = new URLSearchParams()
|
| 203 |
+
form.append('url', url)
|
| 204 |
+
let html = await (await fetch('https://pinterestvideodownloader.com/', { method: 'POST', body: form })).text()
|
| 205 |
+
$ = cheerio.load(html)
|
| 206 |
+
let data = []
|
| 207 |
+
$('table > tbody > tr').each(function (i, e) {
|
| 208 |
+
if ($($(e).find('td')[0]).text() != '') data.push({
|
| 209 |
+
url: $($(e).find('td')[0]).find('a').attr('href')
|
| 210 |
+
})
|
| 211 |
+
})
|
| 212 |
+
if (data.length == 0) return resolve({ status: false })
|
| 213 |
+
resolve({ status: true, data })
|
| 214 |
+
})
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
let is = {
|
| 219 |
+
headers: {
|
| 220 |
+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
| 221 |
+
"sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
|
| 222 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg",
|
| 223 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 224 |
+
}
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
function _token(host) {
|
| 228 |
+
return new Promise(async (resolve, reject) => {
|
| 229 |
+
axios.request({
|
| 230 |
+
url: host, method: 'GET', headers: {
|
| 231 |
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
| 232 |
+
"cookie": "PHPSESSID=ugpgvu6fgc4592jh7ht9d18v49; _ga=GA1.2.1126798330.1625045680; _gid=GA1.2.1475525047.1625045680; __gads=ID=92b58ed9ed58d147-221917af11ca0021:T=1625045679:RT=1625045679:S=ALNI_MYnQToDW3kOUClBGEzULNjeyAqOtg"
|
| 233 |
+
}
|
| 234 |
+
}).then(({ data }) => {
|
| 235 |
+
let $ = cheerio.load(data)
|
| 236 |
+
let token = $('#token').attr('value')
|
| 237 |
+
resolve(token)
|
| 238 |
+
})
|
| 239 |
+
})
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
function facebook(url) {
|
| 243 |
+
return new Promise(async (resolve, reject) => {
|
| 244 |
+
let host = 'https://aiovideodl.ml/'
|
| 245 |
+
let form = { data: { 'url': url, 'token': (await _token(host)) } }
|
| 246 |
+
axios.post(host + '/system/action.php', qs.stringify(form.data), { headers: is.headers })
|
| 247 |
+
.then(({ data }) => {
|
| 248 |
+
if (data.links.lenght == 0) return resolve({ creator: '@neoxrs – Wildan Izzudin', status: false })
|
| 249 |
+
resolve({ creator: '@neoxrs – Wildan Izzudin', status: true, data: data.links })
|
| 250 |
+
})
|
| 251 |
+
})
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
module.exports = { facebook, quotes, igdl, igstory, tiktok, twitter, joox, pin }
|
lib/simple.js
ADDED
|
@@ -0,0 +1,1638 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { imageToWebp, videoToWebp, writeExifImg, writeExifVid } = require('../lib/exif')
|
| 2 |
+
const {
|
| 3 |
+
default: makeWASocket,
|
| 4 |
+
makeWALegacySocket,
|
| 5 |
+
extractMessageContent,
|
| 6 |
+
makeInMemoryStore,
|
| 7 |
+
proto,
|
| 8 |
+
prepareWAMessageMedia,
|
| 9 |
+
downloadContentFromMessage,
|
| 10 |
+
getBinaryNodeChild,
|
| 11 |
+
jidDecode,
|
| 12 |
+
areJidsSameUser,
|
| 13 |
+
generateForwardMessageContent,
|
| 14 |
+
generateWAMessageFromContent,
|
| 15 |
+
WAMessageStubType,
|
| 16 |
+
WA_DEFAULT_EPHEMERAL,
|
| 17 |
+
} = require('@adiwajshing/baileys')
|
| 18 |
+
const { toAudio, toPTT, toVideo } = require('./converter')
|
| 19 |
+
const chalk = require('chalk')
|
| 20 |
+
const fetch = require('node-fetch')
|
| 21 |
+
const FileType = require('file-type')
|
| 22 |
+
const PhoneNumber = require('awesome-phonenumber')
|
| 23 |
+
const fs = require('fs')
|
| 24 |
+
const path = require('path')
|
| 25 |
+
const jimp = require('jimp')
|
| 26 |
+
const pino = require('pino')
|
| 27 |
+
const util = require('util')
|
| 28 |
+
const store = makeInMemoryStore({ logger: pino().child({ level: 'silent', stream: 'store' }) })
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
exports.makeWASocket = (connectionOptions, options = {}) => {
|
| 32 |
+
let conn = (opts['legacy'] ? makeWALegacySocket : makeWASocket)(connectionOptions)
|
| 33 |
+
// conn.ws.on('CB:stream:error', (stream) => {
|
| 34 |
+
// const { code } = stream || {}
|
| 35 |
+
// if (code == '401') conn.ev.emit('connection.update', {
|
| 36 |
+
// connection: 'logged Out',
|
| 37 |
+
// lastDisconnect: {
|
| 38 |
+
// error: {
|
| 39 |
+
// output: {
|
| 40 |
+
// statusCode: DisconnectReason.loggedOut
|
| 41 |
+
// }
|
| 42 |
+
// },
|
| 43 |
+
// date: new Date()
|
| 44 |
+
// }
|
| 45 |
+
// })
|
| 46 |
+
// })
|
| 47 |
+
conn.decodeJid = (jid) => {
|
| 48 |
+
if (!jid) return jid
|
| 49 |
+
if (/:\d+@/gi.test(jid)) {
|
| 50 |
+
const decode = jidDecode(jid) || {}
|
| 51 |
+
return decode.user && decode.server && decode.user + '@' + decode.server || jid
|
| 52 |
+
} else return jid
|
| 53 |
+
}
|
| 54 |
+
if (conn.user && conn.user.id) conn.user.jid = conn.decodeJid(conn.user.id)
|
| 55 |
+
if (!conn.chats) conn.chats = {}
|
| 56 |
+
|
| 57 |
+
function updateNameToDb(contacts) {
|
| 58 |
+
if (!contacts) return
|
| 59 |
+
for (const contact of contacts) {
|
| 60 |
+
const id = conn.decodeJid(contact.id)
|
| 61 |
+
if (!id) continue
|
| 62 |
+
let chats = conn.chats[id]
|
| 63 |
+
if (!chats) chats = conn.chats[id] = { id }
|
| 64 |
+
conn.chats[id] = {
|
| 65 |
+
...chats,
|
| 66 |
+
...({
|
| 67 |
+
...contact, id, ...(id.endsWith('@g.us') ?
|
| 68 |
+
{ subject: contact.subject || chats.subject || '' } :
|
| 69 |
+
{ name: contact.notify || chats.name || chats.notify || '' })
|
| 70 |
+
} || {})
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
conn.ev.on('contacts.upsert', updateNameToDb)
|
| 77 |
+
conn.ev.on('groups.update', updateNameToDb)
|
| 78 |
+
conn.ev.on('chats.set', async ({ chats }) => {
|
| 79 |
+
for (const { id, name, readOnly } of chats) {
|
| 80 |
+
id = conn.decodeJid(id)
|
| 81 |
+
if (!id) continue
|
| 82 |
+
const isGroup = id.endsWith('@g.us')
|
| 83 |
+
let chats = conn.chats[id]
|
| 84 |
+
if (!chats) chats = conn.chats[id] = { id }
|
| 85 |
+
chats.isChats = !readOnly
|
| 86 |
+
if (name) chats[isGroup ? 'subject' : 'name'] = name
|
| 87 |
+
if (isGroup) {
|
| 88 |
+
const metadata = await conn.groupMetadata(id).catch(_ => null)
|
| 89 |
+
if (!metadata) continue
|
| 90 |
+
chats.subject = name || metadata.subject
|
| 91 |
+
chats.metadata = metadata
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
})
|
| 95 |
+
conn.ev.on('group-participants.update', async function updateParticipantsToDb({ id, participants, action }) {
|
| 96 |
+
id = conn.decodeJid(id)
|
| 97 |
+
if (!(id in conn.chats)) conn.chats[id] = { id }
|
| 98 |
+
conn.chats[id].isChats = true
|
| 99 |
+
const groupMetadata = await conn.groupMetadata(id).catch(_ => null)
|
| 100 |
+
if (!groupMetadata) return
|
| 101 |
+
conn.chats[id] = {
|
| 102 |
+
...conn.chats[id],
|
| 103 |
+
subject: groupMetadata.subject,
|
| 104 |
+
metadata: groupMetadata
|
| 105 |
+
}
|
| 106 |
+
})
|
| 107 |
+
|
| 108 |
+
conn.ev.on('groups.update', async function groupUpdatePushToDb(groupsUpdates) {
|
| 109 |
+
for (const update of groupsUpdates) {
|
| 110 |
+
const id = conn.decodeJid(update.id)
|
| 111 |
+
if (!id) continue
|
| 112 |
+
const isGroup = id.endsWith('@g.us')
|
| 113 |
+
if (!isGroup) continue
|
| 114 |
+
let chats = conn.chats[id]
|
| 115 |
+
if (!chats) chats = conn.chats[id] = { id }
|
| 116 |
+
chats.isChats = true
|
| 117 |
+
const metadata = await conn.groupMetadata(id).catch(_ => null)
|
| 118 |
+
if (!metadata) continue
|
| 119 |
+
chats.subject = metadata.subject
|
| 120 |
+
chats.metadata = metadata
|
| 121 |
+
}
|
| 122 |
+
})
|
| 123 |
+
conn.ev.on('chats.upsert', async function chatsUpsertPushToDb(chatsUpsert) {
|
| 124 |
+
console.log({ chatsUpsert })
|
| 125 |
+
const { id, name } = chatsUpsert
|
| 126 |
+
if (!id) return
|
| 127 |
+
let chats = conn.chats[id] = { ...conn.chats[id], ...chatsUpsert, isChats: true }
|
| 128 |
+
const isGroup = id.endsWith('@g.us')
|
| 129 |
+
if (isGroup) {
|
| 130 |
+
const metadata = await conn.groupMetadata(id).catch(_ => null)
|
| 131 |
+
if (metadata) {
|
| 132 |
+
chats.subject = name || metadata.subject
|
| 133 |
+
chats.metadata = metadata
|
| 134 |
+
}
|
| 135 |
+
const groups = await conn.groupFetchAllParticipating().catch(_ => ({})) || {}
|
| 136 |
+
for (const group in groups) conn.chats[group] = { id: group, subject: groups[group].subject, isChats: true, metadata: groups[group] }
|
| 137 |
+
}
|
| 138 |
+
})
|
| 139 |
+
conn.ev.on('presence.update', async function presenceUpdatePushToDb({ id, presences }) {
|
| 140 |
+
const sender = Object.keys(presences)[0] || id
|
| 141 |
+
const _sender = conn.decodeJid(sender)
|
| 142 |
+
const presence = presences[sender]['lastKnownPresence'] || 'composing'
|
| 143 |
+
let chats = conn.chats[_sender]
|
| 144 |
+
if (!chats) chats = conn.chats[_sender] = { id: sender }
|
| 145 |
+
chats.presences = presence
|
| 146 |
+
if (id.endsWith('@g.us')) {
|
| 147 |
+
let chats = conn.chats[id]
|
| 148 |
+
if (!chats) {
|
| 149 |
+
const metadata = await conn.groupMetadata(id).catch(_ => null)
|
| 150 |
+
if (metadata) chats = conn.chats[id] = { id, subject: metadata.subject, metadata }
|
| 151 |
+
}
|
| 152 |
+
chats.isChats = true
|
| 153 |
+
}
|
| 154 |
+
})
|
| 155 |
+
|
| 156 |
+
conn.logger = {
|
| 157 |
+
...conn.logger,
|
| 158 |
+
info(...args) { console.log(chalk.bold.rgb(57, 183, 16)(`INFO [${chalk.rgb(255, 255, 255)(new Date())}]:`), chalk.cyan(util.format(...args))) },
|
| 159 |
+
error(...args) { console.log(chalk.bold.rgb(247, 38, 33)(`ERROR [${chalk.rgb(255, 255, 255)(new Date())}]:`), chalk.rgb(255, 38, 0)(util.format(...args))) },
|
| 160 |
+
warn(...args) { console.log(chalk.bold.rgb(239, 225, 3)(`WARNING [${chalk.rgb(255, 255, 255)(new Date())}]:`), chalk.keyword('orange')(util.format(...args))) }
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
/**
|
| 165 |
+
* getBuffer hehe
|
| 166 |
+
* @param {fs.PathLike} path
|
| 167 |
+
* @param {Boolean} returnFilename
|
| 168 |
+
*/
|
| 169 |
+
conn.getFile = async (PATH, returnAsFilename) => {
|
| 170 |
+
let res, filename
|
| 171 |
+
let data = Buffer.isBuffer(PATH) ? PATH : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await fetch(PATH)).buffer() : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0)
|
| 172 |
+
if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer')
|
| 173 |
+
let type = await FileType.fromBuffer(data) || {
|
| 174 |
+
mime: 'application/octet-stream',
|
| 175 |
+
ext: '.bin'
|
| 176 |
+
}
|
| 177 |
+
if (data && returnAsFilename && !filename) (filename = path.join(__dirname, '../tmp/' + new Date * 1 + '.' + type.ext), await fs.promises.writeFile(filename, data))
|
| 178 |
+
return {
|
| 179 |
+
res,
|
| 180 |
+
filename,
|
| 181 |
+
...type,
|
| 182 |
+
data
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
/**
|
| 187 |
+
* waitEvent
|
| 188 |
+
* @param {Partial<BaileysEventMap>|String} eventName
|
| 189 |
+
* @param {Boolean} is
|
| 190 |
+
* @param {Number} maxTries
|
| 191 |
+
* @returns
|
| 192 |
+
*/
|
| 193 |
+
conn.waitEvent = (eventName, is = () => true, maxTries = 25) => {
|
| 194 |
+
return new Promise((resolve, reject) => {
|
| 195 |
+
let tries = 0
|
| 196 |
+
let on = (...args) => {
|
| 197 |
+
if (++tries > maxTries) reject('Max tries reached')
|
| 198 |
+
else if (is()) {
|
| 199 |
+
conn.ev.off(eventName, on)
|
| 200 |
+
resolve(...args)
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
conn.ev.on(eventName, on)
|
| 204 |
+
})
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
conn.delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
| 208 |
+
|
| 209 |
+
/**
|
| 210 |
+
*
|
| 211 |
+
* @param {String} text
|
| 212 |
+
* @returns
|
| 213 |
+
*/
|
| 214 |
+
conn.filter = (text) => {
|
| 215 |
+
let mati = ["q", "w", "r", "t", "y", "p", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m"]
|
| 216 |
+
if (/[aiueo][aiueo]([qwrtypsdfghjklzxcvbnm])?$/i.test(text)) return text.substring(text.length - 1)
|
| 217 |
+
else {
|
| 218 |
+
let res = Array.from(text).filter(v => mati.includes(v))
|
| 219 |
+
let resu = res[res.length - 1]
|
| 220 |
+
for (let huruf of mati) {
|
| 221 |
+
if (text.endsWith(huruf)) {
|
| 222 |
+
resu = res[res.length - 2]
|
| 223 |
+
}
|
| 224 |
+
}
|
| 225 |
+
let misah = text.split(resu)
|
| 226 |
+
return resu + misah[misah.length - 1]
|
| 227 |
+
}
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
/**
|
| 231 |
+
* ms to date
|
| 232 |
+
* @param {String} ms
|
| 233 |
+
*/
|
| 234 |
+
conn.msToDate = (ms) => {
|
| 235 |
+
let days = Math.floor(ms / (24 * 60 * 60 * 1000));
|
| 236 |
+
let daysms = ms % (24 * 60 * 60 * 1000);
|
| 237 |
+
let hours = Math.floor((daysms) / (60 * 60 * 1000));
|
| 238 |
+
let hoursms = ms % (60 * 60 * 1000);
|
| 239 |
+
let minutes = Math.floor((hoursms) / (60 * 1000));
|
| 240 |
+
let minutesms = ms % (60 * 1000);
|
| 241 |
+
let sec = Math.floor((minutesms) / (1000));
|
| 242 |
+
return days + " Hari " + hours + " Jam " + minutes + " Menit";
|
| 243 |
+
// +minutes+":"+sec;
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
/**
|
| 247 |
+
* isi
|
| 248 |
+
*/
|
| 249 |
+
conn.rand = async (isi) => {
|
| 250 |
+
return isi[Math.floor(Math.random() * isi.length)]
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
/**
|
| 254 |
+
* For Resize the Image By Aine
|
| 255 |
+
* @param {Buffer} image
|
| 256 |
+
* @param {String} ukuran height
|
| 257 |
+
* @param {String} ukuran weight
|
| 258 |
+
* @returns
|
| 259 |
+
*/
|
| 260 |
+
|
| 261 |
+
conn.resize = async (buffer, uk1, uk2) => {
|
| 262 |
+
return new Promise(async(resolve, reject) => {
|
| 263 |
+
var baper = await jimp.read(buffer);
|
| 264 |
+
var ab = await baper.resize(uk1, uk2).getBufferAsync(jimp.MIME_JPEG)
|
| 265 |
+
resolve(ab)
|
| 266 |
+
})
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
/**
|
| 270 |
+
* Send Media All Type
|
| 271 |
+
* @param {String} jid
|
| 272 |
+
* @param {String|Buffer} path
|
| 273 |
+
* @param {Object} quoted
|
| 274 |
+
* @param {Object} options
|
| 275 |
+
*/
|
| 276 |
+
conn.sendMedia = async (jid, path, quoted, options = {}) => {
|
| 277 |
+
let { ext, mime, data } = await conn.getFile(path)
|
| 278 |
+
messageType = mime.split("/")[0]
|
| 279 |
+
pase = messageType.replace('application', 'document') || messageType
|
| 280 |
+
return await conn.sendMessage(jid, { [`${pase}`]: data, mimetype: mime, ...options }, { quoted })
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
/**
|
| 284 |
+
* Send Media/File with Automatic Type Specifier
|
| 285 |
+
* @param {String} jid
|
| 286 |
+
* @param {String|Buffer} path
|
| 287 |
+
* @param {String} filename
|
| 288 |
+
* @param {String} caption
|
| 289 |
+
* @param {proto.WebMessageInfo} quoted
|
| 290 |
+
* @param {Boolean} ptt
|
| 291 |
+
* @param {Object} options
|
| 292 |
+
*/
|
| 293 |
+
conn.getFile = async (PATH, returnAsFilename) => {
|
| 294 |
+
let res, filename
|
| 295 |
+
let data = Buffer.isBuffer(PATH) ? PATH : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await fetch(PATH)).buffer() : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0)
|
| 296 |
+
if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer')
|
| 297 |
+
let type = await FileType.fromBuffer(data) || {
|
| 298 |
+
mime: 'application/octet-stream',
|
| 299 |
+
ext: '.bin'
|
| 300 |
+
}
|
| 301 |
+
if (data && returnAsFilename && !filename) (filename = path.join(__dirname, '../tmp/' + new Date * 1 + '.' + type.ext), await fs.promises.writeFile(filename, data))
|
| 302 |
+
return {
|
| 303 |
+
res,
|
| 304 |
+
filename,
|
| 305 |
+
...type,
|
| 306 |
+
data
|
| 307 |
+
}
|
| 308 |
+
}
|
| 309 |
+
/**
|
| 310 |
+
* Send Media/File with Automatic Type Specifier
|
| 311 |
+
* @param {String} jid
|
| 312 |
+
* @param {String|Buffer} path
|
| 313 |
+
* @param {String} filename
|
| 314 |
+
* @param {String} caption
|
| 315 |
+
* @param {Object} quoted
|
| 316 |
+
* @param {Boolean} ptt
|
| 317 |
+
* @param {Object} options
|
| 318 |
+
*/
|
| 319 |
+
conn.sendFile = async (jid, path, filename = '', caption = '', quoted, ptt = false, options = {}) => {
|
| 320 |
+
let type = await conn.getFile(path, true)
|
| 321 |
+
let { res, data: file, filename: pathFile } = type
|
| 322 |
+
if (res && res.status !== 200 || file.length <= 65536) {
|
| 323 |
+
try { throw { json: JSON.parse(file.toString()) } }
|
| 324 |
+
catch (e) { if (e.json) throw e.json }
|
| 325 |
+
}
|
| 326 |
+
let opt = { filename }
|
| 327 |
+
if (quoted) opt.quoted = quoted
|
| 328 |
+
if (!type) if (options.asDocument) options.asDocument = true
|
| 329 |
+
let mtype = '', mimetype = type.mime
|
| 330 |
+
if (/webp/.test(type.mime)) mtype = 'sticker'
|
| 331 |
+
else if (/image/.test(type.mime)) mtype = 'image'
|
| 332 |
+
else if (/video/.test(type.mime)) mtype = 'video'
|
| 333 |
+
else if (/audio/.test(type.mime)) (
|
| 334 |
+
convert = await (ptt ? toPTT : toAudio)(file, type.ext),
|
| 335 |
+
file = convert.data,
|
| 336 |
+
pathFile = convert.filename,
|
| 337 |
+
mtype = 'audio',
|
| 338 |
+
mimetype = 'audio/ogg; codecs=opus'
|
| 339 |
+
)
|
| 340 |
+
else mtype = 'document'
|
| 341 |
+
return await conn.sendMessage(jid, {
|
| 342 |
+
...options,
|
| 343 |
+
caption,
|
| 344 |
+
ptt,
|
| 345 |
+
[mtype]: { url: pathFile },
|
| 346 |
+
mimetype
|
| 347 |
+
}, {
|
| 348 |
+
...opt,
|
| 349 |
+
...options
|
| 350 |
+
})
|
| 351 |
+
}
|
| 352 |
+
//Wm Sticker
|
| 353 |
+
conn.sendImageAsSticker = async (jid, path, quoted, options = {}) => {
|
| 354 |
+
let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await fetch(path)).buffer() : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
|
| 355 |
+
let buffer
|
| 356 |
+
if (options && (options.packname || options.author)) {
|
| 357 |
+
buffer = await writeExifImg(buff, options)
|
| 358 |
+
} else {
|
| 359 |
+
buffer = await imageToWebp(buff)
|
| 360 |
+
}
|
| 361 |
+
|
| 362 |
+
await conn.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted })
|
| 363 |
+
return buffer
|
| 364 |
+
}
|
| 365 |
+
conn.sendVideoAsSticker = async (jid, path, quoted, options = {}) => {
|
| 366 |
+
let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await fetch(path)).buffer() : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
|
| 367 |
+
let buffer
|
| 368 |
+
if (options && (options.packname || options.author)) {
|
| 369 |
+
buffer = await writeExifVid(buff, options)
|
| 370 |
+
} else {
|
| 371 |
+
buffer = await videoToWebp(buff)
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
await conn.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted })
|
| 375 |
+
return buffer
|
| 376 |
+
}
|
| 377 |
+
/**
|
| 378 |
+
* Send Contact
|
| 379 |
+
* @param {String} jid
|
| 380 |
+
* @param {String[][]} data
|
| 381 |
+
* @param {proto.WebMessageInfo} quoted
|
| 382 |
+
* @param {Object} options
|
| 383 |
+
*/
|
| 384 |
+
conn.sendContact = async (jid, data, quoted, options) => {
|
| 385 |
+
let contacts = []
|
| 386 |
+
for (let [number, name] of data) {
|
| 387 |
+
number = number.replace(/[^0-9]/g, '')
|
| 388 |
+
let njid = number + '@s.whatsapp.net'
|
| 389 |
+
let biz = await conn.getBusinessProfile(njid) || {}
|
| 390 |
+
// N:;${name.replace(/\n/g, '\\n').split(' ').reverse().join(';')};;;
|
| 391 |
+
let vcard = `
|
| 392 |
+
BEGIN:VCARD
|
| 393 |
+
VERSION:3.0
|
| 394 |
+
FN:${name.replace(/\n/g, '\\n')}
|
| 395 |
+
item1.TEL;waid=${number}:${PhoneNumber('+' + number).getNumber('international')}
|
| 396 |
+
item1.X-ABLabel:Ponsel${biz.description ? `
|
| 397 |
+
PHOTO;BASE64:${(await conn.getFile(await conn.profilePictureUrl(njid)).catch(_ => ({})) || {}).data?.toString('base64')}
|
| 398 |
+
X-WA-BIZ-DESCRIPTION:${(biz.description || '').replace(/\n/g, '\\n')}
|
| 399 |
+
X-WA-BIZ-NAME:${(((conn.chats[njid] || {}) || { vname: conn.chats[njid]?.name }).vname || conn.getName(njid) || name).replace(/\n/, '\\n')}
|
| 400 |
+
`.trim() : ''}
|
| 401 |
+
END:VCARD
|
| 402 |
+
`.trim()
|
| 403 |
+
contacts.push({ vcard, displayName: name })
|
| 404 |
+
|
| 405 |
+
}
|
| 406 |
+
return await conn.sendMessage(jid, {
|
| 407 |
+
contacts: {
|
| 408 |
+
...options,
|
| 409 |
+
displayName: (contacts.length > 1 ? `${contacts.length} kontak` : contacts[0].displayName) || null,
|
| 410 |
+
contacts,
|
| 411 |
+
},
|
| 412 |
+
quoted, ...options
|
| 413 |
+
})
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
/**
|
| 417 |
+
* Reply to a message
|
| 418 |
+
* @param {String} jid
|
| 419 |
+
* @param {String|Object} text
|
| 420 |
+
* @param {Object} quoted
|
| 421 |
+
* @param {Object} options
|
| 422 |
+
*/
|
| 423 |
+
conn.reply = (jid, text = '', quoted, options) => {
|
| 424 |
+
return Buffer.isBuffer(text) ? this.sendFile(jid, text, 'file', '', quoted, false, options) : conn.sendMessage(jid, { ...options, text, mentions: conn.parseMention(text) }, { quoted, ...options, mentions: conn.parseMention(text) })
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
conn.decodeJid = (jid) => {
|
| 428 |
+
if (!jid) return jid
|
| 429 |
+
if (/:\d+@/gi.test(jid)) {
|
| 430 |
+
let decode = jidDecode(jid) || {}
|
| 431 |
+
return decode.user && decode.server && decode.user + '@' + decode.server || jid
|
| 432 |
+
} else return jid
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
/**
|
| 436 |
+
*
|
| 437 |
+
* @param {*} jid
|
| 438 |
+
* @param {*} text
|
| 439 |
+
* @param {*} quoted
|
| 440 |
+
* @param {*} options
|
| 441 |
+
* @returns
|
| 442 |
+
*/
|
| 443 |
+
conn.sendText = (jid, text, quoted = '', options) => conn.sendMessage(jid, { text: text, ...options }, { quoted })
|
| 444 |
+
|
| 445 |
+
/**
|
| 446 |
+
* sendGroupV4Invite
|
| 447 |
+
* @param {String} jid
|
| 448 |
+
* @param {*} participant
|
| 449 |
+
* @param {String} inviteCode
|
| 450 |
+
* @param {Number} inviteExpiration
|
| 451 |
+
* @param {String} groupName
|
| 452 |
+
* @param {String} caption
|
| 453 |
+
* @param {*} options
|
| 454 |
+
* @returns
|
| 455 |
+
*/
|
| 456 |
+
conn.sendGroupV4Invite = async (jid, participant, inviteCode, inviteExpiration, groupName = 'unknown subject', caption = 'Invitation to join my WhatsApp group', options = {}) => {
|
| 457 |
+
let msg = proto.Message.fromObject({
|
| 458 |
+
groupInviteMessage: proto.GroupInviteMessage.fromObject({
|
| 459 |
+
inviteCode,
|
| 460 |
+
inviteExpiration: parseInt(inviteExpiration) || + new Date(new Date + (3 * 86400000)),
|
| 461 |
+
groupJid: jid,
|
| 462 |
+
groupName: groupName ? groupName : this.getName(jid),
|
| 463 |
+
caption
|
| 464 |
+
})
|
| 465 |
+
})
|
| 466 |
+
let message = await this.prepareMessageFromContent(participant, msg, options)
|
| 467 |
+
await this.relayWAMessage(message)
|
| 468 |
+
return message
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
/**
|
| 472 |
+
* send Button
|
| 473 |
+
* @param {String} jid
|
| 474 |
+
* @param {String} contentText
|
| 475 |
+
* @param {String} footer
|
| 476 |
+
* @param {Buffer|String} buffer
|
| 477 |
+
* @param {String[]} buttons
|
| 478 |
+
* @param {proto.WebMessageInfo} quoted
|
| 479 |
+
* @param {Object} options
|
| 480 |
+
*/
|
| 481 |
+
conn.sendButton = async (jid, contentText, footer, buffer, buttons, quoted, options) => {
|
| 482 |
+
if (buffer) try { buffer = (await conn.getFile(buffer)).data } catch { buffer = null }
|
| 483 |
+
let message = {
|
| 484 |
+
...options,
|
| 485 |
+
...(buffer ? { caption: contentText || '' } : { text: contentText || '' }),
|
| 486 |
+
footer,
|
| 487 |
+
buttons: buttons.map(btn => {
|
| 488 |
+
return {
|
| 489 |
+
buttonId: btn[1] || btn[0] || '',
|
| 490 |
+
buttonText: {
|
| 491 |
+
displayText: btn[0] || btn[1] || ''
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
}),
|
| 495 |
+
...(buffer ? { image: buffer } : {})
|
| 496 |
+
}
|
| 497 |
+
return await conn.sendMessage(jid, message, {
|
| 498 |
+
quoted,
|
| 499 |
+
upload: conn.waUploadToServer,
|
| 500 |
+
...options
|
| 501 |
+
})
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
conn.sendBut = async(jid, content, footer, button1, row1, quoted) => {
|
| 505 |
+
const buttons = [
|
| 506 |
+
{buttonId: row1, buttonText: {displayText: button1}, type: 1}
|
| 507 |
+
]
|
| 508 |
+
const buttonMessage = {
|
| 509 |
+
text: content,
|
| 510 |
+
footer: footer,
|
| 511 |
+
buttons: buttons,
|
| 512 |
+
headerType: 1,
|
| 513 |
+
mentions: conn.parseMention(footer+content)
|
| 514 |
+
}
|
| 515 |
+
return await conn.sendMessage(jid, buttonMessage, {quoted})
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
conn.send2But = async(jid, content, footer, button1, row1, button2, row2, quoted) => {
|
| 519 |
+
const buttons = [
|
| 520 |
+
{ buttonId: row1, buttonText: { displayText: button1 }, type: 1 },
|
| 521 |
+
{ buttonId: row2, buttonText: { displayText: button2 }, type: 1 }
|
| 522 |
+
]
|
| 523 |
+
const buttonMessage = {
|
| 524 |
+
text: content,
|
| 525 |
+
footer: footer,
|
| 526 |
+
buttons: buttons,
|
| 527 |
+
headerType: 1
|
| 528 |
+
}
|
| 529 |
+
return await conn.sendMessage(jid, buttonMessage, {quoted})
|
| 530 |
+
}
|
| 531 |
+
|
| 532 |
+
conn.send3But = async(jid, content, footer,button1, row1, button2, row2, button3, row3, quoted) => {
|
| 533 |
+
const buttons = [
|
| 534 |
+
{ buttonId: row1, buttonText: { displayText: button1 }, type: 1 },
|
| 535 |
+
{ buttonId: row2, buttonText: { displayText: button2 }, type: 1 },
|
| 536 |
+
{ buttonId: row3, buttonText: { displayText: button3 }, type: 1 }
|
| 537 |
+
]
|
| 538 |
+
const buttonMessage = {
|
| 539 |
+
text: content,
|
| 540 |
+
footer: footer,
|
| 541 |
+
buttons: buttons,
|
| 542 |
+
headerType: 1
|
| 543 |
+
}
|
| 544 |
+
return await conn.sendMessage(jid, buttonMessage, {quoted})
|
| 545 |
+
}
|
| 546 |
+
conn.send4But = async(jid, content, footer,button1, row1, button2, row2, button3, row3, button4, row4, quoted) => {
|
| 547 |
+
const buttons = [
|
| 548 |
+
{ buttonId: row1, buttonText: { displayText: button1 }, type: 1 },
|
| 549 |
+
{ buttonId: row2, buttonText: { displayText: button2 }, type: 1 },
|
| 550 |
+
{ buttonId: row3, buttonText: { displayText: button3 }, type: 1 },
|
| 551 |
+
{ buttonId: row4, buttonText: { displayText: button4 }, type: 1 }
|
| 552 |
+
]
|
| 553 |
+
const buttonMessage = {
|
| 554 |
+
text: content,
|
| 555 |
+
footer: footer,
|
| 556 |
+
buttons: buttons,
|
| 557 |
+
headerType: 1
|
| 558 |
+
}
|
| 559 |
+
return await conn.sendMessage(jid, buttonMessage, {quoted})
|
| 560 |
+
}
|
| 561 |
+
/**
|
| 562 |
+
* send Button Img
|
| 563 |
+
* @param {String} jid
|
| 564 |
+
* @param {String} contentText
|
| 565 |
+
* @param {String} footer
|
| 566 |
+
* @param {Buffer|String} buffer
|
| 567 |
+
* @param {String[]} buttons
|
| 568 |
+
* @param {Object} quoted
|
| 569 |
+
* @param {Object} options
|
| 570 |
+
*/
|
| 571 |
+
conn.sendButtonImg = async (jid, buffer, contentText, footerText, button1, id1, quoted, options) => {
|
| 572 |
+
let type = await conn.getFile(buffer)
|
| 573 |
+
let { res, data: file } = type
|
| 574 |
+
if (res && res.status !== 200 || file.length <= 65536) {
|
| 575 |
+
try { throw { json: JSON.parse(file.toString()) } }
|
| 576 |
+
catch (e) { if (e.json) throw e.json }
|
| 577 |
+
}
|
| 578 |
+
const buttons = [
|
| 579 |
+
{ buttonId: id1, buttonText: { displayText: button1 }, type: 1 }
|
| 580 |
+
]
|
| 581 |
+
|
| 582 |
+
const buttonMessage = {
|
| 583 |
+
image: file,
|
| 584 |
+
fileLength: 887890909999999,
|
| 585 |
+
caption: contentText,
|
| 586 |
+
footer: footerText,
|
| 587 |
+
mentions: await conn.parseMention(contentText + footerText),
|
| 588 |
+
...options,
|
| 589 |
+
buttons: buttons,
|
| 590 |
+
headerType: 4
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
return await conn.sendMessage(jid, buttonMessage, { quoted, ephemeralExpiration: 86400, contextInfo: { mentionedJid: conn.parseMention(contentText + footerText) }, ...options })
|
| 594 |
+
}
|
| 595 |
+
conn.send2ButtonImg = async (jid, buffer, contentText, footerText, button1, id1, button2, id2, quoted, options) => {
|
| 596 |
+
let type = await conn.getFile(buffer)
|
| 597 |
+
let { res, data: file } = type
|
| 598 |
+
if (res && res.status !== 200 || file.length <= 65536) {
|
| 599 |
+
try { throw { json: JSON.parse(file.toString()) } }
|
| 600 |
+
catch (e) { if (e.json) throw e.json }
|
| 601 |
+
}
|
| 602 |
+
const buttons = [
|
| 603 |
+
{ buttonId: id1, buttonText: { displayText: button1 }, type: 1 },
|
| 604 |
+
{ buttonId: id2, buttonText: { displayText: button2 }, type: 1 }
|
| 605 |
+
]
|
| 606 |
+
|
| 607 |
+
const buttonMessage = {
|
| 608 |
+
image: file,
|
| 609 |
+
fileLength: 887890909999999,
|
| 610 |
+
caption: contentText,
|
| 611 |
+
footer: footerText,
|
| 612 |
+
mentions: await conn.parseMention(contentText + footerText),
|
| 613 |
+
...options,
|
| 614 |
+
buttons: buttons,
|
| 615 |
+
headerType: 4
|
| 616 |
+
}
|
| 617 |
+
|
| 618 |
+
return await conn.sendMessage(jid, buttonMessage, { quoted, ephemeralExpiration: 86400, contextInfo: { mentionedJid: conn.parseMention(contentText + footerText) }, ...options })
|
| 619 |
+
}
|
| 620 |
+
conn.send3ButtonImg = async (jid, buffer, contentText, footerText, button1, id1, button2, id2, button3, id3, quoted, options) => {
|
| 621 |
+
let type = await conn.getFile(buffer)
|
| 622 |
+
let { res, data: file } = type
|
| 623 |
+
if (res && res.status !== 200 || file.length <= 65536) {
|
| 624 |
+
try { throw { json: JSON.parse(file.toString()) } }
|
| 625 |
+
catch (e) { if (e.json) throw e.json }
|
| 626 |
+
}
|
| 627 |
+
const buttons = [
|
| 628 |
+
{ buttonId: id1, buttonText: { displayText: button1 }, type: 1 },
|
| 629 |
+
{ buttonId: id2, buttonText: { displayText: button2 }, type: 1 },
|
| 630 |
+
{ buttonId: id3, buttonText: { displayText: button3 }, type: 1 }
|
| 631 |
+
]
|
| 632 |
+
|
| 633 |
+
const buttonMessage = {
|
| 634 |
+
image: file,
|
| 635 |
+
fileLength: 887890909999999,
|
| 636 |
+
caption: contentText,
|
| 637 |
+
footer: footerText,
|
| 638 |
+
mentions: await conn.parseMention(contentText + footerText),
|
| 639 |
+
...options,
|
| 640 |
+
buttons: buttons,
|
| 641 |
+
headerType: 4
|
| 642 |
+
}
|
| 643 |
+
|
| 644 |
+
return await conn.sendMessage(jid, buttonMessage, { quoted, ephemeralExpiration: 86400, contextInfo: { mentionedJid: conn.parseMention(contentText + footerText) }, ...options })
|
| 645 |
+
}
|
| 646 |
+
|
| 647 |
+
conn.sendH3Button = async (jid, content, displayText, link, displayCall, number, quickReplyText, id, quickReplyText2, id2, quickReplyText3, id3, quoted) => {
|
| 648 |
+
let template = generateWAMessageFromContent(jid, proto.Message.fromObject({
|
| 649 |
+
templateMessage: {
|
| 650 |
+
hydratedTemplate: {
|
| 651 |
+
hydratedContentText: content,
|
| 652 |
+
hydratedButtons: [{
|
| 653 |
+
urlButton: {
|
| 654 |
+
displayText: displayText,
|
| 655 |
+
url: link
|
| 656 |
+
}
|
| 657 |
+
}, {
|
| 658 |
+
callButton: {
|
| 659 |
+
displayText: displayCall,
|
| 660 |
+
phoneNumber: number
|
| 661 |
+
}
|
| 662 |
+
},
|
| 663 |
+
{
|
| 664 |
+
quickReplyButton: {
|
| 665 |
+
displayText: quickReplyText,
|
| 666 |
+
id: id,
|
| 667 |
+
}
|
| 668 |
+
|
| 669 |
+
},
|
| 670 |
+
{
|
| 671 |
+
quickReplyButton: {
|
| 672 |
+
displayText: quickReplyText2,
|
| 673 |
+
id: id2,
|
| 674 |
+
}
|
| 675 |
+
},
|
| 676 |
+
{
|
| 677 |
+
quickReplyButton: {
|
| 678 |
+
displayText: quickReplyText3,
|
| 679 |
+
id: id3,
|
| 680 |
+
}
|
| 681 |
+
}]
|
| 682 |
+
}
|
| 683 |
+
}
|
| 684 |
+
}), { userJid: conn.user.jid, quoted: quoted});
|
| 685 |
+
return await conn.relayMessage(
|
| 686 |
+
jid,
|
| 687 |
+
template.message,
|
| 688 |
+
{ messageId: template.key.id }
|
| 689 |
+
)
|
| 690 |
+
}
|
| 691 |
+
|
| 692 |
+
conn.cMod = (jid, message, text = '', sender = conn.user.jid, options = {}) => {
|
| 693 |
+
let copy = message.toJSON()
|
| 694 |
+
let mtype = Object.keys(copy.message)[0]
|
| 695 |
+
let isEphemeral = false // mtype === 'ephemeralMessage'
|
| 696 |
+
if (isEphemeral) {
|
| 697 |
+
mtype = Object.keys(copy.message.ephemeralMessage.message)[0]
|
| 698 |
+
}
|
| 699 |
+
let msg = isEphemeral ? copy.message.ephemeralMessage.message : copy.message
|
| 700 |
+
let content = msg[mtype]
|
| 701 |
+
if (typeof content === 'string') msg[mtype] = text || content
|
| 702 |
+
else if (content.caption) content.caption = text || content.caption
|
| 703 |
+
else if (content.text) content.text = text || content.text
|
| 704 |
+
if (typeof content !== 'string') msg[mtype] = { ...content, ...options }
|
| 705 |
+
if (copy.participant) sender = copy.participant = sender || copy.participant
|
| 706 |
+
else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant
|
| 707 |
+
if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid
|
| 708 |
+
else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid
|
| 709 |
+
copy.key.remoteJid = jid
|
| 710 |
+
copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false
|
| 711 |
+
return proto.WebMessageInfo.fromObject(copy)
|
| 712 |
+
}
|
| 713 |
+
conn.sendHButtonLoc = async (jid, buffer, content, footer, distek, link1, quick1, id1,quoted) => {
|
| 714 |
+
let template = generateWAMessageFromContent(jid, proto.Message.fromObject({
|
| 715 |
+
templateMessage: {
|
| 716 |
+
hydratedTemplate: {
|
| 717 |
+
hydratedContentText: content,
|
| 718 |
+
mentions: conn.parseMention(content + footer),
|
| 719 |
+
locationMessage: {
|
| 720 |
+
jpegThumbnail: buffer },
|
| 721 |
+
hydratedFooterText: footer,
|
| 722 |
+
mentions: conn.parseMention(content + footer),
|
| 723 |
+
hydratedButtons: [{
|
| 724 |
+
urlButton: {
|
| 725 |
+
displayText: distek,
|
| 726 |
+
url: link1
|
| 727 |
+
}
|
| 728 |
+
}, {
|
| 729 |
+
quickReplyButton: {
|
| 730 |
+
displayText:quick1,
|
| 731 |
+
id: id1
|
| 732 |
+
}
|
| 733 |
+
}], mentions: conn.parseMention(content + footer)
|
| 734 |
+
}
|
| 735 |
+
}
|
| 736 |
+
}), { userJid: conn.user.jid, quoted: quoted, mentions: conn.parseMention(content + footer)});
|
| 737 |
+
return await conn.relayMessage(
|
| 738 |
+
jid,
|
| 739 |
+
template.message,
|
| 740 |
+
{ messageId: template.key.id }
|
| 741 |
+
)
|
| 742 |
+
}
|
| 743 |
+
|
| 744 |
+
conn.sendHButt = async (jid, content, distek, link, discall, number, retek, id,quoted) => {
|
| 745 |
+
let template = generateWAMessageFromContent(jid, proto.Message.fromObject({
|
| 746 |
+
templateMessage: {
|
| 747 |
+
hydratedTemplate: {
|
| 748 |
+
hydratedContentText: content,
|
| 749 |
+
hydratedButtons: [{
|
| 750 |
+
urlButton: {
|
| 751 |
+
displayText: distek,
|
| 752 |
+
url: link
|
| 753 |
+
}
|
| 754 |
+
}, {
|
| 755 |
+
callButton: {
|
| 756 |
+
displayText: discall,
|
| 757 |
+
phoneNumber: number
|
| 758 |
+
}
|
| 759 |
+
},
|
| 760 |
+
{
|
| 761 |
+
quickReplyButton: {
|
| 762 |
+
displayText:retek,
|
| 763 |
+
id: id
|
| 764 |
+
}
|
| 765 |
+
}
|
| 766 |
+
]
|
| 767 |
+
}
|
| 768 |
+
}
|
| 769 |
+
}), { userJid: conn.user.jid, quoted: quoted});
|
| 770 |
+
return await conn.relayMessage(
|
| 771 |
+
jid,
|
| 772 |
+
template.message,
|
| 773 |
+
{ messageId: template.key.id }
|
| 774 |
+
)
|
| 775 |
+
}
|
| 776 |
+
conn.sendButtonLoc= async (jid, buffer, content, footer, button1, row1, quoted, options = {}) => {
|
| 777 |
+
let buttons = [{buttonId: row1, buttonText: {displayText: button1}, type: 1}]
|
| 778 |
+
let buttonMessage = {
|
| 779 |
+
location: { jpegThumbnail: buffer },
|
| 780 |
+
caption: content,
|
| 781 |
+
footer: footer,
|
| 782 |
+
buttons: buttons,
|
| 783 |
+
headerType: 6
|
| 784 |
+
}
|
| 785 |
+
return await conn.sendMessage(jid, buttonMessage, {
|
| 786 |
+
quoted,
|
| 787 |
+
upload: conn.waUploadToServer,
|
| 788 |
+
...options
|
| 789 |
+
})
|
| 790 |
+
}
|
| 791 |
+
conn.send2ButtonLoc= async (jid, buffer, content, footer, button1, row1, button2, row2, quoted, options = {}) => {
|
| 792 |
+
let buttons = [{buttonId: row1, buttonText: {displayText: button1}, type: 1},
|
| 793 |
+
{ buttonId: row2, buttonText: { displayText: button2 }, type: 1 }]
|
| 794 |
+
let buttonMessage = {
|
| 795 |
+
location: { jpegThumbnail: buffer },
|
| 796 |
+
caption: content,
|
| 797 |
+
footer: footer,
|
| 798 |
+
buttons: buttons,
|
| 799 |
+
headerType: 6
|
| 800 |
+
}
|
| 801 |
+
return await conn.sendMessage(jid, buttonMessage, {
|
| 802 |
+
quoted,
|
| 803 |
+
upload: conn.waUploadToServer,
|
| 804 |
+
...options
|
| 805 |
+
})
|
| 806 |
+
}
|
| 807 |
+
conn.send3ButtonLoc= async (jid, buffer, content, footer, button1, row1, button2, row2, quoted, options = {}) => {
|
| 808 |
+
let buttons = [{buttonId: row1, buttonText: {displayText: button1}, type: 1},
|
| 809 |
+
{ buttonId: row2, buttonText: { displayText: button2 }, type: 1 },
|
| 810 |
+
{ buttonId: row3, buttonText: { displayText: button3 }, type: 1 }
|
| 811 |
+
]
|
| 812 |
+
let buttonMessage = {
|
| 813 |
+
location: { jpegThumbnail: buffer },
|
| 814 |
+
caption: content,
|
| 815 |
+
footer: footer,
|
| 816 |
+
buttons: buttons,
|
| 817 |
+
headerType: 6
|
| 818 |
+
}
|
| 819 |
+
return await conn.sendMessage(jid, buttonMessage, {
|
| 820 |
+
quoted,
|
| 821 |
+
upload: conn.waUploadToServer,
|
| 822 |
+
...options
|
| 823 |
+
})
|
| 824 |
+
}
|
| 825 |
+
/**
|
| 826 |
+
* send Button Vid
|
| 827 |
+
* @param {String} jid
|
| 828 |
+
* @param {String} contentText
|
| 829 |
+
* @param {String} footer
|
| 830 |
+
* @param {Buffer|String} buffer
|
| 831 |
+
* @param {String} buttons1
|
| 832 |
+
* @param {String} row1
|
| 833 |
+
* @param {Object} quoted
|
| 834 |
+
* @param {Object} options
|
| 835 |
+
*/
|
| 836 |
+
conn.sendButtonVid = async (jid, buffer, contentText, footerText, button1, id1, quoted, options) => {
|
| 837 |
+
let type = await conn.getFile(buffer)
|
| 838 |
+
let { res, data: file } = type
|
| 839 |
+
if (res && res.status !== 200 || file.length <= 65536) {
|
| 840 |
+
try { throw { json: JSON.parse(file.toString()) } }
|
| 841 |
+
catch (e) { if (e.json) throw e.json }
|
| 842 |
+
}
|
| 843 |
+
let buttons = [
|
| 844 |
+
{ buttonId: id1, buttonText: { displayText: button1 }, type: 1 }
|
| 845 |
+
]
|
| 846 |
+
const buttonMessage = {
|
| 847 |
+
video: file,
|
| 848 |
+
fileLength: 887890909999999,
|
| 849 |
+
caption: contentText,
|
| 850 |
+
footer: footerText,
|
| 851 |
+
mentions: await conn.parseMention(contentText),
|
| 852 |
+
...options,
|
| 853 |
+
buttons: buttons,
|
| 854 |
+
headerType: 4
|
| 855 |
+
}
|
| 856 |
+
return await conn.sendMessage(jid, buttonMessage, {
|
| 857 |
+
quoted,
|
| 858 |
+
ephemeralExpiration: 86400,
|
| 859 |
+
...options
|
| 860 |
+
})
|
| 861 |
+
}
|
| 862 |
+
/**
|
| 863 |
+
* cMod
|
| 864 |
+
* @param {String} jid
|
| 865 |
+
* @param {*} message
|
| 866 |
+
* @param {String} text
|
| 867 |
+
* @param {String} sender
|
| 868 |
+
* @param {*} options
|
| 869 |
+
* @returns
|
| 870 |
+
*/
|
| 871 |
+
|
| 872 |
+
conn.cMod = async (jid, message, text = '', sender = conn.user.jid, options = {}) => {
|
| 873 |
+
if (options.mentions && !Array.isArray(options.mentions)) options.mentions = [options.mentions]
|
| 874 |
+
let copy = message.toJSON()
|
| 875 |
+
delete copy.message.messageContextInfo
|
| 876 |
+
delete copy.message.senderKeyDistributionMessage
|
| 877 |
+
let mtype = Object.keys(copy.message)[0]
|
| 878 |
+
let msg = copy.message
|
| 879 |
+
let content = msg[mtype]
|
| 880 |
+
if (typeof content === 'string') msg[mtype] = text || content
|
| 881 |
+
else if (content.caption) content.caption = text || content.caption
|
| 882 |
+
else if (content.text) content.text = text || content.text
|
| 883 |
+
if (typeof content !== 'string') {
|
| 884 |
+
msg[mtype] = { ...content, ...options }
|
| 885 |
+
msg[mtype].contextInfo = {
|
| 886 |
+
...(content.contextInfo || {}),
|
| 887 |
+
mentionedJid: options.mentions || content.contextInfo?.mentionedJid || []
|
| 888 |
+
}
|
| 889 |
+
}
|
| 890 |
+
if (copy.participant) sender = copy.participant = sender || copy.participant
|
| 891 |
+
else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant
|
| 892 |
+
if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid
|
| 893 |
+
else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid
|
| 894 |
+
copy.key.remoteJid = jid
|
| 895 |
+
copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false
|
| 896 |
+
return proto.WebMessageInfo.fromObject(copy)
|
| 897 |
+
}
|
| 898 |
+
|
| 899 |
+
/**
|
| 900 |
+
* cMods
|
| 901 |
+
* @param {String} jid
|
| 902 |
+
* @param {proto.WebMessageInfo} message
|
| 903 |
+
* @param {String} text
|
| 904 |
+
* @param {String} sender
|
| 905 |
+
* @param {*} options
|
| 906 |
+
* @returns
|
| 907 |
+
*/
|
| 908 |
+
conn.cMods = (jid, message, text = '', sender = conn.user.jid, options = {}) => {
|
| 909 |
+
let copy = message.toJSON()
|
| 910 |
+
let mtype = Object.keys(copy.message)[0]
|
| 911 |
+
let isEphemeral = false // mtype === 'ephemeralMessage'
|
| 912 |
+
if (isEphemeral) {
|
| 913 |
+
mtype = Object.keys(copy.message.ephemeralMessage.message)[0]
|
| 914 |
+
}
|
| 915 |
+
let msg = isEphemeral ? copy.message.ephemeralMessage.message : copy.message
|
| 916 |
+
let content = msg[mtype]
|
| 917 |
+
if (typeof content === 'string') msg[mtype] = text || content
|
| 918 |
+
else if (content.caption) content.caption = text || content.caption
|
| 919 |
+
else if (content.text) content.text = text || content.text
|
| 920 |
+
if (typeof content !== 'string') msg[mtype] = { ...content, ...options }
|
| 921 |
+
if (copy.participant) sender = copy.participant = sender || copy.participant
|
| 922 |
+
else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant
|
| 923 |
+
if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid
|
| 924 |
+
else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid
|
| 925 |
+
copy.key.remoteJid = jid
|
| 926 |
+
copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false
|
| 927 |
+
return proto.WebMessageInfo.fromObject(copy)
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
|
| 931 |
+
|
| 932 |
+
/**
|
| 933 |
+
* Exact Copy Forward
|
| 934 |
+
* @param {String} jid
|
| 935 |
+
* @param {proto.WebMessageInfo} message
|
| 936 |
+
* @param {Boolean|Number} forwardingScore
|
| 937 |
+
* @param {Object} options
|
| 938 |
+
*/
|
| 939 |
+
conn.copyNForward = async (jid, message, forwardingScore = true, options = {}) => {
|
| 940 |
+
let m = generateForwardMessageContent(message, !!forwardingScore)
|
| 941 |
+
let mtype = Object.keys(m)[0]
|
| 942 |
+
if (forwardingScore && typeof forwardingScore == 'number' && forwardingScore > 1) m[mtype].contextInfo.forwardingScore += forwardingScore
|
| 943 |
+
m = generateWAMessageFromContent(jid, m, { ...options, userJid: conn.user.id })
|
| 944 |
+
await conn.relayMessage(jid, m.message, { messageId: m.key.id, additionalAttributes: { ...options } })
|
| 945 |
+
return m
|
| 946 |
+
}
|
| 947 |
+
|
| 948 |
+
/**
|
| 949 |
+
* Fake Replies
|
| 950 |
+
* @param {String} jid
|
| 951 |
+
* @param {String|Object} text
|
| 952 |
+
* @param {String} fakeJid
|
| 953 |
+
* @param {String} fakeText
|
| 954 |
+
* @param {String} fakeGroupJid
|
| 955 |
+
* @param {String} options
|
| 956 |
+
*/
|
| 957 |
+
conn.fakeReply = async (jid, text = '', fakeJid = this.user.jid, fakeText = '', fakeGroupJid, options) => {
|
| 958 |
+
return conn.reply(jid, text, { key: { fromMe: areJidsSameUser(fakeJid, conn.user.id), participant: fakeJid, ...(fakeGroupJid ? { remoteJid: fakeGroupJid } : {}) }, message: { conversation: fakeText }, ...options })
|
| 959 |
+
}
|
| 960 |
+
|
| 961 |
+
conn.loadMessage = conn.loadMessage || (async (messageID) => {
|
| 962 |
+
return Object.entries(conn.chats)
|
| 963 |
+
.filter(([_, { messages }]) => typeof messages === 'object')
|
| 964 |
+
.find(([_, { messages }]) => Object.entries(messages)
|
| 965 |
+
.find(([k, v]) => (k === messageID || v.key?.id === messageID)))
|
| 966 |
+
?.[1].messages?.[messageID]
|
| 967 |
+
})
|
| 968 |
+
|
| 969 |
+
/**
|
| 970 |
+
* Download media message
|
| 971 |
+
* @param {Object} m
|
| 972 |
+
* @param {String} type
|
| 973 |
+
* @param {fs.PathLike|fs.promises.FileHandle} filename
|
| 974 |
+
* @returns {Promise<fs.PathLike|fs.promises.FileHandle|Buffer>}
|
| 975 |
+
*/
|
| 976 |
+
conn.downloadM = async (m, type, saveToFile) => {
|
| 977 |
+
if (!m || !(m.url || m.directPath)) return Buffer.alloc(0)
|
| 978 |
+
const stream = await downloadContentFromMessage(m, type)
|
| 979 |
+
let buffer = Buffer.from([])
|
| 980 |
+
for await (const chunk of stream) {
|
| 981 |
+
buffer = Buffer.concat([buffer, chunk])
|
| 982 |
+
}
|
| 983 |
+
if (saveToFile) var { filename } = await conn.getFile(buffer, true)
|
| 984 |
+
return saveToFile && fs.existsSync(filename) ? filename : buffer
|
| 985 |
+
}
|
| 986 |
+
|
| 987 |
+
|
| 988 |
+
conn.downloadAndSaveMediaMessage = async (message, filename, attachExtension = true) => {
|
| 989 |
+
let quoted = message.msg ? message.msg : message
|
| 990 |
+
let mime = (message.msg || message).mimetype || ''
|
| 991 |
+
let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0]
|
| 992 |
+
const stream = await downloadContentFromMessage(quoted, messageType)
|
| 993 |
+
let buffer = Buffer.from([])
|
| 994 |
+
for await(const chunk of stream) {
|
| 995 |
+
buffer = Buffer.concat([buffer, chunk])
|
| 996 |
+
}
|
| 997 |
+
let type = await FileType.fromBuffer(buffer)
|
| 998 |
+
trueFileName = attachExtension ? (filename + '.' + type.ext) : filename
|
| 999 |
+
// save to file
|
| 1000 |
+
await fs.writeFileSync(trueFileName, buffer)
|
| 1001 |
+
return trueFileName
|
| 1002 |
+
}
|
| 1003 |
+
|
| 1004 |
+
|
| 1005 |
+
/**
|
| 1006 |
+
* parseMention(s)
|
| 1007 |
+
* @param {string} text
|
| 1008 |
+
* @returns {string[]}
|
| 1009 |
+
*/
|
| 1010 |
+
conn.parseMention = (text = '') => {
|
| 1011 |
+
return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net')
|
| 1012 |
+
}
|
| 1013 |
+
/**
|
| 1014 |
+
* Read message
|
| 1015 |
+
* @param {String} jid
|
| 1016 |
+
* @param {String|undefined|null} participant
|
| 1017 |
+
* @param {String} messageID
|
| 1018 |
+
*/
|
| 1019 |
+
conn.chatRead = async (jid, participant = conn.user.jid, messageID) => {
|
| 1020 |
+
return await conn.sendReadReceipt(jid, participant, [messageID])
|
| 1021 |
+
}
|
| 1022 |
+
|
| 1023 |
+
/**
|
| 1024 |
+
* Parses string into mentionedJid(s)
|
| 1025 |
+
* @param {String} text
|
| 1026 |
+
*/
|
| 1027 |
+
conn.parseMention = (text = '') => {
|
| 1028 |
+
return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net')
|
| 1029 |
+
}
|
| 1030 |
+
|
| 1031 |
+
conn.sendTextWithMentions = async (jid, text, quoted, options = {}) => conn.sendMessage(jid, { text: text, contextInfo: { mentionedJid: [...text.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net') }, ...options }, { quoted })
|
| 1032 |
+
|
| 1033 |
+
/**
|
| 1034 |
+
* Get name from jid
|
| 1035 |
+
* @param {String} jid
|
| 1036 |
+
* @param {Boolean} withoutContact
|
| 1037 |
+
*/
|
| 1038 |
+
conn.getName = (jid = '', withoutContact = false) => {
|
| 1039 |
+
jid = conn.decodeJid(jid)
|
| 1040 |
+
withoutContact = this.withoutContact || withoutContact
|
| 1041 |
+
let v
|
| 1042 |
+
if (jid.endsWith('@g.us')) return new Promise(async (resolve) => {
|
| 1043 |
+
v = conn.chats[jid] || {}
|
| 1044 |
+
if (!(v.name || v.subject)) v = await conn.groupMetadata(jid) || {}
|
| 1045 |
+
resolve(v.name || v.subject || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international'))
|
| 1046 |
+
})
|
| 1047 |
+
else v = jid === '0@s.whatsapp.net' ? {
|
| 1048 |
+
jid,
|
| 1049 |
+
vname: 'WhatsApp'
|
| 1050 |
+
} : areJidsSameUser(jid, conn.user.id) ?
|
| 1051 |
+
conn.user :
|
| 1052 |
+
(conn.chats[jid] || {})
|
| 1053 |
+
return (withoutContact ? '' : v.name) || v.subject || v.vname || v.notify || v.verifiedName || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international')
|
| 1054 |
+
}
|
| 1055 |
+
|
| 1056 |
+
/**
|
| 1057 |
+
* to process MessageStubType
|
| 1058 |
+
* @param {proto.WebMessageInfo} m
|
| 1059 |
+
*/
|
| 1060 |
+
conn.processMessageStubType = async(m) => {
|
| 1061 |
+
/**
|
| 1062 |
+
* to process MessageStubType
|
| 1063 |
+
* @param {import('@adiwajshing/baileys').proto.WebMessageInfo} m
|
| 1064 |
+
*/
|
| 1065 |
+
if (!m.messageStubType) return
|
| 1066 |
+
const chat = conn.decodeJid(m.key.remoteJid || m.message?.senderKeyDistributionMessage?.groupId || '')
|
| 1067 |
+
if (!chat || chat === 'status@broadcast') return
|
| 1068 |
+
const emitGroupUpdate = (update) => {
|
| 1069 |
+
conn.ev.emit('groups.update', [{ id: chat, ...update }])
|
| 1070 |
+
}
|
| 1071 |
+
switch (m.messageStubType) {
|
| 1072 |
+
case WAMessageStubType.REVOKE:
|
| 1073 |
+
case WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
| 1074 |
+
emitGroupUpdate({ revoke: m.messageStubParameters[0] })
|
| 1075 |
+
break
|
| 1076 |
+
case WAMessageStubType.GROUP_CHANGE_ICON:
|
| 1077 |
+
emitGroupUpdate({ icon: m.messageStubParameters[0] })
|
| 1078 |
+
break
|
| 1079 |
+
default: {
|
| 1080 |
+
console.log({
|
| 1081 |
+
messageStubType: m.messageStubType,
|
| 1082 |
+
messageStubParameters: m.messageStubParameters,
|
| 1083 |
+
type: WAMessageStubType[m.messageStubType]
|
| 1084 |
+
})
|
| 1085 |
+
break
|
| 1086 |
+
}
|
| 1087 |
+
}
|
| 1088 |
+
const isGroup = chat.endsWith('@g.us')
|
| 1089 |
+
if (!isGroup) return
|
| 1090 |
+
let chats = conn.chats[chat]
|
| 1091 |
+
if (!chats) chats = conn.chats[chat] = { id: chat }
|
| 1092 |
+
chats.isChats = true
|
| 1093 |
+
const metadata = await conn.groupMetadata(chat).catch(_ => null)
|
| 1094 |
+
if (!metadata) return
|
| 1095 |
+
chats.subject = metadata.subject
|
| 1096 |
+
chats.metadata = metadata
|
| 1097 |
+
}
|
| 1098 |
+
conn.insertAllGroup = async() => {
|
| 1099 |
+
const groups = await conn.groupFetchAllParticipating().catch(_ => null) || {}
|
| 1100 |
+
for (const group in groups) conn.chats[group] = { ...(conn.chats[group] || {}), id: group, subject: groups[group].subject, isChats: true, metadata: groups[group] }
|
| 1101 |
+
return conn.chats
|
| 1102 |
+
}
|
| 1103 |
+
|
| 1104 |
+
/*conn.processMessageStubType = async (m) => {
|
| 1105 |
+
if (!m.messageStubType) return
|
| 1106 |
+
const mtype = Object.keys(m.message || {})[0]
|
| 1107 |
+
const chat = conn.decodeJid(m.key.remoteJid || m.message[mtype] && m.message[mtype].groupId || '')
|
| 1108 |
+
const isGroup = chat.endsWith('@g.us')
|
| 1109 |
+
if (!isGroup) return
|
| 1110 |
+
let chats = conn.chats[chat]
|
| 1111 |
+
if (!chats) chats = conn.chats[chat] = { id: chat }
|
| 1112 |
+
chats.isChats = true
|
| 1113 |
+
const metadata = await conn.groupMetadata(chat).catch(_ => null)
|
| 1114 |
+
if (!metadata) return
|
| 1115 |
+
chats.subject = metadata.subject
|
| 1116 |
+
chats.metadata = metadata
|
| 1117 |
+
}*/
|
| 1118 |
+
|
| 1119 |
+
/**
|
| 1120 |
+
* pushMessage
|
| 1121 |
+
* @param {proto.WebMessageInfo[]} m
|
| 1122 |
+
*/
|
| 1123 |
+
conn.pushMessage = async(m) => {
|
| 1124 |
+
/**
|
| 1125 |
+
* pushMessage
|
| 1126 |
+
* @param {import('@adiwajshing/baileys').proto.WebMessageInfo[]} m
|
| 1127 |
+
*/
|
| 1128 |
+
if (!m) return
|
| 1129 |
+
if (!Array.isArray(m)) m = [m]
|
| 1130 |
+
for (const message of m) {
|
| 1131 |
+
try {
|
| 1132 |
+
// if (!(message instanceof proto.WebMessageInfo)) continue // https://github.com/adiwajshing/Baileys/pull/696/commits/6a2cb5a4139d8eb0a75c4c4ea7ed52adc0aec20f
|
| 1133 |
+
if (!message) continue
|
| 1134 |
+
if (message.messageStubType && message.messageStubType != WAMessageStubType.CIPHERTEXT) conn.processMessageStubType(message).catch(console.error)
|
| 1135 |
+
const _mtype = Object.keys(message.message || {})
|
| 1136 |
+
const mtype = (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(_mtype[0]) && _mtype[0]) ||
|
| 1137 |
+
(_mtype.length >= 3 && _mtype[1] !== 'messageContextInfo' && _mtype[1]) ||
|
| 1138 |
+
_mtype[_mtype.length - 1]
|
| 1139 |
+
const chat = conn.decodeJid(message.key.remoteJid || message.message?.senderKeyDistributionMessage?.groupId || '')
|
| 1140 |
+
if (message.message?.[mtype]?.contextInfo?.quotedMessage) {
|
| 1141 |
+
/**
|
| 1142 |
+
* @type {import('@adiwajshing/baileys').proto.IContextInfo}
|
| 1143 |
+
*/
|
| 1144 |
+
let context = message.message[mtype].contextInfo
|
| 1145 |
+
let participant = conn.decodeJid(context.participant)
|
| 1146 |
+
const remoteJid = conn.decodeJid(context.remoteJid || participant)
|
| 1147 |
+
/**
|
| 1148 |
+
* @type {import('@adiwajshing/baileys').proto.IMessage}
|
| 1149 |
+
*
|
| 1150 |
+
*/
|
| 1151 |
+
let quoted = message.message[mtype].contextInfo.quotedMessage
|
| 1152 |
+
if ((remoteJid && remoteJid !== 'status@broadcast') && quoted) {
|
| 1153 |
+
let qMtype = Object.keys(quoted)[0]
|
| 1154 |
+
if (qMtype == 'conversation') {
|
| 1155 |
+
quoted.extendedTextMessage = { text: quoted[qMtype] }
|
| 1156 |
+
delete quoted.conversation
|
| 1157 |
+
qMtype = 'extendedTextMessage'
|
| 1158 |
+
}
|
| 1159 |
+
|
| 1160 |
+
if (!quoted[qMtype].contextInfo) quoted[qMtype].contextInfo = {}
|
| 1161 |
+
quoted[qMtype].contextInfo.mentionedJid = context.mentionedJid || quoted[qMtype].contextInfo.mentionedJid || []
|
| 1162 |
+
const isGroup = remoteJid.endsWith('g.us')
|
| 1163 |
+
if (isGroup && !participant) participant = remoteJid
|
| 1164 |
+
const qM = {
|
| 1165 |
+
key: {
|
| 1166 |
+
remoteJid,
|
| 1167 |
+
fromMe: areJidsSameUser(conn.user.jid, remoteJid),
|
| 1168 |
+
id: context.stanzaId,
|
| 1169 |
+
participant,
|
| 1170 |
+
},
|
| 1171 |
+
message: JSON.parse(JSON.stringify(quoted)),
|
| 1172 |
+
...(isGroup ? { participant } : {})
|
| 1173 |
+
}
|
| 1174 |
+
let qChats = conn.chats[participant]
|
| 1175 |
+
if (!qChats) qChats = conn.chats[participant] = { id: participant, isChats: !isGroup }
|
| 1176 |
+
if (!qChats.messages) qChats.messages = {}
|
| 1177 |
+
if (!qChats.messages[context.stanzaId] && !qM.key.fromMe) qChats.messages[context.stanzaId] = qM
|
| 1178 |
+
let qChatsMessages
|
| 1179 |
+
if ((qChatsMessages = Object.entries(qChats.messages)).length > 40) qChats.messages = Object.fromEntries(qChatsMessages.slice(30, qChatsMessages.length)) // maybe avoid memory leak
|
| 1180 |
+
}
|
| 1181 |
+
}
|
| 1182 |
+
if (!chat || chat === 'status@broadcast') continue
|
| 1183 |
+
const isGroup = chat.endsWith('@g.us')
|
| 1184 |
+
let chats = conn.chats[chat]
|
| 1185 |
+
if (!chats) {
|
| 1186 |
+
if (isGroup) await conn.insertAllGroup().catch(console.error)
|
| 1187 |
+
chats = conn.chats[chat] = { id: chat, isChats: true, ...(conn.chats[chat] || {}) }
|
| 1188 |
+
}
|
| 1189 |
+
let metadata, sender
|
| 1190 |
+
if (isGroup) {
|
| 1191 |
+
if (!chats.subject || !chats.metadata) {
|
| 1192 |
+
metadata = await conn.groupMetadata(chat).catch(_ => ({})) || {}
|
| 1193 |
+
if (!chats.subject) chats.subject = metadata.subject || ''
|
| 1194 |
+
if (!chats.metadata) chats.metadata = metadata
|
| 1195 |
+
}
|
| 1196 |
+
sender = conn.decodeJid(message.key?.fromMe && conn.user.id || message.participant || message.key?.participant || chat || '')
|
| 1197 |
+
if (sender !== chat) {
|
| 1198 |
+
let chats = conn.chats[sender]
|
| 1199 |
+
if (!chats) chats = conn.chats[sender] = { id: sender }
|
| 1200 |
+
if (!chats.name) chats.name = message.pushName || chats.name || ''
|
| 1201 |
+
}
|
| 1202 |
+
} else if (!chats.name) chats.name = message.pushName || chats.name || ''
|
| 1203 |
+
if (['senderKeyDistributionMessage', 'messageContextInfo'].includes(mtype)) continue
|
| 1204 |
+
chats.isChats = true
|
| 1205 |
+
if (!chats.messages) chats.messages = {}
|
| 1206 |
+
const fromMe = message.key.fromMe || areJidsSameUser(sender || chat, conn.user.id)
|
| 1207 |
+
if (!['protocolMessage'].includes(mtype) && !fromMe && message.messageStubType != WAMessageStubType.CIPHERTEXT && message.message) {
|
| 1208 |
+
delete message.message.messageContextInfo
|
| 1209 |
+
delete message.message.senderKeyDistributionMessage
|
| 1210 |
+
chats.messages[message.key.id] = JSON.parse(JSON.stringify(message, null, 2))
|
| 1211 |
+
let chatsMessages
|
| 1212 |
+
if ((chatsMessages = Object.entries(chats.messages)).length > 40) chats.messages = Object.fromEntries(chatsMessages.slice(30, chatsMessages.length))
|
| 1213 |
+
}
|
| 1214 |
+
} catch (e) {
|
| 1215 |
+
console.error(e)
|
| 1216 |
+
}
|
| 1217 |
+
}
|
| 1218 |
+
}
|
| 1219 |
+
|
| 1220 |
+
/*conn.pushMessage = async (m) => {
|
| 1221 |
+
if (!m) return
|
| 1222 |
+
if (!Array.isArray(m)) m = [m]
|
| 1223 |
+
for (const message of m) {
|
| 1224 |
+
try {
|
| 1225 |
+
// if (!(message instanceof proto.WebMessageInfo)) continue // https://github.com/adiwajshing/Baileys/pull/696/commits/6a2cb5a4139d8eb0a75c4c4ea7ed52adc0aec20f
|
| 1226 |
+
if (!message) continue
|
| 1227 |
+
if (message.messageStubType) conn.processMessageStubType(message).catch(console.error)
|
| 1228 |
+
let mtype = Object.keys(message.message || {})
|
| 1229 |
+
mtype = mtype[mtype[0] === 'messageContextInfo' && mtype.length == 2 ? 1 : 0]
|
| 1230 |
+
const chat = conn.decodeJid(message.key.remoteJid || message.message[mtype] && message.message[mtype].groupId || '')
|
| 1231 |
+
const isGroup = chat.endsWith('@g.us')
|
| 1232 |
+
let chats = conn.chats[chat]
|
| 1233 |
+
if (!chats) {
|
| 1234 |
+
if (isGroup) {
|
| 1235 |
+
const groups = await conn.groupFetchAllParticipating().catch(_ => ({}))
|
| 1236 |
+
for (const group in groups) conn.chats[group] = { id: group, subject: groups[group].subject, isChats: true, metadata: groups[group] }
|
| 1237 |
+
}
|
| 1238 |
+
chats = conn.chats[chat] = { id: chat, ...(conn.chats[chat] || {}) }
|
| 1239 |
+
}
|
| 1240 |
+
let metadata, sender
|
| 1241 |
+
if (isGroup) {
|
| 1242 |
+
if (!chats.subject || !chats.metadata) {
|
| 1243 |
+
metadata = await conn.groupMetadata(chat).catch(_ => ({})) || {}
|
| 1244 |
+
if (!chats.subject) chats.subject = metadata.subject || ''
|
| 1245 |
+
if (!chats.metadata) chats.metadata = metadata
|
| 1246 |
+
}
|
| 1247 |
+
sender = conn.decodeJid(message.fromMe && conn.user.id || message.participant || message.key.participant || chat || '')
|
| 1248 |
+
if (sender !== chat) {
|
| 1249 |
+
let chats = conn.chats[sender]
|
| 1250 |
+
if (!chats) chats = conn.chats[sender] = { id: sender }
|
| 1251 |
+
if (!chats.name) chats.name = message.pushName || chats.name || ''
|
| 1252 |
+
}
|
| 1253 |
+
} else {
|
| 1254 |
+
if (!chats.name) chats.name = message.pushName || chats.name || ''
|
| 1255 |
+
}
|
| 1256 |
+
if (['senderKeyDistributionMessage', 'protocolMessage'].includes(mtype)) continue
|
| 1257 |
+
chats.isChats = true
|
| 1258 |
+
const fromMe = message.key.fromMe || areJidsSameUser(chat, conn.user.id)
|
| 1259 |
+
if (!chats.messages) chats.messages = {}
|
| 1260 |
+
if (!fromMe) chats.messages[message.key.id] = JSON.parse(JSON.stringify(message, null, 2))
|
| 1261 |
+
} catch (e) {
|
| 1262 |
+
console.error(e)
|
| 1263 |
+
}
|
| 1264 |
+
}
|
| 1265 |
+
}*/
|
| 1266 |
+
|
| 1267 |
+
/**
|
| 1268 |
+
*
|
| 1269 |
+
* @param {...any} args
|
| 1270 |
+
* @returns
|
| 1271 |
+
*/
|
| 1272 |
+
conn.format = (...args) => {
|
| 1273 |
+
return util.format(...args)
|
| 1274 |
+
}
|
| 1275 |
+
|
| 1276 |
+
/**
|
| 1277 |
+
*
|
| 1278 |
+
* @param {String} url
|
| 1279 |
+
* @param {Object} options
|
| 1280 |
+
* @returns
|
| 1281 |
+
*/
|
| 1282 |
+
conn.getBuffer = async (url, options) => {
|
| 1283 |
+
try {
|
| 1284 |
+
options ? options : {}
|
| 1285 |
+
const res = await axios({
|
| 1286 |
+
method: "get",
|
| 1287 |
+
url,
|
| 1288 |
+
headers: {
|
| 1289 |
+
'DNT': 1,
|
| 1290 |
+
'Upgrade-Insecure-Request': 1
|
| 1291 |
+
},
|
| 1292 |
+
...options,
|
| 1293 |
+
responseType: 'arraybuffer'
|
| 1294 |
+
})
|
| 1295 |
+
return res.data
|
| 1296 |
+
} catch (e) {
|
| 1297 |
+
console.log(`Error : ${e}`)
|
| 1298 |
+
}
|
| 1299 |
+
}
|
| 1300 |
+
|
| 1301 |
+
/**
|
| 1302 |
+
* Serialize Message, so it easier to manipulate
|
| 1303 |
+
* @param {Object} m
|
| 1304 |
+
*/
|
| 1305 |
+
conn.serializeM = (m) => {
|
| 1306 |
+
return exports.smsg(conn, m)
|
| 1307 |
+
}
|
| 1308 |
+
|
| 1309 |
+
Object.defineProperty(conn, 'name', {
|
| 1310 |
+
value: 'WASocket',
|
| 1311 |
+
configurable: true,
|
| 1312 |
+
})
|
| 1313 |
+
return conn
|
| 1314 |
+
}
|
| 1315 |
+
/**
|
| 1316 |
+
* Serialize Message
|
| 1317 |
+
* @param {ReturnType<typeof makeWASocket>} conn
|
| 1318 |
+
* @param {proto.WebMessageInfo} m
|
| 1319 |
+
* @param {Boolean} hasParent
|
| 1320 |
+
*/
|
| 1321 |
+
exports.smsg = (conn, m, hasParent) => {
|
| 1322 |
+
if (!m) return m
|
| 1323 |
+
let M = proto.WebMessageInfo
|
| 1324 |
+
m = M.fromObject(m)
|
| 1325 |
+
if (m.key) {
|
| 1326 |
+
m.id = m.key.id
|
| 1327 |
+
m.isBaileys = m.id && m.id.length === 22 || m.id.startsWith('3EB0') && m.id.length === 22 || false
|
| 1328 |
+
m.chat = conn.decodeJid(m.key.remoteJid || message.message?.senderKeyDistributionMessage?.groupId || '')
|
| 1329 |
+
m.isGroup = m.chat.endsWith('@g.us')
|
| 1330 |
+
m.sender = conn.decodeJid(m.key.fromMe && conn.user.id || m.participant || m.key.participant || m.chat || '')
|
| 1331 |
+
m.fromMe = m.key.fromMe || areJidsSameUser(m.sender, conn.user.id)
|
| 1332 |
+
}
|
| 1333 |
+
if (m.message) {
|
| 1334 |
+
let mtype = Object.keys(m.message)
|
| 1335 |
+
m.mtype = (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(mtype[0]) && mtype[0]) || // Sometimes message in the front
|
| 1336 |
+
(mtype.length >= 3 && mtype[1] !== 'messageContextInfo' && mtype[1]) || // Sometimes message in midle if mtype length is greater than or equal to 3!
|
| 1337 |
+
mtype[mtype.length - 1] // common case
|
| 1338 |
+
m.msg = m.message[m.mtype]
|
| 1339 |
+
if (m.chat == 'status@broadcast' && ['protocolMessage', 'senderKeyDistributionMessage'].includes(m.mtype)) m.chat = (m.key.remoteJid !== 'status@broadcast' && m.key.remoteJid) || m.sender
|
| 1340 |
+
if (m.mtype == 'protocolMessage' && m.msg.key) {
|
| 1341 |
+
if (m.msg.key.remoteJid == 'status@broadcast') m.msg.key.remoteJid = m.chat
|
| 1342 |
+
if (!m.msg.key.participant || m.msg.key.participant == 'status_me') m.msg.key.participant = m.sender
|
| 1343 |
+
m.msg.key.fromMe = conn.decodeJid(m.msg.key.participant) === conn.decodeJid(conn.user.id)
|
| 1344 |
+
if (!m.msg.key.fromMe && m.msg.key.remoteJid === conn.decodeJid(conn.user.id)) m.msg.key.remoteJid = m.sender
|
| 1345 |
+
}
|
| 1346 |
+
m.text = m.msg.text || m.msg.caption || m.msg.contentText || m.msg || ''
|
| 1347 |
+
if (typeof m.text !== 'string') {
|
| 1348 |
+
if ([
|
| 1349 |
+
'protocolMessage',
|
| 1350 |
+
'messageContextInfo',
|
| 1351 |
+
'stickerMessage',
|
| 1352 |
+
'audioMessage',
|
| 1353 |
+
'senderKeyDistributionMessage'
|
| 1354 |
+
].includes(m.mtype)) m.text = ''
|
| 1355 |
+
else m.text = m.text.selectedDisplayText || m.text.hydratedTemplate?.hydratedContentText || m.text
|
| 1356 |
+
}
|
| 1357 |
+
m.mentionedJid = m.msg?.contextInfo?.mentionedJid?.length && m.msg.contextInfo.mentionedJid || []
|
| 1358 |
+
let quoted = m.quoted = m.msg?.contextInfo?.quotedMessage ? m.msg.contextInfo.quotedMessage : null
|
| 1359 |
+
if (m.quoted) {
|
| 1360 |
+
let type = Object.keys(m.quoted)[0]
|
| 1361 |
+
m.quoted = m.quoted[type]
|
| 1362 |
+
if (typeof m.quoted === 'string') m.quoted = { text: m.quoted }
|
| 1363 |
+
m.quoted.mtype = type
|
| 1364 |
+
m.quoted.id = m.msg.contextInfo.stanzaId
|
| 1365 |
+
m.quoted.chat = conn.decodeJid(m.msg.contextInfo.remoteJid || m.chat || m.sender)
|
| 1366 |
+
m.quoted.isBaileys = m.quoted.id && m.quoted.id.length === 22 || false
|
| 1367 |
+
m.quoted.sender = conn.decodeJid(m.msg.contextInfo.participant)
|
| 1368 |
+
m.quoted.fromMe = m.quoted.sender === conn.user.jid
|
| 1369 |
+
m.quoted.text = m.quoted.text || m.quoted.caption || m.quoted.contentText || ''
|
| 1370 |
+
m.quoted.name = conn.getName(m.quoted.sender)
|
| 1371 |
+
m.quoted.mentionedJid = m.quoted.contextInfo?.mentionedJid?.length && m.quoted.contextInfo.mentionedJid || []
|
| 1372 |
+
let vM = m.quoted.fakeObj = M.fromObject({
|
| 1373 |
+
key: {
|
| 1374 |
+
fromMe: m.quoted.fromMe,
|
| 1375 |
+
remoteJid: m.quoted.chat,
|
| 1376 |
+
id: m.quoted.id
|
| 1377 |
+
},
|
| 1378 |
+
message: quoted,
|
| 1379 |
+
...(m.isGroup ? { participant: m.quoted.sender } : {})
|
| 1380 |
+
})
|
| 1381 |
+
m.getQuotedObj = m.getQuotedMessage = async () => {
|
| 1382 |
+
if (!m.quoted.id) return null
|
| 1383 |
+
let q = M.fromObject(await conn.loadMessage(m.quoted.id) || vM)
|
| 1384 |
+
return exports.smsg(conn, q)
|
| 1385 |
+
}
|
| 1386 |
+
if (m.quoted.url || m.quoted.directPath) m.quoted.download = (saveToFile = false) => conn.downloadM(m.quoted, m.quoted.mtype.replace(/message/i, ''), saveToFile)
|
| 1387 |
+
|
| 1388 |
+
|
| 1389 |
+
/*exports.smsg = (conn, m, hasParent) => {
|
| 1390 |
+
if (!m) return m
|
| 1391 |
+
let M = proto.WebMessageInfo
|
| 1392 |
+
m = M.fromObject(m)
|
| 1393 |
+
if (m.key) {
|
| 1394 |
+
m.id = m.key.id
|
| 1395 |
+
m.isBaileys = m.id && m.id.length === 16 || m.id.startsWith('3EB0') && m.id.length === 12 || false
|
| 1396 |
+
let mtype = Object.keys(m.message || {})[0]
|
| 1397 |
+
m.chat = conn.decodeJid(m.key.remoteJid || m.message[mtype] && m.message[mtype].groupId || '')
|
| 1398 |
+
m.isGroup = m.chat.endsWith('@g.us')
|
| 1399 |
+
m.sender = conn.decodeJid(m.fromMe && conn.user.id || m.participant || m.key.participant || m.chat || '')
|
| 1400 |
+
m.fromMe = m.key.fromMe || areJidsSameUser(m.sender, conn.user.id)
|
| 1401 |
+
}
|
| 1402 |
+
if (m.message) {
|
| 1403 |
+
let mtype = Object.keys(m.message)
|
| 1404 |
+
m.mtype = mtype[mtype[0] === 'messageContextInfo' && mtype.length == 2 ? 1 : 0]
|
| 1405 |
+
m.msg = m.message[m.mtype]
|
| 1406 |
+
if (m.chat == 'status@broadcast' && ['protocolMessage', 'senderKeyDistributionMessage'].includes(m.mtype)) m.chat = m.sender
|
| 1407 |
+
// if (m.mtype === 'ephemeralMessage') {
|
| 1408 |
+
// exports.smsg(conn, m.msg)
|
| 1409 |
+
// m.mtype = m.msg.mtype
|
| 1410 |
+
// m.msg = m.msg.msg
|
| 1411 |
+
// }
|
| 1412 |
+
if (m.mtype == 'protocolMessage' && m.msg.key) {
|
| 1413 |
+
if (m.msg.key.remoteJid == 'status@broadcast') m.msg.key.remoteJid = m.chat
|
| 1414 |
+
if (!m.msg.key.participant || m.msg.key.participant == 'status_me') m.msg.key.participant = m.sender
|
| 1415 |
+
m.msg.key.fromMe = conn.decodeJid(m.msg.key.participant) === conn.decodeJid(conn.user.id)
|
| 1416 |
+
if (!m.msg.key.fromMe && m.msg.key.remoteJid === conn.decodeJid(conn.user.id)) m.msg.key.remoteJid = m.sender
|
| 1417 |
+
}
|
| 1418 |
+
m.text = m.msg.text || m.msg.caption || m.msg.contentText || m.msg || ''
|
| 1419 |
+
m.mentionedJid = m.msg && m.msg.contextInfo && m.msg.contextInfo.mentionedJid && m.msg.contextInfo.mentionedJid.length && m.msg.contextInfo.mentionedJid || []
|
| 1420 |
+
let quoted = m.quoted = m.msg && m.msg.contextInfo && m.msg.contextInfo.quotedMessage ? m.msg.contextInfo.quotedMessage : null
|
| 1421 |
+
if (m.quoted) {
|
| 1422 |
+
let type = Object.keys(m.quoted)[0]
|
| 1423 |
+
m.quoted = m.quoted[type]
|
| 1424 |
+
if (typeof m.quoted === 'string') m.quoted = { text: m.quoted }
|
| 1425 |
+
m.quoted.mtype = type
|
| 1426 |
+
m.quoted.id = m.msg.contextInfo.stanzaId
|
| 1427 |
+
m.quoted.chat = conn.decodeJid(m.msg.contextInfo.remoteJid || m.chat || m.sender)
|
| 1428 |
+
m.quoted.isBaileys = m.quoted.id && m.quoted.id.length === 16 || false
|
| 1429 |
+
m.quoted.sender = conn.decodeJid(m.msg.contextInfo.participant)
|
| 1430 |
+
m.quoted.fromMe = m.quoted.sender === conn.user.jid
|
| 1431 |
+
m.quoted.text = m.quoted.text || m.quoted.caption || ''
|
| 1432 |
+
m.quoted.name = conn.getName(m.quoted.sender)
|
| 1433 |
+
m.quoted.mentionedJid = m.quoted.contextInfo && m.quoted.contextInfo.mentionedJid && m.quoted.contextInfo.mentionedJid.length && m.quoted.contextInfo.mentionedJid || []
|
| 1434 |
+
let vM = m.quoted.fakeObj = M.fromObject({
|
| 1435 |
+
key: {
|
| 1436 |
+
fromMe: m.quoted.fromMe,
|
| 1437 |
+
remoteJid: m.quoted.chat,
|
| 1438 |
+
id: m.quoted.id
|
| 1439 |
+
},
|
| 1440 |
+
message: quoted,
|
| 1441 |
+
...(m.isGroup ? { participant: m.quoted.sender } : {})
|
| 1442 |
+
})
|
| 1443 |
+
m.getQuotedObj = m.getQuotedMessage = () => {
|
| 1444 |
+
if (!m.quoted.id) return false
|
| 1445 |
+
let q = M.fromObject(((conn.chats[m.quoted.chat] || {}).messages || {})[m.quoted.id])
|
| 1446 |
+
return exports.smsg(conn, q ? q : vM)
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
if (m.quoted.url || m.quoted.directPath) m.quoted.download = (saveToFile = false) => conn.downloadM(m.quoted, m.quoted.mtype.replace(/message/i, ''), saveToFile)*/
|
| 1450 |
+
|
| 1451 |
+
/**
|
| 1452 |
+
* Reply to quoted message
|
| 1453 |
+
* @param {String|Object} text
|
| 1454 |
+
* @param {String|false} chatId
|
| 1455 |
+
* @param {Object} options
|
| 1456 |
+
*/
|
| 1457 |
+
m.quoted.reply = (text, chatId, options) => conn.reply(chatId ? chatId : m.chat, text, vM, options)
|
| 1458 |
+
|
| 1459 |
+
/**
|
| 1460 |
+
* Copy quoted message
|
| 1461 |
+
*/
|
| 1462 |
+
m.quoted.copy = () => exports.smsg(conn, M.fromObject(M.toObject(vM)))
|
| 1463 |
+
|
| 1464 |
+
/**
|
| 1465 |
+
* Forward quoted message
|
| 1466 |
+
* @param {String} jid
|
| 1467 |
+
* @param {Boolean} forceForward
|
| 1468 |
+
*/
|
| 1469 |
+
m.quoted.forward = (jid, forceForward = false) => conn.forwardMessage(jid, vM, forceForward)
|
| 1470 |
+
|
| 1471 |
+
/**
|
| 1472 |
+
* Exact Forward quoted message
|
| 1473 |
+
* @param {String} jid
|
| 1474 |
+
* @param {Boolean|Number} forceForward
|
| 1475 |
+
* @param {Object} options
|
| 1476 |
+
*/
|
| 1477 |
+
m.quoted.copyNForward = (jid, forceForward = true, options = {}) => conn.copyNForward(jid, vM, forceForward, options)
|
| 1478 |
+
|
| 1479 |
+
/**
|
| 1480 |
+
* Modify quoted Message
|
| 1481 |
+
* @param {String} jid
|
| 1482 |
+
* @param {String} text
|
| 1483 |
+
* @param {String} sender
|
| 1484 |
+
* @param {Object} options
|
| 1485 |
+
*/
|
| 1486 |
+
m.quoted.cMod = (jid, text = '', sender = m.quoted.sender, options = {}) => conn.cMod(jid, vM, text, sender, options)
|
| 1487 |
+
|
| 1488 |
+
/**
|
| 1489 |
+
* Delete quoted message
|
| 1490 |
+
*/
|
| 1491 |
+
m.quoted.delete = () => conn.sendMessage(m.quoted.chat, { delete: vM.key })
|
| 1492 |
+
}
|
| 1493 |
+
}
|
| 1494 |
+
m.name = m.pushName || conn.getName(m.sender)
|
| 1495 |
+
if (m.msg && m.msg.url) m.download = (saveToFile = false) => conn.downloadM(m.msg, m.mtype.replace(/message/i, ''), saveToFile)
|
| 1496 |
+
/**
|
| 1497 |
+
* Reply to this message
|
| 1498 |
+
* @param {String|Object} text
|
| 1499 |
+
* @param {String|false} chatId
|
| 1500 |
+
* @param {Object} options
|
| 1501 |
+
*/
|
| 1502 |
+
m.reply = (text, chatId, options) => conn.reply(chatId ? chatId : m.chat, text, m, options)
|
| 1503 |
+
|
| 1504 |
+
/**
|
| 1505 |
+
* Copy this message
|
| 1506 |
+
*/
|
| 1507 |
+
m.copy = () => exports.smsg(conn, M.fromObject(M.toObject(m)))
|
| 1508 |
+
|
| 1509 |
+
/**
|
| 1510 |
+
* Forward this message
|
| 1511 |
+
* @param {String} jid
|
| 1512 |
+
* @param {Boolean} forceForward
|
| 1513 |
+
*/
|
| 1514 |
+
m.forward = (jid = m.chat, forceForward = false) => conn.copyNForward(jid, m, forceForward, options)
|
| 1515 |
+
|
| 1516 |
+
/**
|
| 1517 |
+
* Exact Forward this message
|
| 1518 |
+
* @param {String} jid
|
| 1519 |
+
* @param {Boolean} forceForward
|
| 1520 |
+
* @param {Object} options
|
| 1521 |
+
*/
|
| 1522 |
+
m.copyNForward = (jid = m.chat, forceForward = true, options = {}) => conn.copyNForward(jid, m, forceForward, options)
|
| 1523 |
+
|
| 1524 |
+
/**
|
| 1525 |
+
* Modify this Message
|
| 1526 |
+
* @param {String} jid
|
| 1527 |
+
* @param {String} text
|
| 1528 |
+
* @param {String} sender
|
| 1529 |
+
* @param {Object} options
|
| 1530 |
+
*/
|
| 1531 |
+
m.cMod = (jid, text = '', sender = m.sender, options = {}) => conn.cMod(jid, m, text, sender, options)
|
| 1532 |
+
|
| 1533 |
+
/**
|
| 1534 |
+
* Delete this message
|
| 1535 |
+
*/
|
| 1536 |
+
m.delete = () => conn.sendMessage(m.chat, { delete: m.key })
|
| 1537 |
+
|
| 1538 |
+
try {
|
| 1539 |
+
if (m.msg && m.mtype == 'protocolMessage') conn.ev.emit('message.delete', m.msg.key)
|
| 1540 |
+
} catch (e) {
|
| 1541 |
+
console.error(e)
|
| 1542 |
+
}
|
| 1543 |
+
return m
|
| 1544 |
+
}
|
| 1545 |
+
|
| 1546 |
+
exports.logic = (check, inp, out) => {
|
| 1547 |
+
if (inp.length !== out.length) throw new Error('Input and Output must have same length')
|
| 1548 |
+
for (let i in inp) if (util.isDeepStrictEqual(check, inp[i])) return out[i]
|
| 1549 |
+
return null
|
| 1550 |
+
}
|
| 1551 |
+
|
| 1552 |
+
exports.protoType = () => {
|
| 1553 |
+
Buffer.prototype.toArrayBuffer = function toArrayBufferV2() {
|
| 1554 |
+
const ab = new ArrayBuffer(this.length);
|
| 1555 |
+
const view = new Uint8Array(ab);
|
| 1556 |
+
for (let i = 0; i < this.length; ++i) {
|
| 1557 |
+
view[i] = this[i];
|
| 1558 |
+
}
|
| 1559 |
+
return ab;
|
| 1560 |
+
}
|
| 1561 |
+
/**
|
| 1562 |
+
* @returns {ArrayBuffer}
|
| 1563 |
+
*/
|
| 1564 |
+
Buffer.prototype.toArrayBufferV2 = function toArrayBuffer() {
|
| 1565 |
+
return this.buffer.slice(this.byteOffset, this.byteOffset + this.byteLength)
|
| 1566 |
+
}
|
| 1567 |
+
/**
|
| 1568 |
+
* @returns {Buffer}
|
| 1569 |
+
*/
|
| 1570 |
+
ArrayBuffer.prototype.toBuffer = function toBuffer() {
|
| 1571 |
+
return Buffer.from(new Uint8Array(this))
|
| 1572 |
+
}
|
| 1573 |
+
// /**
|
| 1574 |
+
// * @returns {String}
|
| 1575 |
+
// */
|
| 1576 |
+
// Buffer.prototype.toUtilFormat = ArrayBuffer.prototype.toUtilFormat = Object.prototype.toUtilFormat = Array.prototype.toUtilFormat = function toUtilFormat() {
|
| 1577 |
+
// return util.format(this)
|
| 1578 |
+
// }
|
| 1579 |
+
Uint8Array.prototype.getFileType = ArrayBuffer.prototype.getFileType = Buffer.prototype.getFileType = async function getFileType() {
|
| 1580 |
+
return await fileTypeFromBuffer(this)
|
| 1581 |
+
}
|
| 1582 |
+
/**
|
| 1583 |
+
* @returns {Boolean}
|
| 1584 |
+
*/
|
| 1585 |
+
String.prototype.isNumber = Number.prototype.isNumber = isNumber
|
| 1586 |
+
/**
|
| 1587 |
+
*
|
| 1588 |
+
* @returns {String}
|
| 1589 |
+
*/
|
| 1590 |
+
String.prototype.capitalize = function capitalize() {
|
| 1591 |
+
return this.charAt(0).toUpperCase() + this.slice(1, this.length)
|
| 1592 |
+
}
|
| 1593 |
+
/**
|
| 1594 |
+
* @returns {String}
|
| 1595 |
+
*/
|
| 1596 |
+
String.prototype.capitalizeV2 = function capitalizeV2() {
|
| 1597 |
+
const str = this.split(' ')
|
| 1598 |
+
return str.map(v => v.capitalize()).join(' ')
|
| 1599 |
+
}
|
| 1600 |
+
String.prototype.decodeJid = function decodeJid() {
|
| 1601 |
+
if (/:\d+@/gi.test(this)) {
|
| 1602 |
+
const decode = jidDecode(this) || {}
|
| 1603 |
+
return (decode.user && decode.server && decode.user + '@' + decode.server || this).trim()
|
| 1604 |
+
} else return this.trim()
|
| 1605 |
+
}
|
| 1606 |
+
/**
|
| 1607 |
+
* number must be milliseconds
|
| 1608 |
+
* @returns {string}
|
| 1609 |
+
*/
|
| 1610 |
+
Number.prototype.toTimeString = function toTimeString() {
|
| 1611 |
+
// const milliseconds = this % 1000
|
| 1612 |
+
const seconds = Math.floor((this / 1000) % 60)
|
| 1613 |
+
const minutes = Math.floor((this / (60 * 1000)) % 60)
|
| 1614 |
+
const hours = Math.floor((this / (60 * 60 * 1000)) % 24)
|
| 1615 |
+
const days = Math.floor((this / (24 * 60 * 60 * 1000)))
|
| 1616 |
+
return (
|
| 1617 |
+
(days ? `${days} day(s) ` : '') +
|
| 1618 |
+
(hours ? `${hours} hour(s) ` : '') +
|
| 1619 |
+
(minutes ? `${minutes} minute(s) ` : '') +
|
| 1620 |
+
(seconds ? `${seconds} second(s)` : '')
|
| 1621 |
+
).trim()
|
| 1622 |
+
}
|
| 1623 |
+
Number.prototype.getRandom = String.prototype.getRandom = Array.prototype.getRandom = getRandom
|
| 1624 |
+
}
|
| 1625 |
+
|
| 1626 |
+
function isNumber() {
|
| 1627 |
+
const int = parseInt(this)
|
| 1628 |
+
return typeof int === 'number' && !isNaN(int)
|
| 1629 |
+
}
|
| 1630 |
+
|
| 1631 |
+
function getRandom() {
|
| 1632 |
+
if (Array.isArray(this) || this instanceof String) return this[Math.floor(Math.random() * this.length)]
|
| 1633 |
+
return Math.floor(Math.random() * this)
|
| 1634 |
+
}
|
| 1635 |
+
|
| 1636 |
+
function rand(isi) {
|
| 1637 |
+
return isi[Math.floor(Math.random() * isi.length)]
|
| 1638 |
+
}
|
lib/sticker.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs')
|
| 2 |
+
const path = require('path')
|
| 3 |
+
const crypto = require('crypto')
|
| 4 |
+
const fetch = require('node-fetch')
|
| 5 |
+
const { ffmpeg } = require('./converter')
|
| 6 |
+
const { spawn } = require('child_process')
|
| 7 |
+
const uploadFile = require('./uploadFile')
|
| 8 |
+
const { fromBuffer } = require('file-type')
|
| 9 |
+
const uploadImage = require('./uploadImage')
|
| 10 |
+
|
| 11 |
+
const tmp = path.join(__dirname, '../tmp')
|
| 12 |
+
/**
|
| 13 |
+
* Image to Sticker
|
| 14 |
+
* @param {Buffer} img Image Buffer
|
| 15 |
+
* @param {String} url Image URL
|
| 16 |
+
*/
|
| 17 |
+
function sticker2(img, url) {
|
| 18 |
+
return new Promise(async (resolve, reject) => {
|
| 19 |
+
try {
|
| 20 |
+
if (url) {
|
| 21 |
+
let res = await fetch(url)
|
| 22 |
+
if (res.status !== 200) throw await res.text()
|
| 23 |
+
img = await res.buffer()
|
| 24 |
+
}
|
| 25 |
+
let inp = path.join(tmp, +new Date + '.jpeg')
|
| 26 |
+
await fs.promises.writeFile(inp, img)
|
| 27 |
+
let ff = spawn('ffmpeg', [
|
| 28 |
+
'-y',
|
| 29 |
+
'-i', inp,
|
| 30 |
+
'-vf', 'scale=512:512:flags=lanczos:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1',
|
| 31 |
+
'-f', 'png',
|
| 32 |
+
'-'
|
| 33 |
+
])
|
| 34 |
+
ff.on('error', reject)
|
| 35 |
+
ff.on('close', async () => {
|
| 36 |
+
await fs.promises.unlink(inp)
|
| 37 |
+
})
|
| 38 |
+
let bufs = []
|
| 39 |
+
const [_spawnprocess, ..._spawnargs] = [...(module.exports.support.gm ? ['gm'] : module.exports.magick ? ['magick'] : []), 'convert', 'png:-', 'webp:-']
|
| 40 |
+
let im = spawn(_spawnprocess, _spawnargs)
|
| 41 |
+
im.on('error', e => conn.reply(m.chat, util.format(e), m))
|
| 42 |
+
im.stdout.on('data', chunk => bufs.push(chunk))
|
| 43 |
+
ff.stdout.pipe(im.stdin)
|
| 44 |
+
im.on('exit', () => {
|
| 45 |
+
resolve(Buffer.concat(bufs))
|
| 46 |
+
})
|
| 47 |
+
} catch (e) {
|
| 48 |
+
reject(e)
|
| 49 |
+
}
|
| 50 |
+
})
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
async function canvas(code, type = 'png', quality = 0.92) {
|
| 54 |
+
let res = await fetch('https://nurutomo.herokuapp.com/api/canvas?' + queryURL({
|
| 55 |
+
type,
|
| 56 |
+
quality
|
| 57 |
+
}), {
|
| 58 |
+
method: 'POST',
|
| 59 |
+
headers: {
|
| 60 |
+
'Content-Type': 'text/plain',
|
| 61 |
+
'Content-Length': code.length
|
| 62 |
+
},
|
| 63 |
+
body: code
|
| 64 |
+
})
|
| 65 |
+
let image = await res.buffer()
|
| 66 |
+
return image
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
function queryURL(queries) {
|
| 70 |
+
return new URLSearchParams(Object.entries(queries))
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* Image to Sticker
|
| 75 |
+
* @param {Buffer} img Image Buffer
|
| 76 |
+
* @param {String} url Image URL
|
| 77 |
+
*/
|
| 78 |
+
async function sticker1(img, url) {
|
| 79 |
+
url = url ? url : await uploadImage(img)
|
| 80 |
+
let {
|
| 81 |
+
mime
|
| 82 |
+
} = url ? { mime: 'image/jpeg' } : await fromBuffer(img)
|
| 83 |
+
let sc = `let im = await loadImg('data:${mime};base64,'+(await window.loadToDataURI('${url}')))
|
| 84 |
+
c.width = c.height = 512
|
| 85 |
+
let max = Math.max(im.width, im.height)
|
| 86 |
+
let w = 512 * im.width / max
|
| 87 |
+
let h = 512 * im.height / max
|
| 88 |
+
ctx.drawImage(im, 256 - w / 2, 256 - h / 2, w, h)
|
| 89 |
+
`
|
| 90 |
+
return await canvas(sc, 'webp')
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
/**
|
| 94 |
+
* Image/Video to Sticker
|
| 95 |
+
* @param {Buffer} img Image/Video Buffer
|
| 96 |
+
* @param {String} url Image/Video URL
|
| 97 |
+
* @param {String} packname EXIF Packname
|
| 98 |
+
* @param {String} author EXIF Author
|
| 99 |
+
*/
|
| 100 |
+
async function sticker3(img, url, packname, author) {
|
| 101 |
+
url = url ? url : await uploadFile(img)
|
| 102 |
+
let res = await fetch('https://api.xteam.xyz/sticker/wm?' + new URLSearchParams(Object.entries({
|
| 103 |
+
url,
|
| 104 |
+
packname,
|
| 105 |
+
author
|
| 106 |
+
})))
|
| 107 |
+
return await res.buffer()
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/**
|
| 111 |
+
* Image to Sticker
|
| 112 |
+
* @param {Buffer} img Image/Video Buffer
|
| 113 |
+
* @param {String} url Image/Video URL
|
| 114 |
+
*/
|
| 115 |
+
async function sticker4(img, url) {
|
| 116 |
+
if (url) {
|
| 117 |
+
let res = await fetch(url)
|
| 118 |
+
if (res.status !== 200) throw await res.text()
|
| 119 |
+
img = await res.buffer()
|
| 120 |
+
}
|
| 121 |
+
return await ffmpeg(img, [
|
| 122 |
+
'-vf', 'scale=512:512:flags=lanczos:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1'
|
| 123 |
+
], 'jpeg', 'webp')
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
async function sticker5(img, url, packname, author, categories = ['']) {
|
| 128 |
+
const WSF = require('wa-sticker-formatter')
|
| 129 |
+
const stickerMetadata = {
|
| 130 |
+
type: 'full',
|
| 131 |
+
pack: packname,
|
| 132 |
+
author,
|
| 133 |
+
categories,
|
| 134 |
+
}
|
| 135 |
+
return await new WSF.Sticker(img ? img : url, stickerMetadata).build()
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
/**
|
| 140 |
+
* Add WhatsApp JSON Exif Metadata
|
| 141 |
+
* Taken from https://github.com/pedroslopez/whatsapp-web.js/pull/527/files
|
| 142 |
+
* @param {Buffer} webpSticker
|
| 143 |
+
* @param {String} packname
|
| 144 |
+
* @param {String} author
|
| 145 |
+
* @param {String} categories
|
| 146 |
+
* @param {Object} extra
|
| 147 |
+
* @returns
|
| 148 |
+
*/
|
| 149 |
+
async function addExif(webpSticker, packname, author, categories = [''], extra = {}) {
|
| 150 |
+
const webp = require('node-webpmux') // Optional Feature
|
| 151 |
+
const img = new webp.Image();
|
| 152 |
+
const stickerPackId = crypto.randomBytes(32).toString('hex');
|
| 153 |
+
const json = { 'sticker-pack-id': stickerPackId, 'sticker-pack-name': packname, 'sticker-pack-publisher': author, 'emojis': categories, ...extra };
|
| 154 |
+
let exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
|
| 155 |
+
let jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
|
| 156 |
+
let exif = Buffer.concat([exifAttr, jsonBuffer]);
|
| 157 |
+
exif.writeUIntLE(jsonBuffer.length, 14, 4);
|
| 158 |
+
await img.loadBuffer(webpSticker)
|
| 159 |
+
img.exif = exif
|
| 160 |
+
return await img.saveBuffer()
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
module.exports = {
|
| 164 |
+
/**
|
| 165 |
+
* Image/Video to Sticker
|
| 166 |
+
* @param {Buffer} img Image/Video Buffer
|
| 167 |
+
* @param {String} url Image/Video URL
|
| 168 |
+
* @param {...String}
|
| 169 |
+
*/
|
| 170 |
+
async sticker(img, url, ...args) {
|
| 171 |
+
let lastError
|
| 172 |
+
for (let func of [
|
| 173 |
+
sticker3, // sticker5,
|
| 174 |
+
this.support.ffmpeg && this.support.ffmpegWebp && sticker4,
|
| 175 |
+
this.support.ffmpeg && (this.support.convert || this.support.magick || this.support.gm) && sticker2,
|
| 176 |
+
sticker1
|
| 177 |
+
].filter(f => f)) {
|
| 178 |
+
try {
|
| 179 |
+
let stiker = await func(img, url, ...args)
|
| 180 |
+
if (stiker.includes('RIFF')) {
|
| 181 |
+
try {
|
| 182 |
+
return await addExif(stiker, ...args)
|
| 183 |
+
} catch (e) {
|
| 184 |
+
return stiker
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
throw stiker.toString()
|
| 188 |
+
} catch (err) {
|
| 189 |
+
lastError = err
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
return lastError
|
| 193 |
+
},
|
| 194 |
+
sticker1,
|
| 195 |
+
sticker2,
|
| 196 |
+
sticker3,
|
| 197 |
+
sticker4,
|
| 198 |
+
sticker5,
|
| 199 |
+
addExif,
|
| 200 |
+
support: {
|
| 201 |
+
ffmpeg: true,
|
| 202 |
+
ffprobe: true,
|
| 203 |
+
ffmpegWebp: true,
|
| 204 |
+
convert: true,
|
| 205 |
+
magick: false,
|
| 206 |
+
gm: false,
|
| 207 |
+
find: false
|
| 208 |
+
}
|
| 209 |
+
}
|
lib/tictactoe.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export declare class TicTacToe {
|
| 2 |
+
/* X PlayerName */
|
| 3 |
+
playerX: string;
|
| 4 |
+
/* Y PlayerName */
|
| 5 |
+
playerY: string;
|
| 6 |
+
/* X if true, Y if false */
|
| 7 |
+
_currentTurn: boolean;
|
| 8 |
+
_x: number;
|
| 9 |
+
_y: number;
|
| 10 |
+
_turns: number;
|
| 11 |
+
constructor(playerX: string, playerY: string);
|
| 12 |
+
get board(): number;
|
| 13 |
+
turn(player, index: number): boolean;
|
| 14 |
+
turn(player, x: number, y: number): boolean;
|
| 15 |
+
}
|
lib/tictactoe.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class TicTacToe {
|
| 2 |
+
constructor(playerX = 'x', playerO = 'o') {
|
| 3 |
+
this.playerX = playerX
|
| 4 |
+
this.playerO = playerO
|
| 5 |
+
this._currentTurn = false
|
| 6 |
+
this._x = 0
|
| 7 |
+
this._o = 0
|
| 8 |
+
this.turns = 0
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
get board() {
|
| 12 |
+
return this._x | this._o
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
get currentTurn() {
|
| 16 |
+
return this._currentTurn ? this.playerO : this.playerX
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
get enemyTurn() {
|
| 20 |
+
return this._currentTurn ? this.playerX : this.playerO
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
static check(state) {
|
| 24 |
+
for (let combo of [7, 56, 73, 84, 146, 273, 292, 448])
|
| 25 |
+
if ((state & combo) === combo)
|
| 26 |
+
return !0
|
| 27 |
+
return !1
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
/**
|
| 31 |
+
* ```js
|
| 32 |
+
* TicTacToe.toBinary(1, 2) // 0b010000000
|
| 33 |
+
* ```
|
| 34 |
+
*/
|
| 35 |
+
static toBinary(x = 0, y = 0) {
|
| 36 |
+
if (x < 0 || x > 2 || y < 0 || y > 2) throw new Error('invalid position')
|
| 37 |
+
return 1 << x + (3 * y)
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/**
|
| 41 |
+
* @param player `0` is `X`, `1` is `O`
|
| 42 |
+
*
|
| 43 |
+
* - `-3` `Game Ended`
|
| 44 |
+
* - `-2` `Invalid`
|
| 45 |
+
* - `-1` `Invalid Position`
|
| 46 |
+
* - ` 0` `Position Occupied`
|
| 47 |
+
* - ` 1` `Sucess`
|
| 48 |
+
* @returns {-3|-2|-1|0|1}
|
| 49 |
+
*/
|
| 50 |
+
turn(player = 0, x = 0, y) {
|
| 51 |
+
if (this.board === 511) return -3
|
| 52 |
+
let pos = 0
|
| 53 |
+
if (y == null) {
|
| 54 |
+
if (x < 0 || x > 8) return -1
|
| 55 |
+
pos = 1 << x
|
| 56 |
+
} else {
|
| 57 |
+
if (x < 0 || x > 2 || y < 0 || y > 2) return -1
|
| 58 |
+
pos = TicTacToe.toBinary(x, y)
|
| 59 |
+
}
|
| 60 |
+
if (this._currentTurn ^ player) return -2
|
| 61 |
+
if (this.board & pos) return 0
|
| 62 |
+
this[this._currentTurn ? '_o' : '_x'] |= pos
|
| 63 |
+
this._currentTurn = !this._currentTurn
|
| 64 |
+
this.turns++
|
| 65 |
+
return 1
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
/**
|
| 69 |
+
* @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
|
| 70 |
+
*/
|
| 71 |
+
static render(boardX = 0, boardO = 0) {
|
| 72 |
+
let x = parseInt(boardX.toString(2), 4)
|
| 73 |
+
let y = parseInt(boardO.toString(2), 4) * 2
|
| 74 |
+
return [...(x + y).toString(4).padStart(9, '0')].reverse().map((value, index) => value == 1 ? 'X' : value == 2 ? 'O' : ++index)
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
/**
|
| 78 |
+
* @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
|
| 79 |
+
*/
|
| 80 |
+
render() {
|
| 81 |
+
return TicTacToe.render(this._x, this._o)
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
get winner() {
|
| 85 |
+
let x = TicTacToe.check(this._x)
|
| 86 |
+
let o = TicTacToe.check(this._o)
|
| 87 |
+
return x ? this.playerX : o ? this.playerO : false
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
new TicTacToe().turn
|
| 92 |
+
|
| 93 |
+
module.exports = TicTacToe
|
lib/ular_tangga.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const fs = require('fs');
|
| 2 |
+
const Jimp = require('jimp');
|
| 3 |
+
|
| 4 |
+
// Fungsi untuk menggambar papan permainan dengan pemain
|
| 5 |
+
async function drawBoard(boardImageURL, user1 = null, user2 = null, user3 = null, user4 = null, stabil_x, stabil_y) {
|
| 6 |
+
try {
|
| 7 |
+
// Load gambar papan permainan dari URL
|
| 8 |
+
const board = await Jimp.read(boardImageURL);
|
| 9 |
+
|
| 10 |
+
// Lokasi pemain pada papan permainan
|
| 11 |
+
const playerPositions = [user1, user2, user3, user4].filter(pos => pos !== null && pos >= 1 && pos <= 100);
|
| 12 |
+
|
| 13 |
+
// URL gambar untuk setiap pemain
|
| 14 |
+
const playerImageURLs = [
|
| 15 |
+
"https://telegra.ph/file/30f92f923fb0484f0e4e0.png",
|
| 16 |
+
"https://telegra.ph/file/6e07b5f30b24baedc7822.png",
|
| 17 |
+
"https://telegra.ph/file/34f47137df0dc9aa9c15a.png",
|
| 18 |
+
"https://telegra.ph/file/860b5df98963a1f14a91c.png"
|
| 19 |
+
];
|
| 20 |
+
|
| 21 |
+
// Gambar pion untuk setiap pemain pada posisi mereka
|
| 22 |
+
for (let i = 0; i < playerPositions.length; i++) {
|
| 23 |
+
const position = playerPositions[i];
|
| 24 |
+
const row = Math.floor((position - 1) / 10); // Mulai dari bawah
|
| 25 |
+
const col = (row % 2 === 0) ? (position - 1) % 10 : 9 - (position - 1) % 10;
|
| 26 |
+
|
| 27 |
+
// Posisi pion pada papan permainan
|
| 28 |
+
const x = col * 60 + stabil_x
|
| 29 |
+
const y = (9 - row) * 60 + stabil_y
|
| 30 |
+
|
| 31 |
+
// Load gambar pemain dari URL
|
| 32 |
+
const playerImageURL = playerImageURLs[i];
|
| 33 |
+
const playerImage = await Jimp.read(playerImageURL);
|
| 34 |
+
|
| 35 |
+
// Resize gambar pemain menjadi 38x38 (sesuai dengan ukuran lingkaran)
|
| 36 |
+
playerImage.resize(50, 50);
|
| 37 |
+
|
| 38 |
+
// Gabungkan gambar pemain dengan papan permainan
|
| 39 |
+
board.composite(playerImage, x - 4, y - 4, { mode: Jimp.BLEND_SOURCE_OVER });
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
// Mengembalikan buffer gambar
|
| 43 |
+
return await board.getBufferAsync(Jimp.MIME_PNG);
|
| 44 |
+
} catch (error) {
|
| 45 |
+
console.error('An error occurred:', error);
|
| 46 |
+
return null;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
module.exports = { drawBoard }
|