├── assets ├── icon.png ├── screen.png ├── screen1.png └── screen2.png ├── timeScript.js ├── pageScript.js ├── manifest.json ├── popup.html ├── popup.js ├── README.md ├── content.js └── styles.css /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skhyr/anihilator/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skhyr/anihilator/HEAD/assets/screen.png -------------------------------------------------------------------------------- /assets/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skhyr/anihilator/HEAD/assets/screen1.png -------------------------------------------------------------------------------- /assets/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skhyr/anihilator/HEAD/assets/screen2.png -------------------------------------------------------------------------------- /timeScript.js: -------------------------------------------------------------------------------- 1 | setInterval(() => { 2 | startTime = new Date().getTime() 3 | },250); 4 | -------------------------------------------------------------------------------- /pageScript.js: -------------------------------------------------------------------------------- 1 | try{ 2 | 3 | var original = RegExp.prototype.test; 4 | RegExp.prototype.test = function (s) { 5 | if (this.toString().includes("native code") && this.toString().includes("function")) { 6 | //all is fine man just continue 7 | return true; 8 | } 9 | 10 | var r = original.call(this, s); 11 | return r; 12 | }; 13 | document.hasFocus = function () {return true;}; 14 | 15 | window.postMessage({action: 'GOT_DUCK', payload: true}, '*'); 16 | }catch(error){ 17 | window.postMessage({action: 'GOT_DUCK', payload: false}, '*'); 18 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anihilator", 3 | "version": "3.5", 4 | "manifest_version": 2, 5 | "content_scripts": [ 6 | { 7 | "matches": [ 8 | "*://*.testportal.pl/*", 9 | "*://*.testportal.net/*", 10 | "*://*.teams.microsoft.com/*" 11 | ], 12 | "js": ["content.js"] 13 | }], 14 | 15 | "web_accessible_resources": ["pageScript.js", "timeScript.js"], 16 | "browser_action":{ 17 | "default_title": "Testportal Anihilator", 18 | "default_popup": "popup.html" 19 | }, 20 | "permissions": [ 21 | "storage" 22 | ], 23 | "icons": { 24 | "128": "assets/icon.png" } 25 | } 26 | -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
testportalanihilator
10 | 11 | 15 | 16 |
Wyłącz limit czasu
17 | 18 | 22 | 23 |
24 | 25 | repo 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /popup.js: -------------------------------------------------------------------------------- 1 | var manifest = chrome.runtime.getManifest(); 2 | 3 | const setup = () =>{ 4 | chrome.storage.local.get('state', function({state}){ 5 | document.querySelector('#in').checked = state; 6 | }); 7 | 8 | chrome.storage.local.get('time', function({time}){ 9 | document.querySelector('#time').checked = time; 10 | }); 11 | 12 | fetch('https://raw.githubusercontent.com/skhyr/anihilator/chrome/manifest.json') 13 | .then(response => response.json()) 14 | .then(data => { 15 | if(data.version === manifest.version) document.querySelector('#update').innerText = '' 16 | else document.querySelector('#update').innerText = 'update available'; 17 | }); 18 | 19 | }; 20 | setup(); 21 | 22 | document.querySelector('#in').onclick = () =>{ 23 | const off = document.querySelector('#in').checked; 24 | chrome.storage.local.set({state: off}); 25 | }; 26 | 27 | document.querySelector('#time').onclick = () =>{ 28 | const time = document.querySelector('#time').checked; 29 | chrome.storage.local.set({time}); 30 | }; 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | stan na 04.03.2021: nadal działa 2 | 3 | # Testportal Anihilator 4 | Wtyczka przeglądarkowa pozwalająca ominąć funckję 'uczciwy rozwiązujący' na TestPortalu, która uniemożliwia dezaktywację karty sprawdzianu podczas jego trwania. Pozwala także ominąć limit czasu na test. 5 | 6 | ## Instalacja 7 | * Pobierz ZIP rozwijając opcję 'Clone or download' 8 | * Wejdź w opcje rozszerzeń swojej przeglądarki (ang. extensions) 9 | * Zezwól na tryb developera i dodaj rozszerzenie z pobranego wcześniej ZIPa rozpakowując go wcześniej (wybierz folder bezpośrednio zawierający pliki rozszerzenia) 10 | 11 | ## Używanie 12 | * Znajdź ikonę szpiega wśród aktywnych rozszerzeń 13 | 14 | ![screen](./assets/screen.png) 15 | 16 | * Upewnij się że zaznaczono aktywację (zielony suwak) 17 | * Gotowe! Podczas pomyślnego usunięcia blur-szpiega pojawi się na dole ekranu zielona wiadomość potwierdzająca 18 | 19 | ### Limit czasu 20 | Aby włączyć funkcję omijania limitu czasu wystarczy kliknąć drugi suwak. 21 | 22 | ![screen2](./assets/screen2.png) 23 | 24 | Dzięki temu, limit czasu na test zostaje wyłączony, a nauczyciel nie zostaje o tym powiadomiony. 25 | 26 | ## Aktualizacje 27 | Gdy dostępna będzie nowsza wersja wtyczki niż ta, która jest zainstalowana u Ciebie w przeglądarce, pojawi się opcja "update available". By być pewnym działania wtyczki należy wtedy pobrać najnowszą wersje z repozytorium. 28 | 29 | ![screen1](./assets/screen1.png) 30 | -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('message', function receiveDuck(event) { 2 | if(event.data.action === 'GOT_DUCK') { 3 | const div = document.createElement('div'); 4 | document.body.appendChild(div); 5 | 6 | if(event.data.payload){ 7 | div.innerText = "zanihilowano szpiega"; 8 | div.style.backgroundColor = "#6ade2c"; 9 | } 10 | else{ 11 | div.innerText = "szpieg niezanihilowany"; 12 | div.style.backgroundColor = "#de2c2c"; 13 | } 14 | 15 | div.style.position = "fixed"; 16 | div.style.bottom = "10%"; 17 | div.style.left = "50%"; 18 | div.style.transform = "translate(-50%)"; 19 | div.style.color = "white"; 20 | div.style.height = "2em"; 21 | div.style.width = "15em"; 22 | div.style.borderRadius = ".3em"; 23 | div.style.fontSize = "2em"; 24 | div.style.display = "flex"; 25 | div.style.alignItems = "center"; 26 | div.style.justifyContent = "center"; 27 | div.style.opacity = "0"; 28 | div.style.transition = "opacity .5s ease-in-out"; 29 | div.style.fontFamily = "Arial"; 30 | 31 | 32 | 33 | setTimeout(() => { 34 | div.style.opacity = "1"; 35 | }, 200); 36 | setTimeout(() => { 37 | div.style.opacity = "0"; 38 | }, 1500); 39 | } 40 | }, false); 41 | 42 | 43 | chrome.storage.local.get('state', function({state}){ 44 | console.log(state); 45 | if(state){ 46 | var s = document.createElement('script'); 47 | s.src = chrome.extension.getURL('pageScript.js'); 48 | (document.head || document.documentElement).appendChild(s); 49 | } 50 | }); 51 | 52 | chrome.storage.local.get('time', function({time}){ 53 | console.log(time); 54 | if(time){ 55 | var s = document.createElement('script'); 56 | s.src = chrome.extension.getURL('timeScript.js'); 57 | (document.head || document.documentElement).appendChild(s); 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | body{ 2 | height:12em; 3 | margin-top: 0; 4 | font-size: .7em; 5 | width: 20em; 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | background-color: rgb(54, 54, 54); 10 | --sliderColor: rgb(255, 255, 255); 11 | --sliderActiveColor: rgb(133, 228, 133); 12 | } 13 | #i{ 14 | color: white; 15 | } 16 | .h{ 17 | font-size: 2em; 18 | margin-top: .5em; 19 | margin-bottom: 1em; 20 | color: white; 21 | } 22 | 23 | .h .g{ 24 | color: rgb(133, 228, 133); 25 | } 26 | 27 | #update{ 28 | color: white; 29 | margin-right: auto; 30 | margin-left: auto; 31 | margin-top: .2em; 32 | } 33 | 34 | #timeheader{ 35 | margin-top: .6em; 36 | margin-bottom: .4em; 37 | color: white; 38 | font-size: 1.7em; 39 | } 40 | 41 | a{ 42 | margin-top: auto; 43 | font-size: 1.5em; 44 | color: white; 45 | text-decoration: none; 46 | border-bottom: .1em solid transparent; 47 | transition: border-bottom ease-in-out .5s; 48 | padding-bottom: .4em; 49 | } 50 | a:link { 51 | text-decoration: none; 52 | } 53 | a:visited { 54 | text-decoration: none; 55 | } 56 | a:hover { 57 | text-decoration: none; 58 | border-bottom: .1em solid white; 59 | } 60 | a:active { 61 | text-decoration: none; 62 | } 63 | 64 | .switch { 65 | font-size: .7em; 66 | position: relative; 67 | display: block; 68 | width: 6em; 69 | height: 3.4em; 70 | margin-bottom: 2em; 71 | } 72 | 73 | /*SLIDER STYLE*/ 74 | .switch input { 75 | opacity: 0; 76 | width: 0; 77 | height: 0; 78 | } 79 | .slider { 80 | position: absolute; 81 | cursor: pointer; 82 | top: 0; 83 | left: 0; 84 | right: 0; 85 | bottom: 0; 86 | background-color: var(--sliderColor); 87 | height: 3.4em; 88 | } 89 | .slider:before { 90 | position: absolute; 91 | content: ""; 92 | height: 2.6em; 93 | width: 2.6em; 94 | left: .4em; 95 | bottom: .4em; 96 | background-color: rgb(255, 255, 255); 97 | -webkit-transition: .4s; 98 | transition: .4s; 99 | } 100 | 101 | input:checked + .slider { 102 | background-color: var(--sliderActiveColor); 103 | } 104 | 105 | input:focus + .slider { 106 | box-shadow: 0 0 1px var(--sliderActiveColor); 107 | } 108 | 109 | input:checked + .slider:before { 110 | -webkit-transform: translateX(2.6em); 111 | -ms-transform: translateX(2.6em); 112 | transform: translateX(2.6em); 113 | } 114 | .slider.round { 115 | border-radius: 3.4em; 116 | } 117 | 118 | .slider.round:before { 119 | background-color: rgb(133, 228, 133); 120 | border-radius: 50%; 121 | } 122 | 123 | input:checked + .slider.round:before { 124 | background-color: white; 125 | } 126 | --------------------------------------------------------------------------------