Page 1 of 1

[RELEASE] Impossible POT Challenge

Posted: Mon Apr 06, 2020 11:29 pm
by kHaos86
Hi.

Here's the link : https://milovana.com/webteases/showtease.php?id=45102

I thought it was time for a new POT challenge. :lol:
This thread is for comments, suggestions and bug reports.
Please leave your feedback and suggestions.

Re: [RELEASE] Impossible POT Challenge

Posted: Tue Apr 07, 2020 1:25 pm
by Takenaga
Thanks for your effort! I love POT (but it's a bit hard to do by yourself) and I will give your tease a try as soon as possible.

Re: [RELEASE] Impossible POT Challenge

Posted: Fri Apr 10, 2020 6:25 pm
by Dawn_of_Dark
I think it's a really well done tease, specifically the text.

However, I do think it's too long, even for an "impossible" challenge. Each scene drags on too long, especially since each picture mostly contains only a sentence or two. Maybe only 5 seconds each picture is enough imo.

The overall length of the tease is also admittedly impossibly long. I had the tease runs by itself while looking at other teases/porn and switch back and forth (which is I usually do), and I got to the "end" after like, an hour and a half, or something like that.

I think your idea was good and again, the text was splendid, but the length of the whole thing will make most of your hard work go unread with most of the users here.

Re: [RELEASE] Impossible POT Challenge

Posted: Sun Apr 19, 2020 10:40 am
by kHaos86
Thanks for your feedback

yeah, maybe it's pretty hard to complete the challenge on the first trys :look:
The tease contains 10 picsets and the rules change for the last 3 sets. In the tease, the pages change after 30 seconds.
In the beginning I thought about splitting it in two parts, but that would worsen the experience.

I have a couple of other ideas I want to implement in teases.
But I think I will create a shorter and simpler version of the tease. :smile:

Re: [RELEASE] Impossible POT Challenge

Posted: Sun Apr 19, 2020 12:30 pm
by Khalsissy
Mistype in the very beginning:
1. You must do full and thigt strokes.

Re: [RELEASE] Impossible POT Challenge

Posted: Thu May 27, 2021 7:24 am
by Achatius
It was a Totm... worthy for remastered. is khaos86 still active?

Re: [RELEASE] Impossible POT Challenge

Posted: Sat Dec 04, 2021 3:50 pm
by Ghingis
The thing is it is not so easy to continue after a while, this might help if you have a handy..

* Install the script (google for "tempermonkey" or "greasemonkey" you will find it how)
* Open the tease on oeos.art

How it works in a sentence:
It watches the html dom and if a new sound gets added / removed, it checks the filename if it has *bpm / *bps / *ps in the filename it sets the handy via api, so it would reach that speed / stops it.
(it might work with other teases if the audio filename matches..)

If it bothers you that the handy stops when the page changes, there is a comment in the code: remove the next 3 lines
Just remove them.

Note: you can use the buttons on the handy to stop / move the stoke zone, but it will be changed in the next page.

Code: Select all

// ==UserScript==
// @name         EOS
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://oeos.art/?id=*
// @icon         https://www.google.com/s2/favicons?domain=oeos.art
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const maxStrokeSpeed = 400;
    const maxStrokeLength = 190;
    const apiKey = 'YOUR_HANDY_API_KEY'; // api key
    const api = "https://www.handyfeeling.com/api/handy/v2";
    let lastSpeed = 0;

    const sendRequest = (url, data, verb, onResponse) => {

        let myHeaders = new Headers();
        if (verb.trim().toLowerCase() !== 'option'){
            myHeaders.append('X-Connection-Key', apiKey);
            myHeaders.append('Content-Type', 'application/json');
            myHeaders.append('Accept', 'application/json');
        }

        const options = {
            method: verb,
            headers: myHeaders,
            mode: 'cors',
        }

        if (data) {
            options.body = JSON.stringify(data);
        }

        console.log(url, 'request: ', options);

        fetch(url, options)
            .then(function(response) {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json().then((r)=>{
                console.log('response: ', r);
                onResponse(r);
            });
        })
    }

    sendRequest(api + "/mode", {mode: 0}, 'PUT',(request) => {
        sendRequest(api + "/slide", {min: 0, max: maxStrokeLength}, 'PUT',(request) => {
            sendRequest(api + "/hamp/velocity", {velocity: 20}, 'PUT',()=>{
                console.log('handy set');
            });
        });
    });

    /**
     * Calculates the stroke speed and distance from the specified beats per second.
     *
     * Lookup Table
     * ====================
     * Speed / Stroke = BPS
     * 400 / 80  = 5
     * 400 / 100 = 4
     * 400 / 133 = 3
     * 400 / 200 = 2
     * 300 / 200 = 1.5
     * 200 / 200 = 1
     * 100 / 200 = 0.5
     * 50  / 200 = 0.25
     */
    function getStrokeSpeedAndDistance(bps, maxSpeed = 400, maxLength = 200) {
        maxSpeed = Math.min(maxStrokeSpeed, maxSpeed);
        maxLength = Math.min(maxStrokeLength, maxLength);
        let speed = maxSpeed;
        let length = maxLength;
        const fastestBPS = maxSpeed / maxLength;

        // Decrease stroke speed to increase BPS
        if (bps < fastestBPS) {
            speed = maxLength * bps;
        }

        // Shorten stroke distance to increase BPS
        if (bps > fastestBPS) {
            length = maxSpeed / bps;
        }

        return {
            speed,
            stroke: length,
        };
    }

    function changeSpeed(newState) {
        sendRequest(api + "/hamp/state", null, 'GET',(response)=>{
            console.log('state',response);
            if (response.state !== 2){
                sendRequest(api + "/hamp/start", null, 'PUT',(response)=>{
                    console.log('start')
                    sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                        console.log(request.speed)
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                    });
                });
            } else {
                if (lastSpeed !== newState.speed){
                    if (lastSpeed > newState.speed){
                        sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                        });
                    } else {
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>console.log(request.speed));
                        });
                    }
                }
            }

            lastSpeed = newState.speed;
        });
    }

    const mainWrapperCallback = (records, ob) => {
        records.forEach((record)=>{
            if (record.target.id === 'oeos-sounds'){
                const data = record.target.querySelector('data');
                if (data){
                    const match = data.value.match(/([1-9].+)bpm/);
                    if (match){
                        const bpm = parseInt(match[1],10);
                        console.log('bpm',bpm);
                        const newState = getStrokeSpeedAndDistance(bpm/60);
                        changeSpeed(newState);
                    } else {
                        const bpsMatch = data.value.match(/([1-9].+)bps/);
                        if (bpsMatch){
                            const bps = parseInt(bpsMatch[1],10);
                            const newState = getStrokeSpeedAndDistance(bps);
                            changeSpeed(newState);
                        } else {
                            const bpsMatch = data.value.match(/([1-9].+)ps/);
                            if (bpsMatch){
                                const bps = parseInt(bpsMatch[1],10);
                                const newState = getStrokeSpeedAndDistance(bps);
                                changeSpeed(newState);
                            }
                        }
                    }
                } else {
                    // remove the next 3 lines
                    sendRequest(api + "/hamp/stop", null, 'PUT',(response)=>{
                        console.log('stop', response);
                    });
                }
            }
        });
    };

    const mainWrapper = document.querySelector('.v-main__wrap');
    // Create an observer instance linked to the callback function
    const wrapperObserver = new MutationObserver(mainWrapperCallback);

    // Start observing the target node for configured mutations
    wrapperObserver.observe(mainWrapper, { attributes: false, childList: true, subtree: true });
})();

Re: [RELEASE] Impossible POT Challenge

Posted: Sun Dec 19, 2021 11:17 am
by Achatius
Ghingis wrote: Sat Dec 04, 2021 3:50 pm The thing is it is not so easy to continue after a while, this might help if you have a handy..

* Install the script (google for "tempermonkey" or "greasemonkey" you will find it how)
* Open the tease on oeos.art

How it works in a sentence:
It watches the html dom and if a new sound gets added / removed, it checks the filename if it has *bpm / *bps / *ps in the filename it sets the handy via api, so it would reach that speed / stops it.
(it might work with other teases if the audio filename matches..)

If it bothers you that the handy stops when the page changes, there is a comment in the code: remove the next 3 lines
Just remove them.

Note: you can use the buttons on the handy to stop / move the stoke zone, but it will be changed in the next page.

Code: Select all

// ==UserScript==
// @name         EOS
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://oeos.art/?id=*
// @icon         https://www.google.com/s2/favicons?domain=oeos.art
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const maxStrokeSpeed = 400;
    const maxStrokeLength = 190;
    const apiKey = 'YOUR_HANDY_API_KEY'; // api key
    const api = "https://www.handyfeeling.com/api/handy/v2";
    let lastSpeed = 0;

    const sendRequest = (url, data, verb, onResponse) => {

        let myHeaders = new Headers();
        if (verb.trim().toLowerCase() !== 'option'){
            myHeaders.append('X-Connection-Key', apiKey);
            myHeaders.append('Content-Type', 'application/json');
            myHeaders.append('Accept', 'application/json');
        }

        const options = {
            method: verb,
            headers: myHeaders,
            mode: 'cors',
        }

        if (data) {
            options.body = JSON.stringify(data);
        }

        console.log(url, 'request: ', options);

        fetch(url, options)
            .then(function(response) {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json().then((r)=>{
                console.log('response: ', r);
                onResponse(r);
            });
        })
    }

    sendRequest(api + "/mode", {mode: 0}, 'PUT',(request) => {
        sendRequest(api + "/slide", {min: 0, max: maxStrokeLength}, 'PUT',(request) => {
            sendRequest(api + "/hamp/velocity", {velocity: 20}, 'PUT',()=>{
                console.log('handy set');
            });
        });
    });

    /**
     * Calculates the stroke speed and distance from the specified beats per second.
     *
     * Lookup Table
     * ====================
     * Speed / Stroke = BPS
     * 400 / 80  = 5
     * 400 / 100 = 4
     * 400 / 133 = 3
     * 400 / 200 = 2
     * 300 / 200 = 1.5
     * 200 / 200 = 1
     * 100 / 200 = 0.5
     * 50  / 200 = 0.25
     */
    function getStrokeSpeedAndDistance(bps, maxSpeed = 400, maxLength = 200) {
        maxSpeed = Math.min(maxStrokeSpeed, maxSpeed);
        maxLength = Math.min(maxStrokeLength, maxLength);
        let speed = maxSpeed;
        let length = maxLength;
        const fastestBPS = maxSpeed / maxLength;

        // Decrease stroke speed to increase BPS
        if (bps < fastestBPS) {
            speed = maxLength * bps;
        }

        // Shorten stroke distance to increase BPS
        if (bps > fastestBPS) {
            length = maxSpeed / bps;
        }

        return {
            speed,
            stroke: length,
        };
    }

    function changeSpeed(newState) {
        sendRequest(api + "/hamp/state", null, 'GET',(response)=>{
            console.log('state',response);
            if (response.state !== 2){
                sendRequest(api + "/hamp/start", null, 'PUT',(response)=>{
                    console.log('start')
                    sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                        console.log(request.speed)
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                    });
                });
            } else {
                if (lastSpeed !== newState.speed){
                    if (lastSpeed > newState.speed){
                        sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                        });
                    } else {
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>console.log(request.speed));
                        });
                    }
                }
            }

            lastSpeed = newState.speed;
        });
    }

    const mainWrapperCallback = (records, ob) => {
        records.forEach((record)=>{
            if (record.target.id === 'oeos-sounds'){
                const data = record.target.querySelector('data');
                if (data){
                    const match = data.value.match(/([1-9].+)bpm/);
                    if (match){
                        const bpm = parseInt(match[1],10);
                        console.log('bpm',bpm);
                        const newState = getStrokeSpeedAndDistance(bpm/60);
                        changeSpeed(newState);
                    } else {
                        const bpsMatch = data.value.match(/([1-9].+)bps/);
                        if (bpsMatch){
                            const bps = parseInt(bpsMatch[1],10);
                            const newState = getStrokeSpeedAndDistance(bps);
                            changeSpeed(newState);
                        } else {
                            const bpsMatch = data.value.match(/([1-9].+)ps/);
                            if (bpsMatch){
                                const bps = parseInt(bpsMatch[1],10);
                                const newState = getStrokeSpeedAndDistance(bps);
                                changeSpeed(newState);
                            }
                        }
                    }
                } else {
                    // remove the next 3 lines
                    sendRequest(api + "/hamp/stop", null, 'PUT',(response)=>{
                        console.log('stop', response);
                    });
                }
            }
        });
    };

    const mainWrapper = document.querySelector('.v-main__wrap');
    // Create an observer instance linked to the callback function
    const wrapperObserver = new MutationObserver(mainWrapperCallback);

    // Start observing the target node for configured mutations
    wrapperObserver.observe(mainWrapper, { attributes: false, childList: true, subtree: true });
})();
Thx a lot! Are you able to edit it?

Re: [RELEASE] Impossible POT Challenge

Posted: Mon Dec 20, 2021 12:07 am
by Ghingis
Achatius wrote: Sun Dec 19, 2021 11:17 am
Ghingis wrote: Sat Dec 04, 2021 3:50 pm The thing is it is not so easy to continue after a while, this might help if you have a handy..

* Install the script (google for "tempermonkey" or "greasemonkey" you will find it how)
* Open the tease on oeos.art

How it works in a sentence:
It watches the html dom and if a new sound gets added / removed, it checks the filename if it has *bpm / *bps / *ps in the filename it sets the handy via api, so it would reach that speed / stops it.
(it might work with other teases if the audio filename matches..)

If it bothers you that the handy stops when the page changes, there is a comment in the code: remove the next 3 lines
Just remove them.

Note: you can use the buttons on the handy to stop / move the stoke zone, but it will be changed in the next page.

Code: Select all

// ==UserScript==
// @name         EOS
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://oeos.art/?id=*
// @icon         https://www.google.com/s2/favicons?domain=oeos.art
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const maxStrokeSpeed = 400;
    const maxStrokeLength = 190;
    const apiKey = 'YOUR_HANDY_API_KEY'; // api key
    const api = "https://www.handyfeeling.com/api/handy/v2";
    let lastSpeed = 0;

    const sendRequest = (url, data, verb, onResponse) => {

        let myHeaders = new Headers();
        if (verb.trim().toLowerCase() !== 'option'){
            myHeaders.append('X-Connection-Key', apiKey);
            myHeaders.append('Content-Type', 'application/json');
            myHeaders.append('Accept', 'application/json');
        }

        const options = {
            method: verb,
            headers: myHeaders,
            mode: 'cors',
        }

        if (data) {
            options.body = JSON.stringify(data);
        }

        console.log(url, 'request: ', options);

        fetch(url, options)
            .then(function(response) {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json().then((r)=>{
                console.log('response: ', r);
                onResponse(r);
            });
        })
    }

    sendRequest(api + "/mode", {mode: 0}, 'PUT',(request) => {
        sendRequest(api + "/slide", {min: 0, max: maxStrokeLength}, 'PUT',(request) => {
            sendRequest(api + "/hamp/velocity", {velocity: 20}, 'PUT',()=>{
                console.log('handy set');
            });
        });
    });

    /**
     * Calculates the stroke speed and distance from the specified beats per second.
     *
     * Lookup Table
     * ====================
     * Speed / Stroke = BPS
     * 400 / 80  = 5
     * 400 / 100 = 4
     * 400 / 133 = 3
     * 400 / 200 = 2
     * 300 / 200 = 1.5
     * 200 / 200 = 1
     * 100 / 200 = 0.5
     * 50  / 200 = 0.25
     */
    function getStrokeSpeedAndDistance(bps, maxSpeed = 400, maxLength = 200) {
        maxSpeed = Math.min(maxStrokeSpeed, maxSpeed);
        maxLength = Math.min(maxStrokeLength, maxLength);
        let speed = maxSpeed;
        let length = maxLength;
        const fastestBPS = maxSpeed / maxLength;

        // Decrease stroke speed to increase BPS
        if (bps < fastestBPS) {
            speed = maxLength * bps;
        }

        // Shorten stroke distance to increase BPS
        if (bps > fastestBPS) {
            length = maxSpeed / bps;
        }

        return {
            speed,
            stroke: length,
        };
    }

    function changeSpeed(newState) {
        sendRequest(api + "/hamp/state", null, 'GET',(response)=>{
            console.log('state',response);
            if (response.state !== 2){
                sendRequest(api + "/hamp/start", null, 'PUT',(response)=>{
                    console.log('start')
                    sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                        console.log(request.speed)
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                    });
                });
            } else {
                if (lastSpeed !== newState.speed){
                    if (lastSpeed > newState.speed){
                        sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                        });
                    } else {
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>console.log(request.speed));
                        });
                    }
                }
            }

            lastSpeed = newState.speed;
        });
    }

    const mainWrapperCallback = (records, ob) => {
        records.forEach((record)=>{
            if (record.target.id === 'oeos-sounds'){
                const data = record.target.querySelector('data');
                if (data){
                    const match = data.value.match(/([1-9].+)bpm/);
                    if (match){
                        const bpm = parseInt(match[1],10);
                        console.log('bpm',bpm);
                        const newState = getStrokeSpeedAndDistance(bpm/60);
                        changeSpeed(newState);
                    } else {
                        const bpsMatch = data.value.match(/([1-9].+)bps/);
                        if (bpsMatch){
                            const bps = parseInt(bpsMatch[1],10);
                            const newState = getStrokeSpeedAndDistance(bps);
                            changeSpeed(newState);
                        } else {
                            const bpsMatch = data.value.match(/([1-9].+)ps/);
                            if (bpsMatch){
                                const bps = parseInt(bpsMatch[1],10);
                                const newState = getStrokeSpeedAndDistance(bps);
                                changeSpeed(newState);
                            }
                        }
                    }
                } else {
                    // remove the next 3 lines
                    sendRequest(api + "/hamp/stop", null, 'PUT',(response)=>{
                        console.log('stop', response);
                    });
                }
            }
        });
    };

    const mainWrapper = document.querySelector('.v-main__wrap');
    // Create an observer instance linked to the callback function
    const wrapperObserver = new MutationObserver(mainWrapperCallback);

    // Start observing the target node for configured mutations
    wrapperObserver.observe(mainWrapper, { attributes: false, childList: true, subtree: true });
})();
Thx a lot! Are you able to edit it?
You are welcome, I'm not sure what do you want to edit on this, but anyone could do it.
But I can change things, if you have recommendations.

Re: [RELEASE] Impossible POT Challenge

Posted: Sat Jan 08, 2022 8:30 am
by Achatius
Ghingis wrote: Mon Dec 20, 2021 12:07 am
Achatius wrote: Sun Dec 19, 2021 11:17 am
Ghingis wrote: Sat Dec 04, 2021 3:50 pm The thing is it is not so easy to continue after a while, this might help if you have a handy..

* Install the script (google for "tempermonkey" or "greasemonkey" you will find it how)
* Open the tease on oeos.art

How it works in a sentence:
It watches the html dom and if a new sound gets added / removed, it checks the filename if it has *bpm / *bps / *ps in the filename it sets the handy via api, so it would reach that speed / stops it.
(it might work with other teases if the audio filename matches..)

If it bothers you that the handy stops when the page changes, there is a comment in the code: remove the next 3 lines
Just remove them.

Note: you can use the buttons on the handy to stop / move the stoke zone, but it will be changed in the next page.

Code: Select all

// ==UserScript==
// @name         EOS
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://oeos.art/?id=*
// @icon         https://www.google.com/s2/favicons?domain=oeos.art
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const maxStrokeSpeed = 400;
    const maxStrokeLength = 190;
    const apiKey = 'YOUR_HANDY_API_KEY'; // api key
    const api = "https://www.handyfeeling.com/api/handy/v2";
    let lastSpeed = 0;

    const sendRequest = (url, data, verb, onResponse) => {

        let myHeaders = new Headers();
        if (verb.trim().toLowerCase() !== 'option'){
            myHeaders.append('X-Connection-Key', apiKey);
            myHeaders.append('Content-Type', 'application/json');
            myHeaders.append('Accept', 'application/json');
        }

        const options = {
            method: verb,
            headers: myHeaders,
            mode: 'cors',
        }

        if (data) {
            options.body = JSON.stringify(data);
        }

        console.log(url, 'request: ', options);

        fetch(url, options)
            .then(function(response) {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json().then((r)=>{
                console.log('response: ', r);
                onResponse(r);
            });
        })
    }

    sendRequest(api + "/mode", {mode: 0}, 'PUT',(request) => {
        sendRequest(api + "/slide", {min: 0, max: maxStrokeLength}, 'PUT',(request) => {
            sendRequest(api + "/hamp/velocity", {velocity: 20}, 'PUT',()=>{
                console.log('handy set');
            });
        });
    });

    /**
     * Calculates the stroke speed and distance from the specified beats per second.
     *
     * Lookup Table
     * ====================
     * Speed / Stroke = BPS
     * 400 / 80  = 5
     * 400 / 100 = 4
     * 400 / 133 = 3
     * 400 / 200 = 2
     * 300 / 200 = 1.5
     * 200 / 200 = 1
     * 100 / 200 = 0.5
     * 50  / 200 = 0.25
     */
    function getStrokeSpeedAndDistance(bps, maxSpeed = 400, maxLength = 200) {
        maxSpeed = Math.min(maxStrokeSpeed, maxSpeed);
        maxLength = Math.min(maxStrokeLength, maxLength);
        let speed = maxSpeed;
        let length = maxLength;
        const fastestBPS = maxSpeed / maxLength;

        // Decrease stroke speed to increase BPS
        if (bps < fastestBPS) {
            speed = maxLength * bps;
        }

        // Shorten stroke distance to increase BPS
        if (bps > fastestBPS) {
            length = maxSpeed / bps;
        }

        return {
            speed,
            stroke: length,
        };
    }

    function changeSpeed(newState) {
        sendRequest(api + "/hamp/state", null, 'GET',(response)=>{
            console.log('state',response);
            if (response.state !== 2){
                sendRequest(api + "/hamp/start", null, 'PUT',(response)=>{
                    console.log('start')
                    sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                        console.log(request.speed)
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                    });
                });
            } else {
                if (lastSpeed !== newState.speed){
                    if (lastSpeed > newState.speed){
                        sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>console.log(request.speed));
                        });
                    } else {
                        sendRequest(api + "/slide", {min: 0, max: newState.stroke/2}, 'PUT',(request)=>{
                            console.log(request.speed)
                            sendRequest(api + "/hamp/velocity", {velocity: newState.speed / 4}, 'PUT',(request)=>console.log(request.speed));
                        });
                    }
                }
            }

            lastSpeed = newState.speed;
        });
    }

    const mainWrapperCallback = (records, ob) => {
        records.forEach((record)=>{
            if (record.target.id === 'oeos-sounds'){
                const data = record.target.querySelector('data');
                if (data){
                    const match = data.value.match(/([1-9].+)bpm/);
                    if (match){
                        const bpm = parseInt(match[1],10);
                        console.log('bpm',bpm);
                        const newState = getStrokeSpeedAndDistance(bpm/60);
                        changeSpeed(newState);
                    } else {
                        const bpsMatch = data.value.match(/([1-9].+)bps/);
                        if (bpsMatch){
                            const bps = parseInt(bpsMatch[1],10);
                            const newState = getStrokeSpeedAndDistance(bps);
                            changeSpeed(newState);
                        } else {
                            const bpsMatch = data.value.match(/([1-9].+)ps/);
                            if (bpsMatch){
                                const bps = parseInt(bpsMatch[1],10);
                                const newState = getStrokeSpeedAndDistance(bps);
                                changeSpeed(newState);
                            }
                        }
                    }
                } else {
                    // remove the next 3 lines
                    sendRequest(api + "/hamp/stop", null, 'PUT',(response)=>{
                        console.log('stop', response);
                    });
                }
            }
        });
    };

    const mainWrapper = document.querySelector('.v-main__wrap');
    // Create an observer instance linked to the callback function
    const wrapperObserver = new MutationObserver(mainWrapperCallback);

    // Start observing the target node for configured mutations
    wrapperObserver.observe(mainWrapper, { attributes: false, childList: true, subtree: true });
})();
Thx a lot! Are you able to edit it?
You are welcome, I'm not sure what do you want to edit on this, but anyone could do it.
But I can change things, if you have recommendations.
Would be great to shorten the tease. Every image is too long / there is a lack of input. It's just like fapping 30 seconds for a single sentence. And the first "hour" in a slow rhythm. A 10 Minute "impossible POT-Challenge" is good enough, where you have to have your orgasm at least at minute 7 or 8.

Re: [RELEASE] Impossible POT Challenge

Posted: Sat Jan 08, 2022 5:21 pm
by Ghingis
Achatius wrote: Sat Jan 08, 2022 8:30 am Would be great to shorten the tease. Every image is too long / there is a lack of input. It's just like fapping 30 seconds for a single sentence. And the first "hour" in a slow rhythm. A 10 Minute "impossible POT-Challenge" is good enough, where you have to have your orgasm at least at minute 7 or 8.
You really missed something, I'm not the one who made the tease. I just made a script, that controls your handy to the speed of the beat.. So no I can not shorten the tease.