Learn · concepts
Czym jest ASM (kod bajtowy Java)? Wyjaśnienie biblioteki
ASM to biblioteka Java do odczytu i zapisu kodu bajtowego JVM w czasie działania programu. Oto co robi, jak działa i dlaczego mody Minecraft na niej polegają.
Czym jest ASM w modowaniu Minecrafta?
ASM to biblioteka Java do odczytu, modyfikacji i zapisu kodu bajtowego JVM. Działa na skompilowanych plikach .class zamiast kodu źródłowego, dzięki czemu może sprawdzić lub przepisać klasę bez rekompilacji. Mody Minecraft opierają się na niej, ponieważ pozwala im na poprawianie gry w czasie ładowania, po tym jak gra została już skompilowana.
Dlaczego istnieje poprawianie kodu bajtowego
Gra Minecraft jest dostarczana jako skompilowany kod bajtowy, a nie jako kod źródłowy. Oznacza to, że autor modyfikacji nie może zmienić kodu źródłowego i ponownie skompilować całej gry: kod źródłowy nie istnieje. Jedynym sposobem na poprawianie kodu, którego nie posiadasz, jest sięgnięcie do poziomu kodu bajtowego, czyli zestawu instrukcji, które faktycznie wykonuje Java Virtual Machine. ASM jest praktycznym narzędziem do tego zadania.
Jak działa ASM
ASM przekształca skompilowaną klasę w coś, co program może edytować. Plik .class to po prostu kod bajtowy, czyli instrukcje, które wykonuje Java Virtual Machine. ASM analizuje ten kod bajtowy, udostępnia Ci metody i pola, i pozwala na dodawanie, usuwanie lub zmienianie instrukcji. Następnie zapisuje nową, poprawną klasę.
Czysta Java nie jest w stanie tego zrobić samodzielnie. Kompilator zamienia Twój kod źródłowy na kod bajtowy raz, a po tym kod bajtowy jest ustalony. ASM sięga do poziomu kodu bajtowego, czyli warstwy poniżej kodu źródłowego, który normalnie piszesz.
Wzór obserwatora i API drzew
ASM odczytuje klasę za pomocą ClassReader i zapisuje ją za pomocą ClassWriter. Pomiędzy tymi dwoma, Twój kod przegląda elementy klasy i decyduje, co zmienić. Istnieją dwa podejścia:
Podejście oparte na visitorze przetwarza klasę element po elemencie. Jest szybkie i zużywa mało pamięci, ponieważ nigdy nie przechowuje całej klasy w całości. Podejście oparte na drzewie ładuje klasę do obiektów, po których można swobodnie poruszać się i je edytować, co jest łatwiejsze do zrozumienia przy większych zmianach, ale zużywa więcej pamięci.
| Podejście | Jak działa | Najlepsze dla |
|---|---|---|
| API Visitora | Przetwarza zdarzenia klasy w trakcie odczytu | Małe, szybkie edycje przy niskim zużyciu pamięci |
| API Drzewa | Buduje edytowalny model obiektu klasy | Większe lub bardziej złożone refaktoryzacje |
Dlaczego mody Minecraft używają ASM
Mody muszą zmieniać kod gry, którego nie napisali i nie mogą go ponownie skompilować. Gra jest dostarczana jako skompilowane klasy, więc jedyną drogą jest poziom kodu bajtowego, a ASM to właśnie zapewnia. Mod może wstrzyknąć haczyk do metody gry, przekierować wywołanie lub dodać pole, wszystko podczas uruchamiania.
Większość twórców modów nie wywołuje ASM bezpośrednio. Używają Mixin, frameworku wyższego poziomu, który opiera się na ASM i przekształca proste adnotacje w edycje kodu bajtowego. Piszesz małą klasę Java opisującą zmianę, a framework wykonuje niskopoziomową pracę z ASM za Ciebie. Szczególnie mody Fabric polegają na tym łańcuchu.
Kiedy musisz bezpośrednio pracować z ASM
Rzadko piszesz surowy kod ASM jako autor modyfikacji. Pojawia się to, gdy narzędzie potrzebuje większej kontroli niż ta, którą umożliwiają adnotacje, na przykład w przypadku loadera, obfuscatora lub patchera, który całkowicie przepisuje klasy. Dla codziennych modyfikacji wystarczy warstwa adnotacji, a ona jest znacznie mniej podatna na błędy.
FAQ
Nie. Dekompilator przekształca bytecode z powrotem w czytelny kod źródłowy. ASM operuje bezpośrednio na bytecode i służy do jego modyfikacji, a nie do odzyskiwania kodu źródłowego.
Zazwyczaj nie. Większość modów do Fabric używa Mixin, który ukrywa szczegóły ASM za pomocą adnotacji. Do surowego ASM sięgamy tylko wtedy, gdy potrzebujemy precyzyjnej kontroli.
Nie. ASM to ogólna biblioteka Java używana w wielu narzędziach pracujących z bytecode. Modyfikacje Minecrafta to jedno z popularnych zastosowań, ale nie jedyne.
Nie możesz. Gra jest dystrybuowana w formie skompilowanych plików, a nie kodu źródłowego, który możesz modyfikować i rekompilować. Edycja bytecode'u to praktyczny sposób na poprawki kodu, którego nie posiadasz.