How to fix Minecraft client attempt to authenticate server while playing on LAN with Linux’s network namespaces

So I recently stumbled upon a problem provoked by a random craving of launching a VPN-LAN party with my friends. The game we chose is called Minecraft, and it suggests, that one can easily host a game by launching a singleplayer game and then clicking the “Open to LAN” button. Thing is, it doesn’t work that well on VPN’s.

We chose to connect by a Hamachi network, I was the one who hosted the server. I did it by the means I described in the last paragraph, and – to my sheer surprise – no one could connect, everyone was being kicked from the server with a mysterious prompt of:

mc_error_authFailed to log in: The authentication servers are currently down for maintenance.

That’s weird, isn’t it? But anyway, my idea was – let’s just launch Minecraft with access only to the VPN network, not to the internet itself – maybe there will be no authentication attempts if it detects no Internet?

I proceeded to the scripting. Scripting, because on a Linux, one can run a process in a namespace, where it’s going to be sandboxed only to those network interfaces one selects.

Let’s list my interfaces then:

ifconfig_ham0

As you see, there’s a ham0 VPN interface that pops out after installing Hamachi, and wlp3s0 which provides me the Internet via WIFI. Now, as we know this, we need to run a minecraft-launcher in a namespace with ham0 only:

ham0_script_pyh

It does what it suggests in the echo’s. After running it I exclaimed SUCCESS!
Minecraft successfuly ran in the offline mode:

mc_offline

That’s great, but now it’s the worst part – my friends use Windows and I had no idea of scripting the same thing on it. I had luck, though – after googling I found out that someone wrote a small program that does exactly what my script did, but on Windows – it’s called ForceBindIP, and as it suggests, it binds a specific network interface / port to the process:

https://r1ch.net/projects/forcebindip

After installing, one can call Minecraft binded to its Hamachi IP by calling in cmd:

"C:\Program Files (x86)\ForceBindIP\ForceBindIP.exe" 25.60.2 33.140 "D:\Data\Minecraft\MinecraftLauncher.exe"

Where the first part is the place where ForceBindIP is installed, the second part is Hamachi IP and the third part is the Minecraft Launcher installation directory.

That’s the moment when we tried again to play. I hosted the game with a launcher I started with my script, my friend tried to connect via ForceBindIP and….

working_mc

It worked!
And yes, I know that one can download only a *server* and it’s probably going to work – but if that so, why the Open to lan button anyway?


Sources:

https://superuser.com/questions/241178/how-to-use-different-network-interfaces-for-different-processes/750412#750412

https://superuser.com/questions/1004697/bind-application-to-a-specific-network-interface

Polski przekład poradnika pisania homebrew na NintendoDS

Stworzyłem przekład (polecam sprawdzić różnicę między przekładem a tłumaczeniem!) świetnego tutoriala który można znaleźć pod adresem:

https://patater.com/files/projects/manual/manual.html

O tym że ten przekład był robiony z głową świadczy to, że sam piszę własne homebrew – moje SpelunkyDS są już całkiem rozbudowaną grą i wiem co tłumaczę. Prawdopodobnie wiem co tłumaczę

Mój jedyny komentarz do tego przekładu – początkowe rozdziały, w których mowa o pierwszych kartach do wrzucania homebrew na NDS można pominąć –  wspomniane tam narzędzia to już starocie i w tym momencie zdaje się że jedyną wartą uwagi kartą jest R4. Od rozdziału 4 zaczyna się pisanie kodu.

Poradnik NDS Homebrew

libnds – setting icon for .nds build

tl;dr

  1. Open gimp
  2. Create new 32 px / 32px image, paste there your icon (you may need to rescale it with Tools->Transform tools -> scale) or draw whatever you want. You may want to open a toolbox with Ctrl + B.
  3. Set image to use indexed pallette with maximum of 16 colors
  4. first colour of bitmap would be transparent when rendered on NDS menu, so set it as first in “colors->map->rearrange map”
  5. Save in .bmp format BUT you MUST check the “compatibility options” -> “do not write color space information”
  6. In your projects’ Makefile fill GAME_ICON property with path to your icon
  7. Build your nds project, put it on R4 or something else and enjoy

detailed:

  1. Srsly
  2. File -> New, then in window which appears set width / height. No need to change anything in “Advanced options”.

Screenshot from 2018-05-29 21-21-03

Drawing something ugly:Screenshot from 2018-05-29 21-28-39

3. Image -> Mode -> Indexed. Set max colours to 16. Again, no need to change anything else.

Screenshot from 2018-05-29 21-30-09

4. As I said, choose whatever color that would be unique (you don’t use it in your icon to draw something) – it will stand for the transparence layer. I have arbitrarily choosen this red-pinkish color. Now you have to arrange it to be the first color in the icon palette.

Do this by Colors -> Map -> Rearrange colors map.

Just drag and drop your color to the first place:

Screenshot from 2018-05-29 21-34-32

5. Ctrl + E, name it as something.bmp, click Export,

Screenshot from 2018-05-29 21-37-33

Click Export again.

6.

Screenshot from 2018-05-29 21-40-54

That’s it, finished, you can now build your .nds file with custom icon.

 

Some words on developing SpelunkyDS

I had to remove music from the .nds binaries, you see, the binary as it is, with only sprites packed into it, is ~600kB. With simple sounds like one for the whip or jumping ~1.2MB. Things get hard when music comes in, it is over ~3.3MB with main menu / title song which causes crashing moonshell and prompting an “too large binary file” error.

You would suggest compressing the .wav more, but the compression is already in its really limits, when it comes to decent sound quality.

I wrote a prototype of SpelunkyDS using nitrofs – it streams music from the R4 card, not from the binary itself. Works good enough in desmume, but when copying to the card and trying in moonshell, it can’t find a filesystem. Problem is, to use nitrofs is to use a specific firmware, which is nds-hb-menu.

It would render SpelunkyDS only usable on cards prepared explicitly for homebrew – sad, but that’s the cost of using so fatty assets like music.

But for now – I’ll just focus on coding another things and leave the music for some time, perhaps there’s a better solution.

Also, as I have recently seen, there’s not so many tutorials on homebrew things like putting an icon to NDS file or aforementioned streaming music from filesystem (with nitrofs).

Going to put some posts on these later.

Portowanie Spelunky na NintendoDS

Kod:

https://github.com/dbeef/spelunky-ds

Plik gotowy do uruchomienia w emulatorze nds (np. na Androidowym NDSBoy):

https://github.com/dbeef/spelunky-ds/blob/master/spelunkyds.nds


Na tym etapie, program w końcu zaczyna przypominać oryginalne Spelunky, zebrałem więc krótkie podsumowanie.

Co większą zmianę kręciłem krótko hmm gameplay? Dlatego postępy krok po kroku można po prostu obejrzeć:


Co zostało?
AI, zbieralne przedmioty, wspinanie się na drabinach/linach, druga warstwa tła (nałożona na mapę kafelkową i sprajty), menu, zastanowienie się na tym, czy zostawić mapę współdzieloną między ekranami.

Po skompilowaniu, Spelunky włączam na nds poprzez kartę R4 , ale jeśli faktycznie uda mi się je dokończyć, to spróbuję znaleźć sposób na (bardzo amatorskie) wyprodukowanie kilku kartridży samemu. Dla przykładu, schematy budowy Game Boy Advance są w internecie:

https://dhole.github.io/post/gameboy_cartridge_emu_1/

Jeśli chodzi o trudności jakie napotkałem podczas reprodukowania gry to były ogromne na początku, później (chyba) takie same jak przy każdej innej grze, bez różnicy czy na konsolę.

Najgorszym problemem było rozwiązanie adresowania pamięci, libnds wystawia odpowiednie funkcje do zarządzania VRAM-bankami, ale adres poszczególnego sprajta (np. ikony liny na górze ekranu) zależy od głębi kolorów (ja używam 4 bitowej, 16 kolorów) i wielkości (libnds dzieli podane mu obrazki na kafelki wielkości 8×8, więc zależy od ilości takich kafelków).

Zaadresować należy też oddzielnie palety kolorów, czcionkę i kafelki tła (mają swoje oddzielne banki).

Nie brzmi to tak srogo, ale jeśli chociażby załaduje się grafikę o innej głębi niż podano w kodzie, to całe adresowanie jest niepoprawne i pojawiają się artefakty takie jak ten:

Problem rozwiązują odpowiednie kalkulatory:

https://mtheall.com/vram.html

Konsola obsłuży max 128 sprajtów per ekran (ograniczenia ze względu na ilość pamięci), nie wiem jeszcze jak łatwo będzie zająć 100% CPU (chociażby sprawdzaniem kolizji między wszystkimi obiektami), ale patrząc na to, że ta konsolka z 2004 roku potrafi coś takiego:

czy coś takiego (Minecraft homebrew, https://github.com/smealum/dscraft):

…to jestem spokojny.


Tutorial libnds, jeśli kogoś to zainteresowało:

https://patater.com/files/projects/manual/manual.html

libnds #4 Wykrywanie kolizji z tłem

Postęp prac na ten moment:

Lista problemów które udało mi się rozwiązać od ostatniego postu:

  • Wyświetlanie mapy większej niż 256×256
  • Znalezienie jakiegoś programu do edycji map kafelkowych, kompatybilnego z gba/nds
  • Zrobienie prostego generatora poziomów
  • Sprawdzanie kolizji poszczególnych kafelków z punktem x,y wyznaczonym przez dotyk na ekranie
  • Znalezienie w gimpie opcji konwersji kolorów do takich, które spodobają się libnds (8 bit, indeksowane bmp/png)

Wyświetlanie mapy większej niż 256×256

Przypominając, wyświetlenie mapy kafelkowej w libnds składało się do skopiowania z pamięci tablicy (w przypadku 256 px na 256 px daje to mapę wielkości 1024, bo każdy element mapy zajmuje 8×8 pikseli) do odpowiedniego rejestru w hardwarze NDS.

Z poniższego postu:

https://www.coranac.com/tonc/text/regbg.htm

…można się dowiedzieć, że rysując mapy większe niż 256×256, trzeba rozpatrzyć specjalny przypadek – weźmy na przykład mapę 512×512 z jakiej teraz korzystam w spelunky-ds.

Dzielę moją tablicę 4096 elementów na 4 sektory, jak szachownicę. Robię to tworząc zapasową tablicę, a następnie przechodzę przez nią tak, aby dojść tylko do odpowiedniej połowy na każdej z osi (wiersz ma szerokość 64 elementów, więc dochodzę do 32). Reszta chyba jest oczywista:

schemat

Da się to skrócić, ale to dobry przykład bo widać każdą oddzielną pętlę for odpowiadającą za oddzielną część szachownicy.

Nie wiem czy to część całego standardu C++, ale zauważyłem, że jeśli nie przydzielę pamięci dla tymczasowej tablicy poprzez malloc, to całość nic nie wyświetla (żadnych błędów, po prostu jakby DMA stwierdzało że nie skopiuje tej tablicy już w runtimie), więc trzeba na to zwrócić uwagę.


Znalezienie jakiegoś programu do edycji map, który generowałby tablicę C++

Tutaj padło na program mappy:

https://tilemap.co.uk/mappy.php

Strona wygląda jakby ledwo się trzymała, więc chyba na wszelki wypadek wrzucę binarkę na moje repozytorium z dopiskiem do readme o odpowiedniej licencji i autorze.

Mappy potrzebuje tilemapy – robię ją w gimpie sklejając odpowiednie pliki i koniecznie konwertując je do .bmp, indeksowanego, 256 kolorów (8bit).

Ten sam plik, ale w formacie .png przekazuję do folderu gfx w folderze od spelunky-ds.

To co wychodzi z mappy, to tablica, którą można wkleić bezpośrednio w kod:

const short mapa[1024] = {
1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4,
1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4

…itd.


Zrobienie prostego generatora poziomów

Tutaj wytłumaczenie generowanie spelunkowych poziomów wyłożył ktoś na youtubie, zresztą bardzo dokładnie z przykładem:

Ja napisałem jedynie szybką implementację powyższego w: source/level_layout/LevelGenerator.cpp:

https://github.com/dbeef/spelunky-ds/blob/master/source/level_layout/LevelGenerator.cpp


Sprawdzanie kolizji poszczególnych kafelków

Najmniejsza jednostka podziału grafiki w libnds to kafelek 8×8 (chociaż pewnie można zmienić to w programie grit), ale moje grafiki ze Spelunky są rozmiarów 16×16, więc aby 4 kafelki trzymały jedną logiczną część (np. dla momentów w którym niszczę cały kafelek) stworzyłem klasę MapTile:

Screenshot from 2018-03-10 20-11-49

values zawiera 4 wartości dla 4 różnych kafelków 8×8, map_index zawiera ich adresy w mapie.

Sposób wybierania adresów w mapie jest dość żmudny i nie ma co go tutaj przedstawiać, kto jest zainteresowany niech zobaczy plik LevelGenerator.cpp, w szczególności funkcje:

  • generateRooms()
  • mapFrame()

Mamy już pozycję każdego kafelka, można więc mając pozycje dotknięcia na ekranie sprawdzić teraz, czy któryś z nich nachodzi na ten x,y.

Trzeba pamiętać jednak o szczególe, takim jak pozycja kamery. Sprawdzając kolizję, trzeba sprawdzać pozycję x i y kafelka PLUS pozycja x i y kamery, tak jak poniżej:

Screenshot from 2018-03-10 20-19-45

 


 

To wszystko na dziś.

libnds #3 Kafelkowe tło

Przygotowanie

Za podstawę do napisania kafelkowego tła posłużą:

Przykład z libnds:
devkitPro/examples/nds/Graphics/Backgrounds/all_in_one

Pojedyńczy obrazek tła ze spelunky community update:

SpelunkyCommunityUpdateProject/spelunky/Sprites/Blocks/Background/sCaveBG.images/image 0.png

Program do edycji map na NDS/GBA:

http://www.tilemap.co.uk/mappy.php

Odpowiednie kroki

1

Obrazek wskazany wyżej trzeba najpierw przepuścić przez poniższą stronę:

https://online-converting.com/image/convert2bmp/

Wybieramy tryb 8 (indexed).

Po pobraniu wrzucam go podpisanego jako cavebg.bmp do folderu gfx/tilemaps. W nim napisałem następującą regułę grit (wytłumaczenie – odsyłam do docsów grit):

-p!
-gt
-gB8
-mRtpf
-mLs
-mu32
-Mw16
-Mh16

Mój Makefile (gdzie wskazuję gritowi jakie foldery ma odwiedzić) możecie sprawdzić na Githubie spelunky-ds.

2

Teraz kopiujemy odpowiednie pliki z przykładowego projektu do naszego projektu:

  • scrolling.cpp
  • TextBackgrounds.s

Do main.cpp wystarczy skopiować jedynie linie (podmieniłem argument tak aby pasował do naszego obrazka cavebg):

dmaCopy(cavebgTiles, bgGetGfxPtr(bg), sizeof(cavebgTiles));
dmaCopy(Layer256x256Map, bgGetMapPtr(bg), Layer256x256MapLen);
dmaCopy(cavebgPal, BG_PALETTE, cavebgPalLen);

3

Robimy mapę. Ściągamy edytor który podlinkowałem wyżej.

Tworzymy nową mapę przez File->New map. Korzystamy z faktu, że pojedyńczy tile w NDS jest rozmiarów 8×8, nasz obrazek to 32×32 a rozmiar mapy jaki wybraliśmy to 256×256 – będzie więc miała szerokość i wysokość 32, szerokość i wysokość tile-a 8×8 co podajemy w oknie które wyskoczy.

Importujemy obrazek .bmp który stworzyliśmy wcześniej opcją File->Import.

Rysujemy cokolwiek i eksportujemy do pliku txt przez File->Export as text, w oknie które się pojawi niczego nie zmieniamy.

W pliku txt który się wygenerował interesuje nas pierwsza tablica od góry.

Ponieważ nie do końca wiem, czy to jakaś rzecz wynikająca z C++ czy mój błąd, na razie nie kopiuję tej tablicy bezpośrednio do kodu, ale podmieniam wartości w pliku TextBackgrounds.s – inaczej nie działa.

Miejsce które trzeba podmienić, to Layer256x256Map (ponieważ taki rozmiar mapy wybraliśmy). Miejsce to deklaruje wygląd mapy.

Screenshot from 2018-02-25 17-50-58

Wyrzucamy wszystko co jest po Layer256x256Map i jest przed:

@}}BLOCK(Layer256x256)

Teraz ważna rzecz – nie wklejamy tu bezpośrednio tej tablicy. Przepuszczamy ją przez prosty program który napisałem (zmienia tablicę 2d na 1d, zmienia wartości z decymalnych na hexy + dodaje “.hword” na początku każdej linii) wklejamy dopiero output, który wypuścił ten program.

Wrzuciłem jego source do Githuba projektu, do folderu utils. Przed uruchomieniem trzeba wkleić swoją własną mapę do jego kodu.

Wynik

Mamy scrollowalną mapę jak poniżej:

myimage

Co dalej

Zastanawiałem się więc w którą stronę pójść – wyświetlać jako tiled background jedynie te faktycznie statyczne elementy (tło które jest za niszczalnymi elementami), wyszczególnione tutaj:

background

…a zniszczalne elementy wyswietalać jako sprajty. Wtedy logika wyświetlania zniszczonych elementów byłaby prostsza, zero kombinowania, tak samo sprawdzanie kolizji, np. z kolcami czy podmiana sprajta, jeśli np. ten element wybuchł. Plus wszystkie wartości pomocnicze trzymane byłyby w jednej strukturze.

Pytanie tylko, czy wyświetlanie tego w ten sposób jest dobre – NintendoDS ma rzekomo oddzielny układ odpowiedzialny za wyświetlanie backgroundów, nie obciążałbym więc CPU, po prostu kopiowałbym pamięć do odpowiedniego rejestru przez Direct Memory Access, gdybym nie używał sprajtów tylko wyłącznie background. Być może NDS ma też oddzielny układ do wyświetlania sprajtów i nie musiałbym zastanawiać się jak będzie to wyglądać wydajnościowo – problem w tym:

On the Nintendo DS, we can have up to 128 sprites.

https://patater.com/files/projects/manual/manual.html#id2614195

Więc raczej by to nie wyszło, mapa w Spelunky to około 40×40, nie mówiąc o postaciach czy przeszkodach.

Size was one of the benefits of using tilemaps, speed was another. The rendering of tilemaps in done in hardware and if you’ve ever played PC games in hardware and software modes, you’ll know that hardware is good. Another nice point is that scrolling is done in hardware too. Instead of redrawing the whole scene, you just have to enter some coordinates in the right registers.

https://www.coranac.com/tonc/text/regbg.htm

Drugi pomysł, wykorzystujący w 100% tylko backgroundy, to napisanie pomocnicznego programu, który przejdzie przez plik txt z generatora map i stworzy tablicę elementów (powiedzmy, że nazwiemy te elementy SpriteElement {x, y, typ elementu (zwykły klocek, klocek tła, itd), boolan czyZniszczony, szerokość, wysokość, wskaźnik na tablicę intów który będzie wskaźnikiem na hexy ekwiwalentu tego samego tile-a, ale zniszczonego}).

Wtedy za każdą zmianą takiego kawałka tła (np. zniszczeniem pojedyńczego klocka) będzie można robić wpis do rejestru ze zmienioną tablicą i tło nadal będzie się jakoś wyglądać – to które to będą element listy i na jaką wartość ją podmienić będzie wiadomo ze SpriteElement. Kolizje i odpowiednia logika również wyszłaby z tego.

Plus, i tak muszę zrobić coś co będzie w stanie wygenerować mapę od zera (w Spelunky każda mapa jest losowa, generowana proceduralnie) więc jakieś makra pod poszczególne kafelki będę musiał gdzieś w kodzie zadeklarować.

 

Wkrótce napiszę jakąś wstępną implementację.

Efekt powyższego tutoriala można zobaczyć na Githubie tego projektu:

https://github.com/dbeef/spelunky-ds

 

PS: Zauważyłem, że kolejne hexy: 0x0001, 0x0002, 0x0003…0x000F to kolejne elementy (8×8 tile) naszego obrazka .bmp. Składa się to w całość – gdyby ułożyć je warstwami po 4, narysowalibyśmy nasz obrazek. Można w ramach eksperymentu wkleić coś takiego do pliku TextBackgrounds.s:

.hword 0x0000,0x0001,0x0002,0x0003,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0004,0x0005,0x0006,0x0007,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000


.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0008,0x0009,0x000A,0x000B,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x000C,0x000D,0x000E,0x000F,0x0000,0x0000,0x0000,0x0000

…powinno narysować klocek + powtarzający się, lewy górny róg klocka wokół.

 


Przydatne linki:

libnds

https://www.coranac.com/tonc/text/objbg.htm

https://www.coranac.com/tonc/text/regbg.htm

https://gbatemp.net/threads/ds-programming-for-newbies.322106/

https://gbatemp.net/threads/tile-mapping-libnds-or-palib.325728/

C++

https://stackoverflow.com/questions/1238613/what-is-the-difference-between-the-dot-operator-and-in-c

https://stackoverflow.com/questions/54585/when-should-you-use-a-class-vs-a-struct-in-c

https://stackoverflow.com/questions/38942013/declaring-variables-in-header-files-c

https://stackoverflow.com/questions/10198046/c-member-variables

https://stackoverflow.com/questions/185844/initializing-private-static-members

https://stackoverflow.com/questions/20019441/how-is-a-header-file-being-compiled-into-the-executable-file

Konfiguracja Code::Blocks pod NDS:

https://whatroidoes.wordpress.com/2014/01/09/nds-development-tutorial-how-to-use-devkitpro-with-codeblocks-and-debug-with-insight/