Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
const moment = require("moment-timezone");
const Queque = require("./lib/queque.js");
const messageQueue = new Queque();
const cron = require("node-cron");
const Database = require("./lib/database.js");
const append = require("./lib/append");
const serialize = require("./lib/serialize.js");
Expand Down Expand Up @@ -73,11 +74,13 @@
);
await scraper.watch();

/*
setInterval(async () => {
await db.save();
await pg.load();
await scraper.load();
}, 2000);
*/

const store = makeInMemoryStore({
logger: pino().child({
Expand Down Expand Up @@ -296,5 +299,19 @@

return sock;
}
// Cron job for resetting limits
cron.schedule("0 0 * * *", () => {
console.log("Resetting daily limits...");
let users = db.list().user;
for (let id in users) {
users[id].limit = 100; // or whatever the default limit is
}
db.save(); // Save the database after resetting
console.log("Daily limits have been reset.");
}, {
scheduled: true,
timezone: config.tz || "Asia/Jakarta"
});

system();
})();
100 changes: 70 additions & 30 deletions lib/database.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const fs = require("node:fs");
const fs = require("node:fs").promises;
const path = require("node:path");

class Database {
#data;
constructor(filename) {
this.databaseFile = path.join(".", filename);
this.#data = {};
this.isSaving = false;
}

default = () => {
return {
user: {},
Expand All @@ -22,62 +24,77 @@ class Database {
},
};
};

init = async () => {
const data = await this.read();
this.#data = { ...this.#data, ...data };
return this.#data;
try {
const data = await this.read();
this.#data = { ...this.default(), ...data };
} catch (e) {
console.error("Failed to initialize database, starting with default.", e);
this.#data = this.default();
}
await this.save(); // Initial save to create file if it doesn't exist
};

read = async () => {
if (fs.existsSync(this.databaseFile)) {
const data = fs.readFileSync(this.databaseFile);
return JSON.parse(data);
} else {
return this.default();
try {
const data = await fs.readFile(this.databaseFile, 'utf8');
return JSON.parse(data);
} catch (error) {
if (error.code === 'ENOENT') {
console.log("Database file not found, creating a new one.");
return this.default();
}
throw error;
}
};

save = async () => {
const jsonData = JSON.stringify(this.#data, null, 2);
fs.writeFileSync(this.databaseFile, jsonData);
if (this.isSaving) return;
this.isSaving = true;
try {
const jsonData = JSON.stringify(this.#data, null, 2);
await fs.writeFile(this.databaseFile, jsonData);
} catch (e) {
console.error("Failed to save database:", e);
} finally {
this.isSaving = false;
}
};
add = async (type, id, newData) => {

// Modified to not save automatically
add = (type, id, newData) => {
if (!this.#data[type]) return `- Tipe data ${type} tidak ditemukan!`;
if (!this.#data[type][id]) {
this.#data[type][id] = newData;
}
await this.save();
// await this.save(); // REMOVED
return this.#data[type][id];
};
delete = async (type, id) => {

// Modified to not save automatically
delete = (type, id) => {
if (this.#data[type] && this.#data[type][id]) {
delete this.#data[type][id];
await this.save();
// await this.save(); // REMOVED
return `- ${type} dengan ID ${id} telah dihapus.`;
} else {
return `- ${type} dengan ID ${id} tidak ditemukan!`;
}
};

get = (type, id) => {
if (this.#data[type] && this.#data[type][id]) {
return this.#data[type][id];
} else {
return `- ${type} dengan ID ${id} tidak ditemukan!`;
}
};

// Optimized to only modify in-memory data
main = async (m) => {
await this.read();
if (m.isGroup) {
await this.add("group", m.cht, {
mute: false,
sewa: {
status: false,
expired: 0,
},
message: 0,
status: "not_announcement",
});
}
await this.add("user", m.sender, {
// await this.read(); // REMOVED - data is already in memory
const userDefaults = {
name: "Gak punya nama",
limit: 100,
register: false,
Expand Down Expand Up @@ -107,10 +124,33 @@ class Database {
status: false,
expired: 0,
},
});
await this.save();
};

// Ensure user and group objects exist with default values
if (m.isGroup) {
this.add("group", m.cht, {
mute: false,
sewa: {
status: false,
expired: 0,
},
message: 0,
status: "not_announcement",
});
}
this.add("user", m.sender, userDefaults);

// Deep merge to ensure new properties from updates are added to existing users
if (this.#data.user[m.sender]) {
this.#data.user[m.sender] = { ...userDefaults, ...this.#data.user[m.sender] };
this.#data.user[m.sender].rpg = { ...userDefaults.rpg, ...this.#data.user[m.sender].rpg };
}


// await this.save(); // REMOVED
return this.list();
};

list = () => {
return this.#data;
};
Expand Down
75 changes: 62 additions & 13 deletions lib/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class PluginLoader {
constructor(directory) {
this.directory = directory;
this.plugins = {};
this.commands = new Map();
}

async scandir(dir) {
Expand All @@ -24,12 +25,55 @@ class PluginLoader {
return files.reduce((a, f) => a.concat(f), []);
}

_registerPlugin(plugin, filepath) {
if (!plugin || typeof plugin.command === 'undefined') return;

// Unregister old commands if file is being reloaded
this._unregisterPlugin(filepath);

this.plugins[filepath] = plugin;

const command = plugin.command;
if (this.commands.has(command)) {
console.warn(chalk.yellowBright(`Command ${command} from ${filepath} is already registered. Overwriting.`));
}
this.commands.set(command, plugin);

if (plugin.alias && Array.isArray(plugin.alias)) {
for (const alias of plugin.alias) {
if (this.commands.has(alias)) {
console.warn(chalk.yellowBright(`Alias ${alias} from ${filepath} is already registered. Overwriting.`));
}
this.commands.set(alias, plugin);
}
}
}

_unregisterPlugin(filepath) {
const oldPlugin = this.plugins[filepath];
if (oldPlugin) {
if (oldPlugin.command) {
this.commands.delete(oldPlugin.command);
}
if (oldPlugin.alias && Array.isArray(oldPlugin.alias)) {
for (const alias of oldPlugin.alias) {
this.commands.delete(alias);
}
}
}
delete this.plugins[filepath];
}


load = async () => {
this.commands.clear();
this.plugins = {};
const files = await this.scandir(this.directory);
for (const filename of files) {
const relativePath = path.relative(process.cwd(), filename);
try {
this.plugins[relativePath] = require(filename);
const plugin = require(filename);
this._registerPlugin(plugin, relativePath);
} catch (e) {
console.log(chalk.redBright(`❌ Gagal memuat [ ${relativePath} ]: `) + e);
delete this.plugins[relativePath];
Expand All @@ -46,27 +90,32 @@ class PluginLoader {
watcher
.on("add", async (filename) => {
const relativePath = path.relative(process.cwd(), filename);
if (require.cache[filename]) {
delete require.cache[filename];
try {
if (require.cache[filename]) delete require.cache[filename];
const plugin = require(filename);
this._registerPlugin(plugin, relativePath);
console.log(chalk.cyanBright(`📥 Plugin baru terdeteksi: ${relativePath}`));
} catch (e) {
console.log(chalk.redBright(`❌ Gagal memuat [ ${relativePath} ]: `) + e);
}
this.plugins[relativePath] = require(filename);
console.log(chalk.cyanBright(`📥 Plugin baru terdeteksi: ${filename}`));
return this.load();
})
.on("change", async (filename) => {
if (!filename.endsWith(".js")) return;
const relativePath = path.relative(process.cwd(), filename);
if (require.cache[filename]) {
delete require.cache[filename];
try {
if (require.cache[filename]) delete require.cache[filename];
const plugin = require(filename);
this._registerPlugin(plugin, relativePath);
console.log(chalk.yellowBright(`✏️ File diubah: ${relativePath}`));
} catch(e) {
console.log(chalk.redBright(`❌ Gagal memuat ulang [ ${relativePath} ]: `) + e);
this._unregisterPlugin(relativePath);
}
this.plugins[relativePath] = require(filename);
console.log(chalk.yellowBright(`✏️ File diubah: ${filename}`));
return this.load();
})
.on("unlink", (filename) => {
const relativePath = path.relative(process.cwd(), filename);
console.log(chalk.redBright(`🗑️ File dihapus: ${filename}`));
delete this.plugins[relativePath];
this._unregisterPlugin(relativePath);
console.log(chalk.redBright(`🗑️ File dihapus: ${relativePath}`));
});
};
}
Expand Down
Loading