Last active
September 21, 2015 14:38
-
-
Save asm256/9bfb88336a1433e2328a to your computer and use it in GitHub Desktop.
コンソールの文字化けを直すUnityInjectorプラグイン
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$build_script = 'https://gist.githubusercontent.com/asm256/9bfb88336a1433e2328a/raw/build.ps1' | |
$build_lib = 'https://gist.githubusercontent.com/asm256/ed75d84a9e89802821f8/raw/8015406dcf3eea94e36621cfd9ffb1e891639253/build_lib.ps1' | |
$web = new-object net.webclient | |
[Text.Encoding]::UTF8.GetString($web.DownloadData("$build_lib")) | iex | |
(WebDownloadString $web "$build_script")| iex |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#改変再配布自由 | |
#大抵の場合ここから | |
$prjName = 'ConsoleCodePage' | |
$base = 'https://gist.githubusercontent.com/asm256/9bfb88336a1433e2328a/raw/' | |
$srcs = @('CM3D2.ConsoleCodePage.Plugin.cs') | |
#ここまで | |
Init($prjName) | |
pushd -LiteralPath $prjDir | |
$web = new-object net.webclient | |
$web.BaseAddress = $base | |
Write-Host "ダウンロード" | |
foreach($s in $srcs){ | |
WebDownload $web $s | |
} | |
Write-Host "レシピ作成" | |
$recipe = foreach( $s in $srcs){ | |
make_recipe $s | |
} | |
Write-Host "コンパイル" | |
#csc /t:library /r:Assembly-CSharp-firstpass.dll CM3D2.ArchiveReplacer.Hook.cs | |
# これだけなら楽だったのに… | |
foreach($r in $recipe){ | |
compile $r | |
} | |
Write-Host "インストール" | |
foreach($r in $recipe){ | |
install $r | |
} | |
#パッチ当ては各自で | |
Pop-Location |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://gist.githubusercontent.com/asm256/9bfb88336a1433e2328a/raw/bootstrap.ps1'))" | |
/* | |
コンソールの文字化けを直すUnityInjectorプラグイン | |
必要なもの | |
.net Framework 3.5 | |
ビルド方法 | |
CM3D2_KAIZOU\UnityInjector\ 内に保存して | |
C:\Windows\Microsoft.NET\Framework\v3.5\csc /t:library /lib:..\CM3D2x64_Data\Managed /r:UnityEngine.dll /r:UnityInjector.dll /unsafe CM3D2.ConsoleCodePage.Plugin.cs | |
でビルド | |
*/ | |
// @AB_addarg /lib:%managed% | |
// @AB_addarg /r:UnityEngine.dll | |
// @AB_addarg /r:UnityInjector.dll | |
// @AB_addarg /unsafe | |
// @AB_install %uinjector% | |
// 2015.9.3.1 初版 | |
// 2015.9.3.2 クラス名変更 | |
// 2015.9.3.3 I18N.dll不要化 >>783 thx! | |
// 2015.9.9 簡易インストール対応 | |
using System; | |
using System.Text; | |
using System.Runtime.InteropServices; | |
using System.IO; | |
using UnityEngine; | |
using UnityInjector.Attributes; | |
namespace CM3D2.ConsoleCodePage.Plugin | |
{ | |
[PluginFilter("CM3D2x64"), | |
PluginFilter("CM3D2x86"), | |
PluginFilter("CM3D2VRx64"), | |
PluginName("CM3D2 ConsoleCodePage"), | |
PluginVersion("2015.9.3.3")] | |
public class ConsoleCodePage : UnityInjector.PluginBase | |
{ | |
// P/Invoke required: | |
[DllImport("kernel32.dll")] | |
private static extern IntPtr SetConsoleOutputCP(UInt32 codepage); | |
public const string Version = "2015.9.3.3"; | |
public void Awake() | |
{ | |
//一応、これでも表示はできるが…windows側のバグで酷い事になる | |
//SetConsoleOutputCP(65001); | |
//Console.OutputEncoding = Encoding.UTF8; | |
//表示は化けるが、7bitなので可逆に変換できる | |
//Console.OutputEncoding = Encoding.UTF7; | |
//SJISにない文字は表示できない可能性がある | |
SetConsoleOutputCP(932); | |
Console.OutputEncoding = Win32Encoding.GetEncoding(932); | |
Console.Write("Console コードページ("); | |
Console.Write(Console.OutputEncoding.ToString()); | |
Console.WriteLine(")"); | |
} | |
} | |
#region >>783 thx | |
// WIN32 APIを利用したSystem.Text.Encodingの実装 | |
// パクり元 http://jonskeet.uk/csharp/ebcdic/ | |
public class Win32Encoding : System.Text.Encoding | |
{ | |
uint codePage; | |
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] | |
static extern int WideCharToMultiByte(uint CodePage, uint dwFlags, System.IntPtr lpWideCharStr, int cchWideChar, System.IntPtr lpMultiByteStr, int cbMultiByte, System.IntPtr lpDefaultChar, System.IntPtr lpUsedDefaultChar); | |
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] | |
static extern int MultiByteToWideChar(uint CodePage, uint dwFlags, System.IntPtr lpMultiByteStr, int cbMultiByte, System.IntPtr lpWideCharStr, int cchWideChar); | |
public static Win32Encoding GetEncoding(uint CodePage) | |
{ | |
return new Win32Encoding(CodePage); | |
} | |
Win32Encoding(uint CodePage) | |
{ | |
this.codePage = CodePage; | |
} | |
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) | |
{ | |
int result; | |
unsafe | |
{ | |
fixed (char* pChars = chars) | |
{ | |
fixed (byte* pBytes = bytes) | |
{ | |
int maxByteCount = GetMaxByteCount(charCount); | |
var lpChars = (System.IntPtr)(pChars + charIndex); | |
var lpBytes = (System.IntPtr)(pBytes + byteIndex); | |
result = WideCharToMultiByte(codePage, 0, lpChars, charCount, lpBytes, maxByteCount, System.IntPtr.Zero, System.IntPtr.Zero); | |
} | |
} | |
} | |
return result; | |
} | |
public override int GetByteCount(char[] chars, int index, int count) | |
{ | |
int result; | |
unsafe | |
{ | |
fixed (char* pChars = chars) | |
{ | |
var lpChars = (System.IntPtr)(pChars + index); | |
result = WideCharToMultiByte(codePage, 0, lpChars, count, System.IntPtr.Zero, 0, System.IntPtr.Zero, System.IntPtr.Zero); | |
} | |
} | |
return result; | |
} | |
public override int GetMaxByteCount(int charCount) | |
{ | |
return charCount * 2; // !!! | |
} | |
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) | |
{ | |
int result; | |
unsafe | |
{ | |
fixed (byte* pBytes = bytes) | |
{ | |
fixed (char* pChars = chars) | |
{ | |
int maxCharCount = GetMaxCharCount(byteCount); | |
var lpChars = (System.IntPtr)(pChars + charIndex); | |
var lpBytes = (System.IntPtr)(pBytes + byteIndex); | |
result = MultiByteToWideChar(codePage, 0, lpBytes, byteCount, lpChars, maxCharCount); | |
} | |
} | |
} | |
return result; | |
} | |
public override int GetCharCount(byte[] bytes, int index, int count) | |
{ | |
int result; | |
unsafe | |
{ | |
fixed (byte* pBytes = bytes) | |
{ | |
var lpBytes = (System.IntPtr)(pBytes + index); | |
result = MultiByteToWideChar(codePage, 0, lpBytes, count, System.IntPtr.Zero, 0); | |
} | |
} | |
return result; | |
} | |
public override int GetMaxCharCount(int byteCount) | |
{ | |
return byteCount; | |
} | |
} | |
#endregion | |
} |
This is a nice fix for the console gibberish issue, I'll try to including it on the Core DebugPlugin, as an optional configuration parameter.
Hi, @usagirei
Is there any chance to use GetACP()
to determine system Code Page ?
using System;
using System.Runtime.InteropServices;
class Program {
[DllImport("kernel32.dll")]
private static extern uint GetACP();
static void Main(string[] args) {
// The following line will show "GetACP() = 932" for Japanese Windows system.
Console.WriteLine("GetACP() = {0}", GetACP());
}
}
And you could use GetACP()
in the DebugPlugin something like this :
namespace UnityInjector.Plugins
{
...
public class DebugPlugin : PluginBase
{
[DllImport("kernel32.dll")]
private static extern uint GetACP();
...
public void Awake()
{
if (this.CodePage != -1)
{
if(this.CodePage == 0)
{
this.CodePage = GetACP();
}
Console.OutputEncoding = ConsoleEncoding.GetEncoding(this.CodePage);
...
}
}
}
}
@asm256
UnityInjector 1.0.3.0の対応時に、ConsoleCodePage相当のコードがUnityInjector側に取り込まれたので、自動コンパイル対象から外しました。
つけたり外したりせわしなくて申し訳ない!
@neguse11
Interesting, i'll have a look at GetACP, -1 = disable (since it breaks text mirroring in some cases), 0 to Automatic via GetACP, and >1 manual
EDIT: Included, thanks for the tip, check in UnityInjector 1.0.3.4, 0 should call GetACP
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
勝手に収録させてもらいました。もし問題があれば教えてください。次回以降取り下げます