• 08-01-2025, 00:53:06
    #1
    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()
    }
  • 08-01-2025, 01:15:41
    #2
    hocam direkt hatayi chatgpt ye sor cozum yolunu soyluyor olmazsa kodlari da gonder duzenleyip hallediyor