// ==UserScript==
// @name DuoFarmer
// @namespace https://duo-farmer.vercel.app
// @version 0.4
// @description [ LITE ] DuoFarmer is a tool that helps you earn XP in Duolingo at blazing speed.
// @description:vi [ LITE ] DuoFarmer là một công cụ giúp bạn hack XP trong Duolingo với tốc độ cực nhanh.
// @description:fr [ LITE ] DuoFarmer est un outil qui vous aide à gagner de l'XP sur Duolingo à une vitesse fulgurante.
// @description:es [ LITE ] DuoFarmer es una herramienta que te ayuda a ganar XP en Duolingo a una velocidad asombrosa.
// @description:de [ LITE ] DuoFarmer ist ein Tool, das Ihnen hilft, in Duolingo blitzschnell XP zu verdienen.
// @description:it [ LITE ] DuoFarmer è uno strumento che ti aiuta a guadagnare XP su Duolingo a una velocità incredibile.
// @description:ja [ LITE ] DuoFarmer は、Duolingo で驚異的なスピードで XP を獲得するのに役立つツールです。
// @description:ko [ LITE ] DuoFarmer는 Duolingo에서 엄청난 속도로 XP를 얻을 수 있도록 도와주는 도구입니다.
// @description:ru [ LITE ] DuoFarmer - это инструмент, который помогает вам зарабатывать XP в Duolingo с невероятной скоростью.
// @description:zh-CN [ LITE ] DuoFarmer 是一款可帮助您以惊人的速度在 Duolingo 中赚取 XP 的工具。
// @author Lamduck
// @match https://*.duolingo.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=duolingo.com
// @grant none
// @license none
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
const sessionUrl = "https://www.duolingo.com/2017-06-30/sessions";
let isFarming = false, isVisible = true;
const getJwtToken = () => document.cookie.split(';').find(c => c.trim().startsWith('jwt_token='))?.split('=')[1] || null;
const decodeJwtToken = token => JSON.parse(atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')));
const formatHeaders = jwtToken => ({ "Content-Type": "application/json", "Authorization": `Bearer ${jwtToken}`, "User-Agent": navigator.userAgent });
const getUserInfo = async (sub, headers) => (await fetch(`https://www.duolingo.com/2017-06-30/users/${sub}?fields=username,fromLanguage,learningLanguage`, { headers })).json();
const farmXp = async (headers, sessionPayload, updateSessionPayload) => {
while (isFarming) {
try {
const session = await (await fetch(sessionUrl, { method: 'POST', headers, body: JSON.stringify(sessionPayload) })).json();
const updatedSession = await (await fetch(`${sessionUrl}/${session.id}`, { method: 'PUT', headers, body: JSON.stringify({ ...session, ...updateSessionPayload }) })).json();
document.getElementById("_xpAmount").innerText = parseInt(document.getElementById("_xpAmount").innerText) + updatedSession.xpGain;
} catch (error) {
alert("An error occurred while farming XP. Please try again!");
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
};
const initDuoFarmer = async () => {
const containerHTML = `
DuoFarmer Lite
This is a minimalist version that does not include advanced functions, join the Telegram for more information.
DuoFarmer Lite
Join the Telegram Group for support!
You should not farm too much to avoid being banned!