Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
81b0e56
Update bot.js
mannnayla1-code Nov 10, 2026
4e781a2
Update bot.js
mannnayla1-code Nov 10, 2026
9ced70a
Update fish.js
mannnayla1-code Nov 10, 2026
b8d1925
Update fish.js
mannnayla1-code Nov 10, 2026
cf2a9c5
Update items.js
mannnayla1-code Nov 10, 2026
98fa6c4
Update fish.js
mannnayla1-code Nov 10, 2026
503e9cc
feat: Buat Kode Pancingan dan Ramuan Keberuntungan
mannnayla1-code Nov 11, 2026
6c18db0
nerf: kurangi harga ikan & multiplier rod biar lebih susah
mannnayla1-code Nov 11, 2026
4ec18d7
Update fish.js
mannnayla1-code Nov 11, 2026
a964f14
Update items.js
mannnayla1-code Nov 11, 2026
2ff2509
Update items.js
mannnayla1-code Nov 11, 2026
3bb0b18
Update items.js
mannnayla1-code Nov 11, 2026
e9d7080
Update items.js
mannnayla1-code Nov 11, 2026
fc164e2
Update items.js
mannnayla1-code Nov 11, 2026
d1f2629
fix: move premium bonus to fishing
mannnayla1-code Nov 11, 2026
01b85e3
merge: sync latest main for fishing updates
mannnayla1-code Nov 11, 2026
335b5c6
fix: move premium bonus to fishing (#1)
mannnayla1-code Nov 11, 2026
de92c60
Update items.js
mannnayla1-code Nov 11, 2026
0fc9e0c
Update items.js
mannnayla1-code Nov 11, 2026
37a5f72
Update items.js
mannnayla1-code Nov 11, 2026
9fbd79d
Update items.js
mannnayla1-code Nov 11, 2026
3c24ab4
Update items.js
mannnayla1-code Nov 11, 2026
3f1c475
Update fish.js
mannnayla1-code Nov 11, 2026
ef825a6
Update fish.js
mannnayla1-code Nov 11, 2026
a9f1026
feat: update workspace
mannnayla1-code Nov 11, 2026
c42188b
feat: update workspace
mannnayla1-code Nov 11, 2026
a73a1b1
feat: update workspace
mannnayla1-code Nov 11, 2026
3d737b9
feat: update workspace
mannnayla1-code Nov 11, 2026
0d06e5b
merge: sync origin/main into fishing branch
mannnayla1-code Nov 11, 2026
68f1455
fix: smoother luck potion bias; divine & transcendent stay rare
mannnayla1-code Nov 11, 2026
8eb7206
Update fish.js
mannnayla1-code Nov 11, 2026
12d8e19
feat: add Admin Potion (buy 1x, 1min active/cooldown, divine 30%/tran…
mannnayla1-code Nov 11, 2026
6823af3
Merge remote-tracking branch 'origin/main' into trae/main-fishing-update
mannnayla1-code Nov 11, 2026
e67b979
Update items.js
mannnayla1-code Nov 11, 2026
580c0e1
feat: admin potion becomes inventory item; add /use and /give for tra…
mannnayla1-code Nov 11, 2026
e33447c
Merge remote-tracking branch 'origin/main' into trae/main-fishing-update
mannnayla1-code Nov 11, 2026
664a0ef
feat(fish): show AI-generated image of the caught fish
mannnayla1-code Nov 11, 2026
36a8c7a
perf(fish): reply instantly by using image URL directly (no download/…
mannnayla1-code Nov 11, 2026
37fb91f
revert(fish): remove AI image feature (caused delay)
mannnayla1-code Nov 11, 2026
af8a363
feat(buy): remove admin potion purchase cooldown/time gate
mannnayla1-code Nov 11, 2026
4b6e597
feat(admin_potion): remove purchase limit, extend duration to 5 minutes
mannnayla1-code Nov 11, 2026
17b6b40
Update fish.js
mannnayla1-code Nov 11, 2026
dfb06b4
Update fish.js
mannnayla1-code Nov 11, 2026
3f966c6
Update items.js
mannnayla1-code Nov 11, 2026
d1cb05d
Update items.js
mannnayla1-code Nov 11, 2026
7d18483
chore(fish): change admin potion display to gimmick luck text
mannnayla1-code Nov 11, 2026
00ddacc
Merge remote-tracking branch 'origin/main' into trae/main-fishing-update
mannnayla1-code Nov 11, 2026
dea51de
chore(fish): remove gimmick luck percentage from potion message
mannnayla1-code Nov 11, 2026
0719b38
feat(economy): add personal and public fishdex with caught fish images
mannnayla1-code Nov 11, 2026
d621141
feat(fishdex): enable prefix command support
mannnayla1-code Nov 11, 2026
7d90f91
feat(fishdex): show all fish grouped by rarity selector
mannnayla1-code Nov 11, 2026
81c980f
perf(fishdex): shrink fish images to compact thumbnails
mannnayla1-code Nov 11, 2026
cdbb5e5
feat: update workspace
mannnayla1-code Nov 11, 2026
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
39 changes: 39 additions & 0 deletions riffy_test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { Riffy } = require('riffy');

const nodes = [
{ host: 'lavalinkv4.serenetia.com', port: 443, password: 'https://seretia.link/discord', secure: true, name: 'Serenetia' },
{ host: 'lavalink.jirayu.net', port: 443, password: 'youshallnotpass', secure: true, name: 'Jirayu' },
{ host: 'lava-v4.millohost.my.id', port: 443, password: 'https://discord.gg/mjS5J2K3ep', secure: true, name: 'MilloHost' },
{ host: 'lavalink-v4.triniumhost.com', port: 443, password: 'free', secure: true, name: 'TriniumHost' },
];

const fakeClient = {
user: { id: '123456789' },
guilds: { cache: new Map() },
ws: { shards: new Map([[0, { send() {} }]]) },
on() {},
};

const riffy = new Riffy(fakeClient, nodes, {
send() {},
defaultSearchPlatform: 'ytmsearch',
restVersion: 'v4',
bypassChecks: { nodeFetchInfo: true },
});

let connected = 0;
riffy.on('nodeConnect', (node) => { console.log(`CONNECTED: ${node.name}`); connected++; });
riffy.on('nodeError', (node, err) => console.log(`ERROR ${node.name}: ${err?.message || err}`));
riffy.on('nodeDisconnect', (node) => console.log(`DISCONNECT: ${node.name}`));

riffy.init('123456789');

setTimeout(() => {
console.log(`\n=== After 10s: ${connected} node(s) connected ===`);
for (const node of riffy.nodeMap.values()) {
console.log(` ${node.name}: connected=${node.connected}`);
}
process.exit(0);
}, 10000);
35 changes: 35 additions & 0 deletions riffy_test2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { Riffy } = require('riffy');

const nodes = [
{ host: 'lava-v4.millohost.my.id', port: 443, password: 'https://discord.gg/mjS5J2K3ep', secure: true, name: 'MilloHost' },
];

const fakeClient = {
user: { id: '123456789' },
guilds: { cache: new Map() },
ws: { shards: new Map([[0, { send() {} }]]) },
on() {},
};

const riffy = new Riffy(fakeClient, nodes, {
send() {},
defaultSearchPlatform: 'ytmsearch',
restVersion: 'v4',
// NO bypassChecks
});

riffy.on('nodeConnect', (node) => console.log(`CONNECTED: ${node.name}`));
riffy.on('nodeError', (node, err) => console.log(`ERROR ${node.name}: ${err?.message || err}`));
riffy.on('nodeDisconnect', (node) => console.log(`DISCONNECT: ${node.name}`));
riffy.on('nodeReconnect', (node) => console.log(`RECONNECT: ${node.name}`));

riffy.init('123456789');

setTimeout(() => {
for (const node of riffy.nodeMap.values()) {
console.log(`${node.name}: connected=${node.connected}`);
}
process.exit(0);
}, 8000);
35 changes: 35 additions & 0 deletions riffy_test3.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { Riffy } = require('riffy');

const nodes = [
{ host: 'lava-v4.millohost.my.id', port: 443, password: 'https://discord.gg/mjS5J2K3ep', secure: true, name: 'MilloHost' },
];

const fakeClient = {
user: { id: '123456789' },
guilds: { cache: new Map() },
ws: { shards: new Map([[0, { send() {} }]]) },
on() {},
};

const riffy = new Riffy(fakeClient, nodes, {
send() {},
defaultSearchPlatform: 'ytmsearch',
restVersion: 'v4',
bypassChecks: { nodeFetchInfo: true },
});

riffy.on('debug', (msg) => console.log('[DEBUG]', msg));
riffy.on('nodeConnect', (node) => console.log(`CONNECTED: ${node.name}`));
riffy.on('nodeError', (node, err) => console.log(`ERROR ${node.name}: ${err?.message || err}`));
riffy.on('nodeDisconnect', (node, e) => console.log(`DISCONNECT: ${node.name} code=${e?.event?.code}`));

riffy.init('123456789');

setTimeout(() => {
for (const node of riffy.nodeMap.values()) {
console.log(`${node.name}: connected=${node.connected}, wsUrl=${node.wsUrl}`);
}
process.exit(0);
}, 8000);
24 changes: 23 additions & 1 deletion src/commands/Economy/buy.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import { withErrorHandling, createError, ErrorTypes } from '../../utils/errorHan
import { InteractionHelper } from '../../utils/interactionHelper.js';

const SHOP_ITEMS = shopItems;
const ADMIN_POTION_ID = 'admin_potion';
// Potion ini langsung aktif saat dibeli. Admin potion TIDAK termasuk di sini:
// admin potion disimpan ke inventory dulu supaya bisa dipakai (/use) atau dikirim (/give).
const LUCK_POTION_IDS = new Set([
'luck_potion_1',
'luck_potion_2',
'luck_potion_3',
'luck_potion_4',
'luck_potion_5',
]);
const DEFAULT_LUCK_POTION_DURATION_MS = 5 * 60 * 1000;

export default {
data: new SlashCommandBuilder()
Expand Down Expand Up @@ -136,11 +147,22 @@ export default {
} else if (item.type === "upgrade") {
userData.upgrades[itemId] = true;
successDescription += `\n\n**✨ Your upgrade is now active!**`;
} else if (item.type === "consumable" && LUCK_POTION_IDS.has(itemId)) {
const now = Date.now();
const potionExpiries = userData.luckPotionExpiresAt || {};
const currentExpiry = Math.max(now, Number(potionExpiries[itemId]) || 0);
const duration = Number(item.effect?.duration) || DEFAULT_LUCK_POTION_DURATION_MS;
potionExpiries[itemId] = currentExpiry + (duration * quantity);
userData.luckPotionExpiresAt = potionExpiries;
const activeMinutes = Math.ceil((potionExpiries[itemId] - now) / 60000);
successDescription += `\n\n🧪 **Active for ${activeMinutes} minutes. Timer started at purchase.**`;
} else if (item.type === "consumable" || item.type === "tool") {
userData.inventory[itemId] =
(userData.inventory[itemId] || 0) + quantity;
if (item.type === "tool") {
successDescription += `\n\n**🛠️ ${item.name} added to your inventory!**`;
} else if (itemId === ADMIN_POTION_ID) {
successDescription += `\n\n👑 **Added to your inventory!** Activate it with \`/use item_id:${ADMIN_POTION_ID}\` or gift it with \`/give\`.`;
}
}

Expand All @@ -157,4 +179,4 @@ export default {

await InteractionHelper.safeEditReply(interaction, { embeds: [embed], flags: [MessageFlags.Ephemeral] });
}, { command: 'buy' })
};
};
31 changes: 4 additions & 27 deletions src/commands/Economy/daily.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { SlashCommandBuilder } from 'discord.js';
import { createEmbed, errorEmbed, successEmbed, infoEmbed, warningEmbed } from '../../utils/embeds.js';
import { getEconomyData, setEconomyData } from '../../utils/economy.js';
import { getGuildConfig } from '../../services/config/guildConfig.js';
import { formatDuration } from '../../utils/embeds.js';
import { withErrorHandling, createError, ErrorTypes } from '../../utils/errorHandler.js';
import { logger } from '../../utils/logger.js';
Expand All @@ -10,7 +9,6 @@ import { botConfig } from '../../config/bot.js';

const DAILY_COOLDOWN = 24 * 60 * 60 * 1000;
const DAILY_AMOUNT = botConfig.economy?.dailyAmount ?? 100;
const PREMIUM_BONUS_PERCENTAGE = 0.1;

export default {
data: new SlashCommandBuilder()
Expand Down Expand Up @@ -50,25 +48,7 @@ export default {
);
}

const guildConfig = await getGuildConfig(client, guildId);
const PREMIUM_ROLE_ID = guildConfig.premiumRoleId;

let earned = DAILY_AMOUNT;
let bonusMessage = "";
let hasPremiumRole = false;

if (
PREMIUM_ROLE_ID &&
interaction.member &&
interaction.member.roles.cache.has(PREMIUM_ROLE_ID)
) {
const bonusAmount = Math.floor(
DAILY_AMOUNT * PREMIUM_BONUS_PERCENTAGE,
);
earned += bonusAmount;
bonusMessage = `\n✨ **Premium Bonus:** +$${bonusAmount.toLocaleString()}`;
hasPremiumRole = true;
}
const earned = DAILY_AMOUNT;

userData.wallet = (userData.wallet || 0) + earned;
userData.lastDaily = now;
Expand All @@ -80,25 +60,22 @@ export default {
guildId,
amount: earned,
newWallet: userData.wallet,
hasPremium: hasPremiumRole,
timestamp: new Date().toISOString()
});

const embed = successEmbed(
"✅ Daily Claimed!",
`You have claimed your daily **$${earned.toLocaleString()}**!${bonusMessage}`
`You have claimed your daily **$${earned.toLocaleString()}**!`
)
.addFields({
name: "New Cash Balance",
value: `$${userData.wallet.toLocaleString()}`,
inline: true,
})
.setFooter({
text: hasPremiumRole
? `Next claim in 24 hours. (Premium Active)`
: `Next claim in 24 hours.`,
text: `Next claim in 24 hours.`,
});

await InteractionHelper.safeEditReply(interaction, { embeds: [embed] });
}, { command: 'daily' })
};
};
Loading