PSPのゲーム「戦場の絆ポータブル」のセーブデータについているステージ別のプレビュー画像のハッシュ値から対戦ステージと対戦日時を抽出してタブ区切りテキストで出力するAppleScriptです。
保存された対戦データの内容を集計するために作成したものです。
PSPでメモリースティックに保存された対戦データには、すべて同じファイル名(ICON0.PNG)で異なる画像が添付されていました。ファイル名で対戦ステージを判定しようにも同じファイル名なので区別できません。
そこで、Spotlightの機能を用いて各セーブデータの「ICON0.PNG」をピックアップし、画像の内容のハッシュ値(SHA-1)を計算して、対戦ステージ内容を判定しました。
直近の対戦データをメモリースティック経由でMacに読み込み、本Scriptで分析してみたところ、
ジャブロー地上 2017年9月18日月曜日 14:42:48 ジャブロー地上 2017年9月18日月曜日 14:50:02 ジャブロー地上 2017年9月18日月曜日 14:55:22 タクラマカン砂漠 2017年9月18日月曜日 15:02:32 サイド7 2017年9月18日月曜日 15:09:36 ジャブロー地下 2017年9月18日月曜日 15:17:06 ジャブロー地上 2017年9月18日月曜日 15:31:08 サイド7 2017年9月18日月曜日 15:38:28 ジャブロー地上 2017年9月18日月曜日 15:51:52 ジャブロー地上 2018年1月2日火曜日 16:13:30 サイド7 2018年1月2日火曜日 16:23:04 ジャブロー地下 2018年1月2日火曜日 16:57:22
のようになりました。正月と秋分の日に親戚で集まったときに甥っ子と対戦した様子がありありと記録されています。
本Scriptはたまたまゲームのセーブデータの集計を行っていますが、同様の形式のデータを集計したい場合には使えそうです。
–> md5Lib.framework(To ~/Library/Frameworks)
AppleScript名:チェックサム値から、メモリースティックに保存されたReplay Dataのステージ名とプレイ日時を求める v3.1 |
— Created 2015-04-17 by Takaaki Naganoya — Modified 2018-10-29 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "md5Lib" –https://github.com/JoeKun/FileMD5Hash use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html use mdLib : script "Metadata Lib" version "2.0.0" –https://www.macosxautomation.com/applescript/apps/ property FileHash : a reference to current application’s FileHash property SMSForder : a reference to current application’s SMSForder property NSPredicate : a reference to current application’s NSPredicate property NSFileManager : a reference to current application’s NSFileManager property NSMutableArray : a reference to current application’s NSMutableArray –各SAVEDATAフォルダ中の「ICON0.PNG」のSHA-1ハッシュ値とステージ名の対応表 set shaArray to NSMutableArray’s arrayWithArray:{{stageName:"ニューヤーク", sha1:"dbb9e8e26e96dbb4dd3198e55b6cde41aba8e0a8"}, {stageName:"鉱山都市", sha1:"72f35456504b1957ec85fb6a1597ac1a2baa2ee9"}, {stageName:"グレートキャニオン", sha1:"9de93e8b853fe153bc73066fb07481c774499960"}, {stageName:"サイド7", sha1:"be22fa949bfd78b0cd97596929f07ce4ec501d7b"}, {stageName:"タクラマカン砂漠", sha1:"5284dc5f0f7a53ee5677908f66da1e00b80f76b6"}, {stageName:"トリントン・タワー", sha1:"9f080853dac45ecaf1672ff2230f2b9a80a00eb4"}, {stageName:"ジャブロー地下", sha1:"a93550099419f52444cf77366773192d0bf5f848"}, {stageName:"ヒマラヤ", sha1:"877f998d608dd267c380e59a17b2a95a139baef5"}, {stageName:"ジャブロー地上", sha1:"8c4ee44e8f2fbcbf061e6d5ea2b202b08f42c59a"}} load framework set apPath1 to choose folder with prompt "リプレイデータが入っているフォルダを選択してください" set aRes to perform search in folders {apPath1} predicate string "kMDItemFSName == %@" search arguments {"ICON0.PNG"} set outList to {} set errorList to {} repeat with i in aRes set j to contents of i set sumRes to (FileHash’s sha1HashOfFileAtPath:(j)) as string –チェックサムからステージ名を検索する set aPredStr to "sha1 == ’" & sumRes & "’" set aPredicate to (NSPredicate’s predicateWithFormat:aPredStr) set filteredArray to (shaArray’s filteredArrayUsingPredicate:aPredicate) if filteredArray as list = {} then set the end of errorList to j else set tmpStage to (filteredArray’s valueForKey:"stageName") as string set fAttrib to (NSFileManager’s defaultManager()’s attributesOfItemAtPath:j |error|:(missing value)) set cDat to (fAttrib’s fileCreationDate()) as date set tmpList to {tmpStage, cDat} if tmpList is not in outList then set the end of outList to tmpList end if end if end repeat –2D Listのソート set sortIndexes to {1} –Key Item id: begin from 0 set sortOrders to {true} –ascending = true set sortTypes to {"compare:"} set out2List to (SMSForder’s subarraysIn:(outList) sortedByIndexes:sortIndexes ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list –2D Listをタブ区切りテキストに変換して返す set aText to retItemDelimedAndParagraphDelimedText(out2List, tab, return) of me –入れ子のリストを、アイテム間のデリミタとパラグラフ間のデリミタを指定してテキスト化 –というか、入れ子のリストをタブ区切りテキストにするのが目的 on retItemDelimedAndParagraphDelimedText(aList, itemDelim, paragraphDelim) set aText to "" repeat with i in aList set aStr to retDelimedText(i, itemDelim) of me set aText to aText & aStr & paragraphDelim end repeat return aText end retItemDelimedAndParagraphDelimedText on retDelimedText(aList, aDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimedText |