Advertisement
Guest User

CM3D2.YASDPlus.Plugin

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