Dezvoltare10 min de citit

Compilează clientul Metin2 pentru Android și conectează-te la serverul de test

Compilează portul Android Cemre, pregătește date compatibile și configurează serverul de test. Depanează problemele ABI, protocol și porturi.

De METIN2.GG

Clientul ales și scopul ghidului

Cel mai util punct de pornire public pe care l-am găsit pentru un client Metin2 complet pe Android este cemreefe/metin2-android. Include clientul C++ original, un launcher Android, intrare tactilă, biblioteci native și un ghid de conectare la un server compatibil. Acest tutorial folosește revizia 4ac33651d49000de95e520e6de4373213dc54405. APK-ul nu este universal pentru orice server privat: clientul, datele jocului și serverul trebuie să fie compatibile.

Există o precizare importantă privind termenul open source: la verificarea din 25 octombrie 2026, depozitul principal nu declarase o licență pentru clientul complet. Faptul că sursa este publică nu oferă automat dreptul de redistribuire. Componenta OpenGr2ndma este licențiată MPL-2.0, dar aceasta nu acoperă restul clientului sau datele originale ale jocului. Acest ghid nu include date de joc și nici APK cu astfel de date. Revizia sursei analizate, licența OpenGr2ndma.

Războinic Metin2 în armură albastru-argintie pe telefon lângă un laptop de dezvoltare

Ilustrație: un personaj Metin2 recognoscibil pe telefon în timp ce este pregătit un client. Nu este o captură a compilării sau a jocului.

De ce acest proiect și ce am găsit pe forumuri

În discuția Turkmmo Metin2 Mobile & PC Cross Platform Source, după autentificare sunt disponibile arhive BGFX/OpenGL. Arhiva opengl.zip verificată conține într-adevăr un proiect Android și un client C++. Îi lipsesc însă bibliotecile Android .a/.so necesare compilării; biblioteca Granny pentru Windows inclusă nu le poate înlocui. Nu am găsit un APK gata făcut, un wrapper Gradle complet ori o licență pentru întregul client. Am inspectat fișierele fără să rulăm programele incluse.

Discuția mai nouă cu titlul Mobile Source … Full descrie în postare un prototip Unity. Controalele tactile și Android/iOS sunt prezentate drept lucrări viitoare. Nu am examinat arhiva mare separată legată acolo; titlul singur nu dovedește că există un client mobil complet.

Proiect Ce demonstrează sursele publice Cum se potrivește acestui ghid
Portul Android Cemre C++/Java, biblioteci pentru două ABI-uri, profile, instalator de date, interfață tactilă și sursa serverului local Cel mai puternic candidat dintre cele analizate; licența clientului principal rămâne neclară
Arhiva OpenGL distribuită pe Turkmmo Schelet Android și mult cod de client, dar fără biblioteci Android Necesită portare și dependențe suplimentare
Metin2ToUnity pe M2Dev Instrumente de conversie a resurselor jocului Un importer nu este un client complet de rețea
metin2-godot Licență MIT pentru propriul cod și etape de dezvoltare documentate O bază interesantă de dezvoltare, nu un port Android gata

Autorul portului spune că s-a conectat, a intrat în lume, a luptat, a deschis inventarul și a salvat. Dovezile principale vin de pe un emulator x86_64; un telefon fizic arm64 și sesiunile lungi necesită verificări separate. Pentru contextul proiectelor vezi prezentarea clienților mobili Metin2.

Alege mai întâi o configurație verificabilă

Procedura principală conectează un client Android la propriul server de test prin rețeaua locală. Rulează serverul pe un calculator Linux separat sau într-o mașină virtuală și conectează telefonul la același Wi-Fi. Varianta cu server inclus în APK este descrisă separat mai jos.

Componentă Revizie/versiune fixată
Client Android 4ac33651d49000de95e520e6de4373213dc54405
m2dev-server-src 66068c1
m2dev-server: configurare, hărți, SQL și misiuni ad30738
Structura de date așteptată de m2dev-client 98d2c1af; folosește doar date pe care ai dreptul să le folosești
Java / Gradle JDK 17 / Gradle 8.1.1
Unelte Android platforma 33, Build Tools 33.0.1, NDK 25.2.9519653, CMake 3.22.1
ABI țintă arm64-v8a pentru un telefon compatibil; x86_64 pentru un emulator compatibil

Build Tools 33.0.1 apare în app/build.gradle, deși exemplul de instalare din upstream indică o altă versiune de patch. Nu înlocui automat versiunile fixate cu cele mai noi.

1. Instalează uneltele și descarcă revizia exactă

Comenzile următoare sunt pentru Bash pe Linux. Setează căile reale către Android SDK și o instalare separată de Gradle 8.1.1. JDK 17 trebuie activ în JAVA_HOME. Instalează SDK-ul cu uneltele oficiale Android și citește tu eventualii termeni noi de licență înainte să-i accepți. Documentația SDK Manager.

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"

OpenGr2ndma este fixat la commit-ul 210f5c326531297495c24e7bb1e24dc1b1a77833. Dacă omiți submodulul, CMake va eșua; descărcarea unui ZIP de pe GitHub nu îl inițializează automat. Păstrează între ghilimele calea r10dev.net OPENGL-ITJA, care conține spații.

2. Creează propriul profil și dezactivează catalogul extern

Salvează aceste setări în profiles/home.properties. Înlocuiește 192.168.1.50 cu adresa LAN a serverului tău Linux. Pe telefon, 127.0.0.1 indică telefonul, nu calculatorul pe care rulează serverul.

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=

În servers/servers.json lasă doar serverul tău de test:

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

Valoarea goală m2.serverListUrl= este intenționată. Dacă proprietatea lipsește, build-ul folosește catalogul extern implicit al autorului. Un m2.devUrl= gol dezactivează încărcarea opțională a diagnosticelor și verificarea actualizărilor. Astfel, serverul de dezvoltare al altcuiva nu apare în build-ul tău de laborator. Detalii: ServerCatalog.java și DevReporter.java.

3. Compilează întâi APK-ul fără datele jocului

Astfel separi erorile uneltelor și bibliotecilor native de problemele datelor ori serverului. O compilare reușită nu înseamnă automat că poți intra în lumea jocului.

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

Pentru emulatorul x86_64 schimbă ultimul argument în -Pm2abi=x86_64. ABI-ul trebuie să corespundă dispozitivului. În timpul verificării depozitul nu oferea un APK public gata de instalat; comanda creează propriul build debug.

Rezultatul concret al compilării

Prima noastră compilare Windows a reviziei nemodificate s-a oprit la C++: UserInterface/Locale.h ascundea antetul de sistem <locale.h>. Într-o copie separată am eliminat ${CMAKE_CURRENT_SOURCE_DIR}/UserInterface din lista include_directories(...) din clientsource/CMakeLists.txt și am adăugat imediat după listă:

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

Directorul jocului rămâne disponibil pentru include-urile dintre ghilimele fără să interfereze cu căutarea antetelor de sistem. Cu schimbarea, assembleDebug s-a încheiat cu succes pentru x86_64 și a produs un APK cu biblioteca nativă a clientului. Este un build al unei copii de lucru ajustate, nu dovada că upstream-ul nemodificat se compilează pe orice Windows. Pașii Linux de mai sus urmează codul și ghidul autorului. Nu am verificat intrarea în lume, un telefon fizic, performanța sau serverul inclus.

4. Pregătește datele compatibile cu scriptul furnizat

Pune un checkout de date cu structura așteptată în ~/metin2-lab/client-data și folosește doar date pe care ai dreptul să le folosești. Ghidul nu acordă drepturi asupra modelelor, hărților sau muzicii originale. Un pack aleatoriu de pe alt server privat nu este un înlocuitor verificat; protourile, interfața Python și formatele pot diferi.

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 unește pack-urile într-o ordine stabilită, pune root deasupra, convertește item_proto/mob_proto și adaugă scripturi de compatibilitate, scalare și HUD tactil. Verifică rezultatul stagingului înainte să suspectezi rendererul. Nu redenumi în masă fișierele coreene cu litere mici.

Clientul are nevoie și de biblioteca standard Python 2.7.18, adică directorul Lib, nu de Python 3 al sistemului. Extrage-l din arhiva oficială de surse Python 2.7.18 într-un director de lucru separat. De exemplu, setează M2_PYLIB=~/metin2-lab/python-2.7.18/Lib. Python 2 nu este un runtime suportat pentru serviciile obișnuite de pe host; aici este o dependență a clientului vechi.

Pentru a include datele în APK, setează m2.dataBundled=true în home.properties, apoi rulează:

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

Rezultatul este ~/metin2-lab/bundle/metin2-home-1.apk și un ZIP cu versiunea datelor. Rezervă spațiu pentru datele pregătite, ZIP și APK. Când schimbi datele, mărește m2.dataVersion; ștergerea ZIP-ului singură nu obligă aplicația instalată să despacheteze din nou aceeași versiune. Numărul de build APK este separat. Detalii în make_bundle.sh.

5. Pregătește un server compatibil și adrese accesibile pentru core-uri

Această parte urmează ghidul autorului pentru găzduire proprie. Folosește o VM Linux separată pentru test; nu modifica un server de producție existent. Upstream indică 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)

Creează bazele de date și un utilizator cu drepturi limitate înainte de pornire. SQL-ul este pentru o VM nouă și separată, fără baze existente cu aceste nume. În sudo mariadb, înlocuiește ambele valori DOPLN_VLASTNI_HESLO cu aceeași parolă puternică. Nu rula SQL-ul cu acel placeholder literal.

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';

Importă apoi cele patru scheme furnizate. Conform runtime-ului, hotbackup trebuie să rămână goală inițial:

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

În share/conf/db.txt, schimbă perechea utilizator/parolă din SQL_ACCOUNT, SQL_PLAYER, SQL_COMMON și SQL_HOTBACKUP cu datele tale m2lab. În share/conf/game.txt fă la fel pentru ACCOUNT_SQL, PLAYER_SQL, COMMON_SQL și LOG_SQL. Păstrează celelalte valori și ordinea câmpurilor fiecărui fișier. Nu salva parole reale într-un depozit Git public. Configurarea DB, configurarea jocului.

MariaDB trebuie să asculte numai pe 127.0.0.1; telefonul nu se conectează la baza de date. În această VM adaugă sub [mysqld] în /etc/mysql/mariadb.conf.d/99-metin2-lab.cnf:

[mysqld]
bind-address=127.0.0.1
sql_mode=NO_ENGINE_SUBSTITUTION

După sudo systemctl restart mariadb, testează conexiunea cu mariadb -h 127.0.0.1 -u m2lab -p account. Introdu parola doar când ți se cere. Runtime-ul vechi are nevoie de modul SQL; nu-l aplica unei baze de date folosite de alt proiect.

Creează un cont nou de test pentru joc în această bază; dump-ul conține și conturi predefinite. Înlocuiește exemplele cu datele tale:

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

După pregătirea bazelor rulează python3 install.py în m2srv. Acesta generează fișierele de configurare. Apoi setează adresa accesibilă de telefon în fiecare fișier channels/channel1/coreN/CONFIG pentru joc:

BIND_IP: 192.168.1.50

Detectarea implicită poate omite adresa LAN a serverului. Fiecare core își anunță propria adresă clientului. Verifică din nou setarea după o nouă rulare install.py, deoarece fișierele sunt regenerate.

Conexiune Port TCP implicit Acces de pe telefon
Login 11000 Da, numai în LAN-ul de test
Core-urile de joc ale canalului 1 11011, 11012, 11013 Toate trei; schimbarea hărții poate redirecționa clientul
Procesul DB 9000 Comunicare internă a serverului
P2P între core-uri 12000 și următoarele Comunicare internă a serverului

În m2srv, pornește canalul cu python3 start.py 1 și oprește-l cu python3 stop.py. Verifică logurile de autentificare și ale celor trei core-uri. Dacă loginul funcționează, dar după alegerea personajului revii la lista serverelor, verifică mai întâi adresa și portul core-ului destinație. Portul de login singur nu este suficient.

Nu actualiza serverul fără verificare. Începând cu commit-ul serverului 0cc595bf097dcf89ddba60615e56fe790823cd22, handshake-ul trece la 0xf8 cu libsodium/XChaCha20. Clientul selectat așteaptă vechiul 0xfb/0xfa. Un server mai nou cere portarea efectivă a protocolului în client; schimbarea IP-ului sau a parolei nu rezolvă problema.

6. Instalează pe telefon și verifică prima pornire

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

Deschide aplicația, alege propriul Home Lab și conectează-te numai cu contul de test al serverului tău. ID-ul pachetului pentru acest profil este com.metin2.client.lab; directorul extern de date este de obicei:

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

Pachetul de bază folosește com.metin2.client, iar profilul offline upstream com.metin2.client.offline. Căile diferă. Aplicația folosește getExternalFilesDir(null), deci verifică directorul real pe dispozitiv. Dacă actualizarea eșuează, controlează întâi ABI-ul, ID-ul pachetului și semnătura APK-ului. Dezinstalarea fără verificare poate șterge personajele offline.

Simptom Ce verifici mai întâi
CMake nu găsește OpenGr2ndma Inițializarea submodulului și commit-ul fixat
APK-ul nu se instalează pentru ABI ro.product.cpu.abilist față de -Pm2abi
Deconectare imediat după login Versiunea handshake-ului serverului, apoi logurile
Revenire după alegerea personajului IP-ul redirecționat, BIND_IP și toate porturile core
UI lipsă sau ecran negru Staging, protouri, Python Lib și syserr.txt
Date vechi după actualizare m2.dataVersion mai mare, profilul și ZIP-ul corecte

Include întregul server în APK

Profilul upstream bundled compilează procesele serverului pentru Android, adaugă un strat SQLite în locul MySQL și împachetează datele serverului cu clientul. Telefonul nu mai are nevoie de un server la distanță. Este un build separat cu propriul pachet de date, nu o funcție automată a APK-ului de la pasul 3.

Pentru modul offline, înlocuiește mai întâi servers/servers.json cu acest catalog local:

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

Altfel, după pașii LAN de mai sus va rămâne în listă doar serverul Home Lab de la distanță. În profiles/bundled.properties, lasă goale m2.serverListUrl=, m2.devUrl= și m2.updateChannel=. Păstrează m2.serverMode=embedded, m2.dataBundled=true și sufixul .offline. Mărește m2.dataVersion pentru un pachet de date nou. Cu checkout-urile source/runtime pregătite, rulează:

"$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

Înainte, verifică bundled.properties, catalogul local, dataVersion și contul de test din baza seed. make-server-pack.sh așteaptă checkout-ul runtime, checkout-ul sursă și directorul de ieșire, în această ordine. Nu copia aici exemplul diferit din secțiunea web upstream. Sarcina Gradle pentru serverul embedded folosește căi NDK specifice Linux; build-ul offline pentru Windows nu a fost verificat.

Build-ul reușit, aplicația pornită, loginul și jocul continuu sunt rezultate diferite. Pentru testul propriu creează un personaj, intră pe o hartă, luptă, schimbă core-ul, repornește aplicația și verifică salvarea inventarului. Fără aceste verificări nu poți afirma că o anumită combinație de telefon și server a fost testată.

Întrebări frecvente

Se va conecta acest client la serverul meu privat preferat?

Numai dacă operatorul oferă un protocol și date compatibile și permite acest client. Ghidul acoperă combinația menționată Cemre/m2dev, nu toate serverele cu modificări proprii. APK-ul nu înlocuiește universal launcherele lor.

Este și un ghid pentru iPhone?

Nu. Proiectul și uneltele descrise țintesc Android. Menționarea iOS într-o altă discuție de dezvoltare nu confirmă existența unei versiuni iOS a acestui client.

Pot distribui public APK-ul cu datele jocului?

Codul sursă public sau licența unei biblioteci nu rezolvă drepturile asupra întregului client ori asupra datelor originale ale jocului. Înainte de distribuire, clarifică permisiunile pentru fiecare componentă inclusă. Acest articol nu acordă aceste drepturi.

Pagini asociate

Găsește serverul perfect

Navighează prin cele mai bine clasate servere private Metin2 pe METIN2.GG sau adaugă propriul server în clasament.