Tworzenie gier9 min czytania

Zbuduj klienta Metin2 na Androida i połącz go z testowym serwerem

Zbuduj port Cemre na Androida, przygotuj zgodne dane i skonfiguruj serwer testowy. Rozwiąż problemy ABI, protokołu i portów.

Autor METIN2.GG

Wybrany klient i zakres poradnika

Najbardziej przydatnym publicznym punktem wyjścia, jaki znaleźliśmy do uruchomienia pełnego klienta Metin2 na Androidzie, jest cemreefe/metin2-android. Projekt zawiera oryginalnego klienta C++, launcher Androida, sterowanie dotykiem, biblioteki natywne i instrukcję połączenia z kompatybilnym serwerem. Poradnik dotyczy konkretnej rewizji 4ac33651d49000de95e520e6de4373213dc54405. To nie jest uniwersalna APK dla każdego prywatnego serwera: klient, dane gry i serwer muszą być zgodne.

Ważne zastrzeżenie dotyczące określenia open source: 25 października 2026 r. główne repozytorium nie podawało licencji obejmującej cały klient. Publicznie widoczny kod nie oznacza automatycznej zgody na jego dalsze rozpowszechnianie. Komponent OpenGr2ndma ma licencję MPL-2.0, lecz nie obejmuje całego klienta ani oryginalnych danych gry. Ten poradnik nie zawiera danych gry ani APK z tymi danymi. Wybrana rewizja źródeł, licencja OpenGr2ndma.

Wojownik Metin2 w srebrnoniebieskiej zbroi na telefonie obok laptopa deweloperskiego

Ilustracja: rozpoznawalna postać Metin2 na telefonie podczas przygotowywania klienta. To nie jest zrzut ekranu kompilacji ani rozgrywki.

Dlaczego ten projekt i co znaleźliśmy na forach

W wątku Metin2 Mobile & PC Cross Platform Source na Turkmmo po zalogowaniu dostępne są archiwa BGFX/OpenGL. Sprawdzone opengl.zip rzeczywiście zawiera projekt Android i klienta C++. Brakuje w nim jednak wymaganych do kompilacji bibliotek Android .a/.so; dołączona biblioteka Granny dla Windows ich nie zastępuje. Nie znaleźliśmy gotowego APK, pełnego wrappera Gradle ani licencji na cały klient. Przejrzeliśmy pliki, lecz nie uruchamialiśmy dołączonych programów.

Nowszy wątek zatytułowany Mobile Source … Full opisuje w treści prototyp Unity. Sterowanie dotykowe oraz Android/iOS są tam wymienione jako dalsze prace. Nie sprawdziliśmy osobnego dużego archiwum podanego w tym wątku; sam tytuł nie dowodzi istnienia gotowego klienta mobilnego.

Projekt Co potwierdzają publiczne materiały Przydatność w tym poradniku
Port Android Cemre C++/Java, biblioteki dla dwóch ABI, profile, instalator danych, dotykowy interfejs i kod lokalnego serwera Najmocniejszy kandydat spośród sprawdzonych; licencja głównego klienta pozostaje niejasna
Udostępnione archiwum OpenGL z Turkmmo Szkielet Android i dużo kodu klienta, ale brak bibliotek Android Wymaga dalszego portowania i uzupełnienia zależności
Metin2ToUnity na M2Dev Narzędzia do konwersji zasobów gry Importer nie jest pełnym klientem sieciowym
metin2-godot Licencja MIT na własny kod i opisane etapy rozwoju Ciekawa baza do tworzenia, ale nie gotowy port Android

Autor portu informuje o logowaniu, wejściu do świata, walce, ekwipunku i zapisie. Główne dowody pochodzą z emulatora x86_64; osobnych testów wymaga telefon arm64 i dłuższa gra. Szerszy przegląd projektów znajdziesz w naszym artykule o mobilnych klientach Metin2.

Najpierw wybierz jedną sprawdzalną konfigurację

Główna procedura łączy klienta Android z własnym serwerem testowym przez sieć lokalną. Uruchom serwer na osobnym komputerze lub maszynie wirtualnej z Linuksem, a telefon podłącz do tej samej sieci Wi-Fi. Wariant z serwerem w APK opisujemy osobno na końcu.

Element Przypięta rewizja/wersja
Klient Android 4ac33651d49000de95e520e6de4373213dc54405
m2dev-server-src 66068c1
m2dev-server: konfiguracja, mapy, SQL i zadania ad30738
Oczekiwana struktura danych m2dev-client 98d2c1af; używaj tylko danych, do których masz prawa
Java / Gradle JDK 17 / Gradle 8.1.1
Narzędzia Android platforma 33, Build Tools 33.0.1, NDK 25.2.9519653, CMake 3.22.1
Docelowe ABI arm64-v8a dla zgodnego telefonu, x86_64 dla zgodnego emulatora

Build Tools 33.0.1 jest ustawione w app/build.gradle, choć przykład instalacji w upstream wymienia inną poprawkę wersji. Nie zamieniaj przypiętych narzędzi na najnowsze bez sprawdzenia.

1. Zainstaluj narzędzia i pobierz dokładną rewizję

Poniższe polecenia są przeznaczone dla Bash w Linuksie. Ustaw prawdziwą ścieżkę SDK Android i osobną instalację Gradle 8.1.1. JDK 17 musi być aktywne w JAVA_HOME. SDK instaluj oficjalnymi narzędziami Androida i samodzielnie przeczytaj oraz zaakceptuj ewentualne nowe warunki licencji. Dokumentacja SDK Managera.

java -version
gradle --version
sdkmanager "platforms;android-33" "build-tools;33.0.1" \
  "ndk;25.2.9519653" "cmake;3.22.1" "platform-tools"

mkdir -p "$HOME/metin2-lab"
cd "$HOME/metin2-lab"
git clone https://github.com/cemreefe/metin2-android.git
cd metin2-android
git checkout --detach 4ac33651d49000de95e520e6de4373213dc54405
git submodule update --init --recursive
git submodule status

export M2_REPO="$PWD"
export M2_ANDROID="$M2_REPO/r10dev.net OPENGL-ITJA/android"
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
export GRADLE="/opt/gradle-8.1.1/bin/gradle"
printf 'sdk.dir=%s\n' "$ANDROID_SDK_ROOT" > "$M2_ANDROID/local.properties"

W tej rewizji OpenGr2ndma wskazuje commit 210f5c326531297495c24e7bb1e24dc1b1a77833. Pominięcie submodułu powoduje błąd CMake; pobranie ZIP-a z GitHuba nie inicjuje go automatycznie. Ścieżkę r10dev.net OPENGL-ITJA ujmij w cudzysłowy z powodu spacji.

2. Utwórz własny profil i wyłącz zewnętrzny katalog

Zapisz te ustawienia w profiles/home.properties. Zastąp 192.168.1.50 lokalnym adresem serwera Linux. Na telefonie 127.0.0.1 oznacza sam telefon, a nie komputer z serwerem.

m2.abi=arm64-v8a
m2.serverMode=remote
m2.serverHost=192.168.1.50
m2.authPort=11000
m2.channelPort=11011
m2.gamePortOffset=0
m2.applicationIdSuffix=.lab
m2.appLabel=Metin2 Local Lab
m2.versionName=home
m2.dataBundled=false
m2.dataUrl=
m2.dataVersion=1
m2.serverListUrl=
m2.devUrl=
m2.updateChannel=

W servers/servers.json umieść wyłącznie własny serwer testowy:

{
  "version": 1,
  "servers": [
    {
      "name": "Home Lab",
      "host": "192.168.1.50",
      "authPort": 11000,
      "channelPort": 11011
    }
  ]
}

Puste m2.serverListUrl= jest celowe. Gdy brakuje tej właściwości, build używa domyślnego zewnętrznego katalogu autora. Puste m2.devUrl= wyłącza opcjonalne wysyłanie diagnostyki i sprawdzanie aktualizacji. Dzięki temu build laboratoryjny nie wyświetla serwera deweloperskiego innej osoby. Zobacz ServerCatalog.java i DevReporter.java.

3. Najpierw zbuduj APK bez danych gry

Dzięki temu błędy łańcucha narzędzi i natywnych bibliotek odróżnisz od problemów z danymi lub serwerem. Sam poprawny build nie oznacza jeszcze wejścia do świata gry.

cd "$M2_ANDROID"
"$GRADLE" --no-daemon --max-workers=4 assembleDebug \
  -Pm2profile=home -Pm2abi=arm64-v8a
ls -lh app/build/outputs/apk/debug/app-debug.apk

Dla emulatora x86_64 zmień ostatni argument na -Pm2abi=x86_64. ABI musi odpowiadać urządzeniu. Podczas tej kontroli repozytorium nie miało gotowego publicznego APK; polecenie tworzy własny build debug.

Konkretny wynik kompilacji

Pierwsza próba z niezmienioną rewizją na Windows zatrzymała się podczas kompilacji C++: UserInterface/Locale.h zasłaniał systemowe <locale.h>. W osobnej kopii roboczej usunęliśmy ${CMAKE_CURRENT_SOURCE_DIR}/UserInterface z listy include_directories(...) w clientsource/CMakeLists.txt i bezpośrednio za nią dodaliśmy:

add_compile_options("-iquote${CMAKE_CURRENT_SOURCE_DIR}/UserInterface")

Katalog gry nadal jest dostępny dla nagłówków wpisywanych w cudzysłowie, ale nie przeszkadza w wyszukiwaniu nagłówków systemowych. Po zmianie assembleDebug zakończył się poprawnie dla x86_64 i utworzył APK z natywną biblioteką klienta. To potwierdzenie kompilacji zmodyfikowanej kopii roboczej, a nie dowód, że niezmieniony upstream zbuduje się na każdym Windows. Kroki Linuksowe pochodzą z kodu i instrukcji autora. Nie testowaliśmy wejścia do świata, telefonu fizycznego, wydajności ani serwera wbudowanego.

4. Przygotuj zgodne dane za pomocą dołączonego skryptu

Umieść checkout danych o oczekiwanej strukturze w ~/metin2-lab/client-data i używaj wyłącznie danych, do których masz prawo. Ten poradnik nie udziela praw do modeli, map ani muzyki. Losowy pack innego prywatnego serwera nie jest sprawdzonym zamiennikiem; mogą różnić się proto, interfejs Python i formaty plików.

sudo apt install rsync patch python3-pil libsodium23 liblzo2-2 zip imagemagick ninja-build
export M2_DATA="$HOME/metin2-lab/client-data"
export M2_STAGE="$HOME/metin2-lab/staged-data"
test -d "$M2_DATA/assets/root"
"$M2_ANDROID/tools/stage_client_data.sh" "$M2_DATA" "$M2_STAGE" en

stage_client_data.sh scala packi w określonej kolejności, nakłada katalog root, konwertuje item_proto/mob_proto i dodaje skrypty zgodności, skalowanie oraz dotykowy HUD. Zanim zaczniesz szukać problemu w rendererze, sprawdź wynik stagingu. Nie zmieniaj masowo koreańskich nazw plików na małe litery.

Klient potrzebuje też standardowej biblioteki Python 2.7.18, czyli katalogu Lib, a nie systemowego Python 3. Rozpakuj ją z oficjalnego archiwum źródłowego Python 2.7.18 do osobnego katalogu roboczego. Przykładowo ustaw M2_PYLIB=~/metin2-lab/python-2.7.18/Lib. Python 2 nie jest wspieranym środowiskiem dla zwykłych usług; tutaj to zależność starego klienta.

Aby umieścić dane w APK, ustaw m2.dataBundled=true w home.properties, a następnie uruchom:

export M2_PYLIB="$HOME/metin2-lab/python-2.7.18/Lib"
test -f "$M2_PYLIB/os.py"
M2_CLIENT_DATA="$M2_STAGE" M2_PYLIB="$M2_PYLIB" \
M2_BUNDLE_OUT="$HOME/metin2-lab/bundle" GRADLE="$GRADLE" \
  "$M2_ANDROID/tools/make_bundle.sh" home 1

Wynikiem będzie ~/metin2-lab/bundle/metin2-home-1.apk oraz wersjonowany ZIP z danymi. Zostaw miejsce na dane, ZIP i APK. Po zmianie danych zwiększ m2.dataVersion; samo skasowanie ZIP-a nie powoduje ponownego rozpakowania tej samej wersji w już zainstalowanej aplikacji. Numer buildu APK jest osobny. Szczegóły zawiera make_bundle.sh.

5. Przygotuj zgodny serwer i osiągalne adresy core'ów

Ta część opiera się na instrukcji self-hostingu autora. Użyj osobnej testowej VM z Linuksem, nie istniejącego serwera produkcyjnego. Upstream podaje Ubuntu 22.04, g++ 11, CMake 3.22 i MariaDB 10.6.

sudo apt install build-essential cmake git mariadb-server python3
cd "$HOME/metin2-lab"
git clone https://github.com/d1str4ught/m2dev-server-src.git
git -C m2dev-server-src checkout --detach 66068c1
git -C m2dev-server-src apply "$M2_REPO/server/m2dev-server-src-linux.patch"
cmake -S m2dev-server-src -B m2dev-server-src/build -DCMAKE_BUILD_TYPE=Release
cmake --build m2dev-server-src/build -j4

git clone https://github.com/d1str4ught/m2dev-server.git m2srv
git -C m2srv checkout --detach ad30738
cp m2dev-server-src/build/bin/{db,game,qc} m2srv/share/bin/
cp m2srv/share/bin/qc m2srv/share/locale/english/quest/qc
(cd m2srv/share/locale/english/quest && python3 make.py)

Przed uruchomieniem utwórz bazy i użytkownika o ograniczonych uprawnieniach. SQL dotyczy nowej, osobnej VM, na której nie ma jeszcze baz o tych nazwach. W sudo mariadb zastąp oba wystąpienia DOPLN_VLASTNI_HESLO tym samym mocnym hasłem; nie uruchamiaj kodu z dosłownym placeholderem.

CREATE DATABASE account;
CREATE DATABASE common;
CREATE DATABASE player;
CREATE DATABASE log;
CREATE DATABASE hotbackup;
CREATE USER 'm2lab'@'127.0.0.1' IDENTIFIED BY 'DOPLN_VLASTNI_HESLO';
CREATE USER 'm2lab'@'localhost' IDENTIFIED BY 'DOPLN_VLASTNI_HESLO';
GRANT ALL ON account.* TO 'm2lab'@'127.0.0.1', 'm2lab'@'localhost';
GRANT ALL ON common.* TO 'm2lab'@'127.0.0.1', 'm2lab'@'localhost';
GRANT ALL ON player.* TO 'm2lab'@'127.0.0.1', 'm2lab'@'localhost';
GRANT ALL ON log.* TO 'm2lab'@'127.0.0.1', 'm2lab'@'localhost';
GRANT ALL ON hotbackup.* TO 'm2lab'@'127.0.0.1', 'm2lab'@'localhost';

Zaimportuj następnie cztery dostarczone schematy. Według runtime baza hotbackup początkowo powinna pozostać pusta:

cd "$HOME/metin2-lab/m2srv"
for db in account common player log; do
  sudo mariadb "$db" < "sql/$db.sql"
done

W share/conf/db.txt zmień użytkownika i hasło w wierszach SQL_ACCOUNT, SQL_PLAYER, SQL_COMMON i SQL_HOTBACKUP na własne dane m2lab. W share/conf/game.txt zrób to samo dla ACCOUNT_SQL, PLAYER_SQL, COMMON_SQL i LOG_SQL. Zachowaj pozostałe wartości i kolejność pól w obu plikach. Nie zapisuj prawdziwych haseł w publicznym Git. Konfiguracja DB, konfiguracja gry.

MariaDB ma nasłuchiwać wyłącznie na 127.0.0.1; telefon nie łączy się z bazą. Na tej VM dodaj pod [mysqld] w /etc/mysql/mariadb.conf.d/99-metin2-lab.cnf:

[mysqld]
bind-address=127.0.0.1
sql_mode=NO_ENGINE_SUBSTITUTION

Po sudo systemctl restart mariadb sprawdź połączenie poleceniem mariadb -h 127.0.0.1 -u m2lab -p account. Hasło wpisz dopiero po wyświetleniu monitu. Stary runtime wymaga tego trybu SQL; nie ustawiaj go w bazie współdzielonej przez inny projekt.

Utwórz nowe testowe konto gry w tej bazie; dump zawiera też gotowe konta. Zastąp przykładowe wartości własnymi:

INSERT INTO account.account (login, password, social_id, status)
VALUES ('VLASTNI_TEST_LOGIN', PASSWORD('VLASTNI_TEST_HESLO'), '1234567', 'OK');

Po przygotowaniu baz uruchom python3 install.py w m2srv. Skrypt generuje konfiguracje. Następnie w każdym pliku channels/channel1/coreN/CONFIG ustaw adres osiągalny z telefonu:

BIND_IP: 192.168.1.50

Automatyczne wykrywanie może pominąć lokalny adres serwera. Każdy core ogłasza klientowi własny adres. Po ponownym uruchomieniu install.py sprawdź to ustawienie, bo pliki zostaną wygenerowane od nowa.

Połączenie Domyślny port TCP Dostępność z telefonu
Logowanie 11000 Tak, tylko w testowej sieci LAN
Core'y gry kanału 1 11011, 11012, 11013 Wszystkie trzy, bo zmiana mapy może przekierować klienta
Proces DB 9000 Komunikacja wewnętrzna serwera
P2P między core'ami 12000 i kolejne Komunikacja wewnętrzna serwera

W m2srv uruchom kanał przez python3 start.py 1, a zatrzymaj przez python3 stop.py. Sprawdź logi auth i wszystkich trzech core'ów. Jeżeli logowanie działa, ale po wyborze postaci wracasz do listy serwerów, najpierw sprawdź adres i port docelowego core'a. Sam port logowania nie wystarczy.

Nie aktualizuj serwera w ciemno. Od commitu 0cc595bf097dcf89ddba60615e56fe790823cd22 handshake zmienia się na 0xf8 z libsodium/XChaCha20. Ten klient oczekuje starszego 0xfb/0xfa. Nowszy serwer wymaga przeniesienia jego protokołu do klienta; zmiana IP lub hasła nie pomoże.

6. Zainstaluj klienta na telefonie i sprawdź pierwsze uruchomienie

adb devices
adb shell getprop ro.product.cpu.abilist
adb install -r "$HOME/metin2-lab/bundle/metin2-home-1.apk"
adb shell pm path com.metin2.client.lab

Uruchom aplikację, wybierz swój Home Lab i zaloguj się testowym kontem z własnego serwera. Identyfikator pakietu tego profilu to com.metin2.client.lab; zewnętrzne dane aplikacji zwykle są tutaj:

adb shell ls /sdcard/Android/data/com.metin2.client.lab/files/
adb shell cat /sdcard/Android/data/com.metin2.client.lab/files/syserr.txt
adb logcat -d > metin2-android-logcat.txt

Pakiet podstawowy używa com.metin2.client, a upstreamowy profil offline com.metin2.client.offline. Nie myl ich ścieżek. Aplikacja korzysta z getExternalFilesDir(null), więc sprawdź rzeczywisty katalog na urządzeniu. Przy problemach z aktualizacją najpierw skontroluj ABI, identyfikator pakietu i podpis APK. Pochopne odinstalowanie może usunąć postacie offline.

Objaw Co sprawdzić najpierw
CMake nie znajduje OpenGr2ndma Inicjalizację submodułu i przypięty commit
APK nie instaluje się dla ABI ro.product.cpu.abilist względem -Pm2abi
Rozłączenie zaraz po logowaniu Wersję handshake serwera, potem logi
Powrót po wyborze postaci Przekierowane IP, BIND_IP i porty wszystkich core'ów
Brak UI lub czarny ekran Staging, proto, Python Lib i syserr.txt
Po aktualizacji stare dane Wyższe m2.dataVersion, profil i ZIP

Cały serwer wewnątrz APK

Profil bundled buduje procesy serwera dla Androida, dodaje warstwę SQLite zamiast MySQL i pakuje dane serwera razem z klientem. Telefon nie potrzebuje wtedy zewnętrznego serwera. Wymaga to osobnego buildu i pakietu danych; nie jest to automatyczna funkcja APK z kroku 3.

Przed trybem offline zastąp servers/servers.json lokalnym katalogiem:

{
  "version": 2,
  "servers": [
    { "name": "Single Player", "embedded": true }
  ]
}

W przeciwnym razie po wcześniejszej konfiguracji LAN na liście zostanie wyłącznie zdalny Home Lab. W profiles/bundled.properties ustaw puste m2.serverListUrl=, m2.devUrl= i m2.updateChannel=. Zachowaj m2.serverMode=embedded, m2.dataBundled=true i sufiks .offline. Przy nowym pakiecie danych zwiększ m2.dataVersion. Mając przygotowane checkouty source/runtime, uruchom:

"$M2_REPO/r10dev.net OPENGL-ITJA/server/tools/make-server-pack.sh" \
  "$HOME/metin2-lab/m2srv" \
  "$HOME/metin2-lab/m2dev-server-src" \
  "$HOME/metin2-lab/server-pack"

M2_SERVER_PACK="$HOME/metin2-lab/server-pack" \
M2_CLIENT_DATA="$M2_STAGE" M2_PYLIB="$M2_PYLIB" \
M2_BUNDLE_OUT="$HOME/metin2-lab/bundle" GRADLE="$GRADLE" \
  "$M2_ANDROID/tools/make_bundle.sh" bundled 1

Wcześniej sprawdź bundled.properties, własny katalog, dataVersion i konto testowe w bazie seed. make-server-pack.sh przyjmuje kolejno checkout runtime, checkout source i katalog wyjściowy. Nie kopiuj odmiennego przykładu z webowej części dokumentacji upstream. Zadanie Gradle dla serwera wbudowanego używa ścieżek NDK specyficznych dla Linuksa, więc kompilacja offline na Windows nie została tu zweryfikowana.

Udany build, uruchomiona aplikacja, logowanie i dłuższa rozgrywka to różne wyniki. We własnym teście utwórz postać, wejdź na mapę, walcz, przejdź między core'ami, uruchom aplikację ponownie i sprawdź zapisany ekwipunek. Bez tych prób nie można twierdzić, że konkretna kombinacja telefonu i serwera została sprawdzona.

Najczęściej Zadawane Pytania

Czy ten klient połączy się z moim ulubionym prywatnym serwerem?

Tylko jeśli operator obsługuje zgodny protokół i dane oraz dopuszcza ten klient. Poradnik dotyczy opisanej kombinacji Cemre/m2dev, a nie serwerów z własnymi zmianami. APK nie zastępuje uniwersalnie ich launcherów.

Czy to również instrukcja dla iPhone'a?

Nie. Projekt i narzędzia opisane tutaj obsługują Androida. Wzmianka o iOS w innym wątku developerskim nie potwierdza istnienia wersji iOS tego klienta.

Czy mogę publicznie udostępnić APK z danymi gry?

Publiczny kod źródłowy ani licencja pojedynczej biblioteki nie rozstrzygają praw do całego klienta i oryginalnych danych gry. Przed dystrybucją sprawdź uprawnienia do każdego składnika. Ten artykuł ich nie nadaje.

Powiązane Strony

Znajdź swój idealny serwer

Przeglądaj najlepiej oceniane prywatne serwery Metin2 na METIN2.GG lub dodaj własny serwer do rankingu.