Perbaiki bug dalam game 2000 di Shockwave

gambar

Riwayat Penggantian Byte Tunggal


Kartun Kartun Summer Resort


Itu adalah musim panas tahun 2000. Saya berusia enam tahun, saya baru saja selesai kelas satu, dan liburan dimulai. Ini berarti bahwa saya dapat bermain untuk waktu yang lama di jalan, menonton kartun dan menyalakan komputer ayah saya dengan Windows 98 untuk mencari game di negara yang benar-benar baru dan belum dipetakan bernama Internet. Salah satu favorit saya adalah situs web Cartoon Network. Di atasnya saya menemukan banyak game flash yang menarik berdasarkan kartun televisi. Musim panas itu mereka merilis serangkaian permainan yang disebut Cartoon Cartoon Summer Resort.


Gameplay dari episode pertama Cartoon Cartoon Summer Resort

Game ini adalah RPG dua dimensi / petualangan dengan tampilan atas dari samping, terdiri dari empat episode. Pemain mengendalikan karakter kartun yang sedang berlibur di resor dengan karakter kartun lainnya. Di setiap episode, masalah muncul di resor yang perlu diselesaikan. Pemain harus menyelesaikannya dengan berinteraksi dengan karakter dan menemukan objek atau menukarnya.

Kembali 18 tahun


Dalam salah satu serangan nostalgia baru-baru ini, saya ingat permainan ini dan menyadari bahwa saya akan memainkannya lagi. Dia hampir berusia dua dekade, jadi sulit untuk menemukan tautan yang berfungsi.

Selain itu, tidak ada browser modern yang akan meluncurkan pemain Shockwave kuno dan rentan ... kecuali untuk Internet Explorer. Saya mungkin orang pertama yang menemukan alasan yang bisa dibenarkan untuk menggunakan Internet Explorer pada tahun 2018.

Setelah bermain sedikit, saya perhatikan momen yang tidak bisa diabaikan. Misalnya, musik latar yang monoton diputar dalam satu putaran tanpa akhir, dan pengakuan tabrakan yang buruk.

Bug yang sama


Setelah beberapa waktu, saya menemukan bug di permainan:

Saat bergerak melalui area di mana tidak ada yang seharusnya terjadi, kotak dialog terkadang muncul.

Seperti yang bisa dilihat dari animasi, dalam gim Anda bisa menyewa perahu untuk bergerak di sekitar air. Ketika Anda mencoba menyewa kapal lain, pesan β€œHari ini tidak ada lagi kapal sewaan!” Muncul. Jika Anda berlayar ke utara dan berjalan di sepanjang tepi kanan pulau, tetapi teks yang sama terbuka yang akan muncul di dermaga kapal.


Pada tahap ini, setiap orang waras yang menghargai waktu dan energinya akan menganggap bug sebagai gangguan kecil, mengingatkan dirinya sendiri bahwa itu adalah permainan web yang biasa-biasa saja untuk anak-anak, dibuat dua dekade lalu, dan akan terus dimainkan. Tapi bukan aku.

Sudah memiliki semua pengetahuan pemrograman saya dan melihat permainan, saya menganggap bug ini anehnya menarik. Tampaknya bagi saya bahwa saya telah menggali sebuah makam kuno dan menemukan di dalamnya sebuah teka-teki tak tersentuh yang bisa menghilang, yang tidak pernah diselesaikan oleh siapa pun. Bagi saya, bug ini adalah kesempatan untuk belajar dan menemukan sesuatu yang baru. Menariknya, justru peluang inilah yang diberikan oleh proses permainan itu sendiri di masa kecil saya. Ada sesuatu yang hampir puitis dalam bagaimana sesuatu dapat, secara tidak sengaja, menimbulkan tantangan baru jika Anda melihatnya dari sudut yang berbeda.

Game Dekonstruksi


Untuk memperbaiki bug, saya perlu memahami cara kerja internal game. Setelah memeriksa masalah ini, saya mengetahui bahwa game itu dibuat di Shockwave dalam aplikasi Direktur . Ketika bekerja dengan Direktur, proyek disimpan sebagai file .dir (Direktur). File ini mirip dengan file PSD untuk Photoshop. Sama seperti file PSD yang berisi informasi non-destruktif tentang lapisan dan teks, proyek .dir menyimpan semua sumber daya, kode sumber mentah, dan informasi lain yang membantu dalam proses pengembangan. Sutradara menggunakan bahasa scripting eksklusif Lingo untuk menghidupkan adegan.

Jika game disimpan dalam file .dir , saya bisa membukanya di Director dan dengan mudah mempelajari cara kerjanya. Namun, game ini diterbitkan sebagai file .dcr . File .dcr adalah versi kompilasi dari proyek Director. Artinya, semua kode sumber dikompilasi menjadi bytecode yang berjalan pada platform Shockwave. Proses ini mirip dengan bagaimana file PSD disederhanakan dan menjadi gambar PNG. Gambar PNG (dalam kasus kami, file DCR) berukuran lebih kecil, tetapi tidak mengandung informasi tentang lapisan dan pengeditan, dan hanya ditujukan untuk distribusi.

Ini berarti bahwa saya memegang objek biner 500 KB tanpa dokumentasi strukturnya. Bahkan jika saya menemukan cara untuk menemukan bytecode tingkat rendah, tampaknya tidak ada yang melakukan reverse-engineering bytecode Lingo dan mendokumentasikan prinsip platform Shockwave. Semua informasi ini adalah hak milik, milik Adobe, yang tidak memiliki alasan untuk mempublikasikannya. Peluang memahami permainan tampak agak suram.

Dekompresi


Merasa dikalahkan karena kemungkinan besar saya tidak bisa menghilangkan bug ini, saya memutuskan untuk mencari tahu apakah sumber daya dapat diekstraksi dari permainan. Saya pikir itu mungkin untuk menemukan bagian dari data yang dikompresi atau yang serupa. Setelah mencari, saya menemukan beberapa program yang disebut offzip dan packzip . Alat-alat ini dapat mencari data zlib dalam binari yang sewenang-wenang, menunjukkan offset dan mengekstraknya ke dalam file terpisah.

Saya berlari offzip dengan file DCR dan saya terkejut, itu benar-benar menemukan arsip! 249 buah, lebih tepatnya.

$ ./offzip.exe -a 1.dcr

- open input file: 1.dcr
- zip data to check: 32 bytes
- zip windowBits: 15
- seek offset: 0x00000000 (0)
+------------+-----+----------------------------+----------------------+
| hex_offset | ... | zip -> unzip size / offset | spaces before | info |
+------------+-----+----------------------------+----------------------+
0x00000026 . 164 -> 214 / 0x000000ca _ 38 8:7:26:0:1:7b6349f6
0x000000d3 .. 3932 -> 9169 / 0x0000102f _ 9 8:7:26:0:1:c1079d84
...
0x00080490 . 265 -> 472 / 0x00080599 _ 0 8:7:26:0:1:04d6b43f
0x00080599 . 209 -> 366 / 0x0008066a _ 0 8:7:26:0:1:7da3ba08

- 249 valid compressed streams found
- 0x0004040d -> 0x001565c8 bytes covering the 50% of the file


Saya mengekstrak semua file ini ke dalam folder dan mulai mempelajari hasilnya. Ada 206 file .dat , 38 file .fff , 4 .atn dan satu file .ini .


Penemuan


Saya mulai dengan file INI, tetapi tidak ada gunanya. Itu adalah tabel konversi font sederhana dari Direktori 7.0 antara Windows dan Mac. Kemudian saya pindah ke file DAT. Kebanyakan dari mereka adalah 1KB, jadi saya mulai dengan 144KB besar. Saya membukanya di hex editor dan belajar. Sebagian besar itu adalah data yang tidak terbaca. Namun, seiring waktu, saya menemukan beberapa kata di dalamnya yang tampaknya menjadi pengidentifikasi Lingo.


Analisis file DAT besar memberi saya beberapa petunjuk, mereka menyimpan beberapa pesan menarik. Saya menemukan bahwa Photoshop 3.0 kemungkinan besar digunakan untuk grafik. Saya juga belajar bahwa permainan memiliki alat pengeditan peta internal yang disebut Map-O-Matic v1 . Saya ingin melihat bagaimana tampilannya dan dibuat.

Saya juga menemukan nama perusahaan yang mengembangkan game: Funny Garbage . Nama pengembang utama juga ada di file, tapi saya tidak akan menyebutkannya. Sungguh luar biasa menemukan penulis permainan, yang dengan keras kepala saya coba untuk perbaiki setelah hampir 20 tahun, dan akhirnya melihat wajah orang yang menjadi kemungkinan penyebab penderitaan ini. Semua remah-remah informasi ini tentu saja menarik, tetapi mereka tidak banyak membantu.

Terobosan


Kemudian saya mulai mempelajari file .fff di hex editor. Saya sangat terkejut, semua data dalam file ini dapat dibaca dan tampak seperti data peta:


Saya secara manual mengekstrak beberapa data ini dan membersihkannya di editor teks. Apa yang saya lakukan sangat mirip dengan array JSON:

[
#member: "block.104",
#type: #FLOR,
#location: [16, 9],
#width: 64,
#WSHIFT: 0,
#height: 32,
#HSHIFT: 0,
#data: [
#item: [
#name: "",
#type: #WALL,
#visi: [
#visiObj: "",
#visiAct: "",
#inviObj: "",
#inviAct: ""
],
#COND: [[#hasObj: "", #hasAct: "", #giveObj: "sunscreen", #giveAct: "gotscreen"], #none, #none, #none]
],
#move: [#U: 0, #d: 0, #L: 0, #R: 0, #COND: 1, #TIMEA: 0, #TIMEB: 0],
#message: [
[#text: "You bought the sun screen.", #plrObj: "", #plrAct: ""],
[#text: "No more sunscreen today!", #plrObj: "", #plrAct: "gotscreen"]
]
]
]


Itu sangat penting, karena saya berhasil belajar banyak tentang cara permainan bekerja.

  1. Gim ini mengharapkan data peta, teks, dan acara berada di Objek Lingo seperti JSON
  2. Setiap entri #member adalah ubin, blok, atau karakter yang dapat digambar.
  3. Koordinat dan ukuran #member dapat diedit.

Mengetahui bahwa dialog game disimpan ke file-file ini, saya menulis garis pendek untuk mengekspor hanya satu dialog ke file:

grep -a -o '#text: "[^"]*' Uncompressed/*.fff | awk '{print $0,"\r"}' > Dialogue.txt

Dengan menggunakan file ini, saya dapat dengan cepat menemukan teks yang salah dan melihat file apa yang ada di dalamnya:


Teks yang salah adalah dalam 0004eda0.fff , atau di 0004f396.fff . Dalam kasus kami, teks bug muncul di file pertama. Kami tahu ini, karena tepat setelah itu adalah pesan yang kami terima saat berinteraksi dengan Og, yang merupakan karakter pada peta yang sama dengan ubin dengan bug.

Perbaikan bug


Sekarang saya bisa membuka 0004eda0.fff dan menemukan baris tentang kapal di hex editor. Setelah menemukannya, saya dapat menemukan objek #member terkait dengannya. Kemudian ubah propertinya dan simpan file tersebut. Lalu saya mengompresnya lagi dan menambalnya ke file sumber game DCR menggunakan packzip .


$ ./packzip -o 0x0004EDA0 Uncompressed/0004eda0.fff test.dcr

Ketika saya mengubah jenis blok dari block.11 ke block.13 dan menambal game, saya dapat melihat dengan jelas garis besar ubin kesalahan:


Dengan mengubah ID ubin, Anda dapat melihat batas-batas area masalah

Perbaikan bug itu sendiri sangat sederhana. Yang harus saya lakukan adalah mengubah pengidentifikasi # #message untuk #message kesalahan ini ke #fessage :


Sekarang, jika kami menambal perubahan dan kembali ke area ini, pesan tidak akan muncul lagi!


Memperbaiki bug dalam game, secara harfiah mengubah 1 byte

Mengapa bisa memperbaiki kesalahan?


Saya hanya bisa berasumsi bahwa mesin game cenderung memeriksa ubin yang berdiri ketika pemain bergerak. Jika beberapa kondisi terpenuhi, maka itu akan menampilkan pesan yang sesuai dengan ubin ini dari array #message . Setelah mengubah # #message ke # #fessage tautan ke susunan #message yang #message oleh kode tidak lagi ditemukan. Dia menganggap ini sebagai objek kosong (atau tidak terdefinisi?) Dan tidak menampilkan apa pun.

Pertimbangkan sebuah contoh di JS:

 function foo(bar) { if (bar["message"] !== undefined) { // display the message } } 

Misalkan kita tidak dapat mengubah fungsi foo() , tetapi kita perlu mengubah hasilnya. Kami memiliki akses ke data yang dikirimkan kepadanya. Anda dapat mengubah nama properti message dari objek yang diteruskan dan fungsi akan berpikir bahwa itu tidak ada.

Bagaimana bug ini muncul?


Saya kira karena malas. Pengembang menggunakan editor peta untuk membuat area ini. Kemungkinan besar, mereka menyalin kartu yang sudah dibuat sebelumnya ke area baru, dan kemudian mengubahnya. Ini lebih mudah daripada membuat semuanya dari awal. Tetapi karena data acara dan teks dicampur, mereka kemungkinan besar diabaikan di beberapa tempat dan lupa untuk menghapus atau menggantinya. Ini terlihat paling logis, karena dialog yang salah sering diambil dari kartu tetangga, di mana ia digunakan dengan benar.

Mengapa menghabiskan begitu banyak pekerjaan untuk sesuatu yang begitu tidak penting?


Saya tidak tahu. Mungkin karena nostalgia?

Source: https://habr.com/ru/post/id425601/


All Articles