備忘録:O'Reilly の Ebook を Fire HD で読む

情報を集めて整理したので自分のために記録しておく。(2019/04/23)
手間はかかるが、リフロー形式のKindle本と同じことができた。

端末

  • Fire HD 第8世代

書籍

  • O'Reilly Ebook Real World HTTP ミニ版 mobi形式

準備

  1. Send-to-Kindle Eメールアドレスの確認

    • パーソナル・ドキュメントを送信する宛先アドレスを確認します。
      コンテンツと端末の管理 設定タブ -> パーソナル・ドキュメント設定 -> Send-to-Kindle Eメールアドレスの設定
  2. Send-to-Kindle Eメールアドレスへの送信許可設定

    • パーソナル・ドキュメントの送信元アドレスを予め承認します。
      コンテンツと端末の管理 設定タブ -> パーソナル・ドキュメント設定 -> 承認済みEメールアドレス一覧

手順

  1. mobi形式のファイルをPCもしくはスマホへダウンロードします。
  2. 準備.1で確認したSend-to-Kindle Eメールアドレスのどれかに手順.1でダウンロードしたファイルをEメールに添付して送信します。
    送信元Eメールアドレスは予め承認済み(準備.2の手順)にする必要があります。
  3. コンテンツと端末の管理 コンテンツタブ -> 表示 -> パーソナル・ドキュメント より、手順.2で送信したパーソナル・ドキュメントを検索します。
  4. 「アクション」ボタンを押します。
  5. ドキュメントのポップアップ画面で「配信」のリンクを押します。
  6. 端末リストからパーソナル・ドキュメントを配信したい端末を選び配信します。

以下 Fire HD での操作

  1. なかなか配信されないので端末側で同期をします。
  2. ドキュメントが同期されていることを確認します。
    • ドキュメントアプリ -> SEND-TO-KINDLEドキュメント

Fire HD できること

  • マーカー、メモ、ブックマーク、位置
    • 他端末との同期もできます。
  • 単語選択時の辞書利用
  • 読み上げ

未確認

  • パーソナル・ドキュメントのサイズ制限
  • パーソナル・ドキュメントの個数制限
  • PDF形式のパーソナル・ドキュメント

MojaveからMinecraft ForgeでLANに公開のサーバーに接続する

gradlew runClientでの起動時に接続したいLAN公開サーバーが表示できない場合の対処

gradleのビルドスクリプト内で以下のように設定

runClient {
    jvmArgs '-Djava.net.preferIPv4Stack=true'
}

環境

参考URL

Stackdriver Loggingに出ている自ホストじゃないログはどうやって記録されるか

自ホストのものでないアクセスログが、Stackdriver LoggingのHTTPロードバランサーに度々出力されなんだろうとおもって調べた。

送信者の意図はわからないが、Hostタグを操作したリクエストのログがこのように出力されていることがわかった。

HTTPSの証明書自体は、www.example.comのものが使われているようで、ログから遡って考えるとなんとなく不思議な気がする。

検証したコード(仮に自ホストをwww.example.comに置き換え)

>>> import requests
>>> r = requests.get('https://www.example.com/testapi/search', headers={'Host':'www.google.com'})
>>> r.status_code
200

Stackdriver LoggingのHTTPロードバランサーのログ

2019-01-04 14:30:35.063 JST GET 200 1.42 KiB    null    python-requests/2.18.4  https://www.google.com/testapi/search

MinecraftForgeのMOD開発環境構築した

動機

FatCatModをv1.12対応しようと思い、MinecraftForgeのビルド環境を構築した

手順

1. MinecraftForgeのビルド環境を構築

情報は豊富にあるので割愛

2. IntelliJのマルチプロジェクト構成で構築

参考:MinecraftForge導入手順

ディレクトリ構成

MinecraftForge直下にMODのプロジェクトを配置

├── forge-1.12.2-14.23.4.2703-mdk
│   ├── CREDITS-fml.txt
│   ├── FatCatMOD
│   │   ├── FatCatMOD
│   │   ├── FatCatMOD.iml
│   │   ├── LICENSE.txt
│   │   ├── README.md
│   │   ├── build.gradle
│   │   ├── src
│   │   └── work
│   ├── LICENSE-new.txt
│   ├── MinecraftForge-Credits.txt
│   ├── Paulscode\ IBXM\ Library\ License.txt
│   ├── Paulscode\ SoundSystem\ CodecIBXM\ License.txt
│   ├── README.txt
│   ├── build
│   │   ├── classes
│   │   ├── dependency-cache
│   │   ├── libs
│   │   ├── resources
│   │   ├── sources
│   │   └── tmp
│   ├── build.gradle
│   ├── eclipse
│   ├── forge-1.12.2-14.23.4.2703-changelog.txt
│   ├── forge-1.12.2-14.23.4.2703-mdk.iml
│   ├── gradle
│   │   └── wrapper
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── out
│   │   └── production
│   ├── run
│   │   ├── addons
│   │   ├── config
│   │   ├── logs
│   │   ├── mods
│   │   ├── options.txt
│   │   ├── resourcepacks
│   │   ├── saves
│   │   ├── screenshots
│   │   ├── servers.dat
│   │   ├── usercache.json
│   │   └── usernamecache.json
│   ├── settings.gradle
│   └── src
│       ├── api
│       ├── main
│       └── test

/build.gradle (参考URLの内容を参考に書き換え)

buildscript {
    repositories {
        jcenter()
        maven { url = "http://files.minecraftforge.net/maven" }
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
    }
}
//apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.

//version = "1.0"
//group = "com.yourname.modid" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
//archivesBaseName = "modid"

allprojects{

apply plugin: 'net.minecraftforge.gradle.forge'
    sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
    compileJava {
        sourceCompatibility = targetCompatibility = '1.8'
    }

runClient {
    args '--username', 'test1'
}


    minecraft {
    version = "1.12.2-14.23.4.2703"
    runDir = "run"
    
    // the mappings can be changed at any time, and must be in the following format.
    // snapshot_YYYYMMDD   snapshot are built nightly.
    // stable_#            stables are built at the discretion of the MCP team.
    // Use non-default mappings at your own risk. they may not always work.
    // simply re-run your setup task after changing the mappings to update your workspace.
    mappings = "snapshot_20171003"
    // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}

archivesBaseName = project.projectDir.name
}

dependencies {
    // you may put jars on which you depend on in ./libs
    // or you may define them like so..
    //compile "some.group:artifact:version:classifier"
    //compile "some.group:artifact:version"
      
    // real examples
    //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev'  // adds buildcraft to the dev env
    //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env

    // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
    //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'

    // the deobf configurations:  'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
    // except that these dependencies get remapped to your current MCP mappings
    //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
    //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'

    // for more info...
    // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
    // http://www.gradle.org/docs/current/userguide/dependency_management.html

}

processResources {
    // this will ensure that this task is redone when the versions change.
    inputs.property "version", project.version
    inputs.property "mcversion", project.minecraft.version

    // replace stuff in mcmod.info, nothing else
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
                
        // replace version and mcversion
        expand 'version':project.version, 'mcversion':project.minecraft.version
    }
        
    // copy everything else except the mcmod.info
    from(sourceSets.main.resources.srcDirs) {
        exclude 'mcmod.info'
    }
}

3. ビルド

MODフォルダ配下の/FatCatMOD/build.gradleからビルド (正しいやり方かはわかりませんが・・・)

/FatCatMOD/build.gradle (変更なし)

sourceSets.main {
    java.srcDirs project.projectDir.name
    resources.srcDirs project.projectDir.name
}
 
version = "1.1.0"
tasks.withType(Jar) {compileJava.options.encoding = 'UTF-8'}
tasks.withType(Jar) {compileApiJava.options.encoding = 'UTF-8'}


processResources
{
    // this will ensure that this task is redone when the versions change.
    inputs.property "version", project.version
    inputs.property "mcversion", project.minecraft.version

    // replace stuff in mcmod.info, nothing else
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
                
        // replace version and mcversion
        expand 'version':project.version, 'mcversion':project.minecraft.version
    }
        
    // copy everything else, thats not the mcmod.info
    from(sourceSets.main.resources.srcDirs) {
        exclude 'mcmod.info'
    }
}

備忘録:Minecraft Forgeでいつも同じユーザーでデバッグする方法

gradleのビルドスクリプト内で以下のように設定 gradle runClient時に、毎回testという名前のユーザーで起動され 前回の状態が引き継がれるのでデバッグが捗る。

runClient {
    args '--username', 'test1'
}

Visual Studio 2017 でシンボルを読み込んでデバッグを試した

動機

WindowsAPI間の関係を調べるため、Visual Studio 2017の逆アセンブリ画面で、シンボル名を表示させられないかと思い、調べた。 Microsoftのシンボルサーバーから、シンボルをダウンロードして逆アセンブリ画面にシンボル名がちゃんと表示された。

設定手順

Microsoftのドキュメントほぼそのままに設定する。

Visual Studio デバッガーでシンボル (.pdb) ファイルとソース ファイルの指定 (C#、C++、Visual Basic、 F#)

  • ツールバーのメニューより、「ツール」→「オプション」から設定画面を開く f:id:n-noguchi:20181128011234p:plain

  • デバッグ」→「シンボル」画面で「Microsoftシンボルサーバー」にチェックを入れ「OK」を押す f:id:n-noguchi:20181128011303p:plain

デバッグ

普通にデバッグ実行すると、逆アセンブリ画面にシンボル名が表示された。

ただし、デバッグ実行時にシンボルをダウンロードに行くので、起動までにいつもより時間がかかる。

f:id:n-noguchi:20181128011740p:plain

Windowsのメモリアロケーション関数の関係について整理した

C++/CLIで、new演算子で確保したアンマネージドメモリをMarshal::FreeHGlobal()で解放しようとするとエラーになってなぜだろうと思い調べた。

ソース抜粋

  • メモリ確保
unsigned char *test = new unsigned char[100];
  • 問題ないメモリ解放
//これは問題ない
delete [] test;
  • 例外が起きるメモリ解放
//こう書くと例外
System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(test));

MSDNのドキュメントとVisual Studioの逆アセンブリ機能で調べると以下が判明

f:id:n-noguchi:20181114212433p:plain

よく見ると、メモリ確保のメカニズムがことなるので正しい関数で解放しなきゃいけないと書いてある。 たぶん、今回の問題も同じようにメモリ確保と対になる正しい関数でメモリ解放しなさいということなんだろう。

Because the different heap allocators provide distinctive functionality by using different mechanisms, you must free memory with the correct function. For example, memory allocated with HeapAlloc must be freed with HeapFree and not LocalFree or GlobalFree. Memory allocated with GlobalAlloc or LocalAlloc must be queried, validated, and released with the corresponding global or local function.

引用元:Comparing Memory Allocation Methods

つまりこういうことなんだろう

メモリ確保関数 メモリ解放関数
HeapAlloc HeapFree
GlobalAlloc GlobalFree
LocalAlloc LocalFree
Marshal::AllocHGlobal Marshal::FreeHGlobal
new演算子 delete演算子
malloc free