Kotlin Gta sanandres proje üzerinde çalışıyorum ama oyunu bitürlü başlatamadı sürekli hata 2 gündür bunla uğraşıyorum 19 saat uymadan hiç bir türlü çalıştıramadım.



LOGCAT

2025-01-08 00:51:14.284 28257-28257 AndroidRuntime          com.sampv2.matite                    E  FATAL EXCEPTION: main (Ask Gemini)
                                                                                                    Process: com.sampv2.matite, PID: 28257
                                                                                                    java.lang.UnsatisfiedLinkError: No implementation found for void com.sampv2.matite.game.SAMPGame.cleanupGame() (tried Java_com_sampv2_matite_game_SAMPGame_cleanupGame and Java_com_sampv2_matite_game_SAMPGame_cleanupGame__) - is the library loaded, e.g. System.loadLibrary?
                                                                                                        at com.sampv2.matite.game.SAMPGame.cleanupGame(Native Method)
                                                                                                        at com.sampv2.matite.game.SAMPGame.onDestroy(SAMPGame.kt:255)
                                                                                                        at android.app.Activity.performDestroy(Activity.java:8504)
                                                                                                        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1377)
                                                                                                        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5538)
                                                                                                        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5596)
                                                                                                        at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:47)
                                                                                                        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
                                                                                                        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
                                                                                                        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
                                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2291)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:211)
                                                                                                        at android.os.Looper.loop(Looper.java:300)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8322)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1038)
---------------------------- PROCESS ENDED (28257) for package com.sampv2.matite ----------------------------

package com.sampv2.matite.game

import android.app.ActivityManager
import android.content.Context
import android.hardware.SensorEvent
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
import android.view.WindowManager
import android.widget.Toast
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.nvidia.devtech.NvEventQueueActivity
import com.sampv2.matite.R
import com.sampv2.matite.SampApplication
import com.sampv2.matite.data.repository.GameRepository
import com.sampv2.matite.network.RetrofitInstance
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.io.File
import java.io.IOException
import javax.microedition.khronos.egl.EGL10
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.egl.EGLContext
import androidx.appcompat.app.AppCompatActivity

@Suppress("KotlinConstantConditions")
class SAMPGame : NvEventQueueActivity() {
    private var isInitialized = false
    private val gameJob = SupervisorJob()
    private val gameScope = CoroutineScope(Dispatchers.Main + gameJob)
    private val gameRepository: GameRepository by lazy { GameRepository(this, RetrofitInstance.api) }

    companion object {
        private const val TAG = "SAMPGame"
        private const val ARM64_LIBS_JSON_URL = "https://sampmobile.com/oyundosya/arm64-v8a/arm64-v8a.json"
        private const val ARM32_LIBS_JSON_URL = "https://sampmobile.com/oyundosya/armeabi-v7a/armeabi-v7a.json"
        private const val GAME_FILES_JSON_URL = "https://sampmobile.com/oyundosya/files/files.json"

        init {
            try {
                System.loadLibrary("samp")
                Log.d(TAG, "SAMP kütüphanesi yüklendi")
            } catch (e: UnsatisfiedLinkError) {
                Log.e(TAG, "SAMP kütüphanesi yüklenemedi: ${e.message}")
            }
        }

        private fun getGameDir(): String {
            return File(SampApplication.instance.getExternalFilesDir(null), "SAMP").absolutePath
        }

        private fun getLibsJsonUrl(): String {
            return if (Build.SUPPORTED_ABIS[0].contains("arm64")) {
                ARM64_LIBS_JSON_URL
            } else {
                ARM32_LIBS_JSON_URL
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.GameTheme)
        super.onCreate(savedInstanceState)
        
        // Tam ekran modunu ayarla
        WindowCompat.setDecorFitsSystemWindows(window, false)
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            window.attributes.layoutInDisplayCutoutMode = 
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
        }
        
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        
        val windowInsetsController = WindowInsetsControllerCompat(window, window.decorView)
        windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
        
        // Ekranı tam ekran yap
        @Suppress("DEPRECATION")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.setDecorFitsSystemWindows(false)
            window.insetsController?.let { controller ->
                controller.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            }
        } else {
            window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
        }

        // OpenGL ES bağlamını oluştur
        initializeOpenGL()
        
        // Oyunu başlat
        startGame()
    }

    private fun initializeOpenGL() {
        try {
            val egl = EGLContext.getEGL() as EGL10
            val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
            if (display == EGL10.EGL_NO_DISPLAY) {
                throw RuntimeException("eglGetDisplay başarısız oldu")
            }

            val version = IntArray(2)
            if (!egl.eglInitialize(display, version)) {
                throw RuntimeException("eglInitialize başarısız oldu")
            }

            val configAttribs = intArrayOf(
                EGL10.EGL_RED_SIZE, 8,
                EGL10.EGL_GREEN_SIZE, 8,
                EGL10.EGL_BLUE_SIZE, 8,
                EGL10.EGL_ALPHA_SIZE, 8,
                EGL10.EGL_DEPTH_SIZE, 16,
                EGL10.EGL_STENCIL_SIZE, 8,
                EGL10.EGL_SAMPLE_BUFFERS, 1,
                EGL10.EGL_SAMPLES, 4,
                EGL10.EGL_NONE
            )

            val configs = arrayOfNulls<EGLConfig>(1)
            val numConfig = IntArray(1)
            if (!egl.eglChooseConfig(display, configAttribs, configs, 1, numConfig)) {
                throw RuntimeException("eglChooseConfig başarısız oldu")
            }

            val surfaceAttribs = intArrayOf(
                EGL10.EGL_WIDTH, 1,
                EGL10.EGL_HEIGHT, 1,
                EGL10.EGL_NONE
            )

            val surface = egl.eglCreatePbufferSurface(display, configs[0], surfaceAttribs)
            if (surface == EGL10.EGL_NO_SURFACE) {
                throw RuntimeException("eglCreatePbufferSurface başarısız oldu")
            }

            val contextAttribs = intArrayOf(
                0x3098, // EGL_CONTEXT_CLIENT_VERSION değeri
                3,     // OpenGL ES 3.0 için versiyon
                EGL10.EGL_NONE
            )

            val context = egl.eglCreateContext(display, configs[0], EGL10.EGL_NO_CONTEXT, contextAttribs)
            if (context == EGL10.EGL_NO_CONTEXT) {
                throw RuntimeException("eglCreateContext başarısız oldu")
            }

            if (!egl.eglMakeCurrent(display, surface, surface, context)) {
                throw RuntimeException("eglMakeCurrent başarısız oldu")
            }

            Log.d(TAG, "OpenGL ES bağlamı başarıyla oluşturuldu")
            isInitialized = true
            
        } catch (e: Exception) {
            Log.e(TAG, "OpenGL ES bağlamı oluşturma hatası: ${e.message}", e)
            throw e
        }
    }

    private fun startGame() {
        gameScope.launch(Dispatchers.Main + CoroutineExceptionHandler { _, exception ->
            Log.e(TAG, "Coroutine hatası: ${exception.message}", exception)
            when (exception) {
                is CancellationException -> {
                    Log.d(TAG, "İşlem iptal edildi, yeniden deneniyor...")
                    retryGameInitialization()
                }
                else -> {
                    val errorMessage = when (exception) {
                        is IOException -> "Dosya indirme hatası: ${exception.message}"
                        else -> "Beklenmeyen hata: ${exception.message}"
                    }
                    Toast.makeText(this@SAMPGame, errorMessage, Toast.LENGTH_LONG).show()
                    finish()
                }
            }
        }) {
            try {
                withContext(Dispatchers.IO) {
                    gameRepository.logGameEvent("Oyun açılıyor...")
                    
                    // Kütüphaneleri kontrol et ve indir
                    if (!checkRequiredLibraries()) {
                        downloadRequiredLibraries()
                    }
                    
                    // Oyun dosyalarını kontrol et ve indir
                    downloadGameFiles()
                    
                    // Oyunu başlat
                    withContext(Dispatchers.Main) {
                        initializeGame()
                        isInitialized = true
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Oyun başlatma hatası: ${e.message}", e)
                withContext(Dispatchers.Main) {
                    when (e) {
                        is CancellationException -> {
                            Log.d(TAG, "İşlem iptal edildi, yeniden deneniyor...")
                            retryGameInitialization()
                        }
                        else -> {
                            val errorMessage = when (e) {
                                is IOException -> "Dosya indirme hatası: ${e.message}"
                                else -> "Beklenmeyen hata: ${e.message}"
                            }
                            Toast.makeText(this@SAMPGame, errorMessage, Toast.LENGTH_LONG).show()
                            finish()
                        }
                    }
                }
            }
        }
    }

    private fun retryGameInitialization() {
        gameJob.cancel() // Mevcut işi iptal et
        gameScope.launch(Dispatchers.IO) {
            delay(1000) // 1 saniye bekle
            withContext(Dispatchers.Main) {
                onCreate(null) // Başlatma işlemini tekrar dene
            }
        }
    }

    override fun onDestroy() {
        try {
            if (isInitialized) {
                Log.d(TAG, "Oyun kapatılıyor...")
                gameRepository.logGameEvent("Oyun kapatılıyor...")
                cleanupGame()
                isInitialized = false
            }
        } catch (e: Exception) {
            Log.e(TAG, "Oyun kapatma hatası: ${e.message}", e)
        } finally {
            gameJob.cancel()
            super.onDestroy()
        }
    }

    private suspend fun downloadRequiredLibraries() {
        withContext(Dispatchers.IO) {
            try {
                Log.d(TAG, "Native kütüphane listesi indiriliyor...")
                val response = RetrofitInstance.api.getLibraryList(getLibsJsonUrl())
                if (!response.isSuccessful) {
                    Log.e(TAG, "Kütüphane listesi alınamadı: HTTP ${response.code()}")
                    // Eğer kütüphaneler zaten varsa devam et
                    if (checkRequiredLibraries()) {
                        Log.d(TAG, "Kütüphaneler zaten mevcut, devam ediliyor")
                        return@withContext
                    }
                    throw IOException("Kütüphane listesi alınamadı: HTTP ${response.code()}")
                }

                val responseBody = response.body() ?: throw IOException("Kütüphane listesi boş")
                val jsonString = responseBody.byteStream().bufferedReader().use { it.readText() }
                Log.d(TAG, "JSON yanıtı: $jsonString")
                
                try {
                    val jsonObject = JSONObject(jsonString.trim())
                    val libsArray = jsonObject.getJSONArray("files")

                    val gameDir = File(getGameDir())
                    if (!gameDir.exists()) {
                        gameDir.mkdirs()
                    }

                    Log.d(TAG, "Native kütüphaneleri indiriliyor...")
                    for (i in 0 until libsArray.length()) {
                        val lib = libsArray.getJSONObject(i)
                        val libName = lib.getString("name")
                        val libUrl = lib.getString("url")
                        val targetFile = File(gameDir, libName)

                        if (!targetFile.exists()) {
                            try {
                                Log.d(TAG, "Kütüphane indiriliyor: $libName")
                                val libResponse = RetrofitInstance.api.downloadFile(libUrl)
                                if (libResponse.isSuccessful) {
                                    libResponse.body()?.byteStream()?.use { input ->
                                        targetFile.outputStream().use { output ->
                                            input.copyTo(output)
                                        }
                                    }
                                    // İzinleri ayarla
                                    targetFile.setExecutable(true, false)
                                    targetFile.setReadable(true, false)
                                    targetFile.setWritable(true, false)
                                    Log.d(TAG, "Kütüphane başarıyla indirildi: $libName")
                                } else {
                                    Log.e(TAG, "Kütüphane indirilemedi: $libName (HTTP ${libResponse.code()})")
                                    // Eğer kütüphane zaten varsa devam et
                                    if (!targetFile.exists()) {
                                        throw IOException("Kütüphane indirilemedi: $libName")
                                    }
                                }
                            } catch (e: Exception) {
                                Log.e(TAG, "Kütüphane indirme hatası - $libName: ${e.message}")
                                // Eğer kütüphane zaten varsa devam et
                                if (!targetFile.exists()) {
                                    throw e
                                }
                            }
                        } else {
                            Log.d(TAG, "Kütüphane zaten mevcut: $libName")
                            // İzinleri kontrol et ve ayarla
                            targetFile.setExecutable(true, false)
                            targetFile.setReadable(true, false)
                            targetFile.setWritable(true, false)
                        }
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "JSON ayrıştırma hatası: ${e.message}")
                    Log.e(TAG, "JSON içeriği: $jsonString")
                    throw e
                }
            } catch (e: Exception) {
                Log.e(TAG, "Native kütüphane indirme hatası", e)
                // Eğer kütüphaneler zaten varsa devam et
                if (checkRequiredLibraries()) {
                    Log.d(TAG, "Kütüphaneler zaten mevcut, devam ediliyor")
                    return@withContext
                }
                throw e
            }
        }
    }

    private fun checkRequiredLibraries(): Boolean {
        val gameDir = File(getGameDir())
        val cpuArch = Build.SUPPORTED_ABIS[0]
        
        val requiredLibs = if (cpuArch.contains("arm64")) {
            listOf(
                "libc++_shared.so",
                "libGTASA.so",
                "libSCAnd.so",
                "libbass.so",
                "libOpenAL64.so",
                "libsamp.so",
                "libcrashlytics.so",
                "libcrashlytics-common.so",
                "libcrashlytics-handler.so",
                "libcrashlytics-trampoline.so",
                "libshadowhook.so"
            )
        } else {
            listOf(
                "libc++_shared.so",
                "libGTASA.so",
                "libImmEmulatorJ.so",
                "libSCAnd.so",
                "libbass.so",
                "libOpenAL32.so",
                "libsamp.so",
                "libcrashlytics.so",
                "libcrashlytics-common.so",
                "libcrashlytics-handler.so",
                "libcrashlytics-trampoline.so",
                "libshadowhook.so"
            )
        }

        return requiredLibs.all { libName ->
            val libFile = File(gameDir, libName)
            val exists = libFile.exists()
            if (!exists) {
                Log.d(TAG, "Eksik kütüphane: $libName")
            }
            exists
        }
    }

    private suspend fun downloadGameFiles() {
        withContext(Dispatchers.IO) {
            try {
                Log.d(TAG, "Oyun dosyaları listesi indiriliyor...")
                val response = RetrofitInstance.api.getLibraryList(GAME_FILES_JSON_URL)
                if (!response.isSuccessful) {
                    Log.e(TAG, "Oyun dosyaları listesi alınamadı: HTTP ${response.code()}")
                    throw IOException("Oyun dosyaları listesi alınamadı: HTTP ${response.code()}")
                }

                val responseBody = response.body() ?: throw IOException("Oyun dosyaları listesi boş")
                val jsonString = responseBody.byteStream().bufferedReader().use { it.readText() }
                
                try {
                    val jsonObject = JSONObject(jsonString.trim())
                    val filesArray = jsonObject.getJSONArray("files")

                    val gameDir = File(getGameDir())
                    if (!gameDir.exists()) {
                        gameDir.mkdirs()
                    }

                    Log.d(TAG, "Oyun dosyaları indiriliyor...")
                    for (i in 0 until filesArray.length()) {
                        val file = filesArray.getJSONObject(i)
                        val fileName = file.getString("path")
                        val fileUrl = file.getString("url")
                        
                        val targetFile = File(gameDir, fileName)
                        val targetDir = targetFile.parentFile
                        
                        targetDir?.let { dir ->
                            if (!dir.exists()) {
                                dir.mkdirs()
                            }
                        }

                        if (!targetFile.exists()) {
                            try {
                                Log.d(TAG, "Dosya indiriliyor: $fileName")
                                val fileResponse = RetrofitInstance.api.downloadFile(fileUrl)
                                if (fileResponse.isSuccessful) {
                                    fileResponse.body()?.byteStream()?.use { input ->
                                        targetFile.outputStream().use { output ->
                                            input.copyTo(output)
                                        }
                                    }
                                    Log.d(TAG, "Dosya başarıyla indirildi: $fileName")
                                } else {
                                    Log.e(TAG, "Dosya indirilemedi: $fileName (HTTP ${fileResponse.code()})")
                                    throw IOException("Dosya indirilemedi: $fileName")
                                }
                            } catch (e: Exception) {
                                Log.e(TAG, "Dosya indirme hatası - $fileName: ${e.message}")
                                throw e
                            }
                        } else {
                            Log.d(TAG, "Dosya zaten mevcut: $fileName")
                        }
                    }
                    Log.d(TAG, "Tüm oyun dosyaları indirildi")
                } catch (e: Exception) {
                    Log.e(TAG, "JSON ayrıştırma hatası: ${e.message}")
                    throw e
                }
            } catch (e: Exception) {
                Log.e(TAG, "Oyun dosyaları indirme hatası", e)
                throw e
            }
        }
    }

    private fun loadSystemLibraries() {
        try {
            // Önce sistem kütüphanelerini yükle
            System.loadLibrary("c++_shared")
            Log.d(TAG, "libc++_shared.so yüklendi")
            Thread.sleep(100)
            
            System.loadLibrary("GLESv2")
            Log.d(TAG, "libGLESv2.so yüklendi")
            Thread.sleep(100)
            
            System.loadLibrary("EGL")
            Log.d(TAG, "libEGL.so yüklendi")
            Thread.sleep(100)
            
            // ImmEmulator sadece 32-bit için
            if (!Build.SUPPORTED_ABIS[0].contains("arm64")) {
                System.loadLibrary("ImmEmulatorJ")
                Log.d(TAG, "libImmEmulatorJ.so yüklendi")
                Thread.sleep(100)
            }
        } catch (e: UnsatisfiedLinkError) {
            Log.e(TAG, "Sistem kütüphaneleri yüklenemedi: ${e.message}")
            throw IOException("Sistem kütüphaneleri yüklenemedi: ${e.message}")
        }
    }

    private fun loadGameLibraries() {
        val libsToLoad = mutableListOf(
            "GTASA",
            "SCAnd",
            "bass",
            if (Build.SUPPORTED_ABIS[0].contains("arm64")) "OpenAL64" else "OpenAL32",
            "samp"
        )
        
        // Crashlytics kütüphanelerini ekle
        libsToLoad.addAll(listOf(
            "crashlytics",
            "crashlytics-common",
            "crashlytics-handler",
            "crashlytics-trampoline"
        ))
        
        // Son olarak shadowhook'u ekle
        libsToLoad.add("shadowhook")

        for (lib in libsToLoad) {
            try {
                System.loadLibrary(lib)
                Log.d(TAG, "$lib kütüphanesi yüklendi")
                Thread.sleep(100) // Her kütüphane yüklemesi arasında kısa bir bekleme
            } catch (e: UnsatisfiedLinkError) {
                Log.e(TAG, "$lib kütüphanesi yüklenemedi: ${e.message}")
                // Eğer kritik bir kütüphane ise hata fırlat
                if (lib in listOf("GTASA", "SCAnd", "samp")) {
                    throw IOException("$lib kütüphanesi yüklenemedi: ${e.message}")
                }
            }
        }
    }

    private fun checkSAMPData(): String? {
        val sampDir = File(getGameDir(), "SAMP")
        if (!sampDir.exists() || !sampDir.isDirectory) {
            return "SAMP veri dizini bulunamadı"
        }

        // SAMP veri dosyalarını kontrol et
        val requiredSampFiles = listOf(
            "samp.dat" to "SAMP Ayar Dosyası",
            "handling.cfg" to "Araç Ayarları",
            "vehicles.txt" to "Araç Listesi",
            "weapons.txt" to "Silah Listesi",
            "animations.txt" to "Animasyon Listesi",
            "server.cfg" to "Sunucu Ayarları"
        )

        for ((file, description) in requiredSampFiles) {
            val sampFile = File(sampDir, file)
            if (!sampFile.exists()) {
                Log.e(TAG, "Eksik SAMP dosyası: $description ($file)")
                return "Eksik SAMP dosyası: $description"
            }
            if (sampFile.length() == 0L) {
                Log.e(TAG, "Bozuk SAMP dosyası: $description ($file)")
                return "Bozuk SAMP dosyası: $description"
            }
        }

        return null
    }

    private fun checkGameFiles(): String? {
        // Önce SAMP verilerini kontrol et
        checkSAMPData()?.let { error ->
            return error
        }

        // Diğer oyun dosyalarını kontrol et
        val gameDir = File(getGameDir())
        
        // Kritik dosyaların kontrolü
        val requiredFiles = mapOf(
            "SAMP/gta.dat" to "GTA:SA Temel Ayar Dosyası",
            "SAMP/handling.cfg" to "Araç Fizik Ayarları",
            "texdb/gta3.img" to "GTA:SA Temel Texture Dosyası",
            "texdb/samp.img" to "SAMP Texture Dosyası",
            "models/gta3.img" to "GTA:SA Model Dosyası",
            "SAMP/script.img" to "SAMP Script Dosyası",
            "audio/SFX/GENRL.osw" to "Ses Dosyası"
        )

        for ((file, description) in requiredFiles) {
            val gameFile = File(gameDir, file)
            if (!gameFile.exists()) {
                Log.e(TAG, "Eksik dosya: $description ($file)")
                return "Eksik dosya: $description"
            }
            if (gameFile.length() == 0L) {
                Log.e(TAG, "Bozuk/boş dosya: $description ($file)")
                return "Bozuk/boş dosya: $description"
            }
        }

        return null
    }

    private fun checkOpenGLSupport(): String? {
        try {
            val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            val configurationInfo = activityManager.deviceConfigurationInfo
            
            // OpenGL ES 3.1 kontrolü
            if (configurationInfo.reqGlEsVersion < 0x30001) {
                return "Bu cihaz OpenGL ES 3.1'i desteklemiyor. Cihazınızın OpenGL ES sürümü: " +
                        "${configurationInfo.reqGlEsVersion}"
            }

            // Android Extension Pack kontrolü
            val pm = packageManager
            val hasAEP = pm.hasSystemFeature("android.hardware.opengles.aep")
            if (!hasAEP) {
                return "Bu cihaz Android Extension Pack'i (AEP) desteklemiyor"
            }

            // OpenGL ES uzantılarını kontrol et
            val egl = EGLContext.getEGL() as EGL10
            val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
            egl.eglInitialize(display, null)
            
            val configAttrs = intArrayOf(
                EGL10.EGL_RED_SIZE, 8,
                EGL10.EGL_GREEN_SIZE, 8,
                EGL10.EGL_BLUE_SIZE, 8,
                EGL10.EGL_ALPHA_SIZE, 8,
                EGL10.EGL_DEPTH_SIZE, 16,
                EGL10.EGL_STENCIL_SIZE, 8,
                EGL10.EGL_NONE
            )
            
            val configs = arrayOfNulls<EGLConfig>(1)
            val numConfig = IntArray(1)
            egl.eglChooseConfig(display, configAttrs, configs, 1, numConfig)
            
            // OpenGL ES 3.1 context oluştur
            val contextAttrs = intArrayOf(
                0x3098, // EGL_CONTEXT_CLIENT_VERSION değeri
                3,     // OpenGL ES 3.1 için versiyon
                EGL10.EGL_NONE
            )
            
            val context = egl.eglCreateContext(display, configs[0], EGL10.EGL_NO_CONTEXT, contextAttrs)
            if (context == EGL10.EGL_NO_CONTEXT) {
                return "OpenGL ES 3.1 context oluşturulamadı"
            }
            
            val gl = context.gl as javax.microedition.khronos.opengles.GL10
            val extensions = gl.glGetString(javax.microedition.khronos.opengles.GL10.GL_EXTENSIONS)
            
            // Gerekli uzantıları kontrol et
            val requiredExtensions = listOf(
                "GL_ANDROID_extension_pack_es31a",
                "GL_KHR_debug",
                "GL_KHR_texture_compression_astc_ldr",
                "GL_KHR_blend_equation_advanced"
            )

            for (ext in requiredExtensions) {
                if (!extensions.contains(ext)) {
                    return "Gerekli OpenGL ES uzantısı eksik: $ext"
                }
            }

            // Kaynakları temizle
            egl.eglDestroyContext(display, context)
            egl.eglTerminate(display)

            return null
        } catch (e: Exception) {
            Log.e(TAG, "OpenGL ES kontrol hatası:", e)
            return "OpenGL ES kontrol hatası: ${e.message}"
        }
    }

    private fun initializeGame() {
        try {
            Log.d(TAG, "Oyun başlatılıyor...")
            
            // Önce sistem kütüphanelerini yükle
            loadSystemLibraries()
            
            // Sonra oyun kütüphanelerini yükle
            loadGameLibraries()
            
            // Oyun dosyalarını kontrol et
            checkGameFiles()?.let { error ->
                Log.e(TAG, "Eksik dosya/kütüphane tespit edildi: $error")
                throw IOException(error)
            }
            
            // OpenGL ES kontrolü
            checkOpenGLSupport()?.let { error ->
                Log.e(TAG, "OpenGL ES hatası: $error")
                throw Exception(error)
            }
            
            // GUI'yi başlat
            initializeGUI()
            
            // Oyun parametrelerini al
            val serverIp = intent.getStringExtra("server_ip") ?: ""
            val serverPort = intent.getIntExtra("server_port", 7777)
            val nickname = intent.getStringExtra("nickname") ?: ""
            
            // Sunucuya bağlan
            Log.d(TAG, "[dbg:raknet:client:connect] : connecting to game server '$serverIp:$serverPort'...")
            startSAMP(serverIp, serverPort, nickname)
            Log.d(TAG, "[dbg:raknet:client:connect] : connected")
            
            Log.d(TAG, "Oyun başarıyla başlatıldı")

        } catch (e: Exception) {
            Log.e(TAG, "Oyun başlatma hatası:", e)
            runOnUiThread {
                val errorMessage = "Hata: ${e.message}\n\n" +
                        "Lütfen şunları kontrol edin:\n" +
                        "1. Tüm oyun dosyalarının tam olduğunu\n" +
                        "2. Cihazınızın OpenGL ES 3.1'i desteklediğini\n" +
                        "3. Yeterli depolama alanı olduğunu\n" +
                        "4. Yeterli RAM olduğunu"
                
                Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show()
            }
            throw e
        }
    }

    private fun initializeGUI() {
        val displayMetrics = resources.displayMetrics
        Log.d(TAG, "GUI | Display size: ${displayMetrics.widthPixels}, ${displayMetrics.heightPixels}")
        Log.d(TAG, "GUI | Scale factor: ${displayMetrics.density}")
    }

    override fun onResume() {
        try {
            super.onResume()
            Log.d(TAG, "SAMPGame onResume çağrıldı")
            
            // Tam ekran modunu ayarla
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                window.setDecorFitsSystemWindows(false)
                window.insetsController?.let { controller ->
                    controller.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                    controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                }
            } else {
                @Suppress("DEPRECATION")
                window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
                        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                        or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
            }

            // OpenGL ES bağlamını yeniden oluştur
            if (!isInitialized) {
                initializeOpenGL()
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "onResume hatası: ${e.message}", e)
            // Kritik hata durumunda aktiviteyi sonlandır
            finish()
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return if (keyCode == KeyEvent.KEYCODE_BACK) {
            true // Geri tuşunu engelle
        } else {
            super.onKeyDown(keyCode, event)
        }
    }

    override fun onSensorChanged(event: SensorEvent) {
        // Sensör değişikliklerini işle
        // Bu metod boş bırakılabilir çünkü oyun sensör kullanmıyor
    }

    // Native metodları tanımla
    private external fun startSAMP(serverIp: String, serverPort: Int, nickname: String)
    private external fun cleanupGame()
}