Di artikel ini, saya akan berbicara tentang bagaimana saya membuat sistem pembaruan otomatis untuk gim klien daring. Tautan ke sumber (Delphi) di akhir artikel. Bahkan, saya menerapkan fitur seperti itu di dua game saya, dan jika pancake pertama keluar agak kental (dalam game Spectromancer), maka implementasi kedua ternyata sangat nyaman dan efektif. Ini adalah artikel pertama saya di Habré, jadi jangan memukul dengan keras, tetapi tunjukkan kekurangan dalam komentar :)
Algoritma pembaruan game
- Memeriksa versi untuk memperbarui.
- Unduh daftar file dari versi saat ini.
- Mengunduh file baru atau yang diubah ke folder sementara.
- Menginstal pembaruan - membawa file klien yang diinstal sesuai dengan daftar.
- Memulai klien yang diperbarui.
Pemeriksaan Versi
Pertama-tama, ketika memulai, klien meminta server untuk nomor versi saat ini (X) dan jumlah minimum yang diizinkan tanpa memperbarui (Y). Jika versi klien tidak lebih rendah dari Y, maka pembaruan tidak diperlukan, jika tidak klien meluncurkan utilitas pembaruan "
GetNewVersion.exe X " dan dimatikan sendiri.
Seperti yang Anda lihat, nomor versi dilewatkan oleh parameter - ini memungkinkan Anda untuk memperbarui game ke versi apa pun yang tersedia di server, dan bahkan menurunkannya. Jika parameter tidak lulus, utilitas itu sendiri akan meminta nomor versi saat ini dari server. Nomor versi hanyalah bilangan bulat, skema penomoran dapat berupa apa saja, misalnya, versi saya 1.12 sesuai dengan angka 1120.
Respons dari server tidak datang secara instan, dan sebelum kami menerimanya, kami tidak dapat membuat jendela permainan, karena Anda mungkin harus segera menutupnya, dan kedipan yang tidak dapat dipahami di layar sama sekali tidak seperti yang kita butuhkan. Batas waktu respons harus mengambil sesuatu, dan klien sibuk memuat / membongkar JPEG terberat. Anda tidak bisa menunggu terlalu lama: pemain meluncurkan game - tetapi tidak ada yang terjadi di layar, berantakan. Karena itu, jika dalam 1,0 detik. respons dari server tidak datang - memuat game berlanjut seperti biasa. Ini bukan masalah besar: begitu pemain mencoba masuk ke server, ia akan menerima pesan tentang perlunya memperbarui klien, atau bahwa server tidak tersedia.
Unduh daftar file
Mengetahui nomor versi, utilitas pembaruan mengunduh daftar file di:
[base_ur]>/[]/filelist
Ini hanya daftar file CSV dengan checksum, serta ukuran terkompresi dan tidak terkompresi, setiap baris terlihat seperti ini:
18*Priest.tga;1053151921D9;91719;107372
Di sini "18 *" berarti bahwa 18 karakter dalam nama file sama dengan file sebelumnya. Karena file biasanya masuk dalam urutan abjad, dan jalur bisa panjang - ini secara signifikan menyimpan ukuran file daftar. Untuk server web di mana kompresi tidak diaktifkan, ini berarti file akan mengunduh lebih cepat dan pembaruan akan dimulai lebih awal.
Unduh file baru atau yang diubah
Kami tidak tahu berapa usia klien game itu, mungkin beberapa file telah diubah atau dihapus secara manual. Kami tidak ingin mengunduh terlalu banyak, karena itu, setelah menerima daftar file, utilitas mulai memeriksanya agar pembaruan: jika file tidak ada di folder permainan atau checksumnya berbeda, file ditambahkan ke antrian unduhan. Pada saat yang sama, tidak lebih dari 2 file dapat dimuat - ini cukup sehingga di satu sisi unduhan tidak melambat, tetapi di sisi lain, itu terjadi secara berurutan.

Topik khusus adalah tampilan kemajuan. Sampai seluruh daftar diproses, kami tidak tahu persis berapa banyak file yang akan diunduh dan berapa ukurannya. Namun, segera setelah file pertama diunggah, kami sudah dapat menampilkan beberapa informasi. Bahkan, progres menampilkan antrian unduhan: berapa banyak untuk diunduh dan berapa banyak yang sudah diunduh.
File yang diunduh segera dibuka dan disimpan dalam folder sementara, saya menggunakan pustaka
zlib
untuk kompresi.
Ketika seluruh daftar file telah diproses dan semua unduhan telah selesai, utilitas memeriksa keberadaan file
changes.txt
dan, jika ada, menampilkannya. Pengguna diminta untuk memulai prosedur pembaruan. Sebelum mengklik tombol "Perbarui", belum ada perubahan yang dilakukan pada folder game, sehingga Anda dapat memilih keluar tanpa masalah.
Ngomong-ngomong, jika pengguna menghentikan unduhan atau menolak untuk menginstal, maka lain kali ia tidak perlu mengunduh semua file lagi: sebelum mengunduh file berikutnya, utilitas memeriksa keberadaannya di folder sementara dan jika checksum cocok, unduhan dianggap berhasil.

Tetapi ketika Anda mengklik "Perbarui", utilitas meluncurkan utilitas lain - "
InstallUpdate.exe ", dan itu mati sendiri.
Instal Pembaruan
Mengapa saya membutuhkan utilitas lain? Sederhana: untuk memperbarui file game yang perlu Anda jalankan dengan hak administrator. Tetapi untuk mengunduh pembaruan, sebaliknya, itu merupakan kontraindikasi. Karena, kecuali Anda adalah pemilik bahagia dari sertifikat penandatanganan kode-EV, memulai proses dengan hak administrator akan menampilkan jendela UAC. Dan jika, ketika memulai permainan, alih-alih antarmuka yang biasa, pemain melihat ini:

... maka ini, setidaknya, alasan untuk waspada, atau bahkan sepenuhnya meninggalkan peluncuran. Hal lain, dengan persetujuan manual untuk menginstal pembaruan - dalam konteks ini, jendela UAC dianggap normal. Sayangnya, proses di Windows tidak dapat meningkatkan haknya saat runtime - properti ini tidak berubah sejak diluncurkan. Karena itu, saya menggunakan dua file terpisah. Faktanya,
GetNewVersion.exe
dan
InstallUpdate.exe
adalah utilitas yang sama, file-nya identik. Dan tindakan ditentukan oleh parameter yang dikirimkan dan nama file yang dapat dieksekusi.
Jadi, saat diluncurkan, InstallUpdate menyalin file klien game dari folder sementara ke folder game, dan kemudian meluncurkan klien yang diperbarui dan berakhir. Dalam hal ini, file
GetNewVersion.exe
juga dapat diperbarui.
Semua tindakan, serta kesalahan yang terjadi, dicatat secara rinci dalam log, ini sangat berguna untuk debugging.
Proses mempersiapkan versi baru
Kami memeriksa skema operasi pembaruan dari sudut pandang klien game, tetapi bagaimana cara membuatnya bekerja? Untuk menyiapkan build baru, saya menulis utilitas lain -
CompressBuild . Secara berulang memindai folder, kompres file menggunakan metode Deflate, dan menulis informasi tentang mereka ke daftar file - daftar
filelist
. Setelah kompresi, simbol "_" ditambahkan ke nama file. File yang dikompresi tidak dikompres lagi, oleh karena itu, jika perlu, hanya file individual yang dapat diperbarui dalam folder build, CompressBuild hanya akan memperbaruinya.
Beberapa file dalam gim klien berubah selama operasi, misalnya, berisi pengaturan. File seperti itu harus diabaikan, utilitas mengambil templat yang sesuai dari file kecualikan. Artinya, file-file ini tidak masuk ke daftar
filelist
dan tidak merusak klien ketika memperbarui.
Jadi, untuk menyiapkan bangunan baru, saya perlu:
1. Salin
\master
folder ke
\[_]
2. Jalankan
CompressBuild , yang akan mengemas file di dalamnya dan membuat daftar mereka.
3. Unggah semuanya ke situs web game.
4. Ubah pada server game nomor versi saat ini ke nomor yang baru saja diunduh. Voila!
Mulai sekarang, ketika memperbarui orang akan menerima versi baru.
Nah, folder dengan build lama di server dapat dihapus agar tidak memakan ruang.
Kesimpulan
Tentu saja, sistem pembaruan saya tidak sempurna dan bukan tanpa cacat. Misalnya, jika file dihapus di klien, itu akan tetap dengan para pemain. Jika file telah diubah namanya, itu akan diunduh sebagai baru, dan contoh lama tidak akan dihapus. Anda tentu saja dapat memperbaiki utilitas pembaruan dengan menambahkan perintah untuk menghapus / mengganti nama file ke daftar file, tetapi secara umum masalah seperti itu tidak relevan untuk permainan saya, jadi saya tidak repot-repot.
Nah, Anda bisa mendapatkan sumbernya di sini:
astralheroes.com/files/UpdaterSrc.zip(dikompilasi dalam Delphi-2006 / Turbo Delphi, saya tidak dapat menjamin untuk kompiler lain).