diff --git a/config.js b/config.js index d72af6a..0d233a5 100644 --- a/config.js +++ b/config.js @@ -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 @@ -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: { @@ -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 @@ -47,4 +54,4 @@ const config = { }; // Export the configuration object -module.exports = config; \ No newline at end of file +module.exports = config; diff --git a/src/events/catching.js b/src/events/catching.js index d7c3c72..786409a 100644 --- a/src/events/catching.js +++ b/src/events/catching.js @@ -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."); + + const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + + // 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; + + 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) + + // 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" diff --git a/src/events/misc.js b/src/events/misc.js index fdbb532..ec15d2e 100644 --- a/src/events/misc.js +++ b/src/events/misc.js @@ -90,164 +90,185 @@ module.exports = async (client, guildId, message) => { // Handling captcha detection if ( - message.content.includes( - `https://verify.poketwo.net/captcha/${client.user.id}` - ) - ) { - if (getWaiting(client.user.username) == true) return; - setWaiting(client.user.username, true); // Setting the bot to a waiting state - sendLog(client.user.username, "Detected captcha.", "captcha"); // Logging captcha detection - // Sending a webhook and a direct message to the owner about the captcha - sendWebhook(null, { - title: `Captcha Found!`, - color: "#FF5600", - url: `https://verify.poketwo.net/captcha/${client.user.id}`, - footer: { - text: "CatchTwo by @kyan0045", - icon_url: - "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", + message.content.includes( + `https://verify.poketwo.net/captcha/${client.user.id}` + ) +) { + /*const clickYesButton = async (msg) => { + let buttonId = 0; // Default button ID + let rowId = 0; + + 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 }); + } else { + console.log("Yes button not found."); + } + };*/ + + if (getWaiting(client.user.username)) return; + setWaiting(client.user.username, true); + + sendLog(client.user.username, "Detected captcha.", "captcha"); + + sendWebhook(null, { + title: `Captcha Found!`, + color: "#FF5600", + url: `https://verify.poketwo.net/captcha/${client.user.id}`, + footer: { + text: "CatchTwo by @kyan0045", + icon_url: + "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", + }, + }); + + config.ownership.OwnerIDs.forEach((id) => { + if (id?.length && id.length <= 16) return; + client.users.fetch(id).then(async (user) => { + dmChannel = await client.channels + .fetch(user.dmChannel?.id) + .catch(() => null); + if (!dmChannel) dmChannel = await user.createDM(); + lastMessage = await dmChannel.messages.fetch(dmChannel.lastMessageId); + + if ( + lastMessage?.content?.includes("captcha") && + lastMessage?.author?.id == client.user.id && + lastMessage?.createdTimestamp > Date.now() - 86400000 + ) { + return; + } else { + return user + .send( + `## DETECTED A CAPTCHA\n> I've detected a captcha. The autocatcher has been paused. To continue, please solve the captcha below.\n* https://verify.poketwo.net/captcha/${client.user.id}\n\n### SOLVED?\n> Once solved, run the command \`\`${config.ownership.CommandPrefix}solved\`\` to continue catching.` + ) + .catch((error) => { + sendLog( + client.user.username, + `Error sending message to ${user.username}: ${error}`, + "error" + ); + }); + } + }); + }); + + /** STOPPING BOT & RELEASING POKEMON */ + if (config.logging.autoStop) { + console.log("AutoStop enabled: Releasing Pokémon..."); + await message.channel.send("<@716390085896962058> inc p all -y"); + + /*let confirmationMessage = await collectMessage(); + if (confirmationMessage) { + await clickYesButton(confirmationMessage); + console.log("Confirmed Release."); + }*/ + + sendWebhook(null, { + title: `AutoStop Triggered!`, + color: "#FF0000", + description: "The bot has been paused and Pokémon were released.", + footer: { + text: "CatchTwo by @kyan0045", + icon_url: + "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", + }, + }); + + setWaiting(client.user.username, false); + return; + } + + if (config.captchaSolving.key) { + let globalTaskId; + + axios + .post( + "https://api.catchtwo.online/solve-captcha", + { + token: client.token, + userId: client.user.id, }, + { + headers: { + "api-key": `${config.captchaSolving.key}`, + }, + } + ) + .then((response) => { + globalTaskId = response.data.requestId; + console.log("Task ID:", globalTaskId); }); - // Notifying all owners about the captcha - config.ownership.OwnerIDs.forEach((id) => { - if (id?.length && id.length <= 16) return; // Skipping invalid IDs - client.users.fetch(id).then(async (user) => { - let dmChannel = await client.channels - .fetch(user.dmChannel?.id) - .catch(() => null); - if (!dmChannel) { - dmChannel = await user.createDM(); - } - let lastMessage = await dmChannel.messages.fetch( - dmChannel.lastMessageId - ); - // Checking if the last message already informed about a captcha within the last 24 hours - if ( - lastMessage?.content?.includes("captcha") && - lastMessage?.author?.id == client.user.id && - lastMessage?.createdTimestamp > Date.now() - 86400000 - ) { - return; // Skipping if a recent captcha message was already sent - } else { - return user - .send( - `## DETECTED A CAPTCHA\n> I've detected a captcha. The autocatcher has been paused. To continue, please solve the captcha below.\n* https://verify.poketwo.net/captcha/${client.user.id}\n\n### SOLVED?\n> Once solved, run the command \`\`${config.ownership.CommandPrefix}solved\`\` to continue catching.` - ) - .catch((error) => { - sendLog( - client.user.username, - `Error sending message to ${user.username}: ${error}`, - "error" - ); - }); - } - }); - }); + sendLog(client.user.username, "Sent captcha to the solver.", "captcha"); - if (config.captchaSolving.key) { - // Declare a global variable for taskid - let globalTaskId; + setTimeout(async () => { + let retries = 5; + let success = false; - axios - .post( - "https://api.catchtwo.online/solve-captcha", - { - token: client.token, - userId: client.user.id, - }, + while (retries > 0 && !success) { + try { + const response = await axios.get( + `https://api.catchtwo.online/check-result/${globalTaskId}`, { headers: { "api-key": `${config.captchaSolving.key}`, }, } - ) - .then((response) => { - // Assign the taskid from the response to the global variable - globalTaskId = response.data.requestId; - console.log("Task ID:", globalTaskId); - sendLog( - client.user.username, - "Solver Task ID: " + globalTaskId, - "debug" - ); - }); + ); - sendLog(client.user.username, "Sent captcha to the solver.", "captcha"); - setTimeout(async () => { - let retries = 9; - let success = false; + if (response.data.status == "completed") { + setWaiting(client.user.username, false); + sendLog(client.user.username, "Successfully solved the captcha!", "captcha"); + sendWebhook(await getMentions(), { + title: `Captcha Solved!`, + color: "#00FF00", + footer: { + text: "CatchTwo by @kyan0045", + icon_url: + "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", + }, + }); - while (retries > 0 && !success) { - try { - const response = await axios.get( - `https://api.catchtwo.online/check-result/${globalTaskId}`, - { - headers: { - "api-key": `${config.captchaSolving.key}`, - }, - } - ); - - if (response.data.status == "completed") { - setWaiting(client.user.username, false); - sendLog( - client.user.username, - "Successfully solved the captcha!", - "captcha" - ); - sendWebhook(await getMentions(), { - title: `Captcha Solved!`, - color: "#00FF00", - footer: { - text: "CatchTwo by @kyan0045", - icon_url: - "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", - }, - }); - success = true; - } else if (response.data.status == "pending") { - sendLog( - client.user.username, - "Captcha solve pending.", - "debug" - ); - } else { - sendLog( - client.user.username, - "Captcha solving failed.", - "captcha" - ); - console.log( - `Please report this to @kyan0045,`, - response, - response.data - ); - sendWebhook(await getMentions(), { - title: `Solve with ${globalTaskId} failed!`, - color: "#FF0000", - footer: { - text: "CatchTwo by @kyan0045", - icon_url: - "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", - }, - }); - } - } catch (error) { - console.error("Error checking captcha result:", error); - } + /** RESTARTING BOT AFTER SOLVE */ + console.log("Restarting Pokémon catching..."); + await message.channel.send("<@716390085896962058> inc r all -y"); - if (!success) { - retries--; - if (retries > 0) { - await new Promise((resolve) => setTimeout(resolve, 5000)); - } - } + /*let restartConfirmation = await collectMessage(); + if (restartConfirmation) { + await clickYesButton(restartConfirmation); + console.log("Confirmed Restart."); + }*/ + + success = true; + } else if (response.data.status == "pending") { + sendLog(client.user.username, "Captcha solve pending.", "debug"); + } else { + sendLog(client.user.username, "Captcha solving failed.", "captcha"); + sendWebhook(await getMentions(), { + title: `Solve with ${globalTaskId} failed!`, + color: "#FF0000", + footer: { + text: "CatchTwo by @kyan0045", + icon_url: + "https://res.cloudinary.com/dppthk8lt/image/upload/v1719331169/catchtwo_bjvlqi.png", + }, + }); } - }, 15000); + } catch (error) { + console.error("Error checking captcha result:", error); + } + + if (!success) { + retries--; + if (retries > 0) { + await new Promise((resolve) => setTimeout(resolve, 5000)); + } + } } - } + }, 15000); } +} // Handling quest completion if (message.content.includes(`You have completed`)) {