public bool SaveFiles(ACCMenu menu) { var outDir = fileUtil.GetACCDirectory(trgtMenu.editfile); if (!Directory.Exists(outDir)) Directory.CreateDirectory(outDir); LogUtil.Debug("output path:", outDir); string filepath = Path.Combine(outDir, menu.EditFileName()); // menu出力 ACCMenu.WriteMenuFile(filepath, menu); var writeFiles = new HashSet<string>(); // filterがあれば、適用しアイコンを変更 string iconfilepath = Path.Combine(outDir, menu.EditIconFileName()); writeFiles.Add(iconfilepath); string icontxt = settings.txtPrefixTex + iconfilepath; fileUtil.CopyTex(menu.icon, iconfilepath, icontxt, null); LogUtil.Debug("tex file:", iconfilepath); // model 出力 (additem) foreach (var pair in menu.itemFiles) { string infile = pair.Key; Item item = pair.Value; if (item.needUpdate) { string filename = item.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) continue; string modelfilepath = Path.Combine(outDir, filename); // modelファイルのスロットのマテリアル/テクスチャ情報を抽出 SlotMaterials slotMat = menu.slotMaterials[item.slot]; // onlyModelでない場合はshader変更のみとしておく // material slotとmatNoで特定 // texture propName // 必要に応じてtex出力 fileUtil.WriteModelFile(infile, modelfilepath, slotMat); LogUtil.Debug("model file:", modelfilepath); } } // mate出力 foreach (var tm in menu.slotMaterials.Values) { foreach(var trgtMat in tm.materials) { // マテリアル変更が指定された場合 => TODO 切り替え可能とする場合:menuにマテリアル変更を追加する必要あり if (!trgtMat.onlyModel) { var filename = trgtMat.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) continue; string matefilepath = Path.Combine(outDir, filename); fileUtil.WriteMateFile(trgtMat.filename, matefilepath, trgtMat); LogUtil.Debug("mate file:", matefilepath); if (trgtMat.needPmatChange) { var name = Path.GetFileNameWithoutExtension(filename); var pmatfile = name + FileConst.EXT_PMAT; string pmatfilepath = Path.Combine(outDir, pmatfile); fileUtil.WritePmat(pmatfilepath, trgtMat.editname, trgtMat.RenderQueue(), trgtMat.ShaderName()); LogUtil.Debug("pmat file:", pmatfilepath); } } // テクスチャ出力 foreach (var trgtTex in trgtMat.texDic.Values) { if (!trgtTex.needOutput) continue; var tex2d = trgtTex.tex as Texture2D; if (tex2d == null) { LogUtil.Debug("tex is not Texture2D", trgtTex.editname); continue; // TODO RenderTexの場合は無理やりTexture2Dに変換も可能だが… } var texfilename = trgtTex.EditFileName(); if (HasAlreadyWritten(writeFiles, texfilename)) continue; string texfilepath = Path.Combine(outDir, texfilename); fileUtil.WriteTexFile(texfilepath, trgtTex.EditTxtPath(), tex2d.EncodeToPNG()); LogUtil.Debug("tex file:", texfilepath); } } } // めくれ、ずらし用menuファイルの出力 foreach (var res in menu.resFiles.Values) { // 各モデルファイルで出力が必要となるファイルについて、 // 元が同名のファイルを参照している場合でも関係なく出力 // 設定が違う場合もある上、editnameはすべて別名になるはず var filename = res.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) continue; string menufilepath = Path.Combine(outDir, filename); var toCreateFiles = fileUtil.WriteMenuFile(res.filename, menufilepath, res); LogUtil.Debug("menu file:", menufilepath); foreach (var toCreate in toCreateFiles) { // modelを出力 if (toCreate.item != null) { var filename0 = toCreate.replaced; if (HasAlreadyWritten(writeFiles, filename0)) continue; string modelfilepath = Path.Combine(outDir, filename0); SlotMaterials slotMat = menu.slotMaterials[toCreate.item.slot]; // TODO リプレースが想定される情報であるかチェック fileUtil.WriteModelFile(toCreate.source, modelfilepath, slotMat); // .mate出力 } else if (toCreate.material != null) { TargetMaterial trgtMat = toCreate.material; var filename0 = toCreate.replaced; if (HasAlreadyWritten(writeFiles, filename0)) continue; // mate出力==別のtexファイルを出力する可能性有り string matefilepath = Path.Combine(outDir, filename0); fileUtil.WriteMateFile(toCreate.source, matefilepath, trgtMat); // マテリアル名は上位と同じにして、同一pmatを使用する //if (trgtMat.needPmatChange) { // var name = Path.GetFileNameWithoutExtension(filename); // var pmatfile = name + FileConst.EXT_PMAT; // string pmatfilepath = Path.Combine(outDir, pmatfile); // outUtil.WritePmat(pmatfilepath, trgtMat.editname, // trgtMat.RenderQueue(), trgtMat.ShaderName()); // LogUtil.DebugLog("pmatファイルを出力しました。", pmatfilepath); //} foreach (var tex in trgtMat.texDic.Values) { if (!tex.needOutput) continue; var tex2d = tex.tex as Texture2D; if (tex2d == null) { LogUtil.Debug("tex is not 2D", tex.editname); continue; } var texfilename = tex.EditFileName(); if (HasAlreadyWritten(writeFiles, texfilename)) continue; // テクスチャをロードし、フィルタを適用 Texture2D loadedTex = null; Texture2D filteredTex = null; if (!tex.fileChanged) { // texファイル変更済の場合はロードされたデータ済みから出力(そのままtex2dを使用) loadedTex = new Texture2D(1, 1, TextureFormat.RGBA32, false); string texfile = tex.workfilename + FileConst.EXT_TEXTURE; if (!fileUtil.Exists(texfile)) { LogUtil.LogF("リソース参照で使用されているtexファイル({0})が見つかりません。texファイルを出力できません。", texfile); continue; } loadedTex.LoadImage( ImportCM.LoadTexture(texfile) ); tex2d = loadedTex; } if (tex.colorChanged) { filteredTex = ACCTexturesView.Filter(tex2d, tex.filter); tex2d = filteredTex; } string texfilepath = Path.Combine(outDir, texfilename); fileUtil.WriteTexFile(texfilepath, tex.EditTxtPath(), tex2d.EncodeToPNG()); LogUtil.Debug("tex file:", texfilepath); if (loadedTex != null) UnityEngine.Object.DestroyImmediate(loadedTex); if (filteredTex != null) UnityEngine.Object.DestroyImmediate(filteredTex); } } } } return true; }
// TODO ファイル名となりうるフィールドの文字列検証(入力フィールドの変更時に行う) //private bool isSavable; // private void CheckFileName(string filename) { // isSavable &= filename.IndexOfAny(INVALID_FILENAMECHARS) < 0; //} // ファイルの重複確認 private bool IsWritable(ACCMenu menu, bool ignoreExists) { if (menu.editfile.Length == 0) return false; bool registed = false;; string outDir = fileUtil.GetACCDirectory(); outDir = Path.Combine(outDir, trgtMenu.editfile); if (!ignoreExists && Directory.Exists(outDir)) { LogUtil.Debug("output directory already exist :", outDir); menu.editfileExist = true; return false; } bool hasDuplicate = false; // 別々の情報ファイルが重複しないか + 登録済みファイルが存在するかをチェック var writeFiles = new HashSet<string> (); var menufile = menu.EditFileName(); writeFiles.Add(menufile); menu.editfileExist = false; if (fileUtil.Exists(menufile)) { LogUtil.Debug("already exist:", menufile); registed = true; menu.editfileExist = true; } // icon menu.editiconExist = false; string iconfilepath = menu.EditIconFileName(); if (fileUtil.Exists(iconfilepath)) { LogUtil.Debug("already exist:", iconfilepath); registed = true; menu.editiconExist = true; } writeFiles.Add(iconfilepath); // modelファイル foreach (var pair in menu.itemFiles) { Item item = pair.Value; if (item.needUpdate) { item.editnameExist = false; // clear string filename = item.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) { hasDuplicate = true; item.editnameExist = true; // フラグを分けるべきか? continue; } if (fileUtil.Exists(filename)) { LogUtil.Debug("already exist:", filename); registed = true; item.editnameExist = true; } } } // mateファイル foreach (var tm in menu.slotMaterials.Values) { foreach(var trgtMat in tm.materials) { // modelファイルのみの場合は好み ⇒変更する場合はmenuにマテリアル変更を追加する必要あり if (trgtMat.onlyModel) continue; trgtMat.editfileExist = false; var filename = trgtMat.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) { hasDuplicate = true; trgtMat.editfileExist = true; // フラグを分けるべきか? continue; } if (fileUtil.Exists(filename)) { LogUtil.Debug("already exist:", filename); registed = true; trgtMat.editfileExist = true; } // pmat if (trgtMat.needPmatChange) { var name = Path.GetFileNameWithoutExtension(filename); var pmatfile = name + FileConst.EXT_PMAT; if (HasAlreadyWritten(writeFiles, pmatfile)) { hasDuplicate = true; trgtMat.editfileExist = true; // フラグを分けるべきか? continue; } if (fileUtil.Exists(pmatfile)) { LogUtil.Debug("already exist:", pmatfile); registed = true; trgtMat.editfileExist = true; } } // texファイル foreach (var trgtTex in trgtMat.texDic.Values) { if (!trgtTex.needOutput) continue; trgtTex.editnameExist = false; var texfilename = trgtTex.EditFileName(); if (HasAlreadyWritten(writeFiles, texfilename)) { hasDuplicate = true; trgtTex.editnameExist = true; // フラグを分けるべきか? continue; } if (fileUtil.Exists(texfilename)) { LogUtil.Debug("already exist:", texfilename); registed = true; trgtTex.editnameExist = true; } } } } // めくれ、ずらし用menuファイルの出力 foreach (var res in menu.resFiles.Values) { res.editfileExist = false; var filename = res.EditFileName(); if (HasAlreadyWritten(writeFiles, filename)) { hasDuplicate = true; res.editfileExist = true; // フラグを分けるべきか? continue; } if (fileUtil.Exists(filename)) { LogUtil.Debug("already exist:", filename); registed = true; res.editfileExist = true; } } // 出力ファイルの重複は無視できない if (hasDuplicate) return false; return ignoreExists || !registed; }
private static void WriteMenuFile(BinaryReader reader, string header, string filepath, ACCMenu menu) { using (var dataStream = new MemoryStream()) using (var dataWriter = new BinaryWriter(dataStream)) using (var writer = new BinaryWriter(File.OpenWrite(filepath))) { writer.Write(header); writer.Write(reader.ReadInt32()); // txtpath reader.ReadString(); var txtpath = menu.txtpath; if (!txtpath.EndsWith(FileConst.EXT_TXT, StringComparison.OrdinalIgnoreCase)) { txtpath += FileConst.EXT_TXT; } writer.Write(txtpath); // name, category, 説明 reader.ReadString(); reader.ReadString(); reader.ReadString(); writer.Write(menu.name); writer.Write(menu.category); var desc = menu.desc.Replace("\n", FileConst.RET); writer.Write(desc); // readBytes var num = reader.ReadInt32(); var priorityWritten = false; while (true) { var size = (int)reader.ReadByte(); if (size == 0) { dataWriter.Write((byte)0); break; } var key = reader.ReadString(); var param = new string[size - 1]; for (var i = 0; i < size - 1; i++) { param[i] = reader.ReadString(); } // パラメータ数が変更される場合があれば… // string[] writeParams = null; // 特定のパラメータを置き換え switch (key) { case "priority": param[0] = menu.priority; priorityWritten = true; break; case "name": param[0] = menu.name; break; case "setumei": param[0] = desc; break; case "icon": case "icons": param[0] = menu.EditIconFileName(); break; case "additem": var modelfile = param[0]; param[0] = menu.itemFiles[modelfile].EditFileName(); LogUtil.Debug("modelfile replaces ", modelfile, "=>", param[0]); break; case "マテリアル変更": var slot = param[0]; var matNo = int.Parse(param[1]); var tm = menu.GetMaterial(slot, matNo); param[2] = tm.EditFileName(); break; case "リソース参照": param[1] = menu.resFiles[param[1]].EditFileName(); break; case "半脱ぎ": param[0] = menu.resFiles[param[0]].EditFileName(); break; } // if (writeParams == null) writeParams = param; dataWriter.Write((byte)(param.Length + 1)); dataWriter.Write(key); foreach (var wparam in param) { dataWriter.Write(wparam); } } if (!priorityWritten) { dataWriter.Write((byte)2); dataWriter.Write("priority"); dataWriter.Write(menu.priority); } writer.Write((int)dataStream.Length); writer.Write(dataStream.ToArray()); } }
// Token: 0x06000110 RID: 272 RVA: 0x0000B9B8 File Offset: 0x00009BB8 private static void WriteMenuFile(BinaryReader reader, string header, string filepath, ACCMenu menu) { using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { using (BinaryWriter binaryWriter2 = new BinaryWriter(File.OpenWrite(filepath))) { binaryWriter2.Write(header); binaryWriter2.Write(reader.ReadInt32()); reader.ReadString(); string text = menu.txtpath; if (!text.EndsWith(FileConst.EXT_TXT, StringComparison.OrdinalIgnoreCase)) { text += FileConst.EXT_TXT; } binaryWriter2.Write(text); reader.ReadString(); reader.ReadString(); reader.ReadString(); binaryWriter2.Write(menu.name); binaryWriter2.Write(menu.category); string text2 = menu.desc.Replace("\n", FileConst.RET); binaryWriter2.Write(text2); reader.ReadInt32(); bool flag = false; for (;;) { int num = (int)reader.ReadByte(); if (num == 0) { break; } string text3 = reader.ReadString(); string[] array = new string[num - 1]; for (int i = 0; i < num - 1; i++) { array[i] = reader.ReadString(); } string key; switch (key = text3) { case "priority": array[0] = menu.priority; flag = true; break; case "name": array[0] = menu.name; break; case "setumei": array[0] = text2; break; case "icon": case "icons": array[0] = menu.EditIconFileName(); break; case "additem": { string text4 = array[0]; array[0] = menu.itemFiles[text4].EditFileName(); LogUtil.Debug(new object[] { "modelfile replaces ", text4, "=>", array[0] }); break; } case "マテリアル変更": { string slot = array[0]; int matNo = int.Parse(array[1]); TargetMaterial material = menu.GetMaterial(slot, matNo); array[2] = material.EditFileName(); break; } case "リソース参照": array[1] = menu.resFiles[array[1]].EditFileName(); break; case "半脱ぎ": array[0] = menu.resFiles[array[0]].EditFileName(); break; } binaryWriter.Write((byte)(array.Length + 1)); binaryWriter.Write(text3); foreach (string value in array) { binaryWriter.Write(value); } } binaryWriter.Write(0); if (!flag) { binaryWriter.Write(2); binaryWriter.Write("priority"); binaryWriter.Write(menu.priority); } binaryWriter2.Write((int)memoryStream.Length); binaryWriter2.Write(memoryStream.ToArray()); } } } }
private static void WriteMenuFile(BinaryReader reader, string header, string filepath, ACCMenu menu) { using (var dataStream = new MemoryStream()) using (var dataWriter = new BinaryWriter(dataStream)) using (var writer = new BinaryWriter(File.OpenWrite(filepath))) { writer.Write(header); writer.Write(reader.ReadInt32()); // txtpath reader.ReadString(); string txtpath = menu.txtpath; if (!txtpath.EndsWith(FileConst.EXT_TXT, StringComparison.OrdinalIgnoreCase)) { txtpath += FileConst.EXT_TXT; } writer.Write(txtpath); // name, category, 説明 reader.ReadString(); reader.ReadString(); reader.ReadString(); writer.Write(menu.name); writer.Write(menu.category); string desc = menu.desc.Replace("\n", FileConst.RET); writer.Write(desc); // readBytes int num = (int)reader.ReadInt32(); bool priorityWritten = false; while (true) { int size = (int)reader.ReadByte(); if (size == 0) { dataWriter.Write((byte)0); break; } string key = reader.ReadString(); var param = new string[size - 1]; for (int i = 0; i < size - 1; i++) { param[i] = reader.ReadString(); } // パラメータ数が変更される場合があれば… // string[] writeParams = null; switch (key) { case "priority": param[0] = menu.priority; priorityWritten = true; break; case "name": param[0] = menu.name; break; case "setumei": param[0] = desc; break; case "icon": case "icons": param[0] = menu.EditIconFileName(); break; case "additem": var modelfile = param[0]; param[0] = menu.itemFiles[modelfile].EditFileName(); LogUtil.Debug("modelfile replaces ", modelfile, "=>", param[0]); break; case "マテリアル変更": string slot = param[0]; int matNo = int.Parse(param[1]); var tm = menu.GetMaterial(slot, matNo); param[2] = tm.EditFileName(); break; case "リソース参照": param[1] = menu.resFiles[param[1]].EditFileName(); break; case "半脱ぎ": param[0] = menu.resFiles[param[0]].EditFileName(); break; //case "color_set": // break; // case "maskitem": // // slot=param[0] // // menu.maskItems.Add(slot0); // break; // // case "delitem": // // slot=param[0] // // menu.delItems.Add(slot0); // break; // // case "node消去": // // menu.delNodes.Add(param[0]); // break; // case "node表示": // // menu.showNodes.Add(param[0]); // break; // case "パーツnode消去": // // menu.delPartsNodes.Add(param); // break; // case "パーツnode表示": // // menu.showPartsNodes.Add(param); // break; //case "メニューフォルダ": // menu.menuFolder = param[0]; // break; //case "category": // menu.category = param[0]; // break; //case "catno": // menu.catno = param[0]; // break; //case "属性追加": // break; //case "アタッチポイントの設定": // break; //case "tex": //case "テクスチャ変更": // break; //case "テクスチャ合成": // break; //case "unsetitem": // break; //case "commenttype": // break; //case "アイテムパラメータ": // if (param.Length == 3) { // param = ; // //Array.Copy(param, 0, itemParam, 0, param.Length); // } // break; //case "アイテム": // menu.items.Add(Path.GetFileNameWithoutExtension(param[0])); // break; } // if (writeParams == null) writeParams = param; dataWriter.Write((byte)(param.Length + 1)); dataWriter.Write(key); foreach (string wparam in param) { dataWriter.Write(wparam); } } if (!priorityWritten) { dataWriter.Write((byte)2); dataWriter.Write("priority"); dataWriter.Write(menu.priority); } writer.Write((int)dataStream.Length); writer.Write(dataStream.ToArray()); } }
private static void WriteMenuFile(BinaryReader reader, string header, string filepath, ACCMenu menu) { using (var dataStream = new MemoryStream()) using (var dataWriter = new BinaryWriter(dataStream)) using (var writer = new BinaryWriter(File.OpenWrite(filepath))) { writer.Write(header); writer.Write(reader.ReadInt32()); // txtpath reader.ReadString(); string txtpath = menu.txtpath; if (!txtpath.EndsWith(FileConst.EXT_TXT, StringComparison.OrdinalIgnoreCase)) { txtpath += FileConst.EXT_TXT; } writer.Write(txtpath); // name, category, 説明 reader.ReadString(); reader.ReadString(); reader.ReadString(); writer.Write(menu.name); writer.Write(menu.category); string desc = menu.desc.Replace("\n", FileConst.RET); writer.Write(desc); // readBytes int num = (int)reader.ReadInt32(); bool priorityWritten = false; while (true) { int size = (int) reader.ReadByte(); if (size == 0) { dataWriter.Write((byte)0); break; } string key = reader.ReadString(); var param = new string[size-1]; for (int i = 0; i < size-1; i++) { param[i] = reader.ReadString(); } // パラメータ数が変更される場合があれば… // string[] writeParams = null; switch (key) { case "priority": param[0] = menu.priority; priorityWritten = true; break; case "name": param[0] = menu.name; break; case "setumei": param[0] = desc; break; case "icon": case "icons": param[0] = menu.EditIconFileName(); break; case "additem": var modelfile = param[0]; param[0] = menu.itemFiles[modelfile].EditFileName(); LogUtil.Debug("modelfile replaces ", modelfile, "=>", param[0]); break; case "マテリアル変更": string slot = param[0]; int matNo = int.Parse(param[1]); var tm = menu.GetMaterial(slot, matNo); param[2] = tm.EditFileName(); break; case "リソース参照": param[1] = menu.resFiles[param[1]].EditFileName(); break; case "半脱ぎ": param[0] = menu.resFiles[param[0]].EditFileName(); break; //case "color_set": // break; // case "maskitem": // // slot=param[0] // // menu.maskItems.Add(slot0); // break; // // case "delitem": // // slot=param[0] // // menu.delItems.Add(slot0); // break; // // case "node消去": // // menu.delNodes.Add(param[0]); // break; // case "node表示": // // menu.showNodes.Add(param[0]); // break; // case "パーツnode消去": // // menu.delPartsNodes.Add(param); // break; // case "パーツnode表示": // // menu.showPartsNodes.Add(param); // break; //case "メニューフォルダ": // menu.menuFolder = param[0]; // break; //case "category": // menu.category = param[0]; // break; //case "catno": // menu.catno = param[0]; // break; //case "属性追加": // break; //case "アタッチポイントの設定": // break; //case "tex": //case "テクスチャ変更": // break; //case "テクスチャ合成": // break; //case "unsetitem": // break; //case "commenttype": // break; //case "アイテムパラメータ": // if (param.Length == 3) { // param = ; // //Array.Copy(param, 0, itemParam, 0, param.Length); // } // break; //case "アイテム": // menu.items.Add(Path.GetFileNameWithoutExtension(param[0])); // break; } // if (writeParams == null) writeParams = param; dataWriter.Write((byte) (param.Length+1)); dataWriter.Write(key); foreach (string wparam in param) { dataWriter.Write(wparam); } } if (!priorityWritten) { dataWriter.Write((byte) 2); dataWriter.Write("priority"); dataWriter.Write(menu.priority); } writer.Write((int)dataStream.Length); writer.Write(dataStream.ToArray()); } }