万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

  • ・資産運用おすすめ
    10万円は1000円くらい利益
    資産運用ブログ アセマネ
    • ・寄付お願いします
      YENTEN:YYzNPzdsZWqr5THWAdMrKDj7GT8ietDc2W
      BitZenny:ZfpUbVya8MWQkjjGJMjA7P9pPkqaLnwPWH
      c0ban:8KG95GXdEquNpPW8xJAJf7nn5kbimQ5wj1
      Skycoin:KMqcn7x8REwwzMHPi9fV9fbNwdofYAWKRo

    MUGENのキャラクターのSFFバージョン解析

    MUGENのキャラクターのSFFバージョン表示のPythonコード

    import struct
    import os
    
    def extract_pcx_from_sff(file_path, output_dir):
        try:
            with open(file_path, 'rb') as file:
                # ヘッダーの確認
                header = file.read(512)
                if header[:12] != b'ElecbyteSpr\0':
                    print("Not a valid SFF file or unknown format")
                    return
    
                # 最初のサブファイルのオフセットを取得
                first_subfile_offset = struct.unpack('<I', header[24:28])[0]
                subheader_size = struct.unpack('<I', header[28:32])[0]
    
                # サブファイルの抽出ループ
                current_offset = first_subfile_offset
                while current_offset != 0:
                    file.seek(current_offset)
    
                    # サブファイルヘッダーを読み込む(32バイト)
                    subfile_header = file.read(32)
                    
                    # サブヘッダーの長さを確認し、読み込みエラーが発生していないかチェック
                    if len(subfile_header) < 32:
                        print(f"Error: Subfile header is too short at offset {current_offset}")
                        break
    
                    # 次のサブファイルのオフセットとサブファイルの長さを取得
                    next_offset, subfile_length = struct.unpack('<II', subfile_header[:8])
    
                    # サブファイルの長さが0の場合はリンクされたスプライト
                    if subfile_length > 0:
                        # PCXデータを読み込む
                        pcx_data = file.read(subfile_length)
    
                        # 画像番号とグループ番号を取得
                        group_number, image_number = struct.unpack('<HH', subfile_header[12:16])
    
                        # 出力ファイル名を決定
                        output_file_name = f"sprite_{group_number}_{image_number}.pcx"
                        output_file_path = os.path.join(output_dir, output_file_name)
    
                        # PCXファイルとして保存
                        with open(output_file_path, 'wb') as pcx_file:
                            pcx_file.write(pcx_data)
                        
                        print(f"Extracted PCX file: {output_file_path}")
    
                    # 次のサブファイルに移動
                    current_offset = next_offset
    
        except Exception as e:
            print(f"Error processing file: {e}")
    
    # 使用例
    file_path = '/mnt/data/KAGE.sff'
    output_dir = '/path/to/output'  # PCXファイルの出力先ディレクトリを指定
    extract_pcx_from_sff(file_path, output_dir)

    gitのログを遡ってコミットログ修正を楽に

    チケット名が [HOGE-BAR]FUGA から [HOHO-MIMI]FUGA に変わる時

    ちまちま変えるのダルい。

    git-filter-repo 使う

    インストール

    pip install git-filter-repo

    以下でやる。

    git filter-repo --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '

    このエラーが出る。

    git filter-repo --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '
    
    Aborting: Refusing to destructively overwrite repo history since
    this does not look like a fresh clone.
      (expected freshly packed repo)
    Please operate on a fresh clone instead.  If you want to proceed
    anyway, use --force.

    このエラーメッセージは、git filter-repoがリポジトリの履歴を書き換える際に、安全な操作であることを確認するために出されます。具体的には、git filter-repoは既存のリポジトリで操作することを防ぐため、クリーンなクローンで作業することを推奨しています。

    理由 git filter-repoは、リポジトリの履歴を大幅に変更する強力なコマンドであり、履歴を完全に書き換えてしまうため、通常の開発作業で使っているリポジトリに対して実行すると、データの損失やチームでの作業に支障をきたす可能性があります。そこで、クリーンなクローン(新しいクローン)で作業することが推奨されています。

    解決方法 リポジトリのクローンを新たに作成してから、git filter-repoを実行するか、もし元のリポジトリで作業を強行したい場合は、--forceオプションを付けて実行できます。

    方法1: クリーンなクローンを作成してから実行 まず、リポジトリを新たにクローンします。

    git clone <リポジトリのURL>

    方法2: --forceオプションを使って強制的に実行

    git filter-repo --force --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '
    git filter-repo --refs refs/heads/main --path myfile.txt --refs $(git rev-list HEAD~10..HEAD) --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '

    ブランチ名、コミット範囲、特定ファイルを同時に指定する方法

    git filter-repo --refs refs/heads/main --path myfile.txt --refs $(git rev-list HEAD~10..HEAD) --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '
    オプションの説明

    --refs refs/heads/main: mainブランチを指定します。対象となるブランチを特定できます。 --path myfile.txt: 特定のファイル(ここではmyfile.txt)に限定して操作を行います。 --refs $(git rev-list HEAD~10..HEAD): コミット範囲を指定します。HEAD~10からHEADまでのコミットを対象にしています。 --message-callback: コミットメッセージの置換を行うスクリプトです。

    ブランチ名、コミット範囲、強制適用を同時に指定する方法

    git filter-repo --refs $(git rev-list HEAD~10..HEAD) --refs refs/heads/main --force --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '
    オプションの説明

    --refs $(git rev-list HEAD~10..HEAD): コミット範囲を指定します。HEAD~10からHEADまでの範囲。 --refs refs/heads/main: mainブランチを指定します。 --force: このオプションは、git filter-repoが通常は安全のために中止するような状況(既存のリポジトリに変更を加える場合など)で強制的に実行させるために使用します。 --message-callback: コミットメッセージを置換するスクリプトです。

    --refs $(git rev-list HEAD~10..HEAD): コミット範囲を指定します。HEAD~10からHEADまでの範囲。

    は意味なさそう

    git filter-repo --refs refs/heads/main --force --message-callback '
        return message.replace(b"[HOGE-BAR]FUGA", b"[HOHO-MIMI]FUGA")
    '

    がいいかも? main のところを適宜変える。

    gitコマンドのコメントを遡って修正

    コメントを遡って修正したい時、

    後でチケット名 みたいなコメントを含めておく。

    コメントが連続している場合、

    git log --grep="後でチケット名" --oneline | wc -l

    すると行数の数字が返ってくる

    41なら

    git rebase -i HEAD~41

    する。連続した場合限定だが。

    そして、リストはpickからeditにする!

    コメント変更

    git commit --amend

    その後

    git rebase --continue

    でちまちまやる。