using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Diagnostics; using System.Text; using System.Windows.Forms; using System.IO; using CommonAI.Zone; using CommonFroms.Utils; using CommonAI.Zone.ZoneEditor; using CommonLang.Xml; using System.Xml; using CommonAIEditor.Plugins.Win32; using CommonLang.IO; using CommonAI.Zone.Attributes; using CommonLang.File; using System.Threading; using GameEditorPlugin.Utils; using CommonLang; using CommonLang.Property; using CommonLang.Concurrent; using CommonAIEditor.Scene; using CommonAI.Zone.ZoneEditor.EventTrigger; using CommonLang.Protocol; using CommonLang.XCSV; using GameEditorPlugin.Win32.Runtime; using CommonAI.Zone.Replay; using CommonAIEditor.EventEditor; using CommonFroms.G2D; using CommonFroms.G2D.DataGrid; namespace CommonAIEditor { public partial class Editor : Form { //------------------------------------------------------------------------------ #region static_fields public static string EditorRootDir { get { return s_editroot.FullName; } } public static string EditorSettingDir { get { return s_proj_setting_root.FullName; } } public static string DataDir { get { return s_datadir.FullName; } } public static string DataDir_units { get { return Editor.DataDir + "/units"; } } public static string DataDir_skills { get { return Editor.DataDir + "/skills"; } } public static string DataDir_spells { get { return Editor.DataDir + "/spells"; } } public static string DataDir_buffs { get { return Editor.DataDir + "/buffs"; } } public static string DataDir_items { get { return Editor.DataDir + "/items"; } } public static string DataDir_unit_triggers { get { return Editor.DataDir + "/unit_triggers"; } } public static string DataDir_unit_events { get { return Editor.DataDir + "/unit_events"; } } public static string DataDir_scenes { get { return Editor.DataDir + "/scenes"; } } public static string ResDir { get { return s_resdir.FullName; } } public static Font EditorFont = new System.Drawing.Font( "微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); public static Editor Instance { get { return s_instance; } } private static Editor s_instance; private static DirectoryInfo s_editroot;// GameEditor private static DirectoryInfo s_proj_setting_root;// GameEditor/.setting private static DirectoryInfo s_datadir;// GameEditor/data private static DirectoryInfo s_resdir;// GameEditor/res internal static void SetDataRoot(string root) { s_editroot = new DirectoryInfo(root); s_proj_setting_root = new DirectoryInfo(root + "\\.setting"); s_datadir = new DirectoryInfo(root + "\\data"); s_resdir = new DirectoryInfo(root + "\\res"); DefaultResourceLoader.SetRoot(root); } #endregion //------------------------------------------------------------------------------ #region fields private bool autoSave = false; private HashMap template_panels = new HashMap(); private HashMap page_panels = new HashMap(); private DataManagerPanel units; private DataManagerPanel skills; private DataManagerPanel spells; private DataManagerPanel buffs; private DataManagerPanel items; private DataManagerPanel unit_triggers; private DataManagerPanel unit_events; private DataManagerPanel scenes; public MessageFactoryGenerator MessageFactory { get { return TemplateManager.MessageCodec; } } public ImageList Icons { get { return imageList1; } } #endregion //------------------------------------------------------------------------------ public Editor(bool autoSave = false) { InitializeComponent(); Editor.s_instance = this; if (!s_proj_setting_root.Exists) { s_proj_setting_root.Create(); } GameEditorPropertyAdapter.Init(); this.autoSave = autoSave; } //----------------------------------------------------------------------------------------------------------- public Config CFG { get; private set; } public ICommonConfig ExtCFG { get; private set; } public TerrainDefinitionMap TerrainDefinition { get; private set; } public UnitActionDefinitionMap UnitActionDefinition { get; private set; } public FileInfo SaveCfgFile { get { return new FileInfo(Editor.DataDir + "/config.xml"); } } public FileInfo SaveCfgExtFile { get { return new FileInfo(Editor.DataDir + "/config_ext.xml"); } } public FileInfo SaveTerrainDefinitionFile { get { return new FileInfo(Editor.DataDir + "/terrain_definition.xml"); } } public FileInfo SaveUnitActionDefinition { get { return new FileInfo(Editor.DataDir + "/unit_action_definition.xml"); } } public TerrainDefinitionMap.MapBlockBrush DefaultTerrainBrush { get { foreach (var b in TerrainDefinition.Brushes) { if (b.IsBlock) { return b; } } return null; } } private void InitAllTempaltes() { this.units = new DataManagerPanel("单位", Editor.DataDir + "/units", Editor.EditorSettingDir + "/units", imageList1, "icons_tool_bar2.png", tabPageUnits.ImageKey); this.skills = new DataManagerPanel("技能", Editor.DataDir + "/skills", Editor.EditorSettingDir + "/skills", imageList1, "icons_tool_bar2.png", tabPageSkills.ImageKey); this.spells = new DataManagerPanel("法术", Editor.DataDir + "/spells", Editor.EditorSettingDir + "/spells", imageList1, "icons_tool_bar2.png", tabPageSpells.ImageKey); this.buffs = new DataManagerPanel("BUFF", Editor.DataDir + "/buffs", Editor.EditorSettingDir + "/buffs", imageList1, "icons_tool_bar2.png", tabPageBuffs.ImageKey); this.items = new DataManagerPanel("物品", Editor.DataDir + "/items", Editor.EditorSettingDir + "/items", imageList1, "icons_tool_bar2.png", tabPageItems.ImageKey); this.unit_triggers = new DataManagerPanel("单位触发器", Editor.DataDir + "/unit_triggers", Editor.EditorSettingDir + "/unit_triggers", imageList1, "icons_tool_bar2.png", tabPageUnitTriggers.ImageKey); this.unit_events = new DataManagerPanel("单位事件", Editor.DataDir + "/unit_events", Editor.EditorSettingDir + "/unit_events", imageList1, "icons_tool_bar2.png", tabPageUnitEvents.ImageKey); this.scenes = new DataManagerPanel("场景", Editor.DataDir + "/scenes", Editor.EditorSettingDir + "/scenes", imageList1, "icons_tool_bar2.png", tabPageScene.ImageKey); this.scenes.SetEnableDataGrid(false); tabPageUnits.Controls.Add(units); tabPageSkills.Controls.Add(skills); tabPageSpells.Controls.Add(spells); tabPageBuffs.Controls.Add(buffs); tabPageItems.Controls.Add(items); tabPageUnitTriggers.Controls.Add(unit_triggers); tabPageUnitEvents.Controls.Add(unit_events); tabPageScene.Controls.Add(scenes); //模板类型和DataManagerPanel映射关系// this.template_panels.Add(typeof(UnitInfo), units); this.template_panels.Add(typeof(SkillTemplate), skills); this.template_panels.Add(typeof(SpellTemplate), spells); this.template_panels.Add(typeof(BuffTemplate), buffs); this.template_panels.Add(typeof(ItemTemplate), items); this.template_panels.Add(typeof(UnitTriggerTemplate), unit_triggers); this.template_panels.Add(typeof(UnitEventTemplate), unit_events); this.template_panels.Add(typeof(SceneData), scenes); //TabPage和DataManagerPanel映射关系// this.page_panels.Add(tabPageUnits, units); this.page_panels.Add(tabPageSkills, skills); this.page_panels.Add(tabPageSpells, spells); this.page_panels.Add(tabPageBuffs, buffs); this.page_panels.Add(tabPageItems, items); this.page_panels.Add(tabPageUnitTriggers, unit_triggers); this.page_panels.Add(tabPageUnitEvents, unit_events); this.page_panels.Add(tabPageScene, scenes); //unit events// { ToolStripMenuItem open = new ToolStripMenuItem("单位事件编辑器"); open.Size = new System.Drawing.Size(136, 22); open.Click += openUnitEvent_Click; unit_events.AddChildMenuItem(0, open); unit_events.AddChildMenuItem(1, new ToolStripSeparator()); unit_events.GetTreeView().NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(openUnitEvent_Click); } //scene menu// { { ToolStripMenuItem open_group = new ToolStripMenuItem("场景编辑器"); open_group.Size = new System.Drawing.Size(136, 22); { ToolStripMenuItem open_btn = new ToolStripMenuItem("打开(" + EditorPlugin.CurrentPlugin.Name + ")"); open_btn.Size = new System.Drawing.Size(136, 22); open_btn.Click += new EventHandler(sceneBtn_OpenNode_Click); open_group.DropDownItems.Add(open_btn); ToolStripMenuItem open_win32 = new ToolStripMenuItem("打开(Win32)"); open_win32.Size = new System.Drawing.Size(136, 22); open_win32.Click += new EventHandler(sceneBtn_OpenNodeWin32_Click); open_group.DropDownItems.Add(open_win32); } scenes.AddChildMenuItem(0, open_group); } { ToolStripMenuItem run_btn = new ToolStripMenuItem("运行"); run_btn.Size = new System.Drawing.Size(136, 22); ToolStripMenuItem run_game = new ToolStripMenuItem("运行(" + EditorPlugin.CurrentPlugin.Name + ")"); run_game.Size = new System.Drawing.Size(136, 22); run_game.Click += new EventHandler(sceneBtn_RunGAME_Click); run_btn.DropDownItems.Add(run_game); ToolStripMenuItem run_emu = new ToolStripMenuItem("运行(Win32)"); run_emu.Size = new System.Drawing.Size(136, 22); run_emu.Click += new EventHandler(sceneBtn_RunEMU_Click); run_btn.DropDownItems.Add(run_emu); ToolStripMenuItem run_server = new ToolStripMenuItem("运行(Win32)服务器"); run_server.Size = new System.Drawing.Size(136, 22); run_server.Click += new EventHandler(sceneBtn_RunEMUServer_Click); run_btn.DropDownItems.Add(run_server); run_btn.DropDownItems.Add(new ToolStripSeparator()); ToolStripMenuItem run_rec = new ToolStripMenuItem("运行并录制战报(Win32)"); run_rec.Size = new System.Drawing.Size(136, 22); run_rec.Click += new EventHandler(sceneBtn_RunREC_Click); run_btn.DropDownItems.Add(run_rec); ToolStripMenuItem run_rec_play = new ToolStripMenuItem("播放战报(Win32)"); run_rec_play.Size = new System.Drawing.Size(136, 22); run_rec_play.Click += new EventHandler(sceneBtn_LoadREC_Click); run_btn.DropDownItems.Add(run_rec_play); scenes.AddChildMenuItem(1, run_btn); } { ToolStripMenuItem test_astar = new ToolStripMenuItem("测试寻路"); test_astar.Size = new System.Drawing.Size(136, 22); test_astar.Click += new EventHandler(sceneBtn_TestAstar_Click); scenes.AddChildMenuItem(2, test_astar); } { scenes.AddChildMenuItem(3, new ToolStripSeparator()); } scenes.GetTreeView().NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(sceneBtn_DoubleClickNode); } LoadDataTask task = new LoadDataTask(); new G2DProgressDialog(task).ShowDialog(this); } //----------------------------------------------------------------------------------------------------------- public EditorTemplatesData GetEditorTemplatesData() { return new EditorTemplatesData( TerrainDefinition, UnitActionDefinition, this.units.GetAllNodeData(), this.skills.GetAllNodeData(), this.spells.GetAllNodeData(), this.buffs.GetAllNodeData(), this.items.GetAllNodeData(), this.unit_triggers.GetAllNodeData(), this.unit_events.GetAllNodeData(), this.scenes.GetAllNodeData()); } public void RefreshAll() { this.units.RefreshData(); this.skills.RefreshData(); this.spells.RefreshData(); this.buffs.RefreshData(); this.items.RefreshData(); this.unit_triggers.RefreshData(); this.unit_events.RefreshData(); this.scenes.RefreshData(); } public void SaveEditorStatus() { foreach (var temp in template_panels.Values) { temp.SaveEditorStatus(); } } //----------------------------------------------------------------------------------------------------------- #region _SaveLoad_ //----------------------------------------------------------------------------------------------------------- private void loadCFG() { try { this.CFG = EditorTemplates.LoadXmlAs(SaveCfgFile.FullName, new Config()); this.ExtCFG = EditorTemplates.LoadXmlAs(SaveCfgExtFile.FullName, TemplateManager.Factory.CreateCommonCFG()); this.TerrainDefinition = EditorTemplates.LoadXmlAs(SaveTerrainDefinitionFile.FullName, new TerrainDefinitionMap()); this.UnitActionDefinition = EditorTemplates.LoadXmlAs(SaveUnitActionDefinition.FullName, new UnitActionDefinitionMap()); } catch (Exception err) { MessageBox.Show(err.Message); } } private static void saveCFG(object obj, FileInfo file) { try { string file1 = file.FullName; using (FileStream xmlfs = new FileStream(file1, FileMode.Create, FileAccess.Write)) { XmlUtil.SaveToXML(xmlfs, obj, true); } } catch (Exception err) { MessageBox.Show(err.Message); } } private void saveCFG() { saveCFG(this.CFG, SaveCfgFile); saveCFG(this.ExtCFG, SaveCfgExtFile); saveCFG(this.TerrainDefinition, SaveTerrainDefinitionFile); saveCFG(this.UnitActionDefinition, SaveUnitActionDefinition); } private void saveAll(bool check = false) { SaveDataTask task = new SaveDataTask(this, check); new G2DProgressDialog(task).ShowDialog(this); } private void sceneEditor_onSavedScene(SceneEditor editor, G2DTreeNode node) { scenes.SaveNode(node); } private class LoadDataTask : IProgress { private readonly Editor editor = Editor.Instance; private AtomicInteger mNodeProgress = new AtomicInteger(0); public LoadDataTask() { this.Title = "加载中..."; this.Maximum = editor.units.GetTryLoadCount() + editor.skills.GetTryLoadCount() + editor.spells.GetTryLoadCount() + editor.buffs.GetTryLoadCount() + editor.items.GetTryLoadCount() + editor.unit_triggers.GetTryLoadCount() + editor.unit_events.GetTryLoadCount() + editor.scenes.GetTryLoadCount() + 0; } public override int Value { get { return mNodeProgress.Value; } } public override void Run() { this.Text = "加载单位"; editor.units.LoadAll(mNodeProgress); this.Text = "加载技能"; editor.skills.LoadAll(mNodeProgress); this.Text = "加载法术"; editor.spells.LoadAll(mNodeProgress); this.Text = "加载BUFF"; editor.buffs.LoadAll(mNodeProgress); this.Text = "加载物品"; editor.items.LoadAll(mNodeProgress); this.Text = "加载单位触发器"; editor.unit_triggers.LoadAll(mNodeProgress); this.Text = "加载单位事件"; editor.unit_events.LoadAll(mNodeProgress); this.Text = "加载场景"; editor.scenes.LoadAll(mNodeProgress); } public override void Done() { editor.units.Refresh(); editor.skills.Refresh(); editor.spells.Refresh(); editor.buffs.Refresh(); editor.items.Refresh(); editor.unit_triggers.Refresh(); editor.unit_events.Refresh(); editor.scenes.Refresh(); } } private class SaveDataTask : IProgress { private bool check; private readonly Editor editor; private readonly EditorTemplatesData all_nodes; private readonly List plugin_files; private string mState = ""; private bool mIsDone = false; private AtomicInteger mNodeProgress = new AtomicInteger(0); private AtomicFloat mXLSProgress = new AtomicFloat(0); private AtomicFloat mPluginProgress = new AtomicFloat(0); private AtomicFloat mPluginCSVProgress = new AtomicFloat(0); private AtomicFloat mLanguageProgress = new AtomicFloat(0); private int mNodeMax = 0; private float mXLSMax = 0; public SaveDataTask(Editor editor, bool check) { this.check = check; this.editor = editor; this.all_nodes = editor.GetEditorTemplatesData(); this.plugin_files = checkPlugins(); this.mNodeMax = all_nodes.FileCount; this.mXLSMax = plugin_files.Count; } public override string Title { get { return "保存中..."; } } public override string Text { get { return mState; } } public override int Minimum { get { return 0; } } public override int Maximum { get { return (int)(0 + (100f) // nodes 100% + (100f * (CommonAIEditor.Program.g_SimpleGen ? 0 : 1)) // language 100% + (10f) // plugins saving 100% + (100f * mXLSMax) // plugins csv 100% + (100f * mXLSMax) // xls 2 csv 100% ); } } public override int Value { get { return (int)(0 + (100f * mNodeProgress.Value / mNodeMax) + (100f * mLanguageProgress.Value) + (100f * mPluginProgress.Value) + (100f * mPluginCSVProgress.Value) + (100f * mXLSProgress.Value) ); } } public override bool IsDone { get { return mIsDone; } } public override void Run() { mState = "生成序列号"; new SerialMaker().Gen(all_nodes); List gen_md5_files = new List(); // save all xml { editor.saveCFG(); mState = "保存单位"; editor.units.SaveAll(mNodeProgress, check); mState = "保存技能"; editor.skills.SaveAll(mNodeProgress, check); mState = "保存法术"; editor.spells.SaveAll(mNodeProgress, check); mState = "保存BUFF"; editor.buffs.SaveAll(mNodeProgress, check); mState = "保存物品"; editor.items.SaveAll(mNodeProgress, check); mState = "保存单位触发器"; editor.unit_triggers.SaveAll(mNodeProgress, check); mState = "保存单位事件"; editor.unit_events.SaveAll(mNodeProgress, check); mState = "保存场景"; editor.scenes.SaveAll(mNodeProgress, check); if (!CommonAIEditor.Program.g_SimpleGen) { mState = "生成语言文件"; string language = EditorTemplates.GenLocalizationCsv(all_nodes, mLanguageProgress); // +=1 File.WriteAllText(EditorRootDir + "\\language.csv", language, CUtils.UTF8); } } // add base md5 files { gen_md5_files.Add(editor.SaveCfgFile); gen_md5_files.Add(editor.SaveCfgExtFile); gen_md5_files.Add(editor.SaveTerrainDefinitionFile); gen_md5_files.Add(editor.units.GetMd5File()); gen_md5_files.Add(editor.skills.GetMd5File()); gen_md5_files.Add(editor.spells.GetMd5File()); gen_md5_files.Add(editor.buffs.GetMd5File()); gen_md5_files.Add(editor.items.GetMd5File()); gen_md5_files.Add(editor.unit_triggers.GetMd5File()); gen_md5_files.Add(editor.unit_events.GetMd5File()); gen_md5_files.Add(editor.scenes.GetMd5File()); } // save all game plugins try { mState = "保存各游戏扩展插件:" + TemplateManager.Factory.GetType().Name; TemplateManager.Factory.Formula.OnEditorSaving( all_nodes, new DirectoryInfo(DataDir), gen_md5_files, mPluginProgress); // += 1 List xls2csv = new List(); foreach (FileInfo xls in plugin_files) { mState = "生成插件数据:" + xls.Name; XLS2XCSV csv = new XLS2XCSV(xls); csv.Load(mXLSProgress); // += 1 savedPluginFileTimes.Put(xls.FullName, xls.LastWriteTime); xls2csv.Add(csv.Meta); } mState = "解析插件数据:" + TemplateManager.Factory.GetType().Name; TemplateManager.Factory.Formula.OnEditorPluginSaved(all_nodes, xls2csv, gen_md5_files, mPluginCSVProgress); // += 1 mState = "生成资源版本号"; genResourceVersion(gen_md5_files); if (new FileInfo("../../Http/ResBuilder.exe").Exists) { Process process = Process.Start(new ProcessStartInfo("cmd.exe", "/C ResBuilder.exe -np -!uires -!lua -!uiconvertbin") { CreateNoWindow = true, UseShellExecute = false, WorkingDirectory = "../../Http" }); process.WaitForExit(); process.Close(); } } finally { mState = "完成"; mIsDone = true; } } private void genResourceVersion(List gen_md5_files) { DirectoryInfo root = new DirectoryInfo(DataDir); StringBuilder lines = new StringBuilder(); { foreach (FileInfo sub in gen_md5_files) { string md5 = CMD5.CalculateMD5(sub); long size = sub.Length; lines.AppendLine(string.Format(string.Format("{0} : {1,12} : {2}", md5, size, sub.FullName.Substring(root.FullName.Length)))); } lines.Insert(0, CMD5.CalculateMD5(lines.ToString(), CUtils.UTF8) + "\r\n"); } File.WriteAllText(DataDir + "\\ver.md5", lines.ToString(), CUtils.UTF8); } /// /// 记录文件更新日期 /// private static HashMap savedPluginFileTimes = new HashMap(); // 检测xls目录下游戏插件是否需要存储// private List checkPlugins() { List xls_files = new List(); TemplateManager.Factory.Formula.ListXCSVFiles(new DirectoryInfo(DataDir), xls_files); // foreach (FileInfo sub in CFiles.listAllFiles(xls_dir)) // { // try // { // string ext = sub.Extension.ToLower(); // if (ext.EndsWith(".xls")) // { // string fullname = sub.FullName; // // 检测文件有没有更新 // DateTime lastSaved; // if (!savedPluginFileTimes.TryGetValue(fullname, out lastSaved) || (lastSaved != sub.LastWriteTime)) // { // xls_files.Add(sub); // } // Console.WriteLine("Skip Save : " + fullname); // } // } // catch (Exception err) // { // MessageBox.Show(err.Message); // } // } return xls_files; } } //----------------------------------------------------------------------------------------------------------- class SerialMaker { public void Gen(EditorTemplatesData alldata) { HashMap savedID = new HashMap(); List datas = new List(); List regens = new List(); while (true) { savedID.Clear(); datas.Clear(); regens.Clear(); PropertyUtil.CollectFieldTypeValues(alldata, datas); foreach (ISNData sn in datas) { if (savedID.ContainsKey(sn.SerialNumber)) { regens.Add(sn); } else { savedID.Put(sn.SerialNumber, sn); } } if (regens.Count > 0) { uint nid = 1; foreach (ISNData sn in regens) { for (; nid < uint.MaxValue; nid++) { if (!savedID.ContainsKey(nid)) { sn.RegenSerialNumber(nid); break; } } } } else { break; } } } } //----------------------------------------------------------------------------------------------------------- private class LoadLanguageTask : IProgress { public override int Value { get { return progress.Value; } } private Editor editor; private EditorTemplatesData allnodes; private AtomicInteger progress = new AtomicInteger(0); private CsvTable table = new CsvTable(); public LoadLanguageTask(string file, Editor editor) { this.editor = editor; this.allnodes = editor.GetEditorTemplatesData(); this.table.LoadFromText(File.ReadAllText(file, CUtils.UTF8)); base.Title = "Load Language : " + file; base.Text = "替换字段中..."; base.Maximum = table.MaxRow; base.Minimum = 0; base.IsDone = false; } public override void Run() { EditorTemplates.LoadLocalizationCsv(allnodes, table, progress); this.IsDone = true; } public override void Done() { editor.RefreshAll(); } } //----------------------------------------------------------------------------------------------------------- #endregion // _SaveLoad_ //----------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ #region _Templates_ //------------------------------------------------------------------------------ /// /// 获取模板管理器 /// /// /// public DataManagerPanel GetTemplateManager() where T : class, ITemplateData, new() { Type type = typeof(T); return template_panels[type] as DataManagerPanel; } /// /// 获取模板管理器根节点 /// /// /// public TreeNode GetTemplateManagerTreeRoot() where T : class, ITemplateData, new() { Type type = typeof(T); DataManagerPanel panel = template_panels[type] as DataManagerPanel; if (panel != null) { return panel.TreeRoot; } return null; } public object GetSelectedObject() { IDataManager dm = page_panels[tabControl1.SelectedTab]; if (dm != null) { return dm.SelectedData; } return null; } /// /// 获取模板ID和类型对应的模板对象 /// /// /// /// public T GetTemplateByType(int id) where T : class, ITemplateData, new() { Type type = typeof(T); DataManagerPanel panel = template_panels[type] as DataManagerPanel; if (panel != null) { return panel.GetNodeData(id.ToString()); } return default(T); } public object GetTemplateByType(int id, Type type) { IDataManager panel = template_panels[type] as IDataManager; if (panel != null) { return panel.GetNodeData(id.ToString()); } return null; } /// /// 获取场景中,玩家出生点对应的UnitTemplateID /// /// /// /// public static int GetTestActorTemplateID(SceneData mData, int force) { foreach (RegionData rd in mData.Regions) { foreach (AbilityData tg in rd.Abilities) { if (tg is PlayerStartAbilityData) { PlayerStartAbilityData start = tg as PlayerStartAbilityData; if (start.START_Force == force) { return start.TestActorTemplateID; } } } } return 1; } /// /// 获取 模板数据 对应的 ID /// /// /// /// /// public bool ConvertTemplateID(object obj, out int id) { if (obj != null) { if (obj is ITemplateData) { id = (obj as ITemplateData).TemplateID; return true; } } id = 0; return false; } /// /// 显示选择Template对象对话框 /// /// /// /// /// public object ShowSelectTemplateDialog(object obj, Type elementType) { IDataManager panel = template_panels[elementType] as IDataManager; if (panel != null) { return panel.ShowSelectTemplateDialog(obj); } return null; } /// /// 显示选择TemplateID对话框 /// /// /// /// /// public bool ShowSelectTemplateIDDialog(object obj, Type elementType, out int id) { IDataManager panel = template_panels[elementType] as IDataManager; if (panel != null) { return panel.ShowSelectTemplateIDDialog(obj, out id); } id = 0; return false; } /// /// 选择地块 /// /// /// public FormTerrainDefinition ShowTerrainDefinitionDialog(IWin32Window owner, int color = 0) { var editor = new FormTerrainDefinition(); editor.SelectedColor = color; editor.ShowDialog(owner); this.TerrainDefinition = editor.Data; saveCFG(this.TerrainDefinition, this.SaveTerrainDefinitionFile); return editor; } /// /// /// /// /// /// public FormUnitActionDefinition ShowUnitActionDefinitionDialog(IWin32Window owner) { var editor = new FormUnitActionDefinition(); editor.ShowDialog(owner); this.UnitActionDefinition = editor.Data; saveCFG(this.UnitActionDefinition, this.SaveUnitActionDefinition); return editor; } #endregion //----------------------------------------------------------------------------------------------------------- #region _Resource_ //----------------------------------------------------------------------------------------------------------- private void InitAllResNode() { TreeNode root = new TreeNode("资源"); root.ImageKey = "icons_tool_bar2.png"; root.SelectedImageKey = "icons_tool_bar2.png"; InitResNode(root, new DirectoryInfo(Editor.EditorRootDir)); treeViewRes.Nodes.Clear(); treeViewRes.Nodes.Add(root); treeViewRes.CollapseAll(); } private int InitResNode(TreeNode parent, DirectoryInfo dir) { int count = 0; foreach (FileInfo f in dir.GetFiles()) { if (EditorPlugin.CurrentPlugin.AcceptResource(EditorPlugin.DefaultPlugin, f.Name)) { TreeNode sub = new TreeNode(f.Name); sub.Tag = f; sub.ImageKey = "icon_res.png"; sub.SelectedImageKey = "icon_res.png"; parent.Nodes.Add(sub); count++; } } foreach (DirectoryInfo d in dir.GetDirectories()) { TreeNode sub = new TreeNode(d.Name); int scount = InitResNode(sub, d); if (scount > 0) { sub.Tag = d; sub.ImageKey = "icons_tool_bar2.png"; sub.SelectedImageKey = "icons_tool_bar2.png"; parent.Nodes.Add(sub); } count += scount; } return count; } private void treeViewRes_ItemDrag(object sender, ItemDragEventArgs e) { treeViewRes.DoDragDrop(e.Item, DragDropEffects.Move); } private void listView1_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(TreeNode))) { TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (node.Tag is FileInfo) { FileInfo fi = node.Tag as FileInfo; ListViewItem item = new ListViewItem(fi.Name); item.ImageKey = "icon_res.png"; item.Tag = fi; listViewRes.Items.Add(item); } } } private void listView1_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(TreeNode))) { TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (node.Tag is FileInfo) { e.Effect = DragDropEffects.Move; return; } } e.Effect = DragDropEffects.None; } private void listView1_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(TreeNode))) { TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (node.Tag is FileInfo) { e.Effect = DragDropEffects.Move; return; } } e.Effect = DragDropEffects.None; } private void treeViewRes_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Node.Tag is FileInfo) { try { FileInfo ff = e.Node.Tag as FileInfo; EditorPlugin.CurrentPlugin.RunModelView(EditorPlugin.DefaultPlugin, new string[] { ff.FullName }); } catch (Exception err) { MessageBox.Show(err.Message); } } } private void btnRunRes_Click(object sender, EventArgs e) { List ffs = new List(); foreach (ListViewItem item in listViewRes.Items) { if (item.Tag is FileInfo) { FileInfo ffi = item.Tag as FileInfo; ffs.Add(ffi.FullName); } } try { EditorPlugin.CurrentPlugin.RunModelView(EditorPlugin.DefaultPlugin, ffs.ToArray()); } catch (Exception err) { MessageBox.Show(err.Message); } } private void btnRemoveRes_Click(object sender, EventArgs e) { foreach (ListViewItem item in listViewRes.SelectedItems) { listViewRes.Items.Remove(item); } } private void btnRefreshRes_Click(object sender, EventArgs e) { listViewRes.Items.Clear(); } private void btn_CleanRes_Click(object sender, EventArgs e) { new G2DProgressDialog(new CleanResTask(this)).ShowDialog(this); } private void btn_OutputRes_Click(object sender, EventArgs e) { FolderBrowserDialog dialog = new FolderBrowserDialog(); dialog.SelectedPath = DataDir; if (dialog.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { if (!dialog.SelectedPath.Equals(DataDir)) { new G2DProgressDialog(new CleanResTask(this, dialog.SelectedPath)).ShowDialog(this); } } } public class CleanResTask : IProgress { private readonly Editor editor; private EditorTemplates templates; private EditorTemplatesData datas; private List scenes_list; private AtomicInteger used_progress = new AtomicInteger(0); private SortedDictionary file_list = new SortedDictionary(); private int used_count = 0; private int unused_count = 0; private int miss_count = 0; private StringBuilder logs = new StringBuilder(); private AtomicInteger copy_progress = new AtomicInteger(0); private List copyres = new List(); private HashSet ignores = new HashSet(); private DirectoryInfo output_dir; public override int Value { get { return used_progress.Value + copy_progress.Value; } } public CleanResTask(Editor editor, string outputDir = null) { this.editor = editor; this.templates = new EditorTemplates(DataDir, TemplateManager.MessageCodec); this.templates.LoadAllTemplates(); this.datas = templates.AllTemplatesExcludeScenes; this.scenes_list = templates.ListScenes(); List allfiles = CFiles.listAllFiles(new DirectoryInfo(ResDir)); foreach (FileInfo file in allfiles) { file_list.Add(file.FullName, new AtomicInteger(0)); } if (outputDir != null) { output_dir = new DirectoryInfo(outputDir); CFiles.listAllFiles(copyres, new DirectoryInfo(DataDir)); CFiles.listAllFiles(copyres, new DirectoryInfo(ResDir)); } base.Maximum = datas.FileCount + scenes_list.Count + copyres.Count; base.Minimum = 0; base.Value = 0; base.Title = "检测资源文件使用"; } public override void Run() { logs.AppendLine("------------------------------------------------------------------"); logs.AppendLine("- 缺失文件统计 -"); logs.AppendLine("------------------------------------------------------------------"); //检测所有模板资源使用率// foreach (ITemplateData data in datas.AllTemplates()) { base.Text = string.Format("{0}/{1} : {2}", Value, Maximum, data); try { MarkInResources(data); } catch (Exception err) { logs.AppendLine(err.Message); } finally { this.used_progress.IncrementAndGet(); } } //检测所有场景资源使用率// foreach (int scene_id in scenes_list) { try { SceneData sdata = templates.LoadScene(scene_id); if (sdata != null) { base.Text = string.Format("{0}/{1} : scene : {2}", Value, Maximum, sdata); MarkInResources(sdata); } } catch (Exception err) { logs.AppendLine(err.Message); } finally { this.used_progress.IncrementAndGet(); } } logs.AppendLine("------------------------------------------------------------------"); logs.AppendLine("- 已使用文件统计 -"); logs.AppendLine("------------------------------------------------------------------"); //生成报表// foreach (KeyValuePair used in file_list) { string res = used.Key.Substring(EditorRootDir.Length); int count = used.Value.Value; if (count > 0) { used_count++; logs.AppendLine(string.Format("已使用文件:,{0} ,次数:{1}", res, count)); } } logs.AppendLine("------------------------------------------------------------------"); logs.AppendLine("- 未使用文件统计 -"); logs.AppendLine("------------------------------------------------------------------"); foreach (KeyValuePair used in file_list) { string res = used.Key.Substring(EditorRootDir.Length); int count = used.Value.Value; if (count <= 0) { ignores.Add(used.Key); unused_count++; logs.AppendLine(string.Format("未使用文件:,{0}", res)); } } logs.AppendLine("------------------------------------------------------------------"); File.WriteAllText(EditorRootDir + "\\resource_info.csv", logs.ToString(), CUtils.UTF8); //复制资源// if (output_dir != null && output_dir.Exists) { CFiles.DirectoryCopy(DataDir, output_dir.FullName + "\\data", true, CopyResFilter, copy_progress); CFiles.DirectoryCopy(ResDir, output_dir.FullName + "\\res", true, CopyResFilter, copy_progress); } } private void CopyResFilter(FileInfo src, out bool ignore) { ignore = ignores.Contains(src.FullName); if (!ignore) { base.Text = string.Format("复制资源 : " + src); } } public override void Done() { MessageBox.Show( "资源检测结束!" + "\n * 已使用文件:" + used_count + "\n * 未使用文件:" + unused_count + "\n * 缺失文件数:" + miss_count + "\n报告已存入:" + EditorRootDir + "\\resource_info.csv" ); } private void MarkInResources(object data) { HashMap reses = templates.SelectTemplatesAsMap(data); foreach (KeyValuePair res in reses) { if (!string.IsNullOrWhiteSpace(res.Key)) { FileInfo file = new FileInfo((Editor.EditorRootDir + "\\" + res.Key).Trim()); AtomicInteger usecount; if (file_list.TryGetValue(file.FullName, out usecount)) { usecount.IncrementAndGet(); } else { miss_count++; logs.AppendLine(string.Format("缺失文件:,{0} ,对象:{1}, 类型:{2},字段:{3}", res.Key, data, data.GetType(), res.Value.Field.Name)); } } } } } #endregion //------------------------------------------------------------------------------ #region _Editor_Delegate_And_Events_ //------------------------------------------------------------------------------ private void Editor_Load(object sender, EventArgs e) { try { this.Text = "GameEditor : " + EditorRootDir; loadCFG(); InitAllResNode(); InitAllTempaltes(); if (autoSave) { saveAll(); SaveEditorStatus(); Dispose(true); } // CommonSecure.ConnectWS.Run(this); } catch (Exception err) { MessageBox.Show(err.Message); } } private void Editor_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show(this, "确认关闭?", "确认关闭?", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK) { this.SaveEditorStatus(); } else { e.Cancel = true; } } private void btn_saveAll_Click(object sender, EventArgs e) { saveAll(); } private void btn_saveALLCheck_Click(object sender, EventArgs e) { saveAll(true); } private void sceneBtn_DoubleClickNode(object sender, TreeNodeMouseClickEventArgs e) { OpenScene(scenes.GetSelectedNode(), new Win32ScenePlugin()); } private void sceneBtn_OpenNodeWin32_Click(object sender, EventArgs e) { OpenScene(scenes.GetSelectedNode(), new Win32ScenePlugin()); } private void sceneBtn_OpenNode_Click(object sender, EventArgs e) { OpenScene(scenes.GetSelectedNode(), EditorPlugin.CurrentPlugin.CreateScenePlugin(EditorPlugin.DefaultPlugin)); } private void sceneBtn_TestAstar_Click(object sender, EventArgs e) { var sd = scenes.GetSelectedData(); if (sd != null) { new GameEditorPlugin.Tools.FormAstar(DataDir_scenes, Editor.Instance.TerrainDefinition, sd).Show(); } } private void btn_CopyText_Click(object sender, EventArgs e) { object node = GetSelectedObject(); if (node is ITemplateData) { Clipboard.SetText((node as ITemplateData).TemplateID.ToString()); } } private void sceneBtn_RunEMU_Click(object sender, EventArgs e) { SceneData data = scenes.GetSelectedData(); if (data != null) { IGameEditorPlugin plugin = EditorPlugin.CurrentPlugin; plugin.RunLocalPlay(EditorPlugin.DefaultPlugin, new DirectoryInfo(DataDir), data.ID, false); } } private void sceneBtn_RunEMUServer_Click(object sender, EventArgs e) { SceneData data = scenes.GetSelectedData(); if (data != null) { IGameEditorPlugin plugin = EditorPlugin.CurrentPlugin; plugin.RunServerPlay(EditorPlugin.DefaultPlugin, new DirectoryInfo(DataDir), data.ID); } } private void sceneBtn_RunREC_Click(object sender, EventArgs e) { SceneData data = scenes.GetSelectedData(); if (data != null) { IGameEditorPlugin plugin = EditorPlugin.CurrentPlugin; plugin.RunLocalPlay(EditorPlugin.DefaultPlugin, new DirectoryInfo(DataDir), data.ID, true); } } private void sceneBtn_LoadREC_Click(object sender, EventArgs e) { LoadBattleRecord(); } private void sceneBtn_RunGAME_Click(object sender, EventArgs e) { SceneData data = scenes.GetSelectedData(); if (data != null) { try { IGameEditorPlugin plugin = EditorPlugin.CurrentPlugin; plugin.RunTest(EditorPlugin.DefaultPlugin, DataDir, data.ID, GetTestActorTemplateID(data, 0)); } catch (Exception err) { MessageBox.Show(err.Message); } } } private void btn_SetTemplateConfig_Click(object sender, EventArgs e) { G2DFieldEditor editor = new G2DFieldEditor(this.CFG.GetType(), this.CFG, false); if (editor.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { if (editor.EditObject != null) { this.CFG = (Config)editor.EditObject; saveCFG(this.CFG, this.SaveCfgFile); } } } private void btn_DefineTerrain_Click(object sender, EventArgs e) { ShowTerrainDefinitionDialog(this); } private void btn_DefineUnitAction_Click(object sender, EventArgs e) { ShowUnitActionDefinitionDialog(this); } private void btn_SetTemplateExtConfig_Click(object sender, EventArgs e) { G2DFieldEditor editor = new G2DFieldEditor(this.ExtCFG.GetType(), this.ExtCFG, false); if (editor.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { if (editor.EditObject != null) { this.ExtCFG = (ICommonConfig)editor.EditObject; saveCFG(this.ExtCFG, this.SaveCfgExtFile); } } } private void btn_ScriptEdit_Click(object sender, EventArgs e) { } private void btn_LoadLanguageCsv_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.InitialDirectory = EditorRootDir; ofd.Filter = "CSV语言配置(*.csv)|*.csv|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*"; if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { LoadLanguageTask task = new LoadLanguageTask(ofd.FileName, this); new G2DProgressDialog(task).ShowDialog(this); } catch (Exception err) { MessageBox.Show(err.Message); } } } private void btn_PlayBattleRecord_Click(object sender, EventArgs e) { LoadBattleRecord(); } private void openUnitEvent_Click(object sender, EventArgs e) { UnitEventTemplate temp = unit_events.GetSelectedData(); if (temp != null) { CommonAIEditor.Unit.UnitEventEditor eventEditor = new CommonAIEditor.Unit.UnitEventEditor(unit_events, temp); eventEditor.FormClosed += new FormClosedEventHandler( (object sender2, FormClosedEventArgs e2) => { eventEditor.Save(); eventEditor = null; } ); eventEditor.Show(); } } //----------------------------------------------------------------------------------------------------------- #endregion // Events // //----------------------------------------------------------------------------------------------------------- private void OpenScene(G2DTreeNode node, ISceneEditorPlugin plugin = null) { if (plugin == null) { plugin = EditorPlugin.CurrentPlugin.CreateScenePlugin(EditorPlugin.DefaultPlugin); } if (node != null) { SceneEditor editor = new SceneEditor(scenes, node, plugin); editor.OnSaved += this.sceneEditor_onSavedScene; editor.Show(); } } private void LoadBattleRecord() { OpenFileDialog ofd = new OpenFileDialog(); ofd.InitialDirectory = EditorRootDir; ofd.Filter = "REC战报文件(*.rec)|*.rec|所有文件(*.*)|*.*"; if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { FileStream fis = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read); FormRuntimeGameReplay view = new FormRuntimeGameReplay(); view.StartPlay(DataDir, fis); view.Show(); } catch (Exception err) { MessageBox.Show(err.Message); } } } private void btn_exportAll_Click(object sender, EventArgs e) { Process p = Process.Start("ResBuilder.exe"); p.WaitForExit(); string sPath = null; string tmpCfg = "./lastSave.cfg"; if (File.Exists(tmpCfg)) { try { FileStream fs = new FileStream(tmpCfg, FileMode.Open, FileAccess.Read); byte[] bytes = new byte[256]; int len = fs.Read(bytes, 0, bytes.Length - 1); if (len > 0) { sPath = System.Text.Encoding.UTF8.GetString(bytes, 0, len); if (!Directory.Exists(sPath)) { sPath = null; } } fs.Close(); } catch (Exception) { } } if (sPath == null) { FolderBrowserDialog folder = new FolderBrowserDialog(); folder.Description = "选择文件所在文件夹目录"; //定义在对话框上显示的文本 if (folder.ShowDialog() == DialogResult.OK) { sPath = folder.SelectedPath; try { FileStream fs = new FileStream(tmpCfg, FileMode.OpenOrCreate, FileAccess.ReadWrite); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sPath); fs.Write(bytes, 0, bytes.Length); fs.Close(); } catch (Exception) { } } else { return; } } File.Copy("./resBuilder/out/bin/e1.bin", Path.Combine(sPath, "e1.bin"), true); File.Copy("./resBuilder/out/bin/ex.bin", Path.Combine(sPath, "ex.bin"), true); } } }