2013年12月9日月曜日

CookieClickerのセーブデータの作り方を(ある程度)真似る

進捗どうですか。B4の大矢です。

ゲームを作ってみてブラウザゲームにおけるセーブデータの作り方が気になったので少し前に話題になってあっという間に消え去ったCookieClickerにおけるセーブデータの作り方を調べたのでパクってみます。

CookieClickerのセーブデータ

CookieClickerは独自の文字配列でセーブデータが作成されていました。区切り文字を用いた独自のフォーマットです。また、Base64フォーマットで見ただけでは中身を改変したり読めないようになっていました。

MS4wMzkzfHwxMzg2NTYyNTAyOTk3OzEzODY1NjI1MDI5OTc7MTM4NjU2Njg5MjYwNHwxMTExMTF8MDswOzA7MDswOzA7LTE7LTE7MDswOzA7MDswOzA7MDswOzA7MHwwLDAsMCwwOzAsMCwwLDA7MCwwLDAsMDswLDAsMCwwOzAsMCwwLDA7MCwwLDAsMDswLDAsMCwwOzAsMCwwLDA7MCwwLDAsMDswLDAsMCwwO3wyMjUxNzk5ODEzNjg1MjQ5OzIyNTE3OTk4MTM2ODUyNDk7MjI1MTc5OTgxMzY4NTI0OTsyMjUxNzk5ODEzNjg1MjQ5OzIyNTE3OTk4MTM2ODUyNDk7MTM3NDM4OTUzNDczfDIyNTE3OTk4MTM2ODUyNDk7MjI1MTc5OTgxMzY4NTI0OTsxMDI1%21END%21

素の状態のセーブデータはこのような感じ。このセーブデータを復元した際の中身は以下のような感じでした。

1.0393||1386562502997;1386562502997;1386562683559|111111|0;0;0;0;0;0;-1;-1;0;0;0;0;0;0;0;0;0;0|0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;|2251799813685249;2251799813685249;2251799813685249;2251799813685249;2251799813685249;137438953473|2251799813685249;2251799813685249;

区切り文字は「|」と「;」の2つで、これをプログラム側で読みこむという、傍目で見たらかなりめんどくさい構造になっています。このような独自の構造を1から作るのは流石にめんどくさいので今回はJson形式を使う方向に逃げてしまいます、楽だし。今回の作り方は非常に簡単なので、CookieClickerと同様に解析されてしまう事はもちろん前提で、”普通の人には読まれないくらいの作り”にしたいと思います。一行で扱えるセーブデータとして作成する事も目標です。

jsでセーブデータを作る

CookieClickerと同様にJavaScriptで作成していきます。まず連想配列のセーブデータを用意し、Json形式の文字列に変換します。ついでに日本語が含まれているのでescape関数をかけておきます。

var saveObj = { name: '大矢' , score: '123456', status : '進捗ダメです' };
var saveJson = escape(JSON.stringify(saveObj));

ここまでの中身(saveJson)は以下の通り。

%7B%22name%22%3A%22%u5927%u77E2%22%2C%22score%22%3A%22123456%22%2C%22status%22%3A%22%u9032%u6357%u30C0%u30E1%u3067%u3059%22%7D

escape関数をかけているのでgoogleの検索結果のアドレスなどでよく見るフォーマットになっていると思います。

次に、Base64フォーマットに変換します。こちらは「Base64.js」という便利な物があったのでこれを利用させてもらいます。置いてあるサイトはこちら。

このBase64.jsを読み込んで使用します。エンコードとデコードが可能です。用意した文字列にエンコードをかける事でセーブデータの可読性がかなり下がります。先ほどのソースも含めて記述します。

var saveObj = { name: '大矢' , score: '123456', status : '進捗ダメです' };
var saveJson = escape(JSON.stringify(saveObj));
var saveData = base64encode(saveJson);

最終的なデータ(saveData)の中身は以下の通り。

JTdCJTIybmFtZSUyMiUzQSUyMiV1NTkyNyV1NzdFMiUyMiUyQyUyMnNjb3JlJTIyJTNBJTIyMTIzNDU2JTIyJTJDJTIyc3RhdHVzJTIyJTNBJTIyJXU5MDMyJXU2MzU3JXUzMEMwJXUzMEUxJXUzMDY3JXUzMDU5JTIyJTdE

CookieClickerと同じBase64フォーマットになり、だいぶそれっぽくなりました。これで保存する最終的なセーブデータが完成です。

CookieClickerはCookieを用いて(何らかの因果を感じる)このような一行のデータをセーブしていました。今回は、せっかくなので保存期間の無いlocalStorageを使用してみます。(古いブラウザでは対応していないのでCookieを用いてもOKです)

localStorageについてはこちらを参照すると良いと思います。

localStorage.setItem("GameSaveData",saveData); //localStorage書き込み

これでセーブが完了しました。最後にlocalStorageに書き込んだデータを読み込み、復元してみます。base64decode関数(Base64.js)→unescape関数→JSON.parse関数 の流れでjsの連想配列として復元できます。

var loadSaveData = localStorage.getItem("GameSaveData"); //localStorage読み込み
var loadSaveObj = JSON.parse(unescape(base64decode(loadSaveData)));
console.log(loadSaveObj.name+"さん、進捗どうですか?→"+ loadSaveObj.status);

最後の行でconsole.logに出力しているのでそれを確認します。

結果

今回書いたソースコード全行は以下。

var saveObj = { name: '大矢' , score: '123456', status : '進捗ダメです' };
var saveJson = escape(JSON.stringify(saveObj));
var saveData = base64encode(saveJson);

localStorage.setItem("GameSaveData",saveData); //localStorage書き込み

var loadSaveData = localStorage.getItem("GameSaveData");
var loadSaveObj = JSON.parse(unescape(base64decode(loadSaveData)));
console.log(loadSaveObj.name+"さん、進捗どうですか?→"+ loadSaveObj.status);

console.logの表示。
>大矢さん、進捗どうですか?→進捗ダメです

無事に呪いの文字列が確認できました。ありがとうございました。

1 件のコメント: