SHARE
TWEET

CM3D2.YASDPlus.Plugin

a guest Jun 4th, 2016 4,929 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * CM3D2.YASD.Plugin (Yet Another Soft Demosaic Plugin)+CBL Patch
  3.  *
  4.  * 改造者注:元の作者さんが長らくメンテされてないようなので、自力でChu-B Lip対応と新ダンス・撮影モード
  5.  * 等への対応を行いました。しばりすのGameDataにテクスチャを置けばテクスチャ変更機能は要らなくなる
  6.  * と思いますが、元作者さんに敬意を表してまだ残してあります。でも再帰的に取得できても配置が出来ないから
  7.  * いまとなってはしばりすに任せたほうが……と思います。
  8.  * Chu-B Lip のシーン番号は通常版とは異なるのですが、どうやら飛んでいる番号は未定義のようです。
  9.  *
  10.  * 2.0.0.5 凡ミス。おもちゃ系藻がChu-B Lip版で外れていなかったバグを修正
  11.  * 2.0.0.4 Ver.1.30用VRパッチからUnityバージョンがv5.3.4p4 になったため非推奨となった処理を置き換え
  12.  * 2.0.0.3 複数メイド撮影プラグインの昼/夜メニューからの起動に対応
  13.  * 2.0.0.2 ダンス5のシーン番号を追加 誤記の修正
  14.  * 2.0.0.1 ダンス3、4、デスクトップカスタム、回想、メイドバトル、撮影モードのシーン番号を追加 Chu-B Lip対応を追加
  15.  *
  16.  *
  17.  *
  18.  *
  19.  * モザイクのON/OFFを切り替えたりボディのテクスチャを変更できるUnityInjectorのプラグインです。
  20.  *
  21.  * モザイクはF4でメイド|メイドとおもちゃ|全部|消さないを切り替えます。
  22.  * iniファイルを書き換えるとキーや切り替えの有効無効、モザイクを消す対象を変更できます。
  23.  * 切り替えを無効にしてもiniで指定されたモザイクは消えます。
  24.  * 切り替え機能がいらなければOFFにすると無駄な処理が減る分ちょっとだけ軽くなるかも。
  25.  *
  26.  * テクスチャ変更はメイドのボディ限定でTranslation Loaderと同じような処理をします。
  27.  * Translation Loaderと違いReiPatcherでパッチを当てる必要がないのが強みです。
  28.  * メイドのボディ以外のテクスチャも変更したい場合は素直にTranslation Loaderを使ってください。
  29.  * プラグインを導入して一度ゲームを起動するとUnityInjector\Configに
  30.  * YASD.iniファイルとYASDフォルダが作成されるのでYASDフォルダの中にテクスチャファイルを
  31.  * コピーしてください。
  32.  * テクスチャはpng形式のみに対応しています。
  33.  * メイドが表示されているときにF3を押すとメイドに反映されます。
  34.  * F3を押さずに自動で変更することもできますがデフォルトで無効になっています。
  35.  * 自動で変更する場合はiniファイルの[ChangeTexture]セクションの[AutoChange]を
  36.  * Trueに書き換えてください。
  37.  *
  38.  * 自動変更モードの仕様
  39.  * テクスチャはゲーム起動時にリストが作成されてその中の物のみが反映されます。
  40.  * テクスチャ変更時に何らかの理由で読み込みに失敗したファイルはリストから消去されます。
  41.  * また、一度変更したテクスチャはファイルを入れ替えても即時反映されません。
  42.  * ゲーム内のエディットで肌を変更後元の肌戻すと最新のファイルを読み込みます。
  43.  * また、自動変更中にF3を押すとリストを更新し最新のファイルを強制的に適用します。
  44.  * 要はゲーム中にテクスチャを入れ替えたらF3を押してください。
  45.  *
  46.  *
  47.  * yasd.iniの内容
  48.  * [DeMosaic]セクション
  49.  * ChangeMode={True, False}
  50.  *      キーボードでの切り替えの有効無効を設定します。
  51.  *      True=有効 False=無効
  52.  *
  53.  * Target={None, Maid, MaidAndItem, All}
  54.  *     モザイクを消す対象を指定。
  55.  *     キーボード切り替えが有効な場合は押す度に切り替わります。
  56.  *     無効の場合はiniで指定した値で固定されます。
  57.  *          None=消さない
  58.  *          Maid=女性のみ
  59.  *          MaidAndItem=女性とおもちゃ
  60.  *          All=全て(女性、おもちゃ、男性)
  61.  *
  62.  * HotKey
  63.  *      モザイクモード切替キーの設定。デフォルトはF4。
  64.  *      指定するコードは下記URL参照。
  65.  *      http://docs.unity3d.com/jp/current/ScriptReference/KeyCode.html
  66.  *
  67.  *
  68.  * [ChangeTexture]セクション
  69.  * AutoChange={True, False}
  70.  *      テクスチャ自動変更機能の有効無効を設定します。
  71.  *      True=有効 False=無効
  72.  *
  73.  * HotKey
  74.  *      テクスチャリスト再読み込みキーの設定。デフォルトはF3
  75.  *      自動更新が無効の場合はテクスチャリスト読み込みとテクスチャの変更を行います。
  76.  *      指定するコードはDeMosaicセクションのURL参照。
  77.  *
  78.  *
  79.  * コンパイル時の参照設定
  80.  * /r:UnityEngine.dll /r:UnityInjector.dll /r:Assembly-CSharp.dll /r:Assembly-CSharp-firstpass.dll /r:ExINI.dll
  81.  *
  82. */
  83.  
  84. using ExIni;
  85. using System;
  86. using System.Collections;
  87. using System.Collections.Generic;
  88. using System.Diagnostics;
  89. using System.IO;
  90. using System.Linq;
  91. using System.Text.RegularExpressions;
  92. using UnityEngine;
  93. using UnityInjector;
  94. using UnityInjector.Attributes;
  95. using System.Reflection;
  96.  
  97. namespace CM3D2.YetAnotherSoftDemosaic.Plugin
  98. {
  99.     static internal class LINQExt {
  100.         public static void ForEach<T>(this IEnumerable<T> self , Action<T> act) {
  101.             foreach(var cur in self) act(cur);
  102.         }
  103.     }
  104.  
  105.     public static class UnityExtensionsBridge {
  106.         static UnityExtensionsBridge() {
  107.             klass = Type.GetType("UnityInjector.Extensions,UnityInjector");
  108.         }
  109.         static Type klass = null;
  110.  
  111.         public static string UserDataPath {
  112.             get {
  113.                 return (string)klass.GetMethod("get_UserDataPath").Invoke(null,null);
  114.             }
  115.         }
  116.     }
  117.  
  118.     [PluginFilter("CM3D2x64"),
  119.     PluginFilter("CM3D2x86"),
  120.     PluginFilter("CM3D2VRx64"),
  121.     PluginFilter("CM3D2OHx64"),
  122.     PluginFilter("CM3D2OHx86"),
  123.     PluginFilter("CM3D2OHVRx64"),
  124.     PluginName("Yet Another Soft DeMosaic+CBL Patch"),
  125.     PluginVersion("2.0.0.5")]
  126.     public class YASD : PluginBase
  127.     {
  128.         private Coroutine deMosaicCoroutine;
  129.         private Coroutine[] changeTextureCoroutine = new Coroutine[2];
  130.         private bool runningCoroutine = false;
  131.  
  132.         private bool allowChangeMosaic = true;
  133.         private KeyCode deMosaicHotKey = KeyCode.F4;
  134.  
  135.         private bool allowAutoChangeTexture = true;
  136.         private KeyCode loadTextureKey = KeyCode.F3;
  137.  
  138.         private bool isChubLip = false;
  139.  
  140.         //1fで1秒
  141.         private const float WAIT_SECOND_DEMOSAIC = 0.5f;
  142.  
  143.         private const float WAIT_SECOND_CHANGE_TEXTURE = 1f;
  144.  
  145.         /// <summary>
  146.         /// CM3D2のシーンリスト
  147.         /// </summary>
  148.         private enum Scene
  149.         {
  150.             /// <summary>メイド選択(夜伽、品評会の前など)</summary>
  151.             SceneCharacterSelect = 1,
  152.  
  153.             /// <summary>品評会</summary>
  154.             SceneCompetitiveShow = 2,
  155.  
  156.             /// <summary>昼夜メニュー、仕事結果</summary>
  157.             SceneDaily = 3,
  158.  
  159.             /// <summary>ダンス1</summary>
  160.             SceneDance_DDFL = 4,
  161.  
  162.             /// <summary>メイドエディット</summary>
  163.             SceneEdit = 5,
  164.  
  165.             /// <summary>メーカーロゴ</summary>
  166.             SceneLogo = 6,
  167.  
  168.             /// <summary>メイド管理</summary>
  169.             SceneMaidManagement = 7,
  170.  
  171.             /// <summary>ショップ</summary>
  172.             SceneShop = 8,
  173.  
  174.             /// <summary>タイトル画面</summary>
  175.             SceneTitle = 9,
  176.  
  177.             /// <summary>トロフィー閲覧</summary>
  178.             SceneTrophy = 10,
  179.  
  180.             /// <summary>???</summary>
  181.             SceneTryInfo = 11,
  182.  
  183.             /// <summary>主人公エディット</summary>
  184.             SceneUserEdit = 12,
  185.  
  186.             /// <summary>起動時警告画面</summary>
  187.             SceneWarning = 13,
  188.  
  189.             /// <summary>夜伽</summary>
  190.             SceneYotogi = 14,
  191.  
  192.             /// <summary>ADVパート(kgスクリプト処理)</summary>
  193.             SceneADV = 15,
  194.  
  195.             /// <summary>日付画面</summary>
  196.             SceneStartDaily = 16,
  197.  
  198.             /// <summary>タイトルに戻る</summary>
  199.             SceneToTitle = 17,
  200.  
  201.             /// <summary>MVP</summary>
  202.             SceneSingleEffect = 18,
  203.  
  204.             /// <summary>スタッフロール</summary>
  205.             SceneStaffRoll = 19,
  206.  
  207.             /// <summary>ダンス2</summary>
  208.             SceneDance_ETYL = 20,
  209.  
  210.             /// <summary>ダンス選択</summary>
  211.             SceneDance_Selector = 21,
  212.  
  213.             /// <summary>ダンス_3</summary>
  214.             SceneDance_SL = 22,
  215.  
  216.             /// <summary>デスクトップカスタム</summary>
  217.             SceneEditDesk = 23,
  218.  
  219.             /// <summary>回想</summary>
  220.             SceneRecollection = 24,
  221.  
  222.             /// <summary>メイドバトル</summary>
  223.             SceneMaidBattle = 25,
  224.  
  225.             /// <summary>ダンス_4</summary>
  226.             SceneDance_SMT = 26,
  227.  
  228.             /// <summary>撮影モード</summary>
  229.             ScenePoser = 27,
  230.  
  231.             /// <summary>ダンス5</summary>
  232.             SceneDance_RTY_Release = 28
  233.         }
  234.  
  235.         /// <summary>
  236.         /// CM3D2CBLのシーンリスト
  237.         /// </summary>
  238.         private enum SceneCBL
  239.         {
  240.             /// <summary>1</summary>
  241.  
  242.             /// <summary>CBL:メニュー画面</summary>
  243.             SceneMainMenuWithChubLip = 2,
  244.  
  245.             /// <summary>CBL:ダンス1</summary>
  246.             SceneDance_DDFL_Release = 3,
  247.  
  248.             /// <summary>CBL:メイドエディット</summary>
  249.             SceneEdit = 4,
  250.  
  251.             /// <summary>5</summary>
  252.  
  253.             /// <summary>CBL:タイトル画面</summary>
  254.             SceneTitle = 6,
  255.  
  256.             /// <summary>7</summary>
  257.  
  258.             /// <summary>CBL:主人公エディット</summary>
  259.             SceneUserEdit = 8,
  260.  
  261.             /// <summary>CBL:起動時警告画面</summary>
  262.             SceneWarning = 9,
  263.  
  264.             /// <summary>CBL:夜伽</summary>
  265.             SceneYotogiWithChubLip = 10,
  266.  
  267.             /// <summary>CBL:ADVパート(kgスクリプト処理)</summary>
  268.             SceneADV = 11,
  269.  
  270.             /// <summary>CBL:日付画面</summary>
  271.             SceneStartDaily = 12,
  272.  
  273.             /// <summary>CBL:タイトルに戻る</summary>
  274.             SceneToTitle = 13,
  275.  
  276.             /// <summary>14</summary>
  277.  
  278.             /// <summary>15</summary>
  279.  
  280.             /// <summary>CBL:ダンス2</summary>
  281.             SceneDance_ETYL_Release = 16,
  282.  
  283.             /// <summary>CBL:ダンス選択</summary>
  284.             SceneDanceSelect = 17,
  285.  
  286.            /// <summary>CBL:ダンス3</summary>
  287.             SceneDance_SCL_Release = 18,
  288.  
  289.             /// <summary>CBL:デスクトップカスタム</summary>
  290.             SceneDeskCustomize = 19,
  291.  
  292.             /// <summary>CBL:ダンス4</summary>
  293.             SceneDance_SMT_Release = 20,
  294.  
  295.             /// <summary>CBL:撮影モード</summary>
  296.             ScenePhotoMode = 21,
  297.  
  298.             /// <summary>CBL:ダンス5</summary>
  299.             SceneDance_RTY_Release = 22
  300.         }
  301.  
  302.         /// <summary>
  303.         /// 3Dキャラが描画されるレベル
  304.         /// </summary>
  305.         private enum EnableLevel
  306.         {
  307.             /// <summary>品評会</summary>
  308.             SceneCompetitiveShow = 2,
  309.  
  310.             /// <summary>ダンス1</summary>
  311.             SceneDance_DDFL = 4,
  312.  
  313.             /// <summary>メイドエディット</summary>
  314.             SceneEdit = 5,
  315.  
  316.             /// <summary>ショップ</summary>
  317.             SceneShop = 8,
  318.  
  319.             /// <summary>夜伽</summary>
  320.             SceneYotogi = 14,
  321.  
  322.             /// <summary>ADVパート(kgスクリプト処理)</summary>
  323.             SceneADV = 15,
  324.  
  325.             /// <summary>MVP</summary>
  326.             SceneSingleEffect = 18,
  327.  
  328.             /// <summary>ダンス2</summary>
  329.             SceneDance_ETYL = 20,
  330.  
  331.             /// <summary>ダンス_3</summary>
  332.             SceneDance_SL = 22,
  333.  
  334.             /// <summary>回想</summary>
  335.             SceneRecollection = 24,
  336.  
  337.             /// <summary>メイドバトル</summary>
  338.             SceneMaidBattle = 25,
  339.  
  340.             /// <summary>ダンス_4</summary>
  341.             SceneDance_SMT = 26,
  342.  
  343.             /// <summary>撮影モード</summary>
  344.             ScenePoser = 27,
  345.  
  346.             /// <summary>ダンス5</summary>
  347.             SceneDance_RTY_Release = 28
  348.         }
  349.  
  350.         /// <summary>
  351.         /// 3Dキャラが描画されるレベル Chu-B Lip
  352.         /// </summary>
  353.         private enum EnableLevelCBL
  354.         {
  355.             /// <summary>CBL:メニュー画面</summary>
  356.             SceneMainMenuWithChubLip = 2,
  357.  
  358.             /// <summary>CBL:ダンス1</summary>
  359.             SceneDance_DDFL_Release = 3,
  360.  
  361.             /// <summary>CBL:メイドエディット</summary>
  362.             SceneEdit = 4,
  363.  
  364.             /// <summary>CBL:主人公エディット</summary>
  365.             SceneUserEdit = 8,
  366.  
  367.             /// <summary>CBL:夜伽/チュートリアル感度調整モード</summary>
  368.             SceneYotogiWithChubLip = 10,
  369.  
  370.             /// <summary>CBL:ADVパート(kgスクリプト処理)</summary>
  371.             SceneADV = 11,
  372.  
  373.             /// <summary>CBL:ダンス2</summary>
  374.             SceneDance_ETYL_Release = 16,
  375.  
  376.            /// <summary>CBL:ダンス3</summary>
  377.             SceneDance_SCL_Release = 18,
  378.  
  379.             /// <summary>CBL:ダンス4</summary>
  380.             SceneDance_SMT_Release = 20,
  381.  
  382.             /// <summary>CBL:撮影モード</summary>
  383.             ScenePhotoMode = 21,
  384.  
  385.             /// <summary>CBL:ダンス5</summary>
  386.             SceneDance_RTY_Release = 22
  387.         }
  388.  
  389.         /// <summary>
  390.         /// 男キャラやおもちゃが出現するレベル
  391.         /// </summary>
  392.         private enum ShowMenOrToysLevel
  393.         {
  394.             /// <summary>夜伽</summary>
  395.             SceneYotogi = 14,
  396.  
  397.             /// <summary>ADVパート(kgスクリプト処理)</summary>
  398.             SceneADV = 15,
  399.  
  400.             /// <summary>撮影モード</summary>
  401.             ScenePoser = 27
  402.         }
  403.  
  404.         /// <summary>
  405.         /// 男キャラやおもちゃが出現するレベル Chu-B Lip
  406.         /// </summary>
  407.         private enum ShowMenOrToysLevelCBL
  408.         {
  409.             /// <summary>CBL:夜伽/チュートリアル感度調整モード</summary>
  410.             SceneYotogiWithChubLip = 10,
  411.  
  412.             /// <summary>CBL:ADVパート(kgスクリプト処理)</summary>
  413.             SceneADV = 11,
  414.  
  415.             /// <summary>CBL:撮影モード</summary>
  416.             ScenePhotoMode = 21
  417.         }
  418.  
  419.         /// <summary>
  420.         /// メイドが出現するがキャラ変更や着替えを行わないレベル
  421.         /// </summary>
  422.         private enum NotChangeMaidsLevel
  423.         {
  424.             /// <summary>品評会</summary>
  425.             SceneCompetitiveShow = 2,
  426.  
  427.             /// <summary>ダンス1</summary>
  428.             SceneDance_DDFL = 4,
  429.  
  430.             /// <summary>MVP</summary>
  431.             SceneSingleEffect = 18,
  432.  
  433.             /// <summary>ダンス2</summary>
  434.             SceneDance_ETYL = 20,
  435.  
  436.             /// <summary>ダンス3</summary>
  437.             SceneDance_SL = 22,
  438.  
  439.             /// <summary>ダンス4</summary>
  440.             SceneDance_SMT = 26,
  441.  
  442.             /// <summary>ダンス5</summary>
  443.             SceneDance_RTY_Release = 28
  444.         }
  445.  
  446.         /// <summary>
  447.         /// メイドが出現するがキャラ変更や着替えを行わないレベル Chu-B Lip
  448.         /// </summary>
  449.         private enum NotChangeMaidsLevelCBL
  450.         {
  451.             /// <summary>CBL:ダンス1</summary>
  452.             SceneDance_DDFL_Release = 3,
  453.  
  454.             /// <summary>CBL:ダンス2</summary>
  455.             SceneDance_ETYL_Release = 16,
  456.  
  457.             /// <summary>CBL:ダンス3</summary>
  458.             SceneDance_SCL_Release = 18,
  459.  
  460.             /// <summary>CBL:ダンス4</summary>
  461.             SceneDance_SMT_Release = 20,
  462.  
  463.             /// <summary>CBL:ダンス5</summary>
  464.             SceneDance_RTY_Release = 22
  465.         }
  466.  
  467.         private ChangeBodyTexture changeBodyTexture = new ChangeBodyTexture();
  468.         private DeMosaic deMosaic = new DeMosaic();
  469.  
  470.         private void LoadConfig()
  471.         {
  472.             IniKey changeMosaic = Preferences["DeMosaic"]["ChangeMode"];
  473.             IniKey target = Preferences["DeMosaic"]["Target"];
  474.             IniKey changeMosaicKey = Preferences["DeMosaic"]["HotKey"];
  475.             IniKey changeTex = Preferences["ChangeTexture"]["AutoChange"];
  476.             IniKey changeTexKey = Preferences["ChangeTexture"]["HotKey"];
  477.  
  478.             string dataPath = Application.dataPath;
  479.             isChubLip = dataPath.Contains("CM3D2OH");
  480.  
  481.             if (changeMosaic == null || string.IsNullOrEmpty(changeMosaic.Value))
  482.             {
  483.                 changeMosaic.Value = allowChangeMosaic.ToString();
  484.                 SaveConfig();
  485.             }
  486.             else
  487.             {
  488.                 if (!bool.TryParse(changeMosaic.Value, out allowChangeMosaic))
  489.                 {
  490.                     changeMosaic.Value = allowChangeMosaic.ToString();
  491.                     SaveConfig();
  492.                 }
  493.             }
  494.  
  495.             if (target == null || string.IsNullOrEmpty(target.Value))
  496.             {
  497.                 target.Value = deMosaic.Target.ToString();
  498.                 SaveConfig();
  499.             }
  500.             else
  501.             {
  502.                 if (Enum.IsDefined(typeof(DeMosaic.Switch), target.Value))
  503.                 {
  504.                     deMosaic.Target = (DeMosaic.Switch)Enum.Parse(typeof(DeMosaic.Switch), target.Value, true);
  505.                 }
  506.                 else
  507.                 {
  508.                     target.Value = deMosaic.Target.ToString();
  509.                     SaveConfig();
  510.                 }
  511.             }
  512.  
  513.             if (changeMosaicKey == null || string.IsNullOrEmpty(changeMosaicKey.Value))
  514.             {
  515.                 changeMosaicKey.Value = deMosaicHotKey.ToString();
  516.                 SaveConfig();
  517.             }
  518.             else
  519.             {
  520.                 if (Enum.IsDefined(typeof(KeyCode), changeMosaicKey.Value))
  521.                 {
  522.                     deMosaicHotKey = (KeyCode)Enum.Parse(typeof(KeyCode), changeMosaicKey.Value, true);
  523.                 }
  524.                 else
  525.                 {
  526.                     changeMosaicKey.Value = deMosaicHotKey.ToString();
  527.                     SaveConfig();
  528.                 }
  529.             }
  530.  
  531.             if (changeTex == null || string.IsNullOrEmpty(changeTex.Value))
  532.             {
  533.                 changeTex.Value = allowAutoChangeTexture.ToString();
  534.                 SaveConfig();
  535.             }
  536.             else
  537.             {
  538.                 if (!bool.TryParse(changeTex.Value, out allowAutoChangeTexture))
  539.                 {
  540.                     changeTex.Value = allowAutoChangeTexture.ToString();
  541.                     SaveConfig();
  542.                 }
  543.             }
  544.  
  545.             if (changeTexKey == null || string.IsNullOrEmpty(changeTexKey.Value))
  546.             {
  547.                 changeTexKey.Value = loadTextureKey.ToString();
  548.                 SaveConfig();
  549.             }
  550.             else
  551.             {
  552.                 if (Enum.IsDefined(typeof(KeyCode), changeTexKey.Value))
  553.                 {
  554.                     loadTextureKey = (KeyCode)Enum.Parse(typeof(KeyCode), changeTexKey.Value, true);
  555.                 }
  556.                 else
  557.                 {
  558.                     changeTexKey.Value = loadTextureKey.ToString();
  559.                     SaveConfig();
  560.                 }
  561.             }
  562.         }
  563.  
  564.         private void Awake()
  565.         {
  566.             GameObject.DontDestroyOnLoad(this);
  567.             System.Diagnostics.Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
  568.  
  569.             LoadConfig();
  570.  
  571.             StartCoroutine(GetKeyInput());
  572.         }
  573.  
  574.         private void OnLevelWasLoaded(int level)
  575.         {
  576.             if (runningCoroutine)
  577.             {
  578.                 System.Diagnostics.Debug.WriteLine("Demosaic Coroutine stop.");
  579.                 StopCoroutine(deMosaicCoroutine);
  580.                 StopCoroutine(changeTextureCoroutine[0]);
  581.                 if (allowAutoChangeTexture)
  582.                 {
  583.                     StopCoroutine(changeTextureCoroutine[1]);
  584.                 }
  585.                 runningCoroutine = false;
  586.             }
  587.            
  588.             if ((isChubLip && Enum.IsDefined(typeof(EnableLevelCBL), level)) || (!isChubLip && Enum.IsDefined(typeof(EnableLevel), level)))
  589.             {
  590.                 System.Diagnostics.Debug.WriteLine("Demosaic Coroutine start.");
  591.                 deMosaicCoroutine = StartCoroutine(DeMosaicCoroutine(level));
  592.                 changeTextureCoroutine[0] = StartCoroutine(GetKeyInputForTextureChanger());
  593.                 if (allowAutoChangeTexture)
  594.                 {
  595.                     changeTextureCoroutine[1] = StartCoroutine(AutoTextureChangerCoroutine());
  596.                 }
  597.                 runningCoroutine = true;
  598.             }
  599.         }
  600.  
  601.         private IEnumerator AutoTextureChangerCoroutine()
  602.         {
  603.             while (true)
  604.             {
  605.                 yield return new WaitForSeconds(WAIT_SECOND_CHANGE_TEXTURE);
  606.                 changeBodyTexture.ChangeTexture(false);
  607.             }
  608.         }
  609.  
  610.         private IEnumerator GetKeyInputForTextureChanger()
  611.         {
  612.             while (true)
  613.             {
  614.                 if (Input.GetKeyDown(loadTextureKey))
  615.                 {
  616.                     ChangeBodyTexture.LoadTextureList(ChangeBodyTexture.textureList);
  617.                     changeBodyTexture.ChangeTexture(true);
  618.                 }
  619.                 yield return null;
  620.             }
  621.         }
  622.  
  623.         private IEnumerator GetKeyInput()
  624.         {
  625.             while (true)
  626.             {
  627.                 if (Input.GetKeyDown(deMosaicHotKey) && allowChangeMosaic)
  628.                 {
  629.                     deMosaic.Target++;
  630.                     Console.WriteLine("YADSM Target:{0}", deMosaic.Target.ToString());
  631.                 }
  632.                 yield return null;
  633.             }
  634.         }
  635.  
  636.         private IEnumerator DeMosaicCoroutine(int level)
  637.         {
  638.             while (true)
  639.             {
  640.                 bool result = deMosaic.DeMosaicMaids();
  641.  
  642.                 if (result && !allowChangeMosaic && Enum.IsDefined(typeof(NotChangeMaidsLevel), level))
  643.                 {
  644.                     System.Diagnostics.Debug.WriteLine("DeMosaic Coroutine Break.");
  645.                     runningCoroutine = false;
  646.                     yield break;
  647.                 }
  648.                 yield return null;
  649.  
  650.                 if ((isChubLip && Enum.IsDefined(typeof(ShowMenOrToysLevelCBL), level)) || (!isChubLip && Enum.IsDefined(typeof(ShowMenOrToysLevel), level)))
  651.                 {
  652.                     deMosaic.DeMosaicToys();
  653.                     yield return null;
  654.  
  655.                     deMosaic.DeMosaicMen();
  656.                 }
  657.                 //System.Diagnostics.Debug.WriteLine("DeMosaic Coroutine Continue.");
  658.                 yield return new WaitForSeconds(WAIT_SECOND_DEMOSAIC);
  659.             }
  660.         }
  661.  
  662.         public void OnApplicationQuit()
  663.         {
  664.             Preferences["DeMosaic"]["Target"].Value = deMosaic.Target.ToString();
  665.             SaveConfig();
  666.         }
  667.     }
  668.  
  669.     public class DeMosaic
  670.     {
  671.         public enum Switch
  672.         {
  673.             None,
  674.             Maid,
  675.             MaidAndItem,
  676.             All,
  677.             Max
  678.         }
  679.  
  680.         private Switch _target = Switch.All;
  681.  
  682.         public Switch Target
  683.         {
  684.             get { return _target; }
  685.             set { _target = value == Switch.Max ? Switch.None : value; }
  686.         }
  687.  
  688.         private Shader shaderTransparent;
  689.         private Shader shaderMosaic;
  690.  
  691.         private bool isChubLip = false;
  692.  
  693.         public DeMosaic() {
  694.             shaderTransparent = Shader.Find("CM3D2/Toony_Lighted_Trans");
  695.             shaderMosaic = Shader.Find("CM3D2/Mosaic");
  696.         }
  697.  
  698.         private string getHiraerchy(Transform t)
  699.         {
  700.             string hiraerchy = "/" + t.name;
  701.             while (t.parent)
  702.             {
  703.                 t = t.parent;
  704.                 hiraerchy = "/" + t.name + hiraerchy;
  705.             }
  706.  
  707.             return hiraerchy;
  708.         }
  709.  
  710.         private Renderer[] GetMosaicRenderer(string type)
  711.         {
  712.             GameObject alloffset = GameObject.Find("__GameMain__/Character/Active/AllOffset");
  713.             if (!alloffset)
  714.             {
  715.                 return null;
  716.             }
  717.             Renderer[] mosaic = alloffset.GetComponentsInChildren<Renderer>(true)
  718.                 .Where(_ => _.materials.Any(m => m.name.Contains("moza")))
  719.                 .ToArray();
  720.  
  721.             string s;
  722.  
  723.             if (type.Equals("toy"))
  724.             {
  725.                 return mosaic
  726.                     .Where(_ => _.materials.Any(m => m.name != "moza"))
  727.                     .ToArray();
  728.             }
  729.             else if (type.Equals("man"))
  730.             {
  731.                 s = "Man[";
  732.             }
  733.             else if (type.Equals("maid"))
  734.             {
  735.                 s = "Maid[";
  736.             }
  737.             else
  738.             {
  739.                 Console.WriteLine("YASD.GetMosaicRenderer: Argument error.");
  740.                 return null;
  741.             }
  742.  
  743.             return mosaic
  744.                 .Where(_ => _.name.Equals("moza"))
  745.                 .Where(_ => getHiraerchy(_.transform).Contains(s))
  746.                 .ToArray();
  747.         }
  748.  
  749.         private Renderer[] GetMaidsMosaicRenderer()
  750.         {
  751.             return GetMosaicRenderer("maid");
  752.         }
  753.  
  754.         private Renderer[] GetMenMosaicRenderer()
  755.         {
  756.             return GetMosaicRenderer("man");
  757.         }
  758.  
  759.         private Renderer[] GetToysMosaicRenderer()
  760.         {
  761.             return GetMosaicRenderer("toy");
  762.         }
  763.  
  764.         public bool DeMosaicMaids()
  765.         {
  766.             bool result = false;
  767.             Renderer[] maidsMosaicList = GetMaidsMosaicRenderer();
  768.  
  769.             if (maidsMosaicList != null)
  770.             {
  771.                 result = HumanMosaicSwitcher(maidsMosaicList, (Target == DeMosaic.Switch.None));
  772.             }
  773.             return result;
  774.         }
  775.  
  776.         public void DeMosaicMen()
  777.         {
  778.             Renderer[] menMosaicList = GetMenMosaicRenderer();
  779.  
  780.             if (menMosaicList != null)
  781.             {
  782.                 HumanMosaicSwitcher(menMosaicList, (Target != DeMosaic.Switch.All));
  783.             }
  784.         }
  785.  
  786.         private bool HumanMosaicSwitcher(Renderer[] mosaic, bool enableMosaic)
  787.         {
  788.             bool result = false;
  789.             if (mosaic == null)
  790.             {
  791.                 return result;
  792.             }
  793.             mosaic.Where(_ => _.enabled == !enableMosaic).ForEach(_ =>
  794.             {
  795.                 _.enabled = enableMosaic;
  796.                 System.Diagnostics.Debug.WriteLine(string.Format("{0}'s Mosaic Enable:{1}", _.name, enableMosaic));
  797.                 result = true;
  798.             });
  799.  
  800.             return result;
  801.         }
  802.  
  803.         public void DeMosaicToys()
  804.         {
  805.             Renderer[] rs = GetToysMosaicRenderer();
  806.             if (rs != null)
  807.             {
  808.                 foreach (Renderer r in rs)
  809.                 {
  810.                     ToyMaterialChanger(r);
  811.                 }
  812.             }
  813.         }
  814.  
  815.         private void ToyMaterialChanger(Renderer mosaic)
  816.         {
  817.             if (mosaic.materials.Length == 1)
  818.             {
  819.                 return;
  820.             }
  821.             bool mosaicDisable = Target >= DeMosaic.Switch.MaidAndItem;
  822.             mosaic.materials
  823.                 .Where(_ => mosaicDisable ? _.shader.Equals(shaderMosaic) : _.shader.Equals(shaderTransparent))
  824.                 .ForEach(_ =>
  825.                 {
  826.                     _.shader = mosaicDisable ? shaderTransparent : shaderMosaic;
  827.                     _.color += mosaicDisable ? new Color(0f, 0f, 0f, -1f) : new Color(0f, 0f, 0f, 1f);
  828.                 });
  829.         }
  830.     }
  831.  
  832.     public class ChangeBodyTexture
  833.     {
  834.         public static List<string> textureList;
  835.             public static readonly string path = Path.Combine(
  836.                 UnityExtensionsBridge.UserDataPath,
  837.                 "YASD"
  838.                 );
  839.  
  840.         public ChangeBodyTexture()
  841.         {
  842.             if (!Directory.Exists(path))
  843.             {
  844.                 Directory.CreateDirectory(path);
  845.             }
  846.  
  847.             textureList = new List<string>();
  848.             LoadTextureList(textureList);
  849. #if DEBUG
  850.             foreach (var item in textureList)
  851.             {
  852.                 System.Diagnostics.Debug.WriteLine(item);
  853.             }
  854. #endif
  855.         }
  856.  
  857.         public class TextureSet
  858.         {
  859.  
  860.             private const string diffuseType = "_MainTex";
  861.             private const string toonType = "_ToonRamp";
  862.             private const string shadowType = "_ShadowTex";
  863.             private const string shadowRateToonType = "_ShadowRateToon";
  864.  
  865.             public Tex MainTex;
  866.             public Tex Toon;
  867.             public Tex Shadow;
  868.             public Tex ShadowRateToon;
  869.  
  870.             public TextureSet(Material material, bool force)
  871.             {
  872.                 MainTex = new Tex(diffuseType, material);
  873.                 if (!MainTex.IsReplaced || force)
  874.                 {
  875.                     Toon = new Tex(toonType, material);
  876.                     Shadow = new Tex(shadowType, material);
  877.                     ShadowRateToon = new Tex(shadowRateToonType, material);
  878.                 }
  879.             }
  880.  
  881.             public class Tex
  882.             {
  883.                 private readonly Regex rx = new Regex(@"(?<name>[^:]+)\.tex");
  884.  
  885.                 private Material material;
  886.  
  887.                 private string _type;
  888.  
  889.                 public string Type
  890.                 {
  891.                     get { return _type; }
  892.                 }
  893.  
  894.                 private Texture _texture;
  895.  
  896.                 public Texture Texture
  897.                 {
  898.                     get { return _texture; }
  899.                 }
  900.  
  901.                 private string _name;
  902.  
  903.                 public string Name
  904.                 {
  905.                     get
  906.                     {
  907.                         return _name;
  908.                     }
  909.                 }
  910.  
  911.                 public string FullPath
  912.                 {
  913.                     get {
  914.                         String fullPath = Directory.GetFiles(path, Name, SearchOption.AllDirectories).First();
  915. #if DEBUG
  916.                         Console.WriteLine(fullPath);
  917. #endif
  918.                         return fullPath;
  919.                     }
  920.                 }
  921.  
  922.                 public bool IsReplaced
  923.                 {
  924.                     get { return Path.GetExtension(Texture.name).Equals(".png", System.StringComparison.OrdinalIgnoreCase); }
  925.                 }
  926.  
  927.                 public Tex(String textureType, Material mate)
  928.                 {
  929.                     this.material = mate;
  930.                     _type = textureType;
  931.                     _texture = material.GetTexture(Type);
  932.                     Match m = rx.Match(this._texture.name);
  933.                     if (m.Success)
  934.                     {
  935.                         _name = m.Groups["name"].Value + ".png";
  936.                     }
  937.                     else
  938.                     {
  939.                         _name = Texture.name;
  940.                     }
  941.                 }
  942.  
  943.                 public void ReplaceTex()
  944.                 {
  945.                     System.Diagnostics.Debug.WriteLine(string.Format("YASD.ReplaceTex: Texture Name {0}", Texture.name));
  946. //                    Console.WriteLine("YASD: hoge 1 {0} , {1}", Name, Texture.name);
  947.                     if (!textureList.Any(_ => _.Equals(Name, StringComparison.OrdinalIgnoreCase)))
  948.                     {
  949.                         System.Diagnostics.Debug.WriteLine("YASD.ReplaceTex: FileName not Found in FileList");
  950.                         return;
  951.                     }
  952.                     if (!Texture)
  953.                     {
  954.                         System.Diagnostics.Debug.WriteLine("YASD.ReplaceTex: Texture is NULL.");
  955.  
  956.                         return;
  957.                     }
  958.                     if (string.IsNullOrEmpty(Name))
  959.                     {
  960.                         System.Diagnostics.Debug.WriteLine("YASD.ReplaceTex: Texture's Name is NULL or Empty.");
  961.                         return;
  962.                     }
  963.  
  964.                     try
  965.                     {
  966.                         if (!File.Exists(FullPath))
  967.                         {
  968.                             textureList.Remove(Name);
  969.                             return;
  970.                         }
  971.                         System.Diagnostics.Debug.WriteLine(string.Format("YASD.ReplaceTex: {0} found.", Name));
  972.  
  973.                         using (BinaryReader br = new BinaryReader(File.OpenRead(FullPath)))
  974.                         {
  975.                             byte[] b = br.ReadBytes((int)br.BaseStream.Length);
  976.  
  977.                             Texture2D t = new Texture2D(1, 1, TextureFormat.RGBA32, false);
  978.  
  979.                             if (t.LoadImage(b))
  980.                             {
  981.                                 t.name = Name;
  982.                                 material.SetTexture(Type, t);
  983.                                 System.Diagnostics.Debug.WriteLine(string.Format("YASD.ReplaceTex: {0} Replaced.", Name));
  984.                             }
  985.                         }
  986.                     }
  987.                     catch (Exception ex)
  988.                     {
  989.                         Console.WriteLine("YASD.ReplaceTex: Texture Replace Fail!{0} ({1})", Name, ex);
  990.                         textureList.Remove(Name);
  991.                     }
  992.                 }
  993.             }
  994.  
  995.             public void ReplaceTexture(bool force)
  996.             {
  997.                 if (!MainTex.IsReplaced || force)
  998.                 {
  999.                     MainTex.ReplaceTex();
  1000.                     Toon.ReplaceTex();
  1001.                     Shadow.ReplaceTex();
  1002.                     ShadowRateToon.ReplaceTex();
  1003.                 }
  1004.             }
  1005.  
  1006.         }
  1007.             public static void LoadTextureList(List<string> list)
  1008.             {
  1009.                 list.Clear();
  1010.                 list.AddRange(Directory.GetFiles(path, "*.png", SearchOption.AllDirectories).Select(_ => Path.GetFileName(_)));
  1011.  
  1012.                 Console.WriteLine("YASD: {0} Texture(s) found.", list.Count);
  1013. #if DEBUG
  1014.                 foreach (string file in list)
  1015.                 {
  1016.                     Console.WriteLine(file);
  1017.                 }
  1018. #endif
  1019.             }
  1020.  
  1021.         public void ChangeTexture(bool force)
  1022.         {
  1023.             GameObject maid = GameMain.Instance.CharacterMgr.GetMaid(0).gameObject;
  1024.             GameObject body = maid.transform.Find("Offset/_BO_body001/_SM_body001/body").gameObject;
  1025.             Material[] materials = body.GetComponent<Renderer>().materials;
  1026.  
  1027.             ////GetMaterialsの方がゲーム内で使われている手法に近くて汎用性が高いが1.5倍ぐらい遅い
  1028.             //Maid md = GameMain.Instance.CharacterMgr.GetMaid(0);
  1029.             //Material[] materials = GetMaterials(md, "body");
  1030.  
  1031.             foreach (var material in materials)
  1032.             {
  1033.                 TextureSet tex = new TextureSet(material, force);
  1034.  
  1035.                 if (Directory.Exists(path))
  1036.                 {
  1037.                     tex.ReplaceTexture(force);
  1038.                 }
  1039.             }
  1040.         }
  1041.  
  1042.         public Material[] GetMaterials(Maid maid, string slotname)
  1043.         {
  1044.             TBody tbody = maid.body0;
  1045.             TBodySkin skin = tbody.goSlot[(int)TBody.hashSlotName[slotname]];
  1046.             GameObject go = skin.obj;
  1047.  
  1048.             Renderer[] renderers = go.transform.GetComponentsInChildren<Renderer>(true);
  1049.  
  1050.             return renderers.Where(_ => _ != null || _.sharedMaterials != null).SelectMany(_ => _.materials).ToArray();
  1051.         }
  1052.     }
  1053. }
RAW Paste Data
Top