git ls-fileで抽出したファイルを別フォルダに階層を維持してコピー
背景
「.gitignoreで除外後のファイル一覧を抽出したいな……」「コミットして別フォルダでチェックアウトすればいいかもしれない」「もうちょっとこう、楽したい」「なんか-Recurseでやってもフラットにコピーされるな……ファイル指定だからか」
前提
- コマンド実行時のカレントディレクトリはプロジェクトフォルダ内(git ls-filesするので)
- gitでファイルがコミット済みであること(git ls-filesで一覧を取得するので)
- PowerShell (PSVersion:5.1.22621.2506)
コマンド
# コピー先パス、パスを結合するので末尾は'\'にすること $target="..\copy_dest\" git ls-files | % { $dest = $target + $_ $destDir=Split-Path $dest # フォルダがなければ作成 if (!(Test-Path $destDir)) { mkdir $destDir } Copy-Item $_ -Destination $dest -Force }
Visitorを使って既存のクラスに新規メソッドを追加する
言語はJavaでASM4.0
今回は既存のクラスに新しくメソッドを追加する。
検索して解決策をみつけたのでメモ。
SampleClassに新しく"public void foo() {}"を追加する。
おおまかな流れ
- byte配列が与えられる
- byte配列を用いてClassReaderのインスタンス生成
- ClassWriterのインスタンス生成
- ClassWriterを引数にClassVisitorのインスタンスを生成
- ClassVisitorのインスタンス生成時に無名クラスを用いてvisitEndのメソッドをオーバーライド
- 新しくメソッドを追加する
- ClassReader#acceptに、ClassVisitorに入れていたClassWriterのインスタンスを渡す
- ClassWriter#toByteArrayでbyte配列にする
// 元のファイル public class SampleClass { void f() {} }
// org.objectweb.asm.Opcodes内のstaticなフィールドを参照できる前提 public byte[] transform(byte[] bytes) { ClassReader cr = new ClassReader(bytes); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = new ClassVisitor(ASM4, cw) { @Override public void visitEnd() { // メソッドを新しくつくる // ACC_PUBLICの部分を変えるとアクセサが変わる MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "foo", "()V", null, null); mv.visitMaxs(0, 0);// ClassWriterのCOMPUTE_MAXSのフラグをたてているので勝手に計算してくれる super.visiteEnd(); } }; cr.accept(cw, 0); return cw.toByteArray(); }
// 書き換え後 public class SampleClass { void f() {} public void foo() {} }
メソッドを追加したいときはvisitEndをいじる。
参考URL:
Visitorを使った特定のメソッドへのコードの挿入
言語はJavaで、ASM 4.0のお話。
以前はClassNodeの中身をのぞいて書き換え、ということをしていたがVisitorを使ってみる。
今回は"void targetMethod()"というメソッド内の"f()"という処理の後に"System.out.println();"を挿入するという想定。
おおまかな流れ
- byte配列が与えられる
- byte配列を用いてClassReaderのインスタンス生成
- ClassWriterのインスタンス生成
- ClassWriterを引数にClassVisitorのインスタンスを生成
- ClassVisitorのインスタンス生成時に無名クラスを用いてvisitMethodのメソッドをオーバーライド
- 目標のメソッドをみつけて書き換え
- ClassReader#acceptに、ClassVisitorに入れていたClassWriterのインスタンスを渡す
- ClassWriter#toByteArrayでbyte配列にする
//元ソース public class SampleClass { void targetMethod() { this.f(); } void f() { } }
// org.objectweb.asm.Opcodes内のstaticなフィールドを参照できる前提 // Opcodes: ASM4やGETSTATICやALOADなどが定義されてるInterface public byte[] transform(byte[] bytes) { ClassReader cr = new ClassReader(bytes); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor cv = new ClassVisitor(ASM4, cw) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); // 目的のメソッドを探す // 今回は名前、引数、返り値から特定 // void targetMethod() -> targetMethod()V if (name.equals("targetMethod") && (desc.equals("()V")) { // 引数に事前にsuperで得たMethodVisitorを渡す(重要) // 目的のメソッドのMethodVisitorを置き換え // このときに無名クラスを使ってメソッドをオーバーライド、メソッドの挿入処理をする // 挿入のみならず、置き換えなどができる。また無名クラスじゃなくてもよい mv = new MethodVisitor(ASM4, mv) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { // 処理を消したいわけじゃないので通常の処理をおいておく super.visitMethodInsn(opcode, owner, name, desc, itf); // 目的の処理を探す // void f() -> f()V if (name.equals("f") && desc.equals("()V")) { // System.out.println();を挿入する // super使いながらvisitをして処理を書いていく super.visitFieldInsn(GETSTATIC, "java/lang/System", "out"/ "Ljava/io/PrintStream;");// System.out super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "()V", false);// .println() } } }; } return mv; } }; cr.accept(cw, 0); return cw.toByteArray(); }
これで書き換えができて以下のようになるはず。
// 書き換え後 public class SampleClass { void targetMethod() { this.f(); System.out.println(); } void f() { } }
visitでNodeを追加するイメージでやるといいかもしれない。
参考URL:
StarboundのModding入門の覚書
まずStarboundの公式フォーラムにあるModdingのチュートリアルをみましょう。下のリンクは一覧みたいもの。
Notice - MODDING GUIDES | Official Chucklefish Forums!
で、今回メインにみるのが下のリンクのチュートリアル。
Tutorial - Modding Basics p1 - Editing Vanilla Files | Official Chucklefish Forums!
1.packed.pakをassets_unpacker.exeを用いてunpack
//assets_unpacker.exeの位置 /Starbound/win32/assets_unpacker.exe or /Starbound/win64/assets_unpacker.exe //packed.pakの位置 /Starbound/assets/packed.pak
バッチファイルで次のように実行(コマンドプロンプトでも)
cd {Starboundのルートディレクトリ(assetsとかwin32のフォルダがあるところ)}
win32\asset_unpacker.exe "%CD%\assets\packed.pak" {出力先のファイルパス(フォルダ名になる)}
pause
これでunpackされたpacked.pakがでてきます。
2.いじる
今回はチュートリアルの通りに石炭の説明文をスーパー石炭にしてみましょう。省きます。
3.いじったやつをそのままゲームに導入
導入法は下のリンク参考
Tutorial - [Outdated] The Proper Way to Install Mods | Official Chucklefish Forums!
modsフォルダをStarbound直下に作成、自作MODのフォルダをそこにいれる、assetsの読み込み先に自作MODのフォルダを追加、が一連の流れです。
これでおわり。json形式のファイルだったりするので、カンマや括弧を間違えないように注意。
京都マイクラもぢんぐ会
とてもたのしかった。
ありーた氏はホモ、ちぃおぼえた。
デモで使ったMOD
発表したときに使ったスライド
mikutter_install_battle
この度mikutterの導入が成功したので忘れないうちにその手順をば。
毎度のことながら覚書きのようなものです。
Windows環境での導入法はwikiの方にあるのでそちらを先にみることをおすすめします。
MikutterInstallBattleForWindows - mikutter Wiki
- detail
- RubyInstallerでRubyの32bit版をインストール
まずRubyInstallerでRubyの32bit版をインストールします。64bit版だとgtk2のインストールでつまづいて私はできませんでした。
- DevKitのインストール
RubyInstallerでRubyをインストールしたので、DevKitをインストールします。もちろん、32bit版のものをダウンロードしてください。
DevKitのインストール方法はまずこちらを先にごらんください↓
Development Kit · oneclick/rubyinstaller Wiki · GitHub
ダウンロードし、適当なところにおきます。次にダウンロードした実行可能ファイル(~.exe)をたたいていろいろダウンロードしてもらいます。ディレクトリの設定はご自由に(たぶんスペースを含んだりマルチバイトだと不具合がでるかもしれないのでそこらへんは注意)。
いろいろダウンロードしてもらったら、"dk.rb"というファイルがあるはずです。そのファイルの存在を確認できたら、まずそこのディレクトリにコマンドプロンプトからcdして移動してください。
(例)"C:\devkit"に"dk.rb"がある場合 cd C:\devkit
その後コマンドプロンプトで、
ruby dk.rb init
をした後、
ruby dk.rb install
これでDevKitのインストールができます。これは先ほどのURLの先に書いてあることと同じです。
- gtk2のインストール
コマンドプロンプトを開き、
gem install gtk2
としてgtk2をインストールします。すると、失敗することがあります。
私の場合は、管理者権限でコマンドプロンプトを起動したあと同じようにインストールするとできました。
- mikutterのインストール
配布サイトからダウンロードして適当な場所に解凍、mikutter.rbをたたけば起動するはずです。
たまに起動しなかったりすることはありますが、動きます。
CubeWorldのデモ版の起動にて"Could not initialize Direct3D..."とでて起動できない
CubeWorldのalpha版がでましたね。購入するページはこちら→https://picroma.com/buycubeworld
購入を検討しており、まずDemo版で動作確認をしようとしたところ
Could not initialize Direct3D. Please make sure the latest DirectX End-User Runtime is installed: http://www.microsoft.com/en-us/download/details.aspx?id=35
とでて起動ができませんでした・・・
「Intel HD Graphicsはちゃんと動くかわからないと書いてたな・・・」と思い、そこらへんの線で調べていましたが、違ったようです。
具体的な解決法は下記のURLが情報元です。CubeWorldのフォーラムのトピックです。
http://cubeworldforum.org/topic/5254-fixing-cannot-initialize-direct3d/
環境は
OS: Windows 7
グラボ: Intel HD Graphics
先ほどのURLにかいてある通りに、「swiftshader」というものが必要になります。
そして先ほどのURLの手順の1にあるファイル(.rar)をおとし、解凍します。
その解凍してでてきたファイルをCubeWorldのデモ版(初期の名前は"Cube.exe")と同じディレクトリにおきます。その後、Cube.exeをたたいて起動・・・
これで私は起動できました。
おわりです。