Compilare un client Metin2 Android e collegarlo a un server di test
Guida per compilare il client Metin2 Android Cemre, preparare dati compatibili e collegare un server di test in LAN.
Client scelto e ambito della guida
Tra i progetti pubblici esaminati, cemreefe/metin2-android è la base più completa per provare il client Metin2 su Android. Include il client C++, un launcher Android, comandi touch, librerie native e istruzioni per collegarsi a un server compatibile. Questa guida segue la revisione 4ac33651d49000de95e520e6de4373213dc54405. Non è un APK universale per ogni server privato: client, dati di gioco e server devono essere compatibili.
Una precisazione sull’etichetta «open source»: al 25 ottobre 2026 il repository principale non indicava una licenza per l’intero client. Il codice pubblicamente visibile non autorizza automaticamente la redistribuzione. Il componente OpenGr2ndma è distribuito con MPL-2.0, mentre i dati originali del gioco hanno diritti separati. Questa guida non include né i dati né un APK che li contenga. Codice sorgente, licenza OpenGr2ndma.

Illustrazione: un personaggio riconoscibile di Metin2 su un telefono mentre si prepara un client personalizzato. Non è uno screenshot della compilazione o del gioco.
Perché questo client e cosa abbiamo trovato sui forum
Nel thread Metin2 Mobile & PC Cross Platform Source su Turkmmo sono disponibili, dopo l’accesso, le varianti BGFX e OpenGL. L’archivio opengl.zip esaminato contiene un progetto Android e codice client C++. Mancano però le librerie Android .a/.so necessarie per la compilazione; la libreria Granny per Windows inclusa non le sostituisce. Non abbiamo trovato APK pronto, wrapper Gradle completo o licenza dell’intero client. Abbiamo letto i file senza eseguire i programmi dell’archivio.
Un thread più recente intitolato «Mobile Source … Full» descrive un prototipo Unity e indica comandi touch e versioni Android/iOS tra i lavori futuri. Non abbiamo valutato il suo grande archivio separato. Il titolo del post da solo non dimostra che il client mobile sia completo.
| Progetto | Elementi pubblici osservati | Rilevanza per la guida |
|---|---|---|
| Port Android Cemre | C++/Java, librerie per due ABI, profili, installazione dati, interfaccia touch e server locale | Candidato più solido tra quelli esaminati; licenza del client principale non chiarita |
| Archivio OpenGL su Turkmmo | Struttura Android e codice client, ma senza librerie Android | Richiede altro porting e dipendenze |
| Metin2ToUnity su M2Dev | Strumenti e conversione delle risorse | Importatore, non client di rete completo |
| metin2-godot | Licenza MIT per il proprio codice, tappe di sviluppo documentate | Base utile per sviluppare, non port Android pronto da giocare |
L’autore del port dichiara di aver testato login, ingresso nel mondo, combattimento, inventario e salvataggio. Le sue prove principali provengono da un emulatore x86_64; serve una verifica autonoma su un telefono arm64 e nelle sessioni lunghe. Per il contesto generale, leggi la panoramica dei client mobili Metin2.
Scegli prima una combinazione verificabile
La procedura principale collega un client Android in LAN al proprio server di test. Il server gira su Linux o su una VM separata, mentre il telefono usa la stessa rete Wi-Fi. La modalità con server dentro l’APK è descritta alla fine.
| Componente | Revisione / versione |
|---|---|
| Client Android | 4ac33651d49000de95e520e6de4373213dc54405 |
| m2dev-server-src | 66068c1 |
| m2dev-server: configurazione, mappe, SQL e quest | ad30738 |
| Struttura dati attesa di m2dev-client | 98d2c1af; devi avere il diritto di usare questi dati |
| Java / Gradle | JDK 17 / Gradle 8.1.1 |
| Strumenti Android | piattaforma 33, Build Tools 33.0.1, NDK 25.2.9519653, CMake 3.22.1 |
| ABI obiettivo | arm64-v8a per il telefono compatibile, x86_64 per l’emulatore adatto |
Build Tools 33.0.1 è indicato in app/build.gradle; l’esempio d’installazione upstream riporta un numero minore diverso. Non sostituire automaticamente le versioni bloccate con le ultime disponibili.
1. Installa gli strumenti e scarica la revisione esatta
Questi comandi sono per Bash su Linux. Indica il percorso effettivo dell’SDK Android e di Gradle 8.1.1. JDK 17 deve essere attivo in JAVA_HOME. Installa l’SDK con gli strumenti ufficiali Android e leggi/accetta personalmente ogni nuova licenza. Documentazione SDK.
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"
Il sottomodulo OpenGr2ndma è fissato al commit 210f5c326531297495c24e7bb1e24dc1b1a77833. Se manca, CMake fallisce; scaricare uno ZIP di GitHub non lo inizializza. Mantieni tra virgolette il percorso r10dev.net OPENGL-ITJA.
2. Crea il profilo e disattiva il catalogo di terzi
Inserisci questo contenuto in profiles/home.properties. Sostituisci 192.168.1.50 con l’indirizzo LAN del server Linux. Sul telefono 127.0.0.1 indica il telefono stesso, non il PC server.
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=
In servers/servers.json lascia soltanto il tuo server di test:
{
"version": 1,
"servers": [
{
"name": "Home Lab",
"host": "192.168.1.50",
"authPort": 11000,
"channelPort": 11011
}
]
}
Lasciare vuoto m2.serverListUrl= è intenzionale: se la proprietà manca, la build usa il catalogo remoto predefinito dell’autore. Lasciare vuoto m2.devUrl= disattiva l’invio facoltativo di diagnostica e il controllo degli aggiornamenti. Il laboratorio non proporrà quindi un server di sviluppo di terzi. Vedi ServerCatalog.java e DevReporter.java.
3. Compila prima l’APK senza dati di gioco
Così distingui gli errori degli strumenti e delle librerie native dai problemi di dati o server. La sola compilazione non dimostra che si riesca a entrare nel mondo.
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
Per un emulatore x86_64 usa -Pm2abi=x86_64. L’ABI deve corrispondere al dispositivo. Al momento del controllo il repository non offriva un APK pubblico pronto; questa procedura crea una build debug.
Risultato concreto della build verificata
Su Windows la revisione originale si è fermata durante la compilazione C++: UserInterface/Locale.h copriva l’header di sistema locale.h. In una copia di lavoro separata abbiamo tolto il percorso UserInterface dall’elenco include_directories(...) in clientsource/CMakeLists.txt e poi aggiunto dopo l’elenco:
add_compile_options("-iquote${CMAKE_CURRENT_SOURCE_DIR}/UserInterface")
La cartella del gioco resta disponibile agli include tra virgolette, senza interferire con la ricerca degli header di sistema. Dopo questa modifica assembleDebug è riuscito per x86_64 e arm64-v8a, producendo un APK comune. Il risultato vale per la nostra copia di lavoro, non per il repository upstream senza modifiche su ogni Windows. I passaggi Linux derivano dal codice e dalla procedura dell’autore. Non abbiamo così verificato ingresso nel gioco, telefono fisico, prestazioni o server offline.
4. Prepara i dati con lo script di staging
Metti in ~/metin2-lab/client-data un checkout di dati che sei autorizzato a usare e con la struttura compatibile descritta sopra. Questa guida non concede diritti sui modelli, mappe o musiche originali. Un pack qualsiasi di un altro server privato non è un sostituto verificato: protos, interfaccia Python e formati possono differire.
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 fonde i pack nell’ordine previsto, mette root sopra gli altri, converte item_proto/mob_proto e aggiunge script di compatibilità, ridimensionamento e HUD touch. Se qualcosa non funziona, controlla lo staging prima del motore grafico. Non rinominare in massa i file coreani in minuscolo.
Il client richiede anche la libreria standard Python 2.7.18, nella cartella Lib, non il Python 3 del PC. Scarica il pacchetto sorgente ufficiale Python 2.7.18, estrailo in una cartella di lavoro separata e imposta, ad esempio, M2_PYLIB=~/metin2-lab/python-2.7.18/Lib. Python 2 non è un runtime host supportato per i normali servizi: qui è una dipendenza del vecchio client incorporato.
Per includere i dati nell’APK, imposta m2.dataBundled=true in home.properties, poi:
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
Otterrai ~/metin2-lab/bundle/metin2-home-1.apk e uno ZIP dati versionato. Serve spazio per dati estratti, ZIP e APK. Quando cambi i dati, aumenta m2.dataVersion: eliminare solo il vecchio ZIP non costringe un’app già installata a estrarre di nuovo la stessa versione dati. La versione APK è separata. Vedi make_bundle.sh.
5. Prepara un server compatibile e gli indirizzi dei core
Questa parte segue la guida self-hosting dell’autore. Usa una VM Linux di test separata, senza modificare un server di produzione. La documentazione upstream indica Ubuntu 22.04, g++ 11, CMake 3.22 e 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)
Prima di avviare, crea i database e un utente SQL con privilegi limitati. Questo SQL è destinato a una nuova VM isolata senza database con questi nomi. In sudo mariadb, sostituisci prima entrambe le occorrenze DOPLN_VLASTNI_HESLO con la stessa password robusta. Non lanciare il SQL con il testo segnaposto.
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';
Importa poi i quattro schemi forniti; il runtime prevede che hotbackup sia vuoto inizialmente:
cd "$HOME/metin2-lab/m2srv"
for db in account common player log; do
sudo mariadb "$db" < "sql/$db.sql"
done
In share/conf/db.txt cambia utente e password nelle righe SQL_ACCOUNT, SQL_PLAYER, SQL_COMMON e SQL_HOTBACKUP con il tuo m2lab e la password scelta. Fai lo stesso in share/conf/game.txt per ACCOUNT_SQL, PLAYER_SQL, COMMON_SQL e LOG_SQL. Mantieni gli altri valori e il diverso ordine dei campi nei due file. Non inserire credenziali reali in un repository Git pubblico. Configurazione DB, configurazione game.
MariaDB deve ascoltare solo su 127.0.0.1; il telefono non vi si collega. Nella VM crea il file separato /etc/mysql/mariadb.conf.d/99-metin2-lab.cnf sotto [mysqld]:
[mysqld]
bind-address=127.0.0.1
sql_mode=NO_ENGINE_SUBSTITUTION
Dopo sudo systemctl restart mariadb verifica con mariadb -h 127.0.0.1 -u m2lab -p account e digita la password al prompt. Il vecchio runtime richiede questa modalità SQL. Non estenderla a database condivisi di altri progetti.
Crea nuove credenziali di prova per l’account di gioco; il dump contiene account preconfigurati. Dopo aver sostituito i valori di esempio:
INSERT INTO account.account (login, password, social_id, status)
VALUES ('VLASTNI_TEST_LOGIN', PASSWORD('VLASTNI_TEST_HESLO'), '1234567', 'OK');
Preparati i database, esegui python3 install.py in m2srv. Le configurazioni verranno rigenerate. In ogni channels/channel1/coreN/CONFIG imposta l’indirizzo raggiungibile dal telefono:
BIND_IP: 192.168.1.50
Il rilevamento automatico può ignorare l’indirizzo LAN. Ogni core comunica il proprio IP al client. Se riesegui install.py, ricontrolla la modifica: i file generati vengono riscritti.
| Connessione | Porta TCP predefinita | Accesso dal telefono |
|---|---|---|
| Autenticazione | 11000 | Sì, solo nella LAN di prova |
| Core del canale 1 | 11011, 11012, 11013 | Tutti e tre: un cambio mappa può reindirizzare il client |
| Processo DB | 9000 | Comunicazione interna del server |
| P2P fra core | 12000 e successivi | Comunicazione interna del server |
In m2srv avvia il canale con python3 start.py 1 e fermalo con python3 stop.py. Controlla i log di auth e di tutti e tre i core. Se il login riesce ma dopo la selezione del personaggio torni alla lista server, verifica prima IP e porta del core che ospita la mappa. La sola porta auth non basta.
Non aggiornare il server alla cieca. Dal commit server 0cc595bf097dcf89ddba60615e56fe790823cd22 l’handshake passa a 0xf8 con libsodium/XChaCha20. Il client scelto si aspetta il vecchio 0xfb/0xfa. Per un server più nuovo, il protocollo va portato davvero nel client; cambiare IP o password non risolve.
6. Installa sul telefono e diagnostica il primo avvio
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
Avvia l’app, scegli il tuo Home Lab e accedi solo con l’account di prova del tuo server. Il package di questo profilo è com.metin2.client.lab; i dati esterni di norma sono qui:
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
Il package di base è com.metin2.client, quello del profilo offline upstream com.metin2.client.offline. Non confondere i percorsi. Il codice usa getExternalFilesDir(null), quindi fa fede la directory effettiva dell’app. Se l’aggiornamento fallisce, controlla ABI, package ID e firma APK; disinstallare senza pensarci può cancellare i personaggi offline.
| Problema | Primo controllo |
|---|---|
| CMake non trova OpenGr2ndma | Submodule inizializzato al commit previsto |
| APK incompatibile con ABI | Confronta ro.product.cpu.abilist e -Pm2abi |
| Disconnessione dopo login | Versione handshake server e log |
| Ritorno dopo selezione personaggio | IP reindirizzato, BIND_IP e porte dei core |
| UI assente o schermo nero | Staging, proto, Python Lib e syserr.txt |
| Dati vecchi dopo l’update | m2.dataVersion, profilo e ZIP |
Server incorporato nell’APK
Il progetto upstream include il profilo bundled: compila i processi server per Android, aggiunge un livello SQLite al posto di MySQL e incorpora i dati del server. Il telefono non richiede quindi un server remoto. Serve una build distinta e un pacchetto dati; non è automatico nell’APK del passaggio 3.
Nel file servers/servers.json, indica l’istanza embedded:
{
"version": 2,
"servers": [
{ "name": "Single Player", "embedded": true }
]
}
Nel profilo profiles/bundled.properties lascia vuote m2.serverListUrl=, m2.devUrl= e m2.updateChannel=. Mantieni m2.serverMode=embedded, m2.dataBundled=true e il suffisso .offline. Per ogni nuovo pacchetto dati, incrementa m2.dataVersion.
Una volta pronti i checkout runtime e sorgente, lo script di packaging si usa così:
"$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
Prima dei comandi, verifica bundled.properties, il catalogo personalizzato, dataVersion e l’account di prova nel database seed. Lo script make-server-pack.sh richiede prima il checkout runtime, poi quello delle sorgenti e infine la cartella di output. Non usare al suo posto l’esempio diverso della sezione Web nella documentazione upstream. Il build Gradle del server incorporato ha un percorso NDK specifico per Linux; non lo presentiamo come build offline Windows verificata.
Build completata, app avviata, login e sessione di gioco continuativa sono risultati diversi. Per testare l’insieme crea un personaggio, entra su una mappa, combatti, passa tra core, riavvia il client e verifica il salvataggio dell’inventario. Senza queste prove, non si può affermare che uno specifico telefono e server siano stati verificati insieme.
Domande Frequenti
Funzionerà sul mio server privato preferito?
Vale anche per iPhone?
Posso condividere pubblicamente l’APK e i suoi dati?
Pagine Correlate
Trova il tuo server perfetto
Sfoglia i migliori server privati Metin2 su METIN2.GG o aggiungi il tuo server alla classifica.

