Unity3dControl.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Diagnostics;
  9. using CommonAIEditor;
  10. using CommonAI.Zone.ZoneEditor.Plugin.EditorToScene;
  11. using CommonAI.Zone.ZoneEditor.Plugin;
  12. using CommonAI.Zone.ZoneEditor.Plugin.SceneToEditor;
  13. using System.IO;
  14. using System.Runtime.InteropServices;
  15. using CommonLang.File;
  16. using GameEditorPlugin.Utils;
  17. using CommonAI.Zone;
  18. using CommonLang.Property;
  19. using System.Configuration;
  20. using System.Text.RegularExpressions;
  21. using System.Threading;
  22. using CommonFroms;
  23. using GameEditorPlugin.Win32.Runtime;
  24. using System.Runtime.Remoting;
  25. using System.Runtime.Remoting.Channels;
  26. using System.Runtime.Remoting.Channels.Ipc;
  27. using System.Runtime.Serialization.Formatters;
  28. using System.Collections;
  29. using System.Runtime.Remoting.Channels.Tcp;
  30. using System.Net.NetworkInformation;
  31. using System.Net;
  32. namespace GameEditorUnity3D
  33. {
  34. public partial class Unity3dControl : UserControl, ISceneEditorPlugin
  35. {
  36. public Unity3dControl()
  37. {
  38. InitializeComponent();
  39. }
  40. #region IEditorPlugin
  41. public event PluginMessageHandler OnGetPluginMessage;
  42. public event CallAddSceneObject CallAddObject;
  43. public event CallResetSceneObject CallResetObject;
  44. public Control AsControl()
  45. {
  46. return this;
  47. }
  48. public bool EnableRight { get { return true; } }
  49. private void Response(object resp)
  50. {
  51. this.Invoke(new System.Action(() =>
  52. {
  53. if (resp is RspOnObjectSelected)
  54. {
  55. RspOnObjectSelected rsp = resp as RspOnObjectSelected;
  56. rsp.Selected = true;
  57. }
  58. if (OnGetPluginMessage != null)
  59. {
  60. OnGetPluginMessage.Invoke(resp);
  61. if (resp is RspEditorState)
  62. {
  63. if ((resp as RspEditorState).State == RspEditorState.STATE_SUCCEED)
  64. {
  65. OnEditorStatusOK();
  66. }
  67. }
  68. }
  69. }));
  70. }
  71. public void SendMessage(object data)
  72. {
  73. string output = EditorMessageDecoder.EncodeMessage(data);
  74. Send(output);
  75. return;
  76. }
  77. public static bool PortInUse(int port)
  78. {
  79. bool inUse = false;
  80. IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
  81. IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
  82. foreach (IPEndPoint endPoint in ipEndPoints)
  83. {
  84. if (endPoint.Port == port)
  85. {
  86. inUse = true;
  87. break;
  88. }
  89. }
  90. return inUse;
  91. }
  92. private void OnEditorStatusOK()
  93. {
  94. var timer = new System.Timers.Timer(1);
  95. timer.Elapsed += (sender, e) =>
  96. {
  97. timer.Close();
  98. timer.Dispose();
  99. this.Invoke(new System.Action(() =>
  100. {
  101. ActivateUnityWindow();
  102. }));
  103. };
  104. timer.Start();
  105. }
  106. //------------------------------------------------------------------------------
  107. #endregion
  108. #region 组件设计器生成的代码
  109. private System.ComponentModel.IContainer components = null;
  110. [DllImport("user32.dll")]
  111. static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
  112. internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
  113. [DllImport("user32.dll")]
  114. internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
  115. [DllImport("user32.dll")]
  116. internal static extern IntPtr SetFocus(IntPtr hWnd);
  117. [DllImport("user32.dll")]
  118. static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
  119. private Process process;
  120. private IntPtr unityHWND = IntPtr.Zero;
  121. private const int WM_ACTIVATE = 0x0006;
  122. private readonly IntPtr WA_ACTIVE = new IntPtr(1);
  123. private readonly IntPtr WA_INACTIVE = new IntPtr(0);
  124. public IpcRemoteObject RemoteObject { get; set; }
  125. private ObjRef RemoteObjectRef;
  126. private int MessageProxyServerPort = 9900;
  127. private string MessageProxyServerIP = @"127.0.0.1";
  128. private string MessageProxyServerName = @"GameEditorUnity3D.Server";
  129. private string MessageProxyURLName = @"GameEditorUnity3D";
  130. private string MessageProxyURL;
  131. /// <summary>
  132. /// 初始化进程间消息代理
  133. /// </summary>
  134. public void InitializeIPCMessageProxy()
  135. {
  136. while (PortInUse(MessageProxyServerPort))
  137. {
  138. MessageProxyServerPort++;
  139. }
  140. MessageProxyURLName += System.Guid.NewGuid();
  141. MessageProxyURL = string.Format(@"tcp://{0}:{1}/{2}", MessageProxyServerIP, MessageProxyServerPort, MessageProxyURLName);
  142. BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
  143. serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
  144. BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
  145. IDictionary props = new Hashtable();
  146. props["name"] = MessageProxyServerName;
  147. props["port"] = MessageProxyServerPort;
  148. props["bindTo"] = MessageProxyServerIP;
  149. TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider);
  150. ChannelServices.RegisterChannel(channel, false);
  151. RemoteObject = new IpcRemoteObject();
  152. RemoteObjectRef = RemotingServices.Marshal(RemoteObject, MessageProxyURLName);
  153. //RemoteObject = Activator.GetObject(typeof(IpcRemoteObject), MessageProxyURLName) as IpcRemoteObject;
  154. RemoteObject.ServerCallback = Recv;
  155. }
  156. /// <summary>
  157. /// 释放进程间消息代理
  158. /// </summary>
  159. public void DisposeIPCMessageProxy()
  160. {
  161. RemotingServices.Unmarshal(RemoteObjectRef, true);
  162. IChannel[] regChannels = ChannelServices.RegisteredChannels;
  163. foreach (IChannel item in regChannels)
  164. {
  165. if (item.ChannelName == MessageProxyServerName)
  166. {
  167. TcpChannel channel = item as TcpChannel;
  168. channel.StopListening(null);
  169. ChannelServices.UnregisterChannel(channel);
  170. break;
  171. }
  172. }
  173. }
  174. private void InitializeComponent()
  175. {
  176. try
  177. {
  178. InitializeIPCMessageProxy();
  179. System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Unity3dControl));
  180. this.SuspendLayout();
  181. }
  182. catch (Exception ex)
  183. {
  184. MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
  185. }
  186. {
  187. //-----------------------------------------
  188. try
  189. {
  190. string unitysrc = Application.StartupPath + "\\U3DScene\\U3DEditor.exe";
  191. string u3d_webplayer = ConfigurationManager.AppSettings["u3d_webplayer"];
  192. if (u3d_webplayer != null)
  193. {
  194. unitysrc = Application.StartupPath + u3d_webplayer;
  195. }
  196. process = new Process();
  197. process.StartInfo.FileName = unitysrc;
  198. process.StartInfo.Arguments = "-parentHWND " + this.Handle.ToInt32() + " -ipcPort " + MessageProxyServerPort + " -serviceName " + MessageProxyURLName + " " + Environment.CommandLine;
  199. process.StartInfo.UseShellExecute = true;
  200. process.StartInfo.CreateNoWindow = true;
  201. Application.ThreadExit += new System.EventHandler(this.App_Exit);
  202. process.Start();
  203. process.WaitForInputIdle();
  204. EnumChildWindows(this.Handle, WindowEnum, IntPtr.Zero);
  205. this.Resize += new System.EventHandler(this.Form_Resize);
  206. this.VisibleChanged += new System.EventHandler(this.Form_Activated);
  207. this.Disposed += new System.EventHandler(this.Form_FormClosed);
  208. }
  209. catch (Exception ex)
  210. {
  211. MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
  212. }
  213. //-----------------------------------------
  214. }
  215. //
  216. // Unity3dControl
  217. //
  218. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  219. //this.Controls.Add(this.axUnityWebPlayer1);
  220. this.Name = "Unity3dControl";
  221. this.Size = new System.Drawing.Size(915, 685);
  222. this.ResumeLayout(false);
  223. }
  224. public void ActivateUnityWindow()
  225. {
  226. SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
  227. SetFocus(unityHWND);
  228. }
  229. public void DeactivateUnityWindow()
  230. {
  231. SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
  232. }
  233. private int WindowEnum(IntPtr hwnd, IntPtr lparam)
  234. {
  235. unityHWND = hwnd;
  236. ActivateUnityWindow();
  237. return 0;
  238. }
  239. public void Form_Resize(object sender, EventArgs e)
  240. {
  241. MoveWindow(unityHWND, 0, 0, this.Width, this.Height, true);
  242. ActivateUnityWindow();
  243. //OnGetPluginMessage.Invoke(new RspEditorState());
  244. }
  245. // Close Unity application
  246. public void Form_FormClosed(object sender, EventArgs e)
  247. {
  248. try
  249. {
  250. process.CloseMainWindow();
  251. Thread.Sleep(1000);
  252. while (process.HasExited == false)
  253. process.Kill();
  254. }
  255. catch (Exception)
  256. {
  257. }
  258. }
  259. public void App_Exit(object sender, EventArgs e)
  260. {
  261. try
  262. {
  263. process.Kill();
  264. }
  265. catch (Exception)
  266. {
  267. }
  268. }
  269. public void Form_Activated(object sender, EventArgs e)
  270. {
  271. if (this.Visible)
  272. ActivateUnityWindow();
  273. else
  274. DeactivateUnityWindow();
  275. }
  276. public void Form_Deactivate(object sender, EventArgs e)
  277. {
  278. DeactivateUnityWindow();
  279. }
  280. protected override void Dispose(bool disposing)
  281. {
  282. if (disposing && (components != null))
  283. {
  284. components.Dispose();
  285. }
  286. if (disposing)
  287. {
  288. DisposeIPCMessageProxy();
  289. }
  290. base.Dispose(disposing);
  291. }
  292. #endregion
  293. #region Unity3dControl
  294. const string Prefix = "OnExternalCall(\"";
  295. const string Endfix = "\");";
  296. string Recv(string s)
  297. {
  298. object data = EditorMessageDecoder.DecodeMessage(s);
  299. Response(data);
  300. return "";
  301. }
  302. void Send(string regionmsg)
  303. {
  304. RemoteObject.SendToClient(regionmsg);
  305. }
  306. #endregion
  307. }
  308. public class U3dGamePlugin : IGameEditorPlugin
  309. {
  310. private static string dataRoot;
  311. private static string pluginDll;
  312. [DllImport("user32.dll", SetLastError = true)]
  313. private static extern void SwitchToThisWindow(IntPtr hWnd, bool turnOn);
  314. private string U3DRuntimeEXE = "/U3DScene/U3DSceneRun.exe";
  315. public string Name { get { return "Unity"; } }
  316. public string DataRoot
  317. {
  318. get { return U3dGamePlugin.dataRoot; }
  319. set { U3dGamePlugin.dataRoot = value.Replace('\\', '/'); }
  320. }
  321. public string PluginDLL
  322. {
  323. get { return U3dGamePlugin.pluginDll; }
  324. set { U3dGamePlugin.pluginDll = value.Replace('\\', '/'); }
  325. }
  326. public U3dGamePlugin()
  327. {
  328. string u3d_runtime = ConfigurationManager.AppSettings["u3d_runtime"];
  329. if (u3d_runtime != null)
  330. {
  331. U3DRuntimeEXE = u3d_runtime;
  332. }
  333. }
  334. public ISceneEditorPlugin CreateScenePlugin(IGameEditorPlugin d)
  335. {
  336. return new Unity3dControl();
  337. }
  338. public void RunTest(IGameEditorPlugin d, string data_dir, int sceneID, int actorTemplateID)
  339. {
  340. Type plugintype = ReflectionUtil.GetType(TemplateManager.Factory.GetType().FullName);
  341. string args = string.Format(
  342. "-CustomArgs:RunPlatform={0};MapID={1};FolderPath={2};ResPath={3};UserID={4};Plugin={5};IsNet=0;NetDriver=0;IP=0;UUID=0;Force=0;RoomID=0",
  343. 0,
  344. sceneID,
  345. dataRoot + "/data",
  346. dataRoot,
  347. actorTemplateID,
  348. PluginDLL
  349. );
  350. FileInfo exefile = new FileInfo(Application.StartupPath + U3DRuntimeEXE);
  351. ProcessStartInfo start = new ProcessStartInfo(exefile.FullName, args);
  352. start.WorkingDirectory = exefile.Directory.FullName;
  353. Process p = new Process();
  354. p.StartInfo = start;
  355. p.Start();
  356. new Thread(() =>
  357. {
  358. while (!p.HasExited)
  359. {
  360. Thread.Sleep(1000);
  361. }
  362. Regex regex = new Regex(@"\d{4}-\d{2}-\d{2}_\d*");
  363. foreach (DirectoryInfo dir in exefile.Directory.GetDirectories())
  364. {
  365. if (regex.IsMatch(dir.Name))
  366. {
  367. if (File.Exists(dir.FullName + Path.DirectorySeparatorChar + "crash.dmp"))
  368. {
  369. FileSystem.DeleteToRecycleBin(dir.FullName);
  370. //dir.Delete(true);
  371. }
  372. }
  373. }
  374. }).Start();
  375. }
  376. public void RunModelView(IGameEditorPlugin d, string[] filepath)
  377. {
  378. StringBuilder sb = new StringBuilder();
  379. for (int i = 0; i < filepath.Length; i++)
  380. {
  381. sb.Append(filepath[i].Replace('\\', '/'));
  382. if (i < filepath.Length - 1)
  383. {
  384. sb.Append(",");
  385. }
  386. }
  387. ProcessStartInfo start = new ProcessStartInfo(
  388. Application.StartupPath + "/U3DScene/U3DSceneRun.exe",
  389. "-CustomArgs:" +
  390. "RunPlatform=" + 1 + ";" +
  391. "ModelPath=" + sb.ToString() +
  392. "");
  393. start.WorkingDirectory = Application.StartupPath + "\\U3DScene";
  394. Process p = new Process();
  395. p.StartInfo = start;
  396. p.Start();
  397. }
  398. public bool AcceptResource(IGameEditorPlugin d, string filename)
  399. {
  400. return filename.ToLower().EndsWith(".assetbundles");
  401. }
  402. public void RunLocalPlay(IGameEditorPlugin d, DirectoryInfo data_dir, int sceneID, bool recorder)
  403. {
  404. d.RunLocalPlay(null, data_dir, sceneID, recorder);
  405. }
  406. public void RunServerPlay(IGameEditorPlugin d, DirectoryInfo data_dir, int sceneID)
  407. {
  408. d.RunServerPlay(null, data_dir, sceneID);
  409. }
  410. }
  411. }