Add anti-abuse debounce and throttle functions (#233)

This commit is contained in:
sergystepanov 2020-10-01 21:16:28 +03:00 committed by GitHub
parent 3c756eb548
commit 564b96df8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 13 deletions

7
web/game.html vendored
View file

@ -115,6 +115,7 @@
<script src="/static/js/gui/gui.js?v=1"></script>
<script src="/static/js/log.js?v=5"></script>
<script src="/static/js/utils.js?v1"></script>
<script src="/static/js/event/event.js?v=5"></script>
<script src="/static/js/input/keys.js?v=3"></script>
<script src="/static/js/settings/opts.js?v=1"></script>
@ -124,13 +125,13 @@
<script src="/static/js/gameList.js?v=3"></script>
<script src="/static/js/room.js?v=3"></script>
<script src="/static/js/stats/stats.js?v=1"></script>
<script src="/static/js/network/ajax.js?v=3"></script>
<script src="/static/js/network/socket.js?v=4"></script>
<script src="/static/js/network/rtcp.js?v=3"></script>
<script src="/static/js/controller.js?v=5"></script>
<script src="/static/js/input/keyboard.js?v=5"></script>
<script src="/static/js/input/touch.js?v=3"></script>
<script src="/static/js/input/joystick.js?v=3"></script>
<script src="/static/js/network/ajax.js?v=3"></script>
<script src="/static/js/network/socket.js?v=4"></script>
<script src="/static/js/network/rtcp.js?v=3"></script>
<script src="/static/js/init.js?v=5"></script>

20
web/js/controller.js vendored
View file

@ -175,11 +175,11 @@
input.poll().enable();
};
// !to add debounce
const popup = (msg) => {
popupBox.html(msg);
popupBox.fadeIn().delay(0).fadeOut();
};
const saveGame = utils.debounce(socket.saveGame, 1000);
const loadGame = utils.debounce(socket.loadGame, 1000);
const _popup = (message) => popupBox.html(message).fadeIn().fadeOut();
const popup = utils.throttle(_popup, 1000);
const _dpadArrowKeys = [KEY.UP, KEY.DOWN, KEY.LEFT, KEY.RIGHT];
@ -329,10 +329,10 @@
popup('You are already in menu screen!');
break;
case KEY.LOAD:
popup('Lets play to load game!');
popup('Loading the game.');
break;
case KEY.SAVE:
popup('Lets play to save game!');
popup('Saving the game.');
break;
case KEY.STATS:
event.pub(STATS_TOGGLE);
@ -366,10 +366,10 @@
popup('Copy link to clipboard!');
break;
case KEY.SAVE:
socket.saveGame();
saveGame();
break;
case KEY.LOAD:
socket.loadGame();
loadGame();
break;
case KEY.FULL:
env.display().toggleFullscreen(gameScreen.height() !== window.innerHeight, gameScreen[0]);
@ -464,4 +464,4 @@
// initial app state
setState(app.state.eden);
})($, document, event, env, gameList, input, KEY, log, room, settings, stats);
})($, document, event, env, gameList, input, KEY, log, room, settings, socket, stats, utils);

58
web/js/utils.js vendored Normal file
View file

@ -0,0 +1,58 @@
/**
* Utility module.
* @version 1
*/
const utils = (() => {
return {
/**
* A decorator that passes the call to function at maximum once per specified milliseconds.
* @param f The function to call.
* @param ms The amount of time in milliseconds to ignore the function calls.
* @returns {Function}
* @example
* const showMessage = () => { alert('00001'); }
* const showOnlyOnceASecond = debounce(showMessage, 1000);
*/
debounce: (f, ms) => {
let wait = false;
return function () {
if (wait) return;
f.apply(this, arguments);
wait = true;
setTimeout(() => wait = false, ms);
};
},
/**
* A decorator that blocks and calls the last function until the specified amount of milliseconds.
* @param f The function to call.
* @param ms The amount of time in milliseconds to ignore the function calls.
* @returns {Function}
*/
throttle: (f, ms) => {
let lastCall;
let lastTime;
return function () {
// could be a stack
const lastContext = this;
const lastArguments = arguments;
if (!lastTime) {
f.apply(lastContext, lastArguments);
lastTime = Date.now()
} else {
clearTimeout(lastCall);
lastCall = setTimeout(() => {
if (Date.now() - lastTime >= ms) {
f.apply(lastContext, lastArguments);
lastTime = Date.now()
}
}, ms - (Date.now() - lastTime))
}
}
}
}
})();