I wrote a script to do some automated actions on a website (which is not mine).
That website is some kind of online shop for a pc game. The user selects an item and clicks a "withdraw" button. When the website is under heavy load (quite often), the user often gets a message saying "Heavy load - try again!" and has to click the same button again and again until he either gets the item or receives a message saying "The item was already sold!".
Everything is running inside a chrome extension!
My script does the following:
Add an onClick event to the button to run a function
Click "withdraw"
Read the message that comes from the website
Depends on the message:
"Offer is being sent..." - Do nothing and read again after interval
"Item was already sold!" - Stop the interval
"Heavy load - try again!" - Click an element to remove the message and "withdraw" again
The problem:
The interval is set to 2000ms, but the script just seems to be spamming the withdraw button nonstop and it seems to ignore the clearInterval().
My code:
function buy() {
//Get the innerHTML for the box that displays the message
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
//Message: Offer is being sent! - DO NOTHING!
if (message == "Please wait while your trade offer is being sent...") {
console.log("Loading: Going on!")
}
//Message: Item is gone! - STOP EVERYTHING!
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
clearInterval(buyInterval);
}
//Message: Transaction successfull! - STOP EVERYTHING
if (message.includes("Trade offer has been sent! Code: ")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message == "Heavy load! - Try again!") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click(); //Click to remove the message
document.getElementById("withdraw").click(); //Click withdraw again
}
}
function forceBuy() {
buyInterval = setInterval(function(){ buy() }, 2000);
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ forceBuy () };
Any help is appreciated!
Edit_1
Code right now:
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
if (message == "Please wait while your trade offer is being sent...<br><small>(this might take up to 5 minutes)</small>") {
console.log("Loading: Going on!")
}
if (message == "You cannot afford that withdrawal.") {
console.log("Broke: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message.includes("missing")) {
console.log("Missing: Stopping")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "You can have only one pending deposit or withdrawal.") {
console.log("Pending: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Too many active trades") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click();
document.getElementById("withdraw").click();
}
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
Thanks to Vitalii for this code - It seems to work better now since it's not constantly spamming the button anymore. Sadly, the other problem persists: If the script reaches for example this part of the code:
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
It successfully reads the message and prints out "Success: Stopping!" - once every two seconds ... ongoing until i stop it from doing that by hand. It seems like clearInterval(buyInterval); is still being ignored.
What am I doing wrong here?
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
... buying action
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
rewrite your forceBuy function like this -
function forceBuy() {
if(buyInterval) clearInterval(buyInterval);
buyInterval = setInterval(function(){ buy() }, 2000);
}
Related
After I verify the password reset code via Firebase, I have placed a setTimeout() function to wait five seconds for the page to load. Without it, I get an error saying that it can't find 'userEmail' even though I have a function that waits for the page to load at the top of my script. I have placed several console logs and it stops at "started the wait", the line right before the setTimeout() function starts. The email <h1> that I have in place never updates as it's supposed to after the setTimeout function waits the 5 seconds to execute the code within it.
function handleResetPassword(code) {
auth.verifyPasswordResetCode(code).then(function (email) {
console.log("Code verified");
var accountEmail = email;
window.location.replace("/email/new-password.html");
console.log("started the wait");
setTimeout(() => {
console.log("finished waiting");
userEmail.innerText += accountEmail;
console.log("set email");
submitNewPasswordBtn.addEventListener('click', function (e) {
console.log("submit btn clicked");
e.preventDefault();
var newPassword = newPaswordInput.value;
var confNewPasword = confNewPaswordInput.value;
if (newPassword != confNewPasword) {
alert("The new passwords must match!");
return;
}
auth.confirmPasswordReset(code, newPassword).then(function (resp) {
console.log("password updated");
auth.signInWithEmailAndPassword(accountEmail, newPassword).then(function () {
alert("Password reset successfully and you have been signed in.");
});
}).catch(function (error) {
console.error("error confirming the password");
console.error(error);
});
});
}, 5000);
}).catch(function (error) {
console.log("we have an error");
console.error(error);
window.location.replace('/email/errors/pswd-resetcode-invalid.html');
});
}
I expected the email <h1> to be filled with the user's email and a when they click the submit button, there to be an alert saying the password was reset successfully but the page just doesn't do anything and the console outputs stop at "started the wait." I've waited about 30 seconds and still, there is no output.
It is because of this line.
window.location.replace("/email/new-password.html");
The setTimeout function starts a timer thread in the browser, but before that timer is initialised, the browser replaces the current resource with the one at the provided URL.
After using replace(), the current page will not be saved in session history, as well as it clears the timer thread, which doesn't trigger the code inside setTimeout.
I'm using navigator.geolocation.watchPosition function to check if the browser's location is on or not. But this function is getting called more than once (without page load). For example if i switch to another tab and go back to the page's tab it gets called.
My code is
<script>
navigator.geolocation.watchPosition(function (position) {
alert("i'm tracking you!");
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
}
});
</script>
How can i call that function only once?
Just keep track of whether the watchPosition function has fired your function or not:
var firedAlready = false;
navigator.geolocation.watchPosition(function (position) {
if(!firedAlready) {
alert("i'm tracking you!");
firedAlready = true;
}
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
}
});
Try to create an enclosure for your code! This will make sure it's only performed once.
var something = (function() {
var executed = false;
return function () {
if (!executed) {
executed = true;
// do something
}
};
})();
Also consider disabling the event handler with navigator.geolocation.clearWatch().
E.g.:
var id;
id = navigator.geolocation.watchPosition(function (position) {
alert("i'm tracking you!");
navigator.geolocation.clearWatch(id);
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
// I suspect this is actually unnecessary since we were denied.
navigator.geolocation.clearWatch(id);
}
});
For more details check the MDN page about Geolocation.clearWatch().
You can clear position listener when you have already got the result.
enter link description here
Or you maybe use navigator.geolocation.getCurrentPostion to test whether is on or off.
You need to save the status of checking the permission in local storage for long duration use or better use cookies for that site and save the preferences there.
If you only do a variable when the page is reloaded the variable is reinitialized.
Your data need to be persistent.
Start from here if you are new with cookies
http://www.w3schools.com/js/js_cookies.asp
I am trying to determine when a user closes their connection. The problem is that, when I try to use this._session.socket.on("close",...) it also registers when the user refreshes.
Here is my code:
Meteor.publish("friends", function () {
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function()
{
// This logs when the user disconnects OR refreshes
console.log(id);
}, function(e){console.log(e)}))
return Meteor.users.find({...});
});
How do I differentiate between a refresh and a real disconnection?
EDIT: I would really like to avoid using a 'keep alive' function if possible.
Ok, this is a little bit hacky but I'm not sure if there is a better solution. This requires the mizzao:user-status package. The way I solved this problem is to call a meteor method inside the "on close" function that starts polling the database at 5 second intervals and checks if the user's status is online. After a set amount of time (I said 65 seconds), if the user has come online I know it was a refresh.
Anyway, the above is a little bit confusing, so here is the code:
//server
Meteor.publish("some_collection", function(){
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function(){
Meteor.call("connectionTest", id);
}, function(e){console.log(e)}));
return Meteor.users.find({..});
});
//Meteor method
Meteor.methods({
connectionTest: function(userId){
this.unblock();
var i = 0;
var stop = false;
var id = Meteor.setInterval(function(){
var online = Meteor.users.findOne(userId).status.online;
if(!online){
console.log("offline");
}
else{
stop = true;
console.log("still online");
}
i++;
if(stop || i > 12){
if(online){
//do something
}
else{
// do something else
}
Meteor.clearInterval(id);
}
}, 5000);
}
});
Ok, I have this function below that I am calling every 5 seconds..
function checkVerfToken(user_id) {
// Set file to get results from..
var loadUrl = "ajax_files/check_verf_token.php";
// Set parameters
var dataObject = { user_id: user_id };
// Run request
getAjaxData(loadUrl, dataObject, 'POST', 'html')
.done(function(response) {
if (response == 'success') {
// Reload the page
window.location.replace('payment_completed_verf.php');
}
})
.fail(function() {
alert('There seems to have been a problem with continuing the verification process; please contact us if this continues to occur.');
});
// End
}
I am calling it from a page every 5 seconds with:
<script type="text/javascript">
window.setInterval(function(){
checkVerfToken(<?=$user_id?>);
}, 5000);
</script>
However if fail is executed then it obviously keeps doing it every 5 seconds as it doesn't leave the page.
How can I get it to just show the alert once if there is a problem?
Keep a reference to the interval, and clear it when it fails.
verifyInterval = window.setInterval(function(){
checkVerfToken(<?=$user_id?>);
}, 5000);
.fail(function() {
clearInterval(verifyInterval);
alert('There seems to have been a problem with continuing the verification process; please contact us if this continues to occur.');
});
Not sure if this is the best way, but creating a dom element on the fly and checking for its existence will work, you can even check for its value and change them for any other action; so basically it acts as a flag and if required can be a conditional checker for other event firing:
.fail(function() {
// create a hidden element in dom to check for the alert event execution
if ($('#errorchecker').length === 0) {
$('body').append('<input type="hidden" id="errorchecker" value="executed" />');
alert('There seems to have been a problem with continuing the verification process; please contact us if this continues to occur.');
}
});
I have an app which invokes a WebService (callPathsToMultiTiffWS) which have two possibilities:
complete = true
complete = false
in the case complete = false I want to show a dialog which notifies to user than webService failed and two buttons:
retry action (reinvoke WS)
Exit
this is my code so far:
callPathsToMultiTiffWS(UID_KEY[9], stringCapturePaths, UID_KEY[1], UID_KEY[2], UID_KEY[3], UID_KEY[4], UID_KEY[5], UID_KEY[6]).then(
function (complete) {
if (complete == true) {//if true, it stores the id of the picture to delete
Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(function (complete) {window.close();});
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () { /*code for recall element*/ }));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { /*code for exit*/ }));
messageDialogPopup.showAsync();
_divInput.innerHTML = "";
}
},
function (error) { console.log("function error"); });
This works good so far, but I want the recall feature working
so I thought to embedd my code inside a loop like this
var ban = true;
while (true) {
callPathsToMultiTiffWS(UID_KEY[9], stringCapturePaths, UID_KEY[1], UID_KEY[2], UID_KEY[3], UID_KEY[4], UID_KEY[5], UID_KEY[6]).then(
function (complete) {
if (complete == true) {//if true, it stores the id of the picture to delete
Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(function (complete) { window.close(); });
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () { ban == true; }));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { ban == false; }));
messageDialogPopup.showAsync().then(function (complete) {
console.log("no ps no");
});
}
},
function (error) { console.log("function error"); });
if (ban == false) break;
}
this loop executes the webService, but it doesn't wait for user interaction to trigger the webservice by touching one of the buttons, it is an endless loop with calls to my webService, how to fix this??
thanks in advance for the support
If I'm not missing something, it looks like the error is caused because your code isn't designed to run the next set of tasks after the asynchronous call to showAsync returns. Because the call to showAsync is non-blocking, the while loop will start over again and make another call to the Web service. And because THAT call (callPathsToMultiTiffWS) is also non-blocking, the loop will start over again, triggering another call to callPathsToMultiTiffWS. And over again, and again.
My recommendation is to break out the next call to the Web service so that it will only be triggered when the user makes a selection. If you separate your concerns (move the calls to the Web service into different function or module than the UI that informs the user of an issue), then you can probably fix this.
Kraig BrockSchmidt has a great blog post about the finer details of Promises:
http://blogs.msdn.com/b/windowsappdev/archive/2013/06/11/all-about-promises-for-windows-store-apps-written-in-javascript.aspx
-edit-
Here's some code that I wrote to try to demonstrate how you might accomplish what you're trying:
function tryWebServiceCall(/* args */) {
var url = "some Web service URL";
return new WinJS.xhr({ url: url }).then(
function (complete) {
if (complete) {
return new Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(
function () { /*do something */ });
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () {
return tryWebServiceCall( /* args */);
}));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { return; }));
return messageDialogPopup.showAsync();
}
});
}