Czy widzisz sposób na oszukiwanie w Hat Dash?

Dec 17 2020

Zobacz także: Kapelusz Dash Galeria Sław Białego Kapelusza i odświeżenie tabeli wyników

Aktualizacja 2021-01-13 : Wszystkie nagrody zostały przyznane (w tym poście lub w drugim), dziękujemy wszystkim za udział!

Jak informowali niektórzy użytkownicy, niektóre podejrzane wyniki zaczynają pojawiać się w myślniku. Mam pewne heurystyki i reguły (więcej również w przyszłości), aby złapać niektóre z nich automatycznie (lub po kilku ręcznych krokach ode mnie). To powiedziawszy, jestem zainteresowany utrzymaniem dobrej zabawy i uczciwości dla wszystkich.

Jeśli więc jesteś w stanie (w odpowiedzi na to pytanie) powtórzyć sposób skutecznego oszukiwania, w taki sposób, że wynik pojawia się na tablicy (i nie jest już na mojej liście rzeczy, na które należy zwrócić uwagę, jak np. osoba, która uzyskała 999K w 20 sekund) lub zasugeruję nową skuteczną heurystykę wykraczającą poza to, co jest już dostępne do wykrywania oszustw, zrobię co następuje:

  • Przyznaj nagrodę nagrodę (wartość do ustalenia na podstawie wagi)
  • Daj ci okrzyk na dole tablicy wyników w kapeluszu

Oszukiwanie = albo przez bezpośrednią manipulację API, albo coś po stronie klienta, co pozwala oszukać grę, aby działała bez faktycznego skakania i tym podobne.

Ponadto, jeśli jesteś zaangażowany w testowanie białych kapeluszy i zbanowałem Cię z tego powodu (widząc podejrzane zachowanie), daj mi znać na czacie WB .

Odpowiedzi

38 Zoethe1337Princess Dec 17 2020 at 05:31

Tak!

Proces jest dość prosty. Poszedłem dohttps://winterbash2020.stackexchange.com/run-with-the-hatsbezpośrednio i otworzył plik JS cdn.sstatic.net hd.min.jsza pomocą debugera Chrome.

(ze względu na ułatwienia dostępu w tekście umieściłem numery wierszy. Zauważ, że są one względne wyłącznie w stosunku do tego, jak Chrome upiększał plik, i już różni się między FF i Chrome)

Najpierw dodałem tutaj punkt przerwania (wiersz 526 wspomnianego wcześniej pliku JS):

... choć okazało się to bezcelowe, zmieniłem godzinę startu. Ja i debugger Chrome trochę walczyliśmy, co prawdopodobnie stanowi większość z 67 używanych sekund. Później zauważyłem, że czas tu istnieje, więc mógłbym to później zmienić. Zmodyfikowałem startAt time i odjąłem 90000, choć wątpię, żeby to miało jakikolwiek efekt. Ta modyfikacja została wykonana w konsoli przy użyciu standardowego systemu debugowania. -=Mogłem zapomnieć, kiedy go zmodyfikowałem. /wzruszać ramionami

Po drugie, dodałem tutaj punkt przerwania (wiersz 629 wspomnianego wcześniej pliku JS):

gdzie zaczyna się zabawa. Podniosłem distanceRanzmienną do 9 milionów tylko dlatego, że dlaczego nie. Po walce z Chrome, aby kontynuować (jest trochę błędny, prawdopodobnie artefakt Flatpak, co jest całkowicie moją winą, aby było jasne), kod kontynuował wykonywanie i przesłał wynik.

Próbowałem użyć tej .trigger("gameStarted/gameEnded")funkcji, ale nic nie daje. Próbowałem także zmodyfikować żądanie XHR (z innym punktem przerwania - dzięki uprzejmości Firefoksa "przerwa na XHR"), ale wydaje się, że walidacja powstrzymała mnie pomimo trafienia w oba punkty końcowe.

26 Zoethe1337Princess Dec 17 2020 at 06:09

Runda 2, bo tak naprawdę jest fajnie: D

W tej samej linii, co w przypadku trzech innych odpowiedzi, zaczynamy ponownie. To jest opcja AFK i prawie wymaga czasu. Można osiągnąć śmieszne wyniki.

  1. Otwórz debuger
  2. Skocz, aby rozpocząć grę, a będąc w powietrzu, wstrzymaj wykonanie
  3. Console this.config.GRAVITY = 0.

Grę można teraz pozostawić w tle, aby grindować wynik, ponieważ ustawienie grawitacji na 0 powoduje, że jednorożec zostaje wypuszczony z powrotem na wolność. Podczas testowania tego błędu żaden jednorożec nie ucierpiał. Prawdopodobnie

Gdy wynik jest zadowalający, zatrzymaj grę ponownie i zawołaj this.gameOver(). Ze względu na błąd, gdy GRAVITYjest ustawiony na 0, jedynym sposobem na zatrzymanie gry jest ręczne wywołanie funkcji. Jako bonus, jeśli nie dodasz jakiegoś rodzaju kontroli manipulacji, nie można tego sprawdzić. Czas i wynik rosną zgodnie z oczekiwaniami, z jedyną prawdziwą różnicą, że nie muszę grać w tę grę.

Jeśli chcesz mojej rady, nie akceptuj żadnych wyników przesłanych, jeśli konsola jest otwarta. Wykrywanie otwieranej konsoli jest jednak trudne. Coś jak to może działać za pierwszym razem, ale jak widać tak daleko, cokolwiek umieścić w JS, ktoś z konsolą można modyfikować. użycie czasu może zadziałać przy pierwszej próbie, ale ktoś może łatwo ustawić punkt przerwania, zmodyfikować czas tak, aby był poniżej progu, a następnie kontynuować, omijając ten test.

18 fredley Dec 18 2020 at 02:33

Tak na zawsze!

Napisałem scenariusz, aby stale sprawdzać, czy jesteś na szczycie tabeli liderów, a jeśli nie, aby przesłać wynik, który Cię tam umieści.

Wyobrażam sobie, że jest to takie samo podstawowe podejście, jak inne, ale wszystko, co zrobiłem, to unieszkodliwianie kodu źródłowego, nieznaczne dostosowanie go i pozostawienie uruchomionego na karcie.

Aby obejść heurystykę, dotarłem na szczyt, ustawiając pożądany wynik i sekundy na jeden więcej niż obecny lider.

Streszczenie - pozostaw to włączone, a będzie stale sprawdzać, czy jesteś na szczycie tabeli wyników. Jeśli nie, uruchomi grę, aby zrzucić ich z pierwszego miejsca, a następnie powróci do sprawdzania.

O ile wiem, z zaprojektowanym interfejsem API nie ma sposobu, aby zapobiec tego rodzaju oszukiwaniu, jednak czymś, co może znacznie utrudnić to zadanie, jest wysłanie listy czasów przeskoku (milis od początku) - tj. Znacznik czasu dla każdego naciśnięcia spacji. Znacznie trudniej jest skutecznie symulować.

16 Zoethe1337Princess Dec 17 2020 at 23:02

Runda 4! Chciałem to zrobić od wczoraj, ale nie mogłem wymyślić, jak to zrobić. I to nie są dokładnie prośby XHR, ale zrobię ci jedno lepiej.

Ta gra ma jedną gigantyczną wadę: przeszkody nie boją się wspaniałego jednorożca! Więc uh, tak, naprawiłem dla ciebie twoją grę: p Słyszałem też, że koty i jednorożce współpracują .

Kilka kotów dołączyło do jednorożców w walce o wolność jednorożca podczas testowania tego błędu

(to było z powrotem, kiedy myślałem, że każde 200 ms wystarczy, ale gdy gra przyspieszyła, zbliżyła się zbyt blisko dla wygody, więc zderzałem się z nią co 10 ms)

var intv2 = setInterval(() => {
    Runner.instance_.horizon.obstacles = []
}, 10);

A kiedy jesteś gotowy, aby wygrać, clearInterval(intv2);

Jednak z jakiegoś powodu nie mogę uruchomić tej metody, jeśli przekroczę 10 tys. Punktów. Nie wiem dlaczego, może to być zbyt agresywne unieważnienie lub po prostu pomyślałeś, że nikt nie uzyska tak wysokiego wyniku: P

Mam co najmniej ten wpis w tabeli wyników:

Uwaga: z jakiegoś powodu mogę to uruchomić tylko z https://winterbash2020.stackexchange.com/run-with-the-hats

Bonus: możesz teraz biegać po polach jednorożców zamiast biegać nad i pod kapeluszami.

13 Spevacus Dec 17 2020 at 06:00

Tak!

Zrobiłem coś podobnego do tego, co zrobiła Zoe , otworzyłem debugger Chrome. Zacząłem eksplorować Runnerobiekt i zobaczyłem, że możesz bezpośrednio manipulować distanceRanza pomocą konsoli Chrome. To właśnie zrobiłem podczas mojego biegu o drugie miejsce. Ale nie możesz po prostu ustawić Runner.instance_.distanceRantego, co chcesz ... Jeśli spróbujesz, zostanie pomnożony przez 0,025 (ustawienie go na 100 000 powoduje zmniejszenie do 2500) i naprawdę nie byłem pewien, dlaczego ... Więc zrobiłem Runner.instance_.distanceRan = 100000 / 0.025coś w rodzaju „Cofnij” to i wydawało się, że poprawnie zmieniło to mój wynik na taki, jakiego początkowo chciałem, 100 000.

Mój drugi bieg był nieco inny. Jak wskazała Zoe w swojej odpowiedzi, istnieje gameOver()funkcja, która jest wywoływana, gdy napotkasz przeszkodę. To fajne ... Więc próbowałem po prostu to anulować, Runner.instance_.gameOver = nullale to spowodowało, że gra się zawiesiła, gdy uderzyłem w przeszkodę. Tak więc, zamiast ustawić go do wykroju functionstosując Runner.instance_.gameOver = function() { /*nothing*/ }który pozwolił mi ciągle napotkasz przeszkód, nie tracąc.

Problem polegał jednak na tym, że teraz nie mogłem zakończyć gry i tym samym wypłacić jakikolwiek absurdalny wynik, jaki udało mi się uzyskać, odchodząc i łapiąc sobie drinka. Więc skopiowałem zawartość funkcji z pliku js i gameOverprzywróciłem jej poprzednią zawartość i pozwoliło mi to zakończyć grę ... Brutalnie, mogę dodać. W tym momencie poruszałem się tak szybko, że nie mogłem się przełączyć i spróbować się uratować. Postanowiłem jednak ustawić swój wynik na 50 000, aby po raz drugi znaleźć się w tabeli liderów podczas następnego przejazdu.

11 Ollie Dec 17 2020 at 05:58

Znalazłem piękny sposób na oszukiwanie, taki, który zostawisz na noc.

Kroki ku reprodukcji:

  1. Przejdź do strony Uruchom z kapeluszami , kliknij prawym przyciskiem myszy w dowolnym miejscu i kliknij „Sprawdź element”.
  2. Kliknij kartę „Konsola”.
  3. Skopiuj i wklej to polecenie do konsoli i uderzyć Enter: var original = Runner.prototype.gameOver.
  4. Zrób to samo z kroku # 3, z wyjątkiem tego polecenia: Runner.prototype.gameOver = function (){}.
  5. W następnym wierszu f (){}powinno pojawić się po naciśnięciu klawisza Enter. Jestem prawie pewien, że to robi, to zastąpienie gameOverfunkcji, która jest wywoływana, gdy Jednorożec uderza w przeszkodę, pustą funkcją ( f (){}), więc mój Jednorożec jest obecnie daleko od smyczy.
  6. Skopiuj i wklej polecenie Runner.prototype.gameOver = originaldo konsoli, aby wrócić do normalnego stanu i opublikować swój najlepszy wynik (zatrzymanie może zająć sekundę).
11 Zoethe1337Princess Dec 17 2020 at 18:46

Runda 3, ponieważ widziałem, jak ustalasz grawitację, więc miałem silne pragnienie, aby ponownie ją złamać. import antigravity, czy mam rację? : P

Jest to dość dynamiczny system, ponieważ z jakiegoś powodu nie zawsze zachowuje się konsekwentnie. Za jego pomocą uzyskałem jednak kilka wyników.

Miał też 30k, ale ten został odrzucony przez serwer z jakiegoś powodu. Nie do końca jestem pewien, co się tam stało, ale mogło to wynikać z tego, że ta metoda nie została wówczas odpowiednio dopracowana.

Podczas testowania tego błędu uwolniono kilka jednorożców. #SaveTheUnicorns

Podobnie jak inne spróbuj, wskocz, aby rozpocząć grę, wstrzymaj wykonywanie, otwórz konsolę.

this.tRex.config.DROP_VELOCITY = 0
this.tRex.config.GRAVITY = 0
this.tRex.config.INITIAL_JUMP_VELOCITY = -100

W moich testach odniosło to różny sukces. W niektórych przypadkach jednorożec znika. W innych przypadkach zatrzymuje się i po prostu nie spada i nadal znajduje się w zasięgu niektórych przeszkód. W takim przypadku ponownie wstrzymaj grę, ustaw DROP_VELOCITY = -1. Okno musi pozostać skupione, a samej strony nie można dotykać, ale dzięki temu uzyskałem kolejne 2,4 tys. Na tablicy wyników.

Po ustawieniu wartości ujemnej DROP_VELOCITYbyć może będziesz musiał ponownie odlecieć, aby odlecieć , ale nadal będzie się uruchamiał ponownie, więc w przypadku niepowodzenia rundy 1 łatwo jest ponownie uruchomić i odlecieć w rundzie 2.

W przypadku pierwszej opcji (jednorożec znika), ostatni krok zerwania grawitacji mojej poprzedniej odpowiedzi nadal obowiązuje; gdy jesteś zadowolony z wyniku, wstrzymaj wykonywanie i this.gameOver()w konsoli. Powinien zatrzymać grę i przesłać wynik.

10 iBugsaysReinstateMonica Dec 19 2020 at 16:59

Zhakujmy sam JavaScript!

Krok 1. Zainstaluj zastąpienie zasobów

Działa również na Microsoft Edge (opartym na Chromium).

Zastrzeżenie : nie jestem powiązany z tym rozszerzeniem Chrome.

Krok 2. Otwórz program Microsoft Visual Studio Code (lub JetBrains WebStorm, jeśli chcesz)

Pobierz plik JavaScript stąd: https://cdn.sstatic.net/Winterbash/js/hd.min.js. Zapisz to gdzieś.

Zalecane : użyj programu formatującego (takiego jak VSCode Prettier ) w kodzie, aby ułatwić nawigację.

Zastrzeżenie 2 : Nie jestem powiązany z Microsoft VSCode lub JB WS, ani nie jestem powiązany z rozszerzeniem VSCode Prettier.

Krok 3. Edytuj plik JavaScript pobrany w kroku 2

Załóżmy, że poprawiłeś plik, następujący kod powinien znajdować się w linii 126:

function s(n, t, i, r, u, f, e)

Przejdź do tej funkcji (Porada dla profesjonalistów: Wyszukaj s(przy włączonym dopasowaniu całych słów ) i poszukaj następującego stwierdzenia:

this.xPos = r.WIDTH + (e || 0);

Zmiana (e || 0)do 0i zapisać plik.

Krok 4. Otwórz Zastąpienie zasobu

Potocznie będę dalej nazywać to rozszerzenie RO.

  • Kliknij Add Rulew prawo

  • Wybierz URL → File, nowa linia pojawi się pod

  • Wprowadź to w pasku adresu URL:

    https://cdn.sstatic.net/Winterbash/js/hd.min.js?*
    
  • Wybierz Edit Filepo prawej stronie paska adresu URL i wklej edytowany plik z kroku 3 w. Wybierz Save & Closew prawym dolnym rogu.

Krok 5. Przejdź do Hat Dash i odśwież stronę. Zacznij grać

RO zastąpi JS wersją, którą edytowałeś. Teraz nie będzie żadnych przeszkód.

Krok 5.1. Poczekaj chwilę, aż uzyskasz pożądany wynik. Przełącz się na coś innego niż przeglądarka.

To zakończy grę z obecnym wynikiem. Baw się dobrze!

8 Ollie Dec 17 2020 at 06:10

Jeszcze szybszy sposób. Skopiować wszystkie kroki od mojego inny sposób oszukiwać , ale tym razem, wprowadzić inną komendę: Runner.instance_.setSpeed(10000). Podkręca prędkość Jednorożca do góry. Jednak bardzo szybko wyskoczy z linii, więc musisz nacisnąć strzałkę w górę, aby ją uruchomić.

Dla zainteresowanych widząc Uni w tył przeszkód, wystarczy dodać ten wiersz: Runner.instance_.setSpeed(-1).

8 double-beep Dec 17 2020 at 23:10

Uwaga: dzięki nowej heurystyce przeciwdziałającej oszustwom ta odpowiedź już nie działa. Zobacz ten, aby zapoznać się z metodą pracy.


TL; DR:

(async () => {
    Runner.gameStarted();
    Runner.setCurrentScore(someScore);
    await new Promise(resolve => setTimeout(resolve, seconds * 1000));
    Runner.gameEnded();
})();

Wymień someScorei secondsodpowiednio.


Zrób to ręcznie

To jest metoda, którą oszukiwałem, później zdałem sobie sprawę, że jest dokładnie taka sama jak powyższy fragment kodu.

Po pierwsze, zauważyłem, że niektóre POSTżądania są wykonywane, gdy gra się zaczyna i kończy: /hat-dash/starti /hat-dash/end.

  • Pierwsze żądanie wysyła parametr, startedAtktórym jest czas (milis od epoki). Odpowiedź jest klucz uwierzytelniania: {"auth":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}.

  • Drugie żądanie ma wiele parametrów:

    • startedAt: czas, powinno być takie samo jak poprzednie żądanie.
    • score: suma punktów w grze.
    • authKey: klucz autoryzacji, który otrzymałeś w poprzednim żądaniu.
    • durationMs: czas trwania gry w milisekundach.
    • wiele histKeys[]parametrów, które przechowują poprzednie klucze uwierzytelniania, w tym najnowszy, prawdopodobnie uzyskany z localStorage. Jeśli chcesz zobaczyć swoje, biegnij localStorage.getItem('Game_AuthKeys').split('|');.

Wtedy było to całkiem proste:

  1. Zagraj w krótką grę, aby te prośby zostały spełnione.

  2. Przejdź do zakładki Sieć → kliknij prawym przyciskiem najnowsze /hat-dash/startżądanie → Kopiuj → Kopiuj jako pobranie. Wklej to w konsoli i zmień "body": "startedAt=xxxxxxx"na "body": "startedAt=" + new Date().getTime().

  3. Poczekaj kilka sekund, aby wynik, który wprowadzisz później, wyglądał na prawdziwy, a Yaakov tego nie zauważy 😇.

  4. Następnie skopiuj ostatnie /hat-dash/endżądanie i:

    • Pobierz startedAtz poprzedniego /hat-dash/startżądania i zastąp go datą, którą otrzymałeś wcześniej (Sieć → Zapytanie → przewiń, aż zobaczysz Dane formularza).
    • Zamień wynik na taki, który chcesz.
    • Zastąp authKeywartością uzyskaną w odpowiedzi na poprzednie żądanie.
    • Zmień ...&durationMs=xxxxx...na ...&durationMs=" + (new Date().getTime() - previousStartedAt) + "....
    • Resztę pozostaw histKeys[]niezmienioną, tylko dołącz &histKeys%5B%5D=newestAuthKeydo ciągu.
5 hiineedhelp Dec 18 2020 at 23:00

Zamiast edytować JavaScript, dlaczego nie wysyłać POSTżądań? (Skopiuj i wklej do konsoli przeglądarki)

var startedAtNow = Date.now();
var authkey = "";
var n = {};
$.ajax({ type: "POST", url: "hat-dash/start", data: { startedAt: Date.now() }, dataType: "json", success: function(t) { authkey = t.auth }, error: function(n) { console.log("error starting game"); console.log(n) }, done: function() { this.pendingGameStart = null } }) function doend() { $.ajax({
      type: "POST",
      url: "hat-dash/end",
      data: {
          startedAt: startedAtNow,
          score: Number(6942069420), // You can change this
          authKey: authkey,
          durationMs: 12345, // You can change this
          histKeys: localStorage.getItem("Game_AuthKeys").split("|")
      },
      dataType: "html",
      success: function(t) {
          authkey = null;
          n.pendingGameEnd = !1;
          n.pendingGameStartedAt && ($.ajax({ type: "POST", url: "hat-dash/start", data: { startedAt: Date.now() }, dataType: "json", success: function(t) { authkey = t.auth }, error: function(n) { console.log("error starting game"); console.log(n) }, done: function() { this.pendingGameStart = null } }))(); $(".js-stats-data").remove();
          $(".js-personal-stats").append(localStorage.getItem("Game_AuthKeys"))
      },
      error: function(n) {
          console.log("error ending game");
          console.log(n)
      }
  })
}
setTimeout(doend, 12345); // 12345 should be >= durationMs

Po prostu przejrzałem kod źródłowy i znalazłem. Komentarze wyjaśniają, co należy zmienić. Poleciłbym ustawić realistyczny czas na wynik.

Zasadniczo score: Number(x)jest to wynik, który otrzymujesz, a x to wynik, który chcesz. durationMs: yokreśla, jak długo ma trwać bieg, a y jest liczbą milisekund. setTimeout(doend, z)powinien poczekać kilka milisekund więcej, niż durationMszasymulować fakt, że przebieg faktycznie odbył się w czasie rzeczywistym. Reszta kodu została pobrana z rzeczywistego javascript . Po prostu pobiera dane i wysyła je do serwerów Stack Exchange za pośrednictwem jQuery AJAX POST.

Dowód:

5 Bergi Dec 19 2020 at 05:58

Dzięki za dobrą zabawę :-)

Oto moje podejście:

const origGameOver = Runner.prototype.gameOver;
Runner.prototype.gameOver = function() {
    if (this.runningTime > 133700) {
        this.lastSurrentScoreText = "9001";
        this.currentStartedAt = Date.now() - 133700;
        return origGameOver.call(this);
    }
}

Ciągle zderzam się (oczywiście przypadkowo!) Z przeszkodami, ale gra nie kończy się dopóki nie zagrałem przez 133,7 sekundy. W przeciwnym razie gram normalnie, z oryginalnym kodem na miejscu, aby zbierać naciśnięcia klawiszy i wysyłać standardowe żądania.

Ponieważ przeszkody są generowane losowo na kliencie, nie będziesz mieć szansy ich wykrycia po stronie serwera.

Niestety, podczas pierwszych testów nie zorientowałem się jeszcze, jak poprawnie wysłać oczekiwany czas na serwer (pokazujący się jako 134-kilka sekund), ale nie podjąłem go, aby uniknąć zbytniego bałaganu w rankingu.

4 Ollie Dec 17 2020 at 06:43

Możesz także użyć tego polecenia:

Runner.instance_.distanceRan = 100000 / Runner.instance_.distanceMeter.config.COEFFICIENT

Aby rozpocząć Unicorn od określonej partytury, w tym przypadku 100 tysięcy.

4 KylePollard Dec 17 2020 at 11:23

Nie jestem pewien, czy rozważasz użycie tabletu z oszustwem na klawiaturze, czy po prostu sprytną kombinacją mechaniki, ale pomyślałem, że na wszelki wypadek połączyłbym to:

https://meta.stackexchange.com/a/358130/718314

Granie w grę na ekranie dotykowym z klawiaturą sprawia, że ​​gra jest nieco łatwiejsza, ponieważ latające strzałki są skonfigurowane tak, aby były łatwiejsze.

(Jeśli to oszustwo, nie wymazuj moich wyników! Odkryłem to dopiero w ciągu ostatnich pół godziny, więc tylko moje ostatnie biegi zostały wykonane z tym 😅 Żaden z nich nie znalazł się w tabeli wyników wszechczasów)

4 Hack5 Jan 03 2021 at 00:02

Najpierw zmodyfikowałem kod zapobiegający oszukiwaniu w funkcji, l()aby żądał niewłaściwego adresu URL ( /bam-me...), aby nie zostać zbanowanym, jeśli popełnię błąd.

Następnie zmieniłem kod, aby zakończyć grę podczas kolizji ( f ? (this.gameOver(), this.crashed || l('rewrote gameOver function')) : ...), aby zmienić warunek na f && !1- oznacza to, że gra nie kończy się, jeśli napotkam przeszkodę.

Następnie grałem w tę grę normalnie, aby analityka po stronie serwera nie zauważyła mnie. Kiedy chciałem umrzeć, uderzyłem alt-right, aby opuścić zakładkę, która wywołuje gameOver()(z powodu utraty koncentracji) i informuje serwer, że umarłem.

Oczywiście wszystkie powyższe wymagały ode mnie dodania niestandardowego JS do strony. Aby uniknąć potencjalnych problemów związanych z przeładowywaniem programów obsługi zdarzeń, użyłem rozszerzenia FF „Request Injector”, które pozwoliło mi zmienić odpowiedź na każde żądanie. Mogłem oczywiście użyć lokalnego pliku do zmodyfikowania kodu HTML, ale to zepsuło wszystkie względne adresy URL, więc zasoby użyte na stronie nie załadowały się i nie mogłem zobaczyć jednorożca: „(. I używając lokalny plik JS w zdalnym HTML nie działa z powodu zabezpieczeń file: /// URL, więc użyłem del.dog do hostowania nowego kodu JS.

Moja sugestia, aby to zablokować, polega na dodaniu integrity=...atrybutu do <script src="sstatic...">tagu w kodzie HTML, co przynajmniej będzie oznaczać, że ludzie będą musieli podjąć próbę zastąpienia wszystkich względnych adresów URL w celu zmodyfikowania JS.

Serwer może również blokować wszystkie żądania dostępu, /run-with-the-hatschyba że mają poprawne Referrer, a sprawdzenie po stronie klienta może być również dodane do JS document.referrer(jest to przydatne, więc musisz umieścić maksymalną liczbę stron w przechwytywaczu żądań, co sprawia, że ​​modyfikowanie JS jest bardziej irytujące)

3 Tuqay Dec 22 2020 at 06:06

Myślę, że nie powinienem pisać tego jako odpowiedzi, ale nie znalazłem innego miejsca, w którym mógłbym to napisać. 2 dni temu oszukiwałem ze zmianą prędkości skoku (już naprawione). Ale mój wynik jest na tablicy wyników:

Chcę go tylko usunąć

2 Gismo1337 Dec 19 2020 at 05:00

Właśnie teraz przypadkowo zmieniłem kartę przeglądarki zaraz po naciśnięciu Space. Wróciłem i jednorożec zniknął. Ale gra działa i wydaje dźwięki.

W przeglądarce Google Chrome w systemie Windows 10.

Możesz to zobaczyć tutaj: https://youtu.be/8MZrcbZttHY

1 l-l Jan 05 2021 at 02:26

Znalazłem prosty sposób na oszukiwanie, który nie wymaga żadnego kodowania.

  1. Otwórz grę: Biegnij z kapeluszami
  2. Zacznij grać i po chwili powiększ / pomniejsz stronę. To powoduje zatrzymanie gry
  3. Poczekaj chwilę, a następnie naciśnij spację, aby wznowić grę. Po wznowieniu gry wynik będzie wyższy. (Im dłużej czekasz, tym jest wyżej)
1 WBT Jan 06 2021 at 04:16

Tak! Udało mi się usunąć domyślne detektory zdarzeń i obiekty oraz nadpisać JavaScript po stronie klienta zmodyfikowaną wersją. Zmodyfikowana wersja ma dodaną linię:

n.livesLeft = 1000;

(gdzie wartość można ustawić nieco arbitralnie), którą umieściłem (ponownie, nieco arbitralnie) po

n.defaultDimensions = {
  WIDTH: y,
  HEIGHT: 150
};

i zastąpił logikę wykrywania kolizji

  if (f && ut(f, a, v), y) return [a, v]

z

  if (f && ut(f, a, v), y)  {
    n.livesLeft--;
    if(n.livesLeft<=0) {
        return [a,v];
    }
  }

To w większości działa, ale ostatecznie w grze pojawia się błąd. W szczególności w funkcji aktualizacji znajduje się linia

this.currentSpeed < this.config.MAX_SPEED && (this.currentSpeed += this.config.ACCELERATION))

Ponieważ różnica między prędkością początkową a maksymalną nie jest dokładną wielokrotnością domyślnego parametru PRZYSPIESZENIE, może to prowadzić do przekroczenia maksymalnej prędkości. Następnie podczas skoku funkcja startJump () porównuje aktualną prędkość z MAX_SPEED i uruchamia autoban w przypadku zbyt szybkiego skoku. Rozwiązaniem, które powinno być w oryginale, jest zmiana tego segmentu na

(this.currentSpeed + this.config.ACCELERATION) < this.config.MAX_SPEED && (this.currentSpeed += this.config.ACCELERATION))

Chociaż możliwe jest zneutralizowanie kodu autoban w modyfikacjach skryptu, nie powinno to być absolutnie konieczne, zwłaszcza po usunięciu błędu.

Dzięki tej modyfikacji nadal musisz grać w grę, a Twój wynik końcowy będzie zależał od tego, jak dobrze grasz. Różnica polega po prostu na tym, że gra nie kończy się przy pierwszym zderzeniu; to całkiem wybaczające, jeśli chodzi o liczbę kolizji, które możesz mieć przed zakończeniem gry.

Nie jestem pewien, jak można łatwo bronić tej techniki przy obecnej architekturze i ilości informacji przesyłanych do serwera.

Czasami kod walidacyjny po stronie serwera oflagowuje grę jako podejrzaną, ale może po prostu znajdować się w kategorii ogólnej „zbyt dobra” lub porównywać liczbę skoków z oczekiwaną liczbą przeszkód. Wymagałoby trochę eksperymentów lub spojrzenia na kod po stronie serwera, aby dowiedzieć się, jaka jest prawidłowa częstotliwość skoków, a następnie zmodyfikować kod, który wysyła liczbę skoków w punkcie kontrolnym i na końcu gry. Miałem zamiar zrobić ten kawałek przed ukończeniem tego postu, ale wystarczająca liczba tygodni i reszta Winter Bash minęła bez znalezienia czasu na zrobienie tego, więc pominę ten ostatni krok, który może sprawić, że odejdę od pracy przez cały czas. Myślę, że nadal spełnia to, czego szukał post.

Anonymous Dec 22 2020 at 07:44

Mogę zmienić partyturę, edytując Numberfunkcję. Po zastąpieniu kod próbuje przekonwertować ciąg punktacji na liczbę w wierszu 1168 ładnie wydrukowanego kodu Firefoksa i zamiast tego uruchamia funkcję niestandardową. Wklej ten kod do konsoli JavaScript:

function Number(n) {
  return 1000000;
}