mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-24 00:36:16 -04:00
Added a cyber helper
This commit is contained in:
parent
a5703cb4f1
commit
ef4b977bef
47 changed files with 326 additions and 74 deletions
|
@ -4,6 +4,8 @@
|
|||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import clippy from "clippyjs";
|
||||
|
||||
/**
|
||||
* Waiter to handle seasonal events and easter eggs.
|
||||
*/
|
||||
|
@ -18,6 +20,8 @@ class SeasonalWaiter {
|
|||
constructor(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
this.clippyAgent = null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,6 +32,13 @@ class SeasonalWaiter {
|
|||
// Konami code
|
||||
this.kkeys = [];
|
||||
window.addEventListener("keydown", this.konamiCodeListener.bind(this));
|
||||
|
||||
// Clippy
|
||||
const now = new Date();
|
||||
//if (now.getMonth() === 3 && now.getDate() === 1) {
|
||||
if (now.getMonth() === 2 && now.getDate() === 22) {
|
||||
this.setupClippy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +62,126 @@ class SeasonalWaiter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up Clippy on April Fools Day
|
||||
*/
|
||||
setupClippy() {
|
||||
//const clippyAssets = "./agents/";
|
||||
const clippyAssets = undefined;
|
||||
|
||||
const self = this;
|
||||
clippy.load("Clippy", (agent) => {
|
||||
window.agent = agent;
|
||||
shimClippy(agent);
|
||||
self.clippyAgent = agent;
|
||||
|
||||
agent.show();
|
||||
//agent.animate();
|
||||
agent.speak("Hello, I'm Clippy, your personal cyber assistant!", true);
|
||||
}, undefined, clippyAssets);
|
||||
|
||||
// Watch for the Auto Magic button appearing
|
||||
const magic = document.getElementById("magic");
|
||||
const observer = new MutationObserver((mutationsList, observer) => {
|
||||
let msg, recipe;
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.attributeName === "data-original-title") {
|
||||
msg = magic.getAttribute("data-original-title");
|
||||
}
|
||||
if (mutation.attributeName === "data-recipe") {
|
||||
recipe = magic.getAttribute("data-recipe");
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel current animation and hide balloon (after it has finished)
|
||||
self.clippyAgent._queue.clear();
|
||||
self.clippyAgent._queue.next();
|
||||
self.clippyAgent.stopCurrent();
|
||||
self.clippyAgent._balloon._hold = false;
|
||||
self.clippyAgent._balloon.hide();
|
||||
|
||||
if (recipe) {
|
||||
recipe = this.manager.controls.generateStateUrl(true, true, JSON.parse(recipe));
|
||||
msg = `That looks like encoded data!<br><br>${msg}<br><br>Click <a href="${recipe}">here</a> to load this recipe.`;
|
||||
|
||||
// Stop balloon activity immediately and trigger speak again
|
||||
self.clippyAgent._balloon.pause();
|
||||
delete self.clippyAgent._balloon._addWord;
|
||||
self.clippyAgent._balloon._active = false;
|
||||
self.clippyAgent._balloon.hide(true);
|
||||
self.clippyAgent.speak(msg, true);
|
||||
}
|
||||
});
|
||||
observer.observe(document.getElementById("magic"), {
|
||||
attributes: true
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shims various ClippyJS functions to modify behaviour.
|
||||
*
|
||||
* @param {Agent} agent - The Clippy Agent
|
||||
*/
|
||||
function shimClippy(agent) {
|
||||
// Turn off all sounds
|
||||
agent._animator._playSound = () => {};
|
||||
|
||||
// Improve speak function
|
||||
const self = agent._balloon;
|
||||
agent._balloon.speak = (complete, text, hold) => {
|
||||
self._hidden = false;
|
||||
self.show();
|
||||
const c = self._content;
|
||||
// set height to auto
|
||||
c.height("auto");
|
||||
c.width("auto");
|
||||
// add the text
|
||||
c.html(text);
|
||||
// set height
|
||||
c.height(c.height());
|
||||
c.width(c.width());
|
||||
c.text("");
|
||||
self.reposition();
|
||||
|
||||
self._complete = complete;
|
||||
self._sayWords(text, hold, complete);
|
||||
};
|
||||
|
||||
// Improve the _sayWords function to allow HTML
|
||||
agent._balloon.WORD_SPEAK_TIME = 100;
|
||||
agent._balloon._sayWords = (text, hold, complete) => {
|
||||
self._active = true;
|
||||
self._hold = hold;
|
||||
const words = text.split(/[^\S-]/);
|
||||
const time = self.WORD_SPEAK_TIME;
|
||||
const el = self._content;
|
||||
let idx = 1;
|
||||
|
||||
self._addWord = $.proxy(function () {
|
||||
if (!self._active) return;
|
||||
if (idx > words.length) {
|
||||
delete self._addWord;
|
||||
self._active = false;
|
||||
if (!self._hold) {
|
||||
complete();
|
||||
self.hide();
|
||||
}
|
||||
} else {
|
||||
el.html(words.slice(0, idx).join(" "));
|
||||
idx++;
|
||||
self._loop = window.setTimeout($.proxy(self._addWord, self), time);
|
||||
}
|
||||
}, self);
|
||||
|
||||
self._addWord();
|
||||
};
|
||||
|
||||
// Close the balloon on click
|
||||
agent._balloon._balloon.click(e => {
|
||||
agent._balloon._finishHideBalloon();
|
||||
});
|
||||
}
|
||||
|
||||
export default SeasonalWaiter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue