florr.io | Petal farming progress counter

Petal farming progress counter

目前為 2023-12-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name         florr.io | Petal farming progress counter
// @namespace    Furaken
// @version      1.1.0.1
// @description  Petal farming progress counter
// @author       Furaken
// @match        https://florr.io/*
// @grant        unsafeWindow
// @grant        GM_addStyle
// @license      MIT
// @require      https://unpkg.com/[email protected]/umd/string-similarity.min.js
// ==/UserScript==

var obj =
    {
        rarity: 0,
        id: 1,
        aim: 5,
        basicId: 942239,
        find: {
            petal: "Basic",
            value: [5, 0, 0, 0, 0, 0, 0, 0]
        },
        config: {
            top: false,
            left: false,
            x: "-20px",
            y: "-20px",
            scale: 1,
            key: "Equal"
        },
        version: "1.1"
    },
    petal = "Common Basic",
    rarityArr = [
        "Common",
        "Unusual",
        "Rare",
        "Epic",
        "Legendary",
        "Mythic",
        "Ultra",
        "Super"
    ],
    petalArr = [
        "Basic",
        "Light",
        "Rock",
        "Square",
        "Rose",
        "Stinger",
        "Iris",
        "Wing",
        "Missile",
        "Grapes",
        "Cactus",
        "Faster",
        "Bubble",
        "Pollen",
        "Dandelion",
        "Beetle Egg",
        "Antennae",
        "Heavy",
        "Yin Yang",
        "Web",
        "Honey",
        "Leaf",
        "Salt",
        "Rice",
        "Corn",
        "Sand",
        "Pincer",
        "Yucca",
        "Magnet",
        "Yggdrasil",
        "Starfish",
        "Pearl",
        "Lightning",
        "Jelly",
        "Claw",
        "Shell",
        "Cutter",
        "Dahlia",
        "Uranium",
        "Sponge",
        "Soil",
        "Fangs",
        "Third Eye",
        "Peas",
        "Stick",
        "Clover",
        "Powder",
        "Air",
        "Basil",
        "Orange",
        "Ant Egg",
        "Poo",
        "Relic",
        "Lotus",
        "Bulb",
        "Cotton",
        "Carrot",
        "Bone",
        "Plank",
        "Tomato",
        "Mark",
        "Rubber",
        "Blood Stinger",
        "Bur",
        "Root",
        "Ankh",
        "Dice",
        "Talisman",
        "Battery"
    ]

function getNewPetal() {
    if (petal.split(" ").length <= 0) return
    if (petal.split(" ").length == 1) {
        if (petal.startsWith("un")) obj.rarity = "Unusual"
        else if (petal.startsWith("r")) obj.rarity = "Rare"
        else if (petal.startsWith("e")) obj.rarity = "Epic"
        else if (petal.startsWith("l")) obj.rarity = "Legendary"
        else if (petal.startsWith("m")) obj.rarity = "Mythic"
        else if (petal.startsWith("u")) obj.rarity = "Ultra"
        else if (petal.startsWith("s")) obj.rarity = "Super"
        else obj.rarity = "Common"
        obj.id = stringSimilarity.findBestMatch(petal.slice(1), petalArr)
        petal = obj.rarity + " " + obj.id.bestMatch.target
        obj.rarity = rarityArr.indexOf(obj.rarity)
    } else {
        obj.rarity = stringSimilarity.findBestMatch(petal.split(" ").shift(), rarityArr)
        obj.id = stringSimilarity.findBestMatch(petal.split(" ").splice(1).join(" "), petalArr)
        petal = obj.rarity.bestMatch.target + " " + obj.id.bestMatch.target
        obj.rarity = obj.rarity.bestMatchIndex
    }
    obj.id = obj.id.bestMatchIndex + 1
}
getNewPetal()

function findSequence(seq, mem) {
    let match = 0
    for (let addr = 0; addr < mem.length; addr++) {
        if (mem[addr] === seq[match]) match++
        else if (mem[addr] === seq[0]) match = 1
        else match = 0
        if (match === seq.length) return addr - match + 1
    }
}

if (localStorage.getItem('petalFarmingCounter') == null) {
    localStorage.setItem('petalFarmingCounter', JSON.stringify(obj))
    setTimeout(() => {
        toggleCon()
    }, 5000)
}
else {
    var thisObj = JSON.parse(localStorage.getItem('petalFarmingCounter'))
    if (thisObj.version != obj.version) {
        setTimeout(() => {
            toggleCon()
        }, 5000)
    }
    Object.keys(obj).forEach(k => {
        if (!Object.keys(thisObj).includes(k)) thisObj[k] = obj[k]
    })
    obj = thisObj
    localStorage.setItem('petalFarmingCounter', JSON.stringify(thisObj))
}
var container = document.createElement("div")
container.id = "container"
container.style = `
    padding: 5px;
    height: 24px;
    width: 350px;
    position: absolute;
    transform: translate(${obj.config.x}, ${obj.config.y}) scale(${obj.config.scale});
    background: #333333;
    border-radius: 24px;
    transition: all 1s ease-in-out;
    opacity: 1;
    box-shadow: 5px 5px rgba(0, 0, 0, 0.3);
    pointer-events: all;
    cursor: pointer;
    overflow: hidden;
`
container.onclick = function() {
    toggleCon()
}

function toggleCon() {
    if (conCon.style.overflow == "hidden") {
        container.style.height = "150px"
        container.style.width = "400px"
        conCon.style.overflow = "hidden scroll"
        container.style.borderRadius = "5px"
        barProgress.style.maxHeight = "150px"
        barProgress.style.maxWidth = "400px"
        barProgress.style.height = "150px"
        barProgress.style.width = "400px"
        barProgress.style.borderRadius = "0px"
        barProgress.style.opacity = 0
        barProgress.style.background = "#1FDBDE"
        barProgress.style.pointerEvents = "none"
        barText.style.opacity = 0
        settings.style.pointerEvents = "all"
        settings.style.opacity = 1
        changelog.style.pointerEvents = "all"
        changelog.style.opacity = 1
    } else {
        container.style.height = "24px"
        container.style.width = "350px"
        conCon.style.overflow = "hidden"
        container.style.borderRadius = "24px"
        barProgress.style.maxHeight = "24px"
        barProgress.style.maxWidth = "350px"
        barProgress.style.height = "24px"
        barProgress.style.width = "350px"
        barProgress.style.borderRadius = "24px"
        barProgress.style.opacity = 1
        barProgress.style.background = "#F5FF65"
        barProgress.style.pointerEvents = "all"
        barText.style.opacity = 1
        settings.style.pointerEvents = "none"
        settings.style.opacity = 0
        changelog.style.pointerEvents = "none"
        changelog.style.opacity = 0
        updateProgress()
    }
}
document.querySelector('body').appendChild(container)

var conCon = document.createElement("div")
conCon.style = `
    overflow: hidden;
    height: 150px;
`
container.appendChild(conCon)

containerPos()

petal = rarityArr[obj.rarity] + " " + petalArr[obj.id - 1]
getNewPetal()
function convertNumber(value) {
    return Math.abs(Number(value)) >= 1.0e+9
        ? (Math.abs(Number(value)) / 1.0e+9).toFixed(2) + "B"
    : Math.abs(Number(value)) >= 1.0e+6
        ? (Math.abs(Number(value)) / 1.0e+6).toFixed(2) + "M"
    : Math.abs(Number(value)) >= 1.0e+3
        ? (Math.abs(Number(value)) / 1.0e+3).toFixed(2) + "K"
    : Math.abs(Number(value))
}

function containerPos() {
    if (obj.config.top) {
        container.style.top = "0"
        container.style.bottom = "unset"
    } else {
        container.style.top = "unset"
        container.style.bottom = "0"
    }

    if (obj.config.left) {
        container.style.left = "0"
        container.style.right = "unset"
    } else {
        container.style.left = "unset"
        container.style.right = "0"
    }

    container.style.transform = `translate(${obj.config.x}, ${obj.config.y}) scale(${obj.config.scale})`
}

function coloringBool(bool) {
    if (bool) return `<a style="color: #2BFFA3">${bool}</a>`
    else return `<a style="color: #DB5A5A">${bool}</a>`
}

function coloringValue(value) {
    return `<a style="color: #DBD74B">${value}</a>`
}

obj.aim = Math.abs(Math.floor(obj.aim))
obj.aim = obj.aim == 0 ? 1 : obj.aim

var settings = document.createElement("div")
settings.style = `
    padding: 10px;
    color: white;
    font-family: 'Ubuntu';
    z-index: 1;
    font-size: 12px;
    line-height: 15px;
    opacity: 0;
    transition: all 1s ease-in-out;
    pointer-events: none;
    text-shadow: rgb(0 0 0) 2px 0px 0px, rgb(0 0 0) 1.75517px 0.958851px 0px, rgb(0 0 0) 1.0806px 1.68294px 0px, rgb(0 0 0) 0.141474px 1.99499px 0px, rgb(0 0 0) -0.832294px 1.81859px 0px, rgb(0 0 0) -1.60229px 1.19694px 0px, rgb(0 0 0) -1.97998px 0.28224px 0px, rgb(0 0 0) -1.87291px -0.701566px 0px, rgb(0 0 0) -1.30729px -1.5136px 0px, rgb(0 0 0) -0.421592px -1.95506px 0px, rgb(0 0 0) 0.567324px -1.91785px 0px, rgb(0 0 0) 1.41734px -1.41108px 0px, rgb(0 0 0) 1.92034px -0.558831px 0px;
`
conCon.appendChild(settings)

var settings_transform = document.createElement("div")
settings_transform.innerHTML = `
    <div style="font-size: 18px; margin-bottom: 10px; text-align: center;">Settings</div>
    <div id="sProgress" style="font-size: 15px; margin-top: 5px; margin-bottom: 5px;">Progress Counter</div>
    <div id="kProgress" style="margin-left: 10px; height: 0px; opacity: 0; pointer-events: none;">
        <div id="Cpetal">Petal: ${coloringValue(petal)}</div>
        <div id="Caim">Aim: ${coloringValue(obj.aim)}</div>
    </div>
    <div id="sTransform" style="font-size: 15px; margin-top: 5px; margin-bottom: 5px;">Transform & Hotkeys</div>
    <div id="kTransform" style="margin-left: 10px; height: 0px; opacity: 0; pointer-events: none;">
        <div id="Ctop">top: ${coloringBool(obj.config.top)}</div>
        <div id="Cleft">left: ${coloringBool(obj.config.left)}</div>
        <div id="CposX">x: ${coloringValue(obj.config.x)}</div>
        <div id="CposY">y: ${coloringValue(obj.config.y)}</div>
        <div id="Cscale">scale: ${coloringValue(obj.config.scale)}</div>
        <div id="CkeyToggle">key: ${coloringValue(obj.config.key)}</div>
    </div>
    <div id="sFindId" style="font-size: 15px; margin-top: 5px; margin-bottom: 5px;">Find & Apply Basic ID</div>
    <div id="kFindId" style="margin-left: 10px; height: 0px; opacity: 0; pointer-events: none;">
        <div style="color: #1FDBDE;" id="Cfind">Find & Apply</div>
        <div id="Capply">Basic ID: ${coloringValue(obj.basicId)}</div>
    </div>
`
settings.appendChild(settings_transform);

["sProgress", "sTransform", "sFindId"].forEach(x => {
    document.getElementById(x).onclick = function(e) {
        e.stopPropagation()
        var kTransform = document.getElementById("k"+ this.id.slice(1))
        if (kTransform.style.opacity != 1) {
            kTransform.style.opacity = 1
            kTransform.style.height = "auto"
            kTransform.style.pointerEvents = "all"
        } else {
            kTransform.style.opacity = 0
            kTransform.style.height = "0px"
            kTransform.style.pointerEvents = "none"
        }
    };
});

["Cpetal", "Caim", "Ctop", "Cleft", "CposX", "CposY", "Cscale", "CkeyToggle", "Cfind", "Capply"].forEach(x => {
    document.getElementById(x).onclick = function(e) {
        e.stopPropagation()
        var value = "",
            value2 = []
        if (["Cpetal", "Caim"].includes(this.id)) {
            if (["Cpetal"].includes(this.id)) {
                value = prompt('Petal name?', petal)
                if (petal == null) return
                petal = value
                getNewPetal()
                this.innerHTML = `Petal: ${coloringValue(petal)}`
                barText.innerHTML = `${petal}: ${convertNumber(thisPetal)} / ${convertNumber(obj.aim)} (${(thisPetal * 100 / obj.aim).toFixed(2)}%)`
            } else if (["Caim"].includes(this.id)) {
                value = prompt('Aim?', obj.aim)
                if (value == null) return
                if (isNaN(value)) return
                obj.aim = Number(value)
                obj.aim = Math.abs(Math.floor(obj.aim))
                obj.aim = obj.aim == 0 ? 1 : obj.aim
                this.innerHTML = `Aim: ${coloringValue(obj.aim)}`
            }
        } else if (["Ctop", "Cleft", "CposX", "CposY", "Cscale", "CkeyToggle"].includes(this.id)) {
            if (["Ctop", "Cleft"].includes(this.id)) {
                value = !obj.config[x.slice(1)]
                this.innerHTML = `${x.slice(1)}: ${coloringBool(value)}`
                obj.config[x.slice(1)] = value
            } else if (["CposX", "CposY"].includes(this.id)) {
                value = prompt(x.slice(1), obj.config[x[x.length - 1].toLowerCase()].slice(0, -2))
                if (value == null) return
                if (isNaN(value)) return
                value = Number(value)
                this.innerHTML = `${x[x.length - 1].toLowerCase()}: ${coloringValue(value + "px")}`
                obj.config[x[x.length - 1].toLowerCase()] = value + "px"
            } else if (["Cscale"].includes(this.id)) {
                value = prompt(x.slice(1), obj.config[x.slice(1)])
                if (value == null) return
                if (isNaN(value)) return
                value = Number(value)
                if (value == 0) return
                this.innerHTML = `${x.slice(1)}: ${coloringValue(value)}`
                obj.config[x.slice(1)] = value
            } else if (["CkeyToggle"].includes(this.id)) {
                var endTime = Date.now() + 5 * 1000
                this.innerHTML = `key: <a class="blink">Press a key!</a>`
                var keysPressed = []
                var keyInterval = setInterval(() => {
                    keysPressed.unshift(lastKey)
                    if (keysPressed.length > 2) keysPressed.splice(2)
                    if (keysPressed[keysPressed.length - 1] != keysPressed[0]) {
                        obj.config.key = keysPressed[0]
                        this.innerHTML = `key: ${coloringValue(keysPressed[0])}`
                        clearInterval(keyInterval)
                    }
                    if (Date.now() > endTime) {
                        this.innerHTML = `key: ${coloringValue(obj.config.key)}`
                        clearInterval(keyInterval)
                        return
                    }
                });
            }
            containerPos()
        } else if (["Cfind", "Capply"].includes(this.id)) {
            if (["Cfind"].includes(this.id)) {
                var thisPetalName = ""
                value = prompt("Petal?", obj.find.petal)
                value = stringSimilarity.findBestMatch(value, petalArr)
                thisPetalName = value.bestMatch.target
                value = value.bestMatchIndex + 1
                rarityArr.forEach((x, i) => {
                    var temporaryValue = prompt(`Amount of ${x} ${thisPetalName}`, obj.find.value[i])
                    if (temporaryValue == null) temporaryValue = 0
                    if (isNaN(temporaryValue)) temporaryValue = 0
                    value2.push(Number(temporaryValue))
                })
                obj.find.petal = thisPetalName
                obj.find.value = value2
                obj.basicId = findSequence(value2, unsafeWindow.Module.HEAPU32) - (value * 8) + 8
                document.getElementById("Capply").innerHTML = `Basic ID: ${coloringValue(obj.basicId)}`
            } else if (["Capply"].includes(this.id)) {
                value = prompt('Basic ID?', obj.basicId)
                if (value == null) return
                if (isNaN(value)) return
                obj.basicId = Number(value)
                this.innerHTML = `Basic ID: ${coloringValue(obj.basicId)}`
            }
        }
        localStorage.setItem('petalFarmingCounter', JSON.stringify(obj))
    }
})

var changelog = document.createElement("div")
changelog.style = `
    padding: 10px;
    color: white;
    font-family: 'Ubuntu';
    z-index: 1;
    font-size: 12px;
    line-height: 15px;
    opacity: 0;
    transition: all 1s ease-in-out;
    pointer-events: none;
    text-shadow: rgb(0 0 0) 2px 0px 0px, rgb(0 0 0) 1.75517px 0.958851px 0px, rgb(0 0 0) 1.0806px 1.68294px 0px, rgb(0 0 0) 0.141474px 1.99499px 0px, rgb(0 0 0) -0.832294px 1.81859px 0px, rgb(0 0 0) -1.60229px 1.19694px 0px, rgb(0 0 0) -1.97998px 0.28224px 0px, rgb(0 0 0) -1.87291px -0.701566px 0px, rgb(0 0 0) -1.30729px -1.5136px 0px, rgb(0 0 0) -0.421592px -1.95506px 0px, rgb(0 0 0) 0.567324px -1.91785px 0px, rgb(0 0 0) 1.41734px -1.41108px 0px, rgb(0 0 0) 1.92034px -0.558831px 0px;
`
changelog.innerHTML = `
    <div style="font-size: 18px; margin-bottom: 10px; text-align: center;">Changelog</div>
    <div style="color: #1FDBDE; font-size: 15px; margin-bottom: 5px">December 24th 2023 - v1.1</div>
    <div style="margin-left: 10px">
        - Added 3 new petals.<br>
        - Added a manual way to find Basic ID (Credit to Max Nest).<br>
        - The container is now moveable and scalable.<br>
        - Press = key to show/hide the container, this is also available in earlier versions. You can custom it in settings now.
    </div>
`
conCon.appendChild(changelog)

var barText = document.createElement("div")
barText.style = `
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    position: absolute;
    width: 100%;
    color: white;
    font-family: 'Ubuntu';
    text-align: center;
    transition: all 1s ease-in-out;
    text-wrap: nowrap;
    z-index: 1;
    pointer-events: none;
    font-size: 14px;
    text-shadow: rgb(0 0 0) 2px 0px 0px, rgb(0 0 0) 1.75517px 0.958851px 0px, rgb(0 0 0) 1.0806px 1.68294px 0px, rgb(0 0 0) 0.141474px 1.99499px 0px, rgb(0 0 0) -0.832294px 1.81859px 0px, rgb(0 0 0) -1.60229px 1.19694px 0px, rgb(0 0 0) -1.97998px 0.28224px 0px, rgb(0 0 0) -1.87291px -0.701566px 0px, rgb(0 0 0) -1.30729px -1.5136px 0px, rgb(0 0 0) -0.421592px -1.95506px 0px, rgb(0 0 0) 0.567324px -1.91785px 0px, rgb(0 0 0) 1.41734px -1.41108px 0px, rgb(0 0 0) 1.92034px -0.558831px 0px;
`
container.appendChild(barText)

var barProgress = document.createElement("div")
barProgress.style = `
    background: #F5FF65;
    border-radius: 24px;
    width: 0px;
    max-width: 350px;
    max-height: 24px;
    transition: all 1s ease-in-out;
    opacity: 0;
    height: 0px;
    top: 50%;
    position: absolute;
    transform: translate(0px, -50%);
`
container.appendChild(barProgress)
barText.innerHTML = `${petal}: 0 / ${convertNumber(obj.aim)} (0.00%)`

var thisPetal, thisWidth
function updateProgress() {
    thisPetal = unsafeWindow.Module.HEAPU32[obj.basicId + (obj.id * 8) - (8 - obj.rarity)]
    thisWidth = container.style.width.slice(0, -2) * thisPetal / obj.aim
    barProgress.style.height = thisWidth + "px"
    barProgress.style.width = thisWidth + "px"
    barProgress.style.opacity = thisPetal / (obj.aim * 0.08)
    barText.innerHTML = `${petal}: ${convertNumber(thisPetal)} / ${convertNumber(obj.aim)} (${(thisPetal * 100 / obj.aim).toFixed(2)}%)`
}

setInterval(() => {
    if (conCon.style.overflow != "hidden") return
    updateProgress()
}, 10000)

var lastKey
document.documentElement.addEventListener("keydown", function (e) {
    lastKey = e.code
    if (event.code == obj.config.key) {
        if (container.style.opacity == "0") {
            container.style.opacity = 1
            container.style.pointerEvents = "all"
            settings.style.pointerEvents = "all"
            changelog.style.pointerEvents = "all"
        } else {
            container.style.opacity = 0
            container.style.pointerEvents = "none"
            settings.style.pointerEvents = "none"
            changelog.style.pointerEvents = "none"
        }
    }
})

document.querySelector('canvas').onclick = function () {
    container.style.height = "24px"
    container.style.width = "350px"
    conCon.style.overflow = "hidden"
    container.style.borderRadius = "24px"
    barProgress.style.maxHeight = "24px"
    barProgress.style.maxWidth = "350px"
    barProgress.style.height = "24px"
    barProgress.style.width = "350px"
    barProgress.style.borderRadius = "24px"
    barProgress.style.opacity = 1
    barProgress.style.background = "#F5FF65"
    barProgress.style.pointerEvents = "all"
    barText.style.opacity = 1
    settings.style.pointerEvents = "none"
    settings.style.opacity = 0
    changelog.style.pointerEvents = "none"
    changelog.style.opacity = 0
    updateProgress()
}

GM_addStyle(`
@keyframes blink {
    0% {color: #DBD74B}
    50% {color: #1FDBDE}
    100% {color: #DBD74B}
}

.blink {
    animation-name: blink;
    animation-duration: 1.5s;
    animation-iteration-count: infinite;
}

::-webkit-scrollbar {
    width: 5px;
}
::-webkit-scrollbar-track {
    background: #00000000;
}
::-webkit-scrollbar-thumb {
    background: #444;
    border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
    background: #444;
}
`)

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址