piątek, 1 stycznia 2016

Minecraft - wersje - instalacja forge - różnice

Odpalenie Minecraft - prosta sprawa. Dla zwykłego user-a, który chce sobie pograć nic prostszego. Jakąś wersję można kupić lub wyszukać z lepszym lub gorszym skutkiem. 

Warto wiedzieć

W przypadku moich pociech z gorszym - niektóre są porządnie zawirusowane i system operacyjny komputer-a może nadawać się do ponownej instalacji). Dlaczego tak się dzieje? Przecież to Java bezpieczna swojej piaskownicy? Większość tych "wersji" jest udostępniana w postaci instalatorów binarnych (pliki exe itp). Ludzie w wielu wypadkach nie udostępniają tego bezinteresownie. Są to aplikacje, które świadomie lub nie instalują przeróżne backdoory w naszym systemie. Gdzie szukać tego właściwego i działającego lauchera gdy jeszcze nie mamy tej wersji? Mnie zdarzyło się sprawdzić lauchera z TeamEtreme w wersji 3.5.1, i kilka innych, ale czy to dobra wersja - tego nie odpowiem.

Dlaczego zajmuję się Minecraft

Minecraft jest pisany w Javie. Wydaje się że dla programisty Java ze sporym doświadczeniem, ogarnięcie co tam się dzieje to prosta sprawa. Nie jest jednak łatwo. To spora mikstura różnych rozwiązań i to co znajdziemy po zainstalowaniu wersji to niezła zagadka (szczególnie że nie mam dokumentacji i patrzę na czarną skrzynkę). Informacji na temat Minecraft jest mnóstwo, ale trzeba wiedzieć gdzie patrzeć, aby trafić na coś wartościowego.

Postaram się opowiedzieć co jest w środku (a w właściwie na wierzchu) tego kodu Minecraft-a, bo to mnie interesuje jako developera. Zacznę od analizy samego launcher-a. Moją intencją jest sprawdzenie w jaki sposób do Minecraft jest dodawany forge. Niby instalator forge załatwia temat za nas, ale jakoś ja mam szczęście, że u mnie nie działa choć gdzie indziej to przechodzi bez problemu dlatego ten research.

Co to jest forge 

Dla graczy Minecraft jest to sposób na rozszerzenie funkcjonalności Minecraft poprzez mody. W czystej wersji, rozszerzanie jest możliwe, ale najpopularniejsza jest modyfikacja Minecraft, która dodaje bardziej czytelne interface do modyfikacji gry. I to właśnie forge.

Binarne wersje można pobrać z http://files.minecraftforge.net/. Teoretycznie są źródła, które nawet można skompilować https://github.com/MinecraftForge, ale o tym może później.  

Gdzie jest zainstalowny

Ogólnie (bo nie zawsze tak musi być), ale w większości przypadków Minecraft instaluje się w w lokalizacji %APPDATA%\.minecraft (dla windows).
W zależności od wersji systemu (dla różnych wersji Window będzie inaczej) można sprawdzić gdzie to jest.

>echo %APPDATA%
Dla Windows 7
C:\Users\kcz\AppData\Roaming\
Dla Windows XP
C:\Documents and Settings\kcz\Dane aplikacji\
To jest oczywiście tylko umowna ścieżka (bez problemu da się przygotować instalację gdzie indziej), ale jak oglądałem to najczęściej launchery wybierały tę lokalizację.

Odpalenie launcher


Minecraft Laucher TE 3.5.1
W pierwszej kolejności jest potrzebny tzw. launcher
- podstawowa nakładka do zarządzania wersjami Minecraft, logowania do sieci, raportowania błędów itd.
W wielu wypadkach jest to plik exe które 
W zależności od tego, jak i czy w ogóle na naszym komputerze jest zainstalowana wersja java to albo się to odpali albo nie. W większości wypadków jest to tak spreparowany exe spreparowany do takiej postaci że odpala javę a w środku jest po prostu zawartość taka jak w jar. Da się to podejrzeć przy pomocy np Total Commandera (^C+PGDN) lub 7-Zip
W przypadku wersji TE lancher jest w .minecraft/minecraft
launcher/Minecraft Launcher.exe
W moim wypadku na ekranie wyszło, że jest to lunch4j http://launch4j.sourceforge.net/.

Zawartość Minecraft Laucher
Jak widać zawartość exe w tym wypadku to zwykły zip. Można to wypakować i sprawdzić co tam się w środku dzieje. Co dzieje się w samym exe (tzn czy jest coś więcej niż zip, sobie darowałem, dlatego że wszystkie informacje które były niezbędne do odpalenia tego ręcznie były w tym "zip")

Jeden z ważniejszych elementów który sprawdziłem, to META-INF/META-INF\MANIFEST.MF. Okazało się że klasa exe odpala to co jest w tym manifest

Main-Class: net.minecraft.bootstrap.Bootstrap

Zła wersja java dla Minecraft launcher
Czyli prosty test
> java -jar minecraft launcher\Minecraft Launcher.exe



odpala taki lancher.
W moim wypadku odpalenie tego z exe się nie powiodło - zła wersja java - się zraziłem i zacząłem szukać. W przypadku jawnego podania java coś zaczęło się dziać. Ale nie dlatego że tak jest lepiej... a dlatego że lancher próbował się zaktualizować.

>java -jar "minecraft launcher\Minecraft Launcher.exe"
Updating Launcher...


Ciekawe bo za drugim odpaleniem mam już komunikat, że wymaga java 7?
Dlaczego? Moja wersja od której startowałem to 1.7.2 w tej wersji pewnie wymagana była tylko wersja 1.6 java (ja teraz mam 1.8 x64). Faktycznie po sprawdzeniu kolejnych uruchomień zmienianie ulega Minecraft Launcher.exe. Niestety automatycznie się to aktualizuje i nie znam na razie parametrów które pozwalają to wyłączyć.

Wygląda na to, że to co odpala potem lancher bierze java z JAVA_HOME lub z PATH

Oczywiście postarałem się o wymuszenie javy, jednak kolejna aktualizacja już wymaga więcej niż java 1.6 co raczyło wypluć.
.minecraft.1.7.2>d:\java\jdk\jdk1.6\bin\java.exe -jar "mi
necraft launcher\Minecraft Launcher.exe"
Exception in thread "main" java.lang.UnsupportedClassVersionError: net/minecraft
/bootstrap/Bootstrap : Unsupported major.minor version 51.0


Niestety ta wersja automatycznie się aktualizuje (co mnie akurat się nie podoba...)

Kody wersji Java
J2SE 8 = 52
J2SE 7 = 51
J2SE 6.0 = 50
J2SE 5.0 = 49
JDK 1.4 = 48
JDK 1.3 = 47
JDK 1.2 = 46
JDK 1.1 = 45

Tym  sposobem doszedłem do tego że luncher się w końcu zaktualizował do wymaganej wersji... która była już wystarczająca do tego aby coś zadziałało
Minecraft - lancher wystartowany


Najbardziej mnie interesowało skąd on to ściąga...
Można kilka opcji przećwiczyć...
Puścić ruch przez proxy... i podejrzeć z czego to ciągnie kolejne wersje.

Chciałem zajrzeć do środka tego kodu... ale tu niestety ściana.
Kod jest poddany obfuscacji (zaśmieceniu) i skompilowany bez opcji debugowania, czyli ciężki temat....

Jak widać wszystko co jest konieczne do odpalania tego lancher-a jest w tym "exe" - "jar"
Co tam się dokładnie dzieje to za dużo się nie dowiemy bo komunikaty z konsoli są mocno lakoniczne.

Wybrałem kilka narzędzi do sprawdzenia tego Minecraft Launcher.exe do dekompilacji.

Pierwsze co miałem pod ręką to jd-gui http://jd.benow.ca/

W kodzie pierwsze co się rzuca w oczy to main(String[]...
Analizowane parametry wsadowe to workDir, proxyHost, proxyPort, proxyUser, proxyPass, workDir

Po dodaniu do wywołania parametru help widać że można użyć takich parametrów:
Option                 Description
------                 -----------
--force                Force updating
--help                 Show help
--proxyHost            Optional
--proxyPass            Optional
--proxyPort <Integer>  Optional (default: 8080)
--proxyUser            Optional
--workDir <File>       Optional (default: C:\Users\kcz\AppData\Roaming\.minecraft)


Pierwsze co sprawdzę to zmienie katalog gdzie jest instalowany minecraft z %APPDATA% do mojego katalogu oraz puszczę ruch przez proxy
Jak proxy jest wiele rozwiązań ja skorzystam z mojego własnego
>java -jar "minecraft launcher\Minecr
aft Launcher.exe" -proxyHost 127.0.0.1 -proxyPort 8080


Niestety w tym wypadku coś siadło... aplikacja się zawiesiła i nie ma odzewu.
Może warto sprawdzić przy pomocy stactrace na czym wisi?
Można sprawdzić procesy na z poziomu managera zadań lub przy pomocy jps
>jps
1472 Jps
4048 minecraft


Oto co dostałem? Java pracuje to wątkowo i wszystko się przetwarza w kontekście jakiegoś wątku... To jedyny który wydaje się sensowny...
"Thread-3" #18 prio=6 os_prio=0 tid=0x0000000059ffc800 nid=0x1310 runnable [0x000000005bade000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at sun.net.NetworkClient.doConnect(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    - locked <0x00000000d6de4e68> (a sun.net.www.http.HttpClient)
    at sun.net.www.http.HttpClient.<init>(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)

...
    at java.net.URLConnection.getContentLength(Unknown Source)
    at com.teamextreme.fyre.UpdaterFrame.a(Unknown Source)
    at com.teamextreme.fyre.UpdaterFrame$1.run(Unknown Source)


Wygląda na to że z proxy to nie działa za dobrze z tym lancherem, albo ja coś źle ustawiłem
Sprawdziłem z różnymi wersjami proxy .... ale bez skutku... chociaż przeglądarka z proxy chodziła.
Bez proxy lancher działa bez zarzutu. Ale brak możliwości odpalenia tego przez proxy powoduje że nie mogę się dowiedzić skąd się lancher aktualizuje i czy da się to wyłączyć.

Gdy już udało się uruchomić lancher to nawet po dodaniu parametru workDir dalej jest tworzony katalog %APPDATA%/.minecraft/. Jest teraz tam znacznie mniej danych, ale nadal się tam ściągają  minecraft launcher/ oraz servers.dat

Dekompilacja


Czyli prosty wniosek - tą drogą na razie nie pójdę dalej.
Pozostaje przejrzeć kod i w jakiś sposób go zrozumieć.
Niestety ten kod jest poddany obfuscacji. Klasy, metody, pola maja niezrozumiałe nazwy.
W niektórych wypadkach trafiły się zmienne które miały jakieś nawiedzone znaki unicode których decompiler (w/w) nie dał rade zdekodować i wszystko lądowało do tej samej zmiennej.

Tu pomogło wykorzystanie innych decompilatorów
Z tych co przejrzałem dały radę

MCP

Podczas poszukiwania decompilatrów przypadkowo natrafiłem na projekt MCP (Mod Coder Pack
Modding Minecraft and other games http://www.modcoderpack.com/website/), który pozwalał na dekompilacje bieżącej instalacji Minecraft oraz częściową deobfuscaje kodu. Zadziałała wersja mcp903 z wersją Minecraft 1.7.2. Z innymi wersjami polecam sprawdzenie osobiste.

Po dekompilacji projekt wygląda inaczej niż oryginalny .minecraft. Daje się odpalić skryptami które są przygotowane między innymi startclient.bat. Dekompilację aktualnej instalacji można zrobić przez decompile.bat. Udało mi się to tylko na wersji mcp903 i minecraft 1.7.2. Dekompilacja w tym wypadku robiona jest przy pomocy fernflower. Dla wersji 1.7.10, którą ćwiczyłem przewidziano mcp908. Proces decompile.bat mocno "przymula"... ale rezutlat jest znacznie ciekawszy. Sporo klas ma sensowne nazwy, niestety nie wszystkie.
W katalogu mcpXXX/bin mamy skompilowany na nowo minecraft. Ta wersja daje się już debugować i znacznie więcej widać w eclipse.
Dla takiego projektu można przygotować

Proba zainstalowania na tym katalogu forge nie powidoła się.
Klasa net.minecraft.launchwrapper.Launch która jest odpowiedzialna za startowanie minecraft z forge nie została dograna do katalogu mcp908
Możliwe że da się to ręcznie przygotować... ale to już inna bajka.

Warty je również rozeznania sposób w jaki następuje przekształcenie zaciemnionych nazw w jarach  minecraft na bardziej czytelne nazwy w mcpXXX.


W ramach projektu znajduje się konfiguracja która wersja minecraft jest poddana decomilacji.
Definiuje to plik mcp908\conf\version.cfg
Ważne tu jest parametr
ClientVersion = 1.7.10
Trzeba wspomnieć że wersja która jest uruchamiana znajduje się w .minecraft\versions\${version}
Po dekompilacji (jeżeli się uda) źródła mamy w katalogu mcpxxx/src

Niestety po zainstalowaniu forge decompilacja już się nie udała (oczywiście zmieniłem wpisy w version.cfg
ClientVersion = 1.7.10-Forge10.13.4.1614-1.7.10 

Zainstalowny forge jest traktowany jako minecraft w postaci specjalnej wersji... (dlatego ten katalog .minecraft\versions\1.7.10-Forge10.13.4.1614-1.7.10)

Wypadało by tu przeskoczyć trochę opis przygód i przejść do rezulatatu.
Czyli opisać jaka jest różnica w wywołaniu Minecraft bez forge oraz z forge.

Trzeba by też powiedzieć jak faktycznie jest Minecraft odpalany
Aby tego dokonać trzeba się przegryźć przez to co robi lancher, dlatego że lancher odpala zupełnie oddzielny proces (nie wątek a proces) java. Aby tego dokonać musi przygotować odpowiednie parametry aby wywołać nową komendę java (albo raczej javaw) z odpowiednimi parametrami.

I o to mi właśnie chodzi. Mam takie podejrzenie że po zainstalowaniu forge za odpalenie mincrafta odpowiada zupełnie inna klasa niż w przypadku gołej wersji. Prawdopodobnie

Zanim podam jakie to zaklęcie odpowiada za startowanie minecraft-a sprawdze zawartość
.minecraft\versions\1.7.10\1.7.10.jar\META-INF\MANIFEST.MF
Jak zwykle na wszelki wypadek sprawdzę
Main-Class: net.minecraft.client.Main
Oczywiście można sprawdzić czy czasem się to nie uruchomi w najprostszy sposób
>java  -jar 1.7.10.jar
Niestety to nie pójdzie za mało zależnych bibliotek. O ile lancher dało się tak uruchomić minecraft (gra) już się nie da

Odpalenie Lancher-a z Eclipse

W ramach przykładu niech będzie wersja 1.7.2
Main class:net.minecraft.bootstrap.Bootstrap
Java vm arguments: -Xmx512M -Xmn128M -Dfile.encoding=utf-8 -Djava.library.path=path-tominecraft\versions\1.7.2\1.7.2-natives
Program agruments: force false
Trzeba zadbać aby w versions\1.7.2\ były rozpakowane natives
Można się postarać samemu to wypakować, jednak lepiej doprowadzić do tego aby lancher to sam zrobił. Jeżeli uda nam się poprawnie uruchomić grę przez lancher dociągnie on wszystkie zależności i wrzuci do katalogu .minecraft. Katalogi są różne ogólnie biblioteki lądują w .minecraft/libraries/* ale tu już jest hierachia i nie wiadomo co dodać. Można szukać do skutku ale jest to żmudne.
Tak jak wspomniałem lepiej uruchomić grę przez lancher wtedy zostają dociągnięte zależności oraz rozpakowane natives do dynamicznego katalogu 1.7.2-natives-20274371117558. Niestety po zatrzymaniu gry katalog jest kasowany. Więc zanim zatrzymamy grę możemy go skopiować do innego.

O debugowaniu lanchera można pomarzyć.
Projekt MCP nie obejmuje dekompilacją net.minecraft.bootstrap.Bootstrap
Ta klasa znajduje się we wspomnianym wcześniej Minecraft Launcher.exe o którym opowiadałem.
Jak się dobrać do tego co jest przekazywane do nowego procesu który odpala grę?

Znalazłem na to sposób!
Wykorzystałem Java Instrumentation https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html połączone z asm http://asm.ow2.org/

Pomyślałem że skoro nie mogę poprawnie debugować tego kodu, to jeżeli przy pomocy asm dodam do klas które mnie interesują dodatkowe wywołania mojej klasy przy wejściu do tych metod, będę mógł się przyjemniej zatrzymać w tych miejscach debugerem i pooglądać zawartość rejestrów.

W zdekompilowanym kodzie lancher-a znalazłem potencjalne metody i klasy które warto przejrzeć.
Jako główne podejrzane wziąłem klasy które zawierają tekst "java" lub "javaw" a takie są właśnie.

com.mojang.launcher.d.j() - zwraca wywołanie javaw
com.mojang.launcher.b.a.a - zdaje się jest odpowiedzialna za wywołanie nowej instancji
com.mojang.launcher.b.a.a.c - jest watkiem
net.minecraft.launcher.game.a.B() - wygląda na faktyczne odpalenie gry Launching game

Właśnie do tych klas dopisałem rejestrację MethodVisitor tak aby przechwycić w mojej klasie wywołanie ich metod.

Najbardziej ciekawa jest właśnie
com.mojang.launcher.b.a.a.b.a(com.mojang.launcher.b.a.c)
Przekazany parametr to wszystko co trzeba aby odpalić proces

Pomijam ścieżkę do javaw

Wprawdzie lancher raportuje  Half command

Odpalenie wersji 1.7.2 poza lancherem

Half command: javaw -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.2\1.7.2-natives-21233089533446 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.3\authlib-1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.0\lwjgl-2.9.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.0\lwjgl_util-2.9.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.2\1.7.2.jar net.minecraft.client.main.Main

Wyglada na to że to nie wszystko... Sporo parametrów wywołania zostaje ukrytych
Pobrane z lanchera faktyczne wywołanie wygląda tak
javaw -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.2\1.7.2-natives-21233089533446 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.3\authlib-1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.0\lwjgl-2.9.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.0\lwjgl_util-2.9.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.2\1.7.2.jar net.minecraft.client.main.Main --username xxx --version 1.7.2 --gameDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft --assetsDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft\assets\virtual\legacy --uuid 896c2adcb9ae3a4b823b963b19c0be23 --accessToken 1337535510N force false
Jeżeli chcemy z tego zrobić bat-a, trzeba pamiętać że katalogi które mają spacje trzeba zamknąć w ""

Odpalenie wersji 1.7.10 poza lancherem

Half command: javaw -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10-natives-25439188735719 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\realms\1.3.5\realms-1.3.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.1\lwjgl-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.1\lwjgl_util-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\tv\twitch\twitch\5.16\twitch-5.16.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10.jar net.minecraft.client.main.Main

oraz faktyczne parametry
javaw -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10-natives-25439188735719 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\realms\1.3.5\realms-1.3.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.1\lwjgl-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.1\lwjgl_util-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\tv\twitch\twitch\5.16\twitch-5.16.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10.jar net.minecraft.client.main.Main --username xx --version 1.7.10 --gameDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft --assetsDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft\assets --assetIndex 1.7.10 --uuid 5c9b1881d52f379ba7e222e10b07c20f --accessToken 1337535510N --userProperties {} --userType legacy force false

Na pierwszy rzut oka widać różnicę pomiędzy wersją 1.7.2
Dodany jest parametr --assetIndex 
Inna jest wartość dla --assetsDir
W przypadku wersji 1.7.2 posługiwano się .minecraft\assets\virtual\legacy a tu mamy .minecraft\assets
Niektóre rzeczy się różnią.
Można teraz sprawdzić jak wygląda sprawa po zainstalowaniu forge
Instalator forge

Odpalenie wersji 1.7.10 z forge poza lancherem

Jeżli minecrafta mamy zainstalowanego w standardowym %APPDATA%/.minecraft instalacja forga powinna pójść bez problemu.
Ja odpalam to ręcznie
java -jar forge-1.7.10-10.13.4.1614-1.7.10-installer.jar 

Ściąga się sporo dodatkowych rzeczy.
W każdym z przypadków nie wiadomo skąd to się ściąga,


Na razie nie zawracam sobie tym głowy.
Chce sprawdzić jaki jest command do wywołania minecraft wsadowo z forge

Lancher z dodanym forge
Po zainstalowaniu forge lancher teraz ma dodatkową wersję z forge (nie widać tego w całości)

Katalog .minecraft\versions\1.7.10-Forge10.13.4.1614-1.7.10 nie ma specjalnego jar-a

Plik 1.7.10-Forge10.13.4.1614-1.7.10.json jest niezrozumiały i nie wiem jak go przekonwertować na linię komend - mimo tego że to prosty json.

Half command daje już informacje wstępną że jest inna klasa startująca net.minecraft.launchwrapper.Launch zamiast net.minecraft.client.main.Main. Nie jest to jednak wszystko aby odpalić minecraft z forge

Half command: javaw -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10-Forge10.13.4.1614-1.7.10\1.7.10-Forge10.13.4.1614-1.7.10-natives-27389509725956 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\minecraftforge\forge\1.7.10-10.13.4.1614-1.7.10\forge-1.7.10-10.13.4.1614-1.7.10.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\minecraft\launchwrapper\1.12\launchwrapper-1.12.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\ow2\asm\asm-all\5.0.3\asm-all-5.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\typesafe\akka\akka-actor_2.11\2.3.3\akka-actor_2.11-2.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\typesafe\config\1.2.1\config-1.2.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-actors-migration_2.11\1.1.0\scala-actors-migration_2.11-1.1.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-compiler\2.11.1\scala-compiler-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\plugins\scala-continuations-library_2.11\1.0.2\scala-continuations-library_2.11-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\plugins\scala-continuations-plugin_2.11.1\1.0.2\scala-continuations-plugin_2.11.1-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-library\2.11.1\scala-library-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-parser-combinators_2.11\1.0.1\scala-parser-combinators_2.11-1.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-reflect\2.11.1\scala-reflect-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-swing_2.11\1.0.1\scala-swing_2.11-1.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-xml_2.11\1.0.2\scala-xml_2.11-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\lzma\lzma\0.0.1\lzma-0.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\realms\1.3.5\realms-1.3.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.1\lwjgl-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.1\lwjgl_util-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\tv\twitch\twitch\5.16\twitch-5.16.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10.jar net.minecraft.launchwrapper.Launch

Pobrane z debugera komenda wygląda tak

javaw.exe -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xmx512M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:-UseAdaptiveSizePolicy -Xmn128M -Djava.library.path=C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10-Forge10.13.4.1614-1.7.10\1.7.10-Forge10.13.4.1614-1.7.10-natives-27738863467004 -cp C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\minecraftforge\forge\1.7.10-10.13.4.1614-1.7.10\forge-1.7.10-10.13.4.1614-1.7.10.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\minecraft\launchwrapper\1.12\launchwrapper-1.12.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\ow2\asm\asm-all\5.0.3\asm-all-5.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\typesafe\akka\akka-actor_2.11\2.3.3\akka-actor_2.11-2.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\typesafe\config\1.2.1\config-1.2.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-actors-migration_2.11\1.1.0\scala-actors-migration_2.11-1.1.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-compiler\2.11.1\scala-compiler-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\plugins\scala-continuations-library_2.11\1.0.2\scala-continuations-library_2.11-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\plugins\scala-continuations-plugin_2.11.1\1.0.2\scala-continuations-plugin_2.11.1-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-library\2.11.1\scala-library-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-parser-combinators_2.11\1.0.1\scala-parser-combinators_2.11-1.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-reflect\2.11.1\scala-reflect-2.11.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-swing_2.11\1.0.1\scala-swing_2.11-1.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\scala-lang\scala-xml_2.11\1.0.2\scala-xml_2.11-1.0.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\lzma\lzma\0.0.1\lzma-0.0.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\realms\1.3.5\realms-1.3.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\java3d\vecmath\1.3.1\vecmath-1.3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\io\netty\netty-all\4.0.10.Final\netty-all-4.0.10.Final.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\guava\guava\15.0\guava-15.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.1\lwjgl-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.1\lwjgl_util-2.9.1.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\libraries\tv\twitch\twitch\5.16\twitch-5.16.jar;C:\Documents and Settings\xx\Dane aplikacji\.minecraft\versions\1.7.10\1.7.10.jar net.minecraft.launchwrapper.Launch --username xxx --version 1.7.10-Forge10.13.4.1614-1.7.10 --gameDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft --assetsDir C:\Documents and Settings\xx\Dane aplikacji\.minecraft\assets --assetIndex 1.7.10 --uuid 896c2adcb9ae3a4b823b963b19c0be23 --accessToken 1337535510N --userProperties {} --userType legacy --tweakClass cpw.mods.fml.common.launcher.FMLTweaker force false

Jak widać pojawia się tu dodatkowy parametr --tweakClass cpw.mods.fml.common.launcher.FMLTweaker
Co to jest i czy to wystarczy?

Po zrobieniu z tego bat-a faktycznie minecraft startuje z forge

Wnioski:
Half command faktycznie podaje poprawne wartości jeżeli chodzi o class-loader-a.

Z porówniania wywołania z half command i przechwyconej komendy wynika że różnica opiewa tylko na parametry

--username xxx
--version 1.7.10-Forge10.13.4.1614-1.7.10
--gameDir .
--assetsDir assets
--assetIndex 1.7.10
--uuid 896c2adcb9ae3a4b823b963b19c0be23
--accessToken 1337535510N
--userProperties {}
--userType legacy
--tweakClass cpw.mods.fml.common.launcher.FMLTweaker
force
false


Skąd się ściągają jary zależności w lancher

Zostaje jeszcze jeden fajny temat. Lancher załatwia automatyczne dociąganie wersji, pobiera wymagane jary oraz przygotowuje komendę którą wywołuje. Skąd on to bierze?
Próba przestawienia lanchera na proxy się nie powiodła więc pozstaje RE kodu.

Do zbadania
com.mojang.launcher.updater.download.DownloadJob
.startDownloading(ThreadPoolExecutor paramThreadPoolExecutor)
.popAndDownload()

com.mojang.launcher.updater.download.Downloadable
.makeConnection(URL paramURL)
.download()

Są 2 klasy które to rozszerzają
com.mojang.launcher.updater.download.a
com.mojang.launcher.updater.download.c

Pobieranie jest inicjowane przez
Set<Downloadable> net.minecraft.launcher.updater.CompleteMinecraftVersion.getRequiredDownloadables(com.mojang.launcher.d, java.net.Proxy, java.io.File, boolean)

Konstruktor
com.mojang.launcher.updater.download.a(java.net.Proxy, java.net.URL, java.io.File, boolean)

W tym wypadku przekazane zostają prametry do konstruktora
proxy:DIRECT
url:https://libraries.minecraft.net/com/mojang/realms/1.3.5/realms-1.3.5.jar
file:C:\java\mcp908\libraries\com\mojang\realms\1.3.5\realms-1.3.5.jar
Czyżby dostęp do bibliotek jest anonimowy?
Wygląda na to że dostęp do tych bibliotek jest.
Bezpośrednie wejście na adres https://libraries.minecraft.net/ zgłasza błąd

Okazuje się że url jest raportowany czasem (w jakiejś wersji lanchera), ale nie podczas downloadu

Warto by może dowiedzieć się skąd minecraft zna znależności do kontretnej wersji.

Jak przejrzałem instalację minecraft to znalazłem na sztywno zaszyty w kodzie lancher-a libraries.minecraft.net w medoda zwraca net.minecraft.launcher.updater.Library.getDownloadUrl()na sztywno "https://libraries.minecraft.net/"

net.minecraft.launcher.updater.CompleteMinecraftVersion pole libraries

Warto się dowiedzieć w jaki sposób jest to inicjowane oraz skąd lancher wie jakie jary dociągnąć do konkretnej wersji.

Jestem prawie pewny że jest to ładowane z pliku .minecraft\versions\1.7.10\1.7.10.json ale to trzeba potwierdzić.

Wybranie konkretnej wersji z lanchera też wymaga w pewnym sensie dostępu do net-u dlatego że musi zainicjować pole select z dostępnymi wersjami.
Wybranie konkretnej wersji powoduje prawdopodobnie zaciągnięcie tego pliku json a on inicjuje dalszy proces pobrania zależności.
Trzeba by przejrzeć jak wygląda ten plik version/${version}/${version}.json dokładniej
W przypadku wersji z forge plik 1.7.10-Forge10.13.4.1614-1.7.10.json

Wydaje się że właśnie wymagane argumenty wywołania danej wersji znajdują się w tym pliku
minecraftArguments i właśnie tu widać że w przypadku wersji z forge dodany tam jest parametr --tweakClass

Skąd bierze się informacja o zależnościach

Klasy które kwalifikują się do przeglądu
com.mojang.launcher.updater.VersionSyncInfo
net.minecraft.launcher.updater.PartialVersion
net.minecraft.launcher.updater.LocalVersionList
Zaczytuje dane z .minecraft/versions/1.7.10/1.7.10.json

net.minecraft.launcher.updater.RemoteVersionList
baseUrl - "https://s3.amazonaws.com/Minecraft.Download/" (id=229)
size - co ciekawe już jest 115 wersji

Pytanie dlaczego wybrali jako strore amazon s3?

Strona http://aws.amazon.com/s3/ jest dostępna https://s3.amazonaws.com/Minecraft.Download/ nie da się wywołać. Dodawany do tego jest jakiś extra url
W pierwszej kolejności jest zaczytywany https://s3.amazonaws.com/Minecraft.Download/versions/1.8.9/1.8.9.json

{
  "id": "1.8.9",
  "time": "2015-12-03T09:24:39+00:00",
  "releaseTime": "2015-12-03T09:24:39+00:00",
  "type": "release",
  "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type}",
  "libraries": [
    {
      "name": "oshi-project:oshi-core:1.1"
    },
    {

...
  "minimumLauncherVersion": 14,
...
Pełnej struktury na razie nie będę analizował. Widać jednak ważną informację. Wersja może wymagać określonej minimalnej wersji lancher-a

Warto pewnie przyjrzeć się klasie
net.minecraft.launcher.updater.Library
Wyjątkowo ciekawa jest metoda com.google.gson.Gson.fromJson(String json, Class<T> classOfT)

https://github.com/google/gson
A Java serialization library that can convert Java Objects into JSON and back. 

Pozwala to na konwersję od razu na obiekty z json i na odwrót

Pobranie informacji o konkretnej wersji odbywa się z adresu https://s3.amazonaws.com/Minecraft.Download/indexes/1.7.10.json

Nie dla wszystkich przypadków to działa dobrze np teoretycznie jest wersja 1.8.8 ale pobranie https://s3.amazonaws.com/Minecraft.Download/indexes/1.8.8.json daje AccessDenied

Lista wersji znajduje się w https://s3.amazonaws.com/Minecraft.Download/versions/versions.json

Format pliku jak poniżej
{
  "latest": {
    "snapshot": "15w51b",
    "release": "1.8.9"
  },
  "versions": [
    {
      "id": "15w51b",
      "time": "2015-12-17T15:30:41+00:00",
      "releaseTime": "2015-12-17T15:30:41+00:00",
      "type": "snapshot"
    },...


Właśnie to jest ciekawe że pomimo tego że jest 1.8.9 to z indexes się nie pobiera

Jeszcze jeden ciekawy adres to
http://resources.download.minecraft.net/

Ściąganie zależności

Poprawność ściągania pliku jest weryfikowana przez sha1
W pierwszej kolejności jest ściągane sha1
https://libraries.minecraft.net/com/mojang/realms/1.3.5/realms-1.3.5.jar.sha1
Potem w zleżności od efektu weryfikiacji jest pobierany plik 
https://libraries.minecraft.net/com/mojang/realms/1.3.5/realms-1.3.5.jar

Liczenie sha1

public static String getDigest(File paramFile, String paramString, int paramInt) {
 DigestInputStream localDigestInputStream = null;
 try {
  localDigestInputStream = new DigestInputStream(new FileInputStream(paramFile), MessageDigest.getInstance(paramString));
  paramFile = new byte[65536];
  while (localDigestInputStream.read(paramFile) > 0) {}
 } catch (Exception localException){
  return null;
 } finally {
  closeSilently(localDigestInputStream);
 }
 return String.format("%1$0" + paramInt + "x", new Object[] { new BigInteger(1, localDigestInputStream.getMessageDigest().digest()) });
}


Okienko lancher-a

Całość jest opakowana w interface JavaFX
Za tworzenie interface odpowiadają klasy w pakiecie
net.minecraft.launcher.ui.*
Skąd są ściągane news ...
Sprawdzam Updating News...

Sprawdzenie czy jest jfx
new File(System.getProperty("java.home"), "lib/jfxrt.jar")

Ładowanie JFX

File localFile = new File(System.getProperty("java.home"), "lib/jfxrt.jar"));
try
{
 if ((ClassLoader.getSystemClassLoader() instanceof URLClassLoader)){
  URLClassLoader localURLClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();

 try { 
  Method localMethod;
 (localMethod = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class })).setAccessible(true);
        localMethod.invoke(localURLClassLoader, new Object[] { localFile.toURI().toURL() });
      } catch (Throwable localThrowable2) {
   // Couldn't add " + localFile + " to system classloader";
  }
 }
 // JFX has been detected & successfully loaded
 return ...
}
catch (Throwable localThrowable1)
{
 // JFX has been detected but unsuccessfully loaded
}


Do czego jest wykorzystywane fyre

Wydajność

Nie mierzyłem tego bezpośrednio jednak po dodaniu forge fps pobrane z samego minecraft wydaje się być w pewnym stopniu słabsze. Czy tak jest? Na razie to pomijam.
Na pewno proces ładowania gry się mocno wydłuża w zależności oczywiście od ilości modułów.