Logo OmniDevvKANA Web
Kembali ke katalog plugin

owner

reload

Muat ulang semua plugin tanpa restart bot

Reload all plugins without restarting the bot

plugins/owner/reload.js

Lokasi file di repo kana-md

1

Perintah termasuk alias

3.4 KB

Ukuran file sumber

4/11/2026

Update terakhir, commit a0f6049

Daftar perintah

Ketuk tombol salin untuk menyalin perintah, lalu tempel di chat WhatsApp bot KANA.

.reload

Cara pakai

.reload [nama]

Contoh

.reload ping

Kode sumber plugin

Unduh .js

Cara pasang: simpan file ini ke folder plugins/owner/ di bot KANA kamu, lalu restart bot. Pemilik source code lain bisa mengambil update plugin terbaru dari halaman ini kapan saja.

import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { sendButtons } from '../../src/ui/buttons.js'
import { loadPlugins } from '../../src/core/plugin-loader.js'

const here = dirname(fileURLToPath(import.meta.url))

export const config = {
  name: 'reload',
  alias: [],
  category: 'owner',
  description: { id: 'Muat ulang semua plugin tanpa restart bot', en: 'Reload all plugins without restarting the bot' },
  usage: '.reload [nama]',
  example: '.reload ping',
  cooldown: 5,
  isOwner: true,
}

export const i18n = {
  id: {
    reload: {
      done: 'Reload beres, Master~ Plugin aktif: {active}, karantina: {quarantined}. {mood}',
      statusActive: 'Plugin "{name}": aktif.',
      statusQuarantined: 'Plugin "{name}": karantina. Alasan: {reason}',
      statusUnknown: 'Plugin "{name}": nggak ketemu setelah reload.',
      btnOwner: 'Status Bot',
    },
  },
  en: {
    reload: {
      done: 'Reload done, Master~ Active plugins: {active}, quarantined: {quarantined}. {mood}',
      statusActive: 'Plugin "{name}": active.',
      statusQuarantined: 'Plugin "{name}": quarantined. Reason: {reason}',
      statusUnknown: 'Plugin "{name}": not found after reload.',
      btnOwner: 'Bot Status',
    },
  },
}

export const test = { input: '.reload', expect: /reload/i }

export async function handler(ctx) {
  const dir = join(here, '..', '..', 'plugins')
  const fresh = await loadPlugins(dir)
  const registry = ctx.registry

  if (registry.plugins instanceof Map && registry.aliases instanceof Map) {
    // Ganti isi Map yang sama: closure resolve/list di loader lama membaca
    // Map ini, jadi mutasi di tempat membuat reload terasa tanpa restart.
    registry.plugins.clear()
    for (const [name, plugin] of fresh.plugins) registry.plugins.set(name, plugin)
    registry.aliases.clear()
    for (const [alias, name] of fresh.aliases) registry.aliases.set(alias, name)
  } else {
    registry.plugins = fresh.plugins
    registry.aliases = fresh.aliases
  }
  if (Array.isArray(registry.befores)) {
    registry.befores.length = 0
    registry.befores.push(...fresh.befores)
  } else {
    registry.befores = fresh.befores
  }
  if (Array.isArray(registry.participantHandlers)) {
    registry.participantHandlers.length = 0
    registry.participantHandlers.push(...fresh.participantHandlers)
  } else {
    registry.participantHandlers = fresh.participantHandlers
  }
  if (Array.isArray(registry.quarantined)) {
    registry.quarantined.length = 0
    registry.quarantined.push(...fresh.quarantined)
  } else {
    registry.quarantined = fresh.quarantined
  }

  let body = ctx.t('reload.done', {
    active: fresh.plugins.size,
    quarantined: fresh.quarantined.length,
    mood: ctx.say('sukses'),
  })
  const target = (ctx.args[0] || '').toLowerCase()
  if (target) {
    if (fresh.plugins.has(target)) {
      body += `\n${ctx.t('reload.statusActive', { name: target })}`
    } else {
      const hit = fresh.quarantined.find((q) => q.file.endsWith(`/${target}.js`) || q.file.includes(target))
      body += `\n${
        hit
          ? ctx.t('reload.statusQuarantined', { name: target, reason: hit.reason })
          : ctx.t('reload.statusUnknown', { name: target })
      }`
    }
  }
  return sendButtons(ctx.sock, ctx.chat, {
    title: 'KANA',
    body,
    footer: ctx.t('menu.footer'),
    replies: [{ text: ctx.t('reload.btnOwner'), id: '.owner' }],
    textFallback: body,
  })
}