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
11 changes: 9 additions & 2 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config = {
AI: true, // Enable or disable AI behavior
Sleeping: false, // Enable or disable sleeping behavior
Catching: true, // Enable or disable catching behavior (CURRENTLY GLOBAL)
Daycare: true, //Enable or disable daycare
Spamming: true // Enable or disable spamming behavior (CURRENTLY GLOBAL)
},
// Incense settings
Expand All @@ -22,7 +23,9 @@ const config = {
LogCatches: true, // Enable or disable logging of catches
LowIVThreshold: 15.00, // Threshold for low IV logging
HighIVThreshold: 85.00, // Threshold for high IV logging
LogWebhook: "Webhook" // Webhook URL for logging
daycareID: "channel id", //channel id to send daycare cmds in
LogWebhook: "Webhook", // Webhook URL for logging
autoStop: true
},
// Ownership settings
ownership: {
Expand All @@ -34,6 +37,10 @@ const config = {
GlobalCatch: false, // Enable or disable global catching
BlacklistedGuilds: ["716390832034414685", "..."] // List of blacklisted guild IDs
},
//daycare
daycare: {
pokemon: "oddish" //pokemon u want to add to day care
},
// Hunting settings
hunting: {
HuntPokemons: ["rayquaza", "solosis"], // List of Pokémon to hunt on your hunt account
Expand All @@ -47,4 +54,4 @@ const config = {
};

// Export the configuration object
module.exports = config;
module.exports = config;
278 changes: 277 additions & 1 deletion src/events/catching.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,283 @@ module.exports = async (client, guildId, message) => {
message.channel.send("<@716390085896962058> sh solosis");
await wait(2000);
message.channel.send("<@716390085896962058> order iv");
} else if (
} else if (config.behavior.Daycare && message.content.includes("in the daycare have produced a")) {
console.log("Daycare condition triggered.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging is not really needed, if any, then ìt should be using sendLog and only in debug mode, I'll change it in a commit

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ Referring to the many unnecessary logs in the file, (this particular log above will have to be reformatted but can stay)


const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait() is already imported from src/utils/utils.js, no need to redefine the same function as a variable


// Send message to the Fletch channel or fallback to spam channel if not found
const sendInChannel = async (msg) => {
const channelID = config.logging.daycareID;
const channel = channelID
? message.guild.channels.cache.get(channelID)
: message.guild.channels.cache.find((channel) => channel.name.toLowerCase() === "spam");
if (channel) {
console.log(`Sending message to ${channel.name} channel.`);
await channel.send(msg);
return channel;
} else {
console.log("No valid channel found. Sending in the current channel.");
await message.channel.send(msg);
return message.channel;
}
};

try {

const pokemonName = config.daycare?.pokemon ? `--n ${config.daycare.pokemon}` : "";

const activeChannel = await sendInChannel(`<@716390085896962058> p${pokemonName ? ` ${pokemonName}` : ""} --b`);


const filter = (m) => m.author.id === "716390085896962058" && m.embeds.length > 0;

Comment on lines +304 to +305
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is never even used

const collectMessage = async () => {
console.log("🔄 Waiting for confirmation message...");

let attempts = 0;
const maxAttempts = 5; // Retry up to 5 times

while (attempts < maxAttempts) {
attempts++;

// Fetch the latest 20 messages
const messages = await activeChannel.messages.fetch({ limit: 20 }).catch(() => null);

if (messages) {
// Find a message that contains the confirmation text
const confirmationMessage = messages.find(msg =>
msg.content.includes("Are you sure you want to add"));

if (confirmationMessage) {
console.log(`✅ Found confirmation message on attempt ${attempts}.`);
return confirmationMessage;
}
}

console.log(`❌ No confirmation found. Attempt ${attempts}/${maxAttempts}. Retrying...`);
await sleep(1000); // Wait before retrying
}

console.log("❌ No confirmation message found after max attempts.");
return null;
}

const collectEmbed = async () => {
console.log("🔄 Waiting for embed...");

let collected;
let attempts = 0;
const maxAttempts = 300; // Retry for 5 minutes (300 x 1 sec)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retrying for 5 minutes is outrageous and quite frankly stupid, generally Pokétwo will respond within the first 15 seconds, even if it needs to filter through 100k pokemon in your account...


// Step 1: Get the latest bot command message
const botMessages = await activeChannel.messages.fetch({ limit: 20 }).catch(() => null);
const lastBotMessage = botMessages?.find(msg => msg.author.id === "716390085896962058");

if (!lastBotMessage) {
console.log("❌ No recent bot messages found.");
return null;
}

console.log("🔎 Found bot command message. Searching for embed...");

while (attempts < maxAttempts) {
attempts++;

// Step 2: Fetch the latest 50 messages again
const messages = await activeChannel.messages.fetch({ limit: 50 }).catch(() => null);

if (messages) {
// Step 3: Find an embed message AFTER the last bot command
const embedMessage = messages
.filter(msg => msg.createdTimestamp > lastBotMessage.createdTimestamp) // Ignore messages before bot's response
.find(msg => msg.embeds.length > 0);

if (embedMessage) {
console.log("✅ Found embed message.");
return embedMessage;
}
}

console.log(`❌ No embed found. Attempt ${attempts}/${maxAttempts}. Retrying...`);
await sleep(1000);
}

console.log("❌ No embed received after 5 minutes.");
return null;
};


const extractPokemonInfo = (line) => {
console.log("\nProcessing line:", line);


const numMatch = line.match(/`\s*(\d+)\s*`/);
const num = numMatch ? numMatch[1].trim() : null;

if (!num) {
console.log("❌ No valid number found, returning null");
return null;
}


const nameMatch = line.match(/\*\*<:.*?>\s*([\w\s-]+)/);
const species = nameMatch ? nameMatch[1].trim().toLowerCase() : null;

if (!species) {
console.log("❌ No valid species found, returning null");
return null;
}

// Detect gender (male, female, unknown)
let gender = "unknown";
const genderMatch = line.match(/<:(male|female|unknown):\d+>/);
if (genderMatch) gender = genderMatch[1];

console.log("✅ Extracted info:", { num, species, gender });
return { num, species, gender };
};


const processPage = async (embedMessage) => {
console.log("Processing page...");
let embedTitle = embedMessage.embeds[0]?.title;

// Retry until we find an embed with the title that contains "Your Pokémon"
while (!embedTitle || !embedTitle.includes("Your pokémon")) {
console.log("Embed title doesn't match. Retrying...");
embedMessage = await collectEmbed();
if (!embedMessage) return null;
embedTitle = embedMessage.embeds[0]?.title;
}

console.log("Found the correct embed title with 'Your Pokémon'.");

const embedDescription = embedMessage.embeds[0]?.description;
if (!embedDescription) {
console.log("No description found in embed.");
return { malePokemon: [], femalePokemon: [] };
}

const lines = embedDescription.trim().split("\n");
let malePokemon = [];
let femalePokemon = [];

for (const line of lines) {
const info = extractPokemonInfo(line);
if (info.num && info.species) {
if (info.gender === "male") {
malePokemon.push(info);
} else if (info.gender === "female") {
femalePokemon.push(info);
}
}
}

console.log(`Found ${malePokemon.length} male and ${femalePokemon.length} female Pokemon.`);
return { malePokemon, femalePokemon };
};

const findPairs = (malePokemon, femalePokemon) => {
console.log("Finding pairs...");
const pairs = [];
const usedFemales = new Set();

malePokemon.forEach((male) => {
const femaleMatch = femalePokemon.find((female) =>
female.species === male.species && !usedFemales.has(female.num)
);
if (femaleMatch) {
pairs.push({ male, female: femaleMatch });
usedFemales.add(femaleMatch.num);
console.log(`Same Species Pair: Male ${male.species} (${male.num}) & Female ${femaleMatch.species} (${femaleMatch.num})`);
}
});

malePokemon.forEach((male) => {
if (!pairs.some((pair) => pair.male.num === male.num)) {
const anyFemale = femalePokemon.find((female) => !usedFemales.has(female.num));
if (anyFemale) {
pairs.push({ male, female: anyFemale });
usedFemales.add(anyFemale.num);
console.log(`Different Species Pair: Male ${male.species} (${male.num}) & Female ${anyFemale.species} (${anyFemale.num})`);
}
}
});

console.log(`Total pairs found: ${pairs.length}`);
return pairs;
};

const clickYesButton = async (msg) => {
let buttonId = 0; // Default button ID
let rowId = 0;
//const button = msg.components[0]?.components.find(comp => comp.style === 3); // Style 3 = Green (Yes)
if (msg.content.includes("Are you sure you want to")) {
console.log("Clicking the Yes button...");
await msg.clickButton({ X: isNaN(buttonId) ? 0 : buttonId, Y: rowId }); //button.click();
} else {
console.log("Yes button not found.");
}
};

let pairs = [];
while (pairs.length === 0) {
const embedMessage = await collectEmbed();
if (!embedMessage) break;

const { malePokemon, femalePokemon } = await processPage(embedMessage);
pairs = findPairs(malePokemon, femalePokemon);
}

if (pairs.length === 0) {
console.log("No suitable pairs found.");
return;
}


for (const pair of pairs) {
console.log(`Attempting to add Pair (Male: ${pair.male.num}, Female: ${pair.female.num})`);

// Step 1: Add Male Pokémon
await activeChannel.send(`<@716390085896962058> daycare add ${pair.male.num}`);
await sleep(3000); // Wait before checking messages

let confirmationMessage = await collectMessage(); // Wait for up to 5 attempts to find confirmation

if (confirmationMessage && confirmationMessage.content.includes("Are you sure you want to add")) {
await clickYesButton(confirmationMessage);
console.log(`Confirmed Male Pokémon: ${pair.male.num}`);
} else {
console.log(`Failed to confirm Male Pokémon: ${pair.male.num}, skipping this pair.`);
continue; // Skip this pair if confirmation not found
}

await sleep(5000); // Natural delay before adding the female Pokémon

// Step 2: Add Female Pokémon
await activeChannel.send(`<@716390085896962058> daycare add ${pair.female.num}`);
await sleep(3000); // Wait before checking messages

confirmationMessage = await collectMessage(); // Wait again for up to 5 attempts

if (confirmationMessage && confirmationMessage.content.includes("Are you sure you want to add")) {
await clickYesButton(confirmationMessage);
console.log(`Confirmed Female Pokémon: ${pair.female.num}`);
} else {
console.log(`Failed to confirm Female Pokémon: ${pair.female.num}, skipping this pair.`);
continue;
}

console.log(`Pair successfully added to daycare! (Male: ${pair.male.num}, Female: ${pair.female.num})`);
await sleep(5000);
break;
}

} catch (err) {
console.error("Error in daycare process:", err);
}
} else if (
config.logging.LogCatches &&
message.content.includes(
"Congratulations <@" + client.user.id + ">! You caught"
Expand Down
Loading