Kegagalan operasi file pada game crash / kill oleh OS / Pengguna di Android

13

Game saya menyimpan statusnya setelah interval tetap pada file di penyimpanan internal game / aplikasi. Ketika game saya terbunuh atau hancur oleh pengguna atau OS masing-masing, Kami menulis status permainan saat ini pada file itu. Menulis file setelah interval perbaikan berfungsi dengan baik tetapi ketika game macet / terbunuh oleh OS atau pengguna, operasi penulisan file gagal. Kegagalan operasi menghasilkan keadaan gim yang tidak lengkap atau keadaan gim kosong yaitu tidak ada data yang tertulis di file sama sekali. Saya telah mencoba beberapa solusi menggunakan layanan android, Seandainya layanan ini NON STICKY layanan terbunuh dengan aplikasi. Di sisi lain jika layanan STICKY maka itu restart tetapi niat yang dilampirkan pada awalnya dengan layanan adalah nol atau baru.

Pertanyaannya adalah bagaimana saya bisa menyimpan data saya (bisa ~ 2-3MB) sepenuhnya pada file di penyimpanan internal ketika game / aplikasi saya terbunuh oleh pengguna / OS?

Faisal Imran
sumber
Anda harus menangani SIGTERM dan SIGKILL Anda (mungkin juga bukan SIGKILL, Android mungkin menggunakan SIGTERM). (Tidak punya waktu untuk meneliti / menulis jawaban lengkap tapi itu ide dasarnya.)
John Hamilton
2
@JohnHamilton SIGKILL tidak dapat ditangani, menurut definisi.
Darkhogg
@ Arkhogg Yah, tidak di Unity, itu sudah pasti. (Saya memang mengubah kernel linux pada satu titik untuk sebuah proyek untuk tujuan khusus ini dan tentu saja memungkinkan untuk membiarkan program menangani SIGKILL)
John Hamilton

Jawaban:

20

Saya menyarankan Anda untuk menulis save state dengan buffered ganda, seperti yang biasa dilakukan pada judul konsol di masa lalu (di mana Anda harus mengatasi kartu memori yang dihapus saat menulis dan menulis lambat).

Menyimpan:

  • Jika tidak ada file, tulis status ke file A
  • Jika A ada, tulis ke B
  • Jika A dan B keduanya ada, cari yang lebih tua, hapus, lalu tulis ke yang itu

Beban:

  • Jika A dan B ada, coba muat yang lebih baru dari keduanya. Jika gagal (karena file tidak lengkap atau rusak), hapus dan muat yang lain
  • Jika hanya ada satu, muat
  • Jika keduanya rusak, beri tahu pengguna bahwa kondisi penyimpanan mereka tidak dapat diperbaiki (seperti Anda mungkin sudah harus)

Alur ini akan berfungsi untuk memastikan selalu ada setidaknya satu penyimpanan yang valid masih ada di penyimpanan Anda, bahkan jika aplikasi tersebut terbunuh pada pertengahan penulisan. Pemain tidak akan mendapatkan perubahan apa pun dalam status permainan sejak save sebelumnya jika kegagalan semacam itu terjadi, tetapi mereka tidak harus memulai lagi.

Selain itu, Anda harus menyimpan segera setelah peristiwa utama (seperti pembelian dalam aplikasi) selain penghematan interval Anda, untuk meminimalkan jendela kerentanan di mana crash / kill akan menyebabkan acara utama tersebut hilang. Ini juga perlindungan terhadap eksploitasi gim (mis. Membunuh paksa aplikasi setelah kehilangan nyawa, karena Anda tahu Anda akan kembali ke keadaan gim sebelum Anda kehilangan nyawa, dan coba lagi). Tentu saja jika melakukan ini, Anda harus melindungi interval penyimpanan Anda dengan logika yang mengatakan "jika suatu penyimpanan sudah berlangsung, jangan mencoba untuk mulai menabung lagi."

MrCranky
sumber
Terima kasih MrCranky ini adalah solusi parsial untuk masalah saya bagaimana saya bisa menyimpan data sesi terakhir yaitu sebelum membunuh aplikasi / game? Misalnya dia membuat pembelian dalam aplikasi dan membunuh aplikasi.
Faisal Imran
12
Anda bahkan tidak perlu dua file. Menulis ke B, jika dan hanya jika penulisan berhasil, hapus A dan ganti nama B menjadi A. java.nio.file.Files.move(Path source, Path target, CopyOption... options)dapat melakukan penggantian nama dan penulisan ulang sebagai operasi atom.
Polygnome
6
@Polygnome: Perhatikan bahwa dalam kasus kegagalan daya ini tidak akan selalu memberikan jaminan yang Anda harapkan, kecuali jika Anda memanggil sync()file B sebelum Anda memindahkannya ke file A (bahkan saat itu tidak ada jaminan lengkap, tetapi sync()cukup bagus).
Dietrich Epp
1
@FaisalImran Simpan data tepat setelah operasi penting, misalnya, setelah IAP. Jika operasi terganggu oleh telepon dimatikan, saya kira itu tidak akan pernah mengambil uang dari orang itu. Tapi untuk berjaga-jaga, Anda mungkin ingin menyimpan data akunnya dalam pembelian di beberapa platform sebagai upaya untuk membeli sesuatu. Kemudian Anda dapat membandingkan penghasilan Anda dengan data itu dan melihat apakah orang ini benar-benar membeli sesuatu. Dan kemudian buka fitur ini untuknya melalui layanan online yang Anda gunakan untuk menyimpan semua data. Jika Anda menggunakan penyimpanan lokal untuk IAP, maka itu lebih buruk dari masalah ini.
Candid Moon _Max_
1
Terakhir, meskipun ini mungkin tidak menyelesaikan semua masalah Anda, saya akan mengatakan bahwa masalah Anda tidak sepenuhnya dapat dipecahkan. Anda tidak dapat mendukung "pengguna dapat mematikan aplikasi saya kapan saja" dan "tidak ada data yang harus hilang" karena akan selalu ada jendela setelah suatu peristiwa terjadi tetapi sebelum tetap disimpan di tempat pengguna dapat membunuh aplikasi dan kehilangan data.
MrCranky
3

Android hanya membunuh aplikasi saat mereka berada di latar belakang. Apakah data game Anda benar-benar perlu diperbarui ketika aplikasi di latar belakang, atau bisakah Anda berhenti memperbarui data sampai aplikasi kembali ke latar depan? Anda mungkin dapat menunda pembaruan bahkan dalam gim multipemain, jika Anda dapat mengambil riwayat acara atau bahkan hanya keadaan saat ini ketika aplikasi kembali ke latar depan. Ini adalah sesuatu yang Anda mungkin harus lakukan untuk kepentingan CPU, jaringan, dan efisiensi baterai.

Jika pengguna membunuh aplikasi Anda, menjalankan layanan harus menerima panggilan ke onTaskRemoved. Saya tidak tahu apa yang akan terjadi jika Anda mencoba melakukan banyak pemrosesan dalam metode ini. Saya berharap jika itu tidak kembali dalam waktu tertentu, Android akan menjadi kill -9aplikasi Anda.

Kevin Krumwiede
sumber
aplikasi tidak perlu diperbarui di latar belakang, tetapi aplikasi harus menyimpan datanya yaitu file json sebelum pergi ke latar belakang atau menghancurkan.
Faisal Imran
Anda benar metode onTaskRemoved akan memanggil tetapi waktu yang diperlukan untuk menyimpan file lebih atau kita bisa mengatakan waktu komputasi besar. Ketika pengguna membunuh aplikasi, metode ini akan dihentikan.
Faisal Imran