private void OnEnable() { edittingAvatar = new VRCAvatar(); editorFolderPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this))); editorFolderPath = editorFolderPath.Substring(0, editorFolderPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); saveFolder = "Assets/"; licenseText = FileUtility.GetFileTexts(editorFolderPath + LICENSE_FILE_NAME); readmeText = FileUtility.GetFileTexts(editorFolderPath + README_FILE_NAME); usingSoftwareLicenseText = FileUtility.GetFileTexts(editorFolderPath + USING_SOFTWARE_FILE_NAME); avatarMonitorGUI = ScriptableObject.CreateInstance <AvatarMonitorGUI>(); animationsGUI = ScriptableObject.CreateInstance <AnimationsGUI>(); avatarInfoGUI = ScriptableObject.CreateInstance <AvatarInfoGUI>(); faceEmotionGUI = ScriptableObject.CreateInstance <FaceEmotionGUI>(); probeAnchorGUI = ScriptableObject.CreateInstance <ProbeAnchorGUI>(); meshBoundsGUI = ScriptableObject.CreateInstance <MeshBoundsGUI>(); shaderGUI = ScriptableObject.CreateInstance <ShaderGUI>(); toolGUIs.Add(ToolFunc.AvatarInfo, avatarInfoGUI); toolGUIs.Add(ToolFunc.FaceEmotion, faceEmotionGUI); toolGUIs.Add(ToolFunc.ProbeAnchor, probeAnchorGUI); toolGUIs.Add(ToolFunc.Bounds, meshBoundsGUI); toolGUIs.Add(ToolFunc.Shader, shaderGUI); avatarMonitorGUI.Initialize(CurrentTool); animationsGUI.Initialize(edittingAvatar, originalAvatar, saveFolder, this, faceEmotionGUI); avatarInfoGUI.Initialize(originalAvatar, edittingAvatar, avatarMonitorGUI); probeAnchorGUI.Initialize(originalAvatar); selectedToolGUI = avatarInfoGUI; CurrentTool = ToolFunc.AvatarInfo; (layoutType, language) = EditorSetting.instance.LoadSettingDataFromScriptableObject( editorFolderPath, language, avatarMonitorGUI, faceEmotionGUI); // Windowを開いたときにオブジェクトが選択されていればそれをアバターとして設定する if (Selection.gameObjects.Length == 1) { var selectionTransform = Selection.gameObjects.Single().transform; while (selectionTransform != null) { targetAvatarDescriptor = selectionTransform.GetComponent <VRC_AvatarDescriptor>(); if (targetAvatarDescriptor != null) { OnChangedAvatar(); break; } selectionTransform = selectionTransform.parent; } } SceneView.onSceneGUIDelegate += OnSceneGUI; }
private void OnChangedAvatar() { edittingAvatar = avatarMonitorGUI.SetAvatarPreview(targetAvatarDescriptor); originalAvatar = new VRCAvatar(targetAvatarDescriptor); EditorSetting.instance.ApplySettingsToEditorGUI(edittingAvatar, faceEmotionGUI); var targetAvatarObj = targetAvatarDescriptor.gameObject; targetAvatarObj.SetActive(true); avatarMonitorGUI.MoveAvatarCam(false, false); animationsGUI.Initialize(edittingAvatar, originalAvatar, saveFolder, this, faceEmotionGUI); avatarInfoGUI.Initialize(originalAvatar, edittingAvatar, avatarMonitorGUI); meshBoundsGUI.Initialize(originalAvatar); probeAnchorGUI.Initialize(originalAvatar); CurrentTool = ToolFunc.AvatarInfo; }
private void DrawToolSwitchTab() { using (new EditorGUILayout.HorizontalScope()) { using (var check = new EditorGUI.ChangeCheckScope()) { GUILayout.FlexibleSpace(); // タブを描画する var currentTool = (ToolFunc)GUILayout.Toolbar((int)CurrentTool, LocalizeText.instance.toolTabTexts, "LargeButton", GUI.ToolbarButtonSize.Fixed); GUILayout.FlexibleSpace(); if (check.changed) { CurrentTool = currentTool; } } } }
public static void RunIronPython(MCCSAPI api) { List <IntPtr> uuid = new List <IntPtr>(); const String path = "./ipy"; bool pfapi = false; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("[IPYR] IronPython插件运行平台开始装载。"); if (!File.Exists("./ipy/NOWEB")) { Console.WriteLine("[IPYR] 登记中,请稍候..."); string porrt = FindPort("server.properties"); string urldata = HttpGet("*****", ""); var webmsg = JsonConvert.DeserializeObject <Urldata>(urldata); if (webmsg.load) { Console.WriteLine("[IPYR] 登记成功,IronPythonRunner开始装载..."); } else { Console.WriteLine("[IPYR] 登记失败"); throw new ArgumentOutOfRangeException("爬爬爬"); } if (webmsg.version != version) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[IPYR] IronPythonRunner有新版本需要您更新!"); Console.WriteLine("[IPYR] 当前版本:" + version + ",新版本:" + webmsg.version); Console.ForegroundColor = ConsoleColor.White; } string[] PArray = webmsg.message.Split('*'); foreach (string i in PArray) { Console.WriteLine("[IPYR]|网络公告| " + i.ToString()); } localip = webmsg.IP; } if (File.Exists("./csr/PFEssentials.csr.dll")) { Console.WriteLine("[IPYR] 找到PFessentials,加载PFessAPI"); pfapi = true; } if (!File.Exists("./IronPython27.zip")) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[IPYR] 无法找到依赖库,请将IronPython27.zip放到BDS根目录!"); Console.ForegroundColor = ConsoleColor.White; } Console.WriteLine("[IPYR] 读取插件列表"); var PyFun = new List <dynamic>(); DirectoryInfo Allfolder = new DirectoryInfo(path); var mc = new MCPYAPI(api); GC.KeepAlive(mc); var tool = new ToolFunc(); GC.KeepAlive(tool); var _pfapi = new PFessAPI(); GC.KeepAlive(_pfapi); foreach (FileInfo file in Allfolder.GetFiles("*.net.py")) { try { Console.WriteLine("[IPYR] Load\\" + file.Name); ScriptEngine pyEngine = Python.CreateEngine(); var Libpath = pyEngine.GetSearchPaths(); List <string> LST = new List <string>(Libpath.Count) { "C:\\Program Files\\IronPython 2.7\\Lib", ".\\IronPython27.zip" }; pyEngine.SetSearchPaths(LST.ToArray()); pyEngine.CreateModule("mc"); pyEngine.CreateModule("tool"); if (pfapi) { pyEngine.CreateModule("pfapi"); } dynamic py = pyEngine.ExecuteFile(file.FullName); py.SetVariable("mc", new MCPYAPI(api)); py.SetVariable("tool", new ToolFunc()); if (pfapi) { py.SetVariable("pfapi", new PFessAPI()); } var main = py.load_plugin(); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(file.Name + " Load Successful"); Console.ForegroundColor = ConsoleColor.White; PyFun.Add(py); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); Console.WriteLine("Failed to load " + file.Name); Console.ForegroundColor = ConsoleColor.White; } } var tmp = new Action <string, dynamic>((k, obj) => { Console.WriteLine("[IPYR] 接受对象 " + k); foreach (var py in PyFun) { py.SetVariable(k, obj); } }); GC.KeepAlive(tmp); var FuncPointer = Marshal.GetIUnknownForObject(tmp); Console.Write("*" + FuncPointer); api.setSharePtr("ipyr", FuncPointer); #region 监听器 api.addBeforeActListener(EventKey.onLoadName, x => { var a = BaseEvent.getFrom(x) as LoadNameEvent; uuid.Add(a.playerPtr); ptr.Add(a.uuid, a.playerPtr); CallPyFunc(PyFun, func => { CsPlayer p = new CsPlayer(api, a.playerPtr); string list = "{\'playername\':\'" + a.playername + "\',\'uuid\':\'" + a.uuid + "\',\'xuid\':\'" + a.xuid + "\',\'IPport\':\'" + p.IpPort + "\'}"; //string[] list = { a.playername, a.uuid, a.xuid }; var re = func.load_name(list); }); return(true); }); api.addBeforeActListener(EventKey.onPlayerLeft, x => { var a = BaseEvent.getFrom(x) as PlayerLeftEvent; uuid.Remove(a.playerPtr); ptr.Remove(a.uuid); CallPyFunc(PyFun, func => { string list = "{\'playername\':\'" + a.playername + "\',\'uuid\':\'" + a.uuid + "\',\'xuid\':\'" + a.xuid + "\'}"; var re = func.player_left(list); }); return(true); }); api.addBeforeActListener(EventKey.onServerCmd, x => { var a = BaseEvent.getFrom(x) as ServerCmdEvent; if (a.cmd.StartsWith("ipy ")) { string[] sArray = a.cmd.Split(new char[2] { ' ', ' ' }); if (sArray[1] == "info") { string msg = "窗体关闭,控制台已恢复"; MessageBox.Show("感谢使用IronPythonRunner\n作者:Sbaoor", "IronPythonRunner", MessageBoxButtons.OK, MessageBoxIcon.Information); Console.Write($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss} "); Console.Write("INFO]["); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write("IPYR"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("] " + msg); return(false); }
public static void RunCSharpLuaRunner(MCCSAPI api) { List <IntPtr> uuid = new List <IntPtr>(); const String path = "./cslr"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); Console.WriteLine("[INFO] [CSLR] 已创建文件夹"); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("[INFO] [CSLR] CSharpLuaRunner加载中"); var LuaFun = new List <dynamic>(); DirectoryInfo Allfolder = new DirectoryInfo(path); var mc = new MCLUAAPI(api); GC.KeepAlive(mc); var tool = new ToolFunc(); GC.KeepAlive(tool); foreach (FileInfo file in Allfolder.GetFiles("*.cs.lua")) { try { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("[INFO] [CSLR] 正在加载" + file.Name); // Console.WriteLine("[INFO] [CSLR] " + file.Name + "加载成功"); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[ERROR] [CSLR] " + e.Message); Console.WriteLine("[ERROR] [CSLR] 加载" + file.Name + "失败"); Console.ForegroundColor = ConsoleColor.White; } } api.addBeforeActListener(EventKey.onLoadName, x => { var a = BaseEvent.getFrom(x) as LoadNameEvent; uuid.Add(a.playerPtr); ptr.Add(a.uuid, a.playerPtr); CallLuaFunc(LuaFun, func => { CsPlayer p = new CsPlayer(api, a.playerPtr); string list = "{\'playername\':\'" + a.playername + "\',\'uuid\':\'" + a.uuid + "\',\'xuid\':\'" + a.xuid + "\',\'IPport\':\'" + p.IpPort + "\'}"; var re = func.load_name(list); }); return(true); }); api.addBeforeActListener(EventKey.onPlayerLeft, x => { var a = BaseEvent.getFrom(x) as PlayerLeftEvent; uuid.Remove(a.playerPtr); ptr.Remove(a.uuid); CallLuaFunc(LuaFun, func => { string list = "{\'playername\':\'" + a.playername + "\',\'uuid\':\'" + a.uuid + "\',\'xuid\':\'" + a.xuid + "\'}"; var re = func.player_left(list); }); return(true); }); api.addBeforeActListener(EventKey.onServerCmd, x => { var a = BaseEvent.getFrom(x) as ServerCmdEvent; if (a.cmd.StartsWith("cslr ")) { string[] sArray = a.cmd.Split(new char[2] { ' ', ' ' }); if (sArray[1] == "help") { Console.WriteLine("[INFO] [CSLR] help 使用帮助\n[INFO] [CSLR] info CSLR信息\n[INFO] [CSLR] list 插件列表\n[INFO] [CSLR] reload 重载插件\n[INFO] [CSLR] unload 卸载插件"); return(false); } if (sArray[1] == "info") { MessageBox.Show("感谢使用CSharpLuaRunner\n作者:SeaIceNX", "当前版本" + version, MessageBoxButtons.OK, MessageBoxIcon.Information); Console.Write("[INFO] [CSLR] 窗体关闭 控制台已恢复"); return(false); } if (sArray[1] == "list") { DirectoryInfo folder = new DirectoryInfo(path); int total = 0; Console.WriteLine("[INFO] [CSLR] 正在读取插件列表"); foreach (FileInfo file in Allfolder.GetFiles("*.cs.lua")) { Console.WriteLine(" - " + file.Name + " | ID: " + total); total += 1; } Console.WriteLine($"[INFO] [CSLR]共加载了{total}个插件"); return(false); } if (sArray[1] == "unload") { try { Console.WriteLine("[INFO] [CSLR] 正在卸载ID为" + sArray[2] + "的插件"); // Console.WriteLine("[INFO] [CSLR] 已卸载ID为" + sArray[2] + "的插件"); return(false); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[ERROR] [CSLR] " + e.Message); Console.ForegroundColor = ConsoleColor.White; } } if (sArray[1] == "reload") { LuaFun.Clear(); ShareDatas.Clear(); DirectoryInfo folder = new DirectoryInfo(path); foreach (FileInfo file in folder.GetFiles("*.cs.lua")) { try { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("[INFO] [CSLR] 正在加载" + file.Name); // Console.WriteLine("[INFO] [CSLR] " + file.Name + "加载成功"); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[ERROR] [CSLR] " + e.Message); Console.WriteLine("[ERROR] [CSLR] 加载" + file.Name + "失败"); Console.ForegroundColor = ConsoleColor.White; } } Console.WriteLine("[INFO] [CSLR] 重载成功"); return(false); } return(true); } else { var re = true; CallLuaFunc(LuaFun, func => { string list = $"{{\'cmd\':\' {a.cmd }\'}}"; re = func.server_command(list); }); return(re); } }); api.addBeforeActListener(EventKey.onEquippedArmor, x => { var a = BaseEvent.getFrom(x) as EquippedArmorEvent; CallLuaFunc(LuaFun, func => { string list = "{\'playername\':\'" + a.playername + "\',\'itemid\':\'" + a.itemid + "\',\'itemname\':\'" + a.itemname + "\',\'itemcount\':\'" + a.itemcount + "\',\'itemaux\':\'" + a.itemaux + "\',\'slot\':\'" + a.slot + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "]}"; var re = func.equippedarm(list); }); return(true); }); api.addBeforeActListener(EventKey.onAttack, x => { var a = BaseEvent.getFrom(x) as AttackEvent; var re = true; CallLuaFunc(LuaFun, func => { string list = "{\'actorname\':\'" + a.actorname + "\',\'dimensionid\':\'" + a.dimensionid + "\',\'playername\':\'" + a.playername + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "]}"; re = func.attack(list); }); return(re); }); api.addBeforeActListener(EventKey.onInputText, x => { var a = BaseEvent.getFrom(x) as InputTextEvent; var re = true; CallLuaFunc(LuaFun, func => { string list = "{\'msg\':\'" + a.msg + "\',\'dimensionid\':\'" + a.dimensionid + "\',\'uuid\':\'" + CsGetUuid(uuid, a.playername, api) + "\',\'playername\':\'" + a.playername + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "]}"; re = func.inputtext(list); }); return(re); }); api.addBeforeActListener(EventKey.onDestroyBlock, x => { var a = BaseEvent.getFrom(x) as DestroyBlockEvent; var re = true; string list = "{\'blockid\':\'" + a.blockid + "\',\'uuid\':\'" + CsGetUuid(uuid, a.playername, api) + "\',\'position\':[" + Convert.ToInt32(a.position.x) + "," + Convert.ToInt32(a.position.y) + "," + Convert.ToInt32(a.position.z) + "],\'blockname\':\'" + a.blockname + "\',\'dimensionid\':\'" + a.dimensionid + "\',\'playername\':\'" + a.playername + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "]}"; CallLuaFunc(LuaFun, func => { re = func.destroyblock(list); }); return(re); }); api.addBeforeActListener(EventKey.onMobDie, x => { var a = BaseEvent.getFrom(x) as MobDieEvent; var re = true; string list = "{\'mobname\':\'" + a.mobname + "\',\'mobtype\':\'" + a.mobtype + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "],\'srcname\':\'" + a.srcname + "\',\'dimensionid\':\'" + a.dimensionid + "\',\'playername\':\'" + a.playername + "\'}"; CallLuaFunc(LuaFun, func => { re = func.mobdie(list); }); return(true); }); api.addBeforeActListener(EventKey.onRespawn, x => { var a = BaseEvent.getFrom(x) as RespawnEvent; string list = "{\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "],\'dimensionid\':\'" + a.dimensionid + "\',\'playername\':\'" + a.playername + "\',\'uuid\':\'" + CsGetUuid(uuid, a.playername, api) + "\'}"; CallLuaFunc(LuaFun, func => { var re = func.respawn(list); }); return(true); }); api.addBeforeActListener(EventKey.onInputCommand, x => { var a = BaseEvent.getFrom(x) as InputCommandEvent; var re = true; string list = "{\'cmd\':\'" + a.cmd + "\',\'XYZ\':[" + Convert.ToInt32(a.XYZ.x) + "," + Convert.ToInt32(a.XYZ.y) + "," + Convert.ToInt32(a.XYZ.z) + "],\'dimensionid\':\'" + a.dimensionid + "\',\'playername\':\'" + a.playername + "\',\'uuid\':\'" + CsGetUuid(uuid, a.playername, api) + "\'}"; CallLuaFunc(LuaFun, func => { re = func.inputcommand(list); }); return(re); }); api.addBeforeActListener(EventKey.onFormSelect, x => { var a = BaseEvent.getFrom(x) as FormSelectEvent; string list = $"{{\'playername\':\'{a.playername}\',\'selected\':{a.selected},\'uuid\':\'{a.uuid}\',\'formid\':\'{a.formid}\'}}"; CallLuaFunc(LuaFun, func => { var re = func.formselect(list); }); return(true); }); api.addBeforeActListener(EventKey.onUseItem, x => { var a = BaseEvent.getFrom(x) as UseItemEvent; string list = $"{{\'playername\':\'{a.playername}\',\'itemid\':\'{a.itemid}\',\'itemaux\':\'{a.itemaux}\',\'itemname\':\'{a.itemname}\',\'XYZ\':[{a.XYZ.x},{a.XYZ.y},{a.XYZ.z}],\'postion\':[{a.position.x},{a.position.y},{a.position.z}],\'blockname\':\'{a.blockname}\',\'blockid\':\'{a.blockid}\'}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.useitem(list); }); return(re); }); api.addBeforeActListener(EventKey.onPlacedBlock, x => { var a = BaseEvent.getFrom(x) as PlacedBlockEvent; string list = $"{{\'playername\':\'{a.playername}\',\'blockid\':\'{a.blockid}\',\'blockname\':\'{a.blockname}\',\'XYZ\':[{a.XYZ.x},{a.XYZ.y},{a.XYZ.z}],\'postion\':[{a.position.x},{a.position.y},{a.position.z}],\'dimensionid\':\'{a.dimensionid}\'}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.placeblock(list); }); return(re); }); api.addBeforeActListener(EventKey.onLevelExplode, x => { var a = BaseEvent.getFrom(x) as LevelExplodeEvent; string list = $"{{\'explodepower\':\'{a.explodepower}\',\'blockid\':\'{a.blockid}\',\'blockname\':\'{a.blockname}\',\'entity\':\'{a.entity}\',\'entityid\':\'{a.entityid}\',\'dimensionid\':\'{a.dimensionid}\',\'postion\':[{a.position.x},{a.position.y},{a.position.z}]}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.levelexplode(list); }); return(re); }); api.addBeforeActListener(EventKey.onNpcCmd, x => { var a = BaseEvent.getFrom(x) as NpcCmdEvent; string list = $"{{\'npcname\':\'{a.npcname}\',\'actionid\':\'{a.actionid}\',\'actions\':\'{a.actions}\',\'dimensionid\':\'{a.dimensionid}\',\'entity\':\'{a.entity}\',\'entityid\':\'{a.entityid}\',\'postion\':[{a.position.x},{a.position.y},{a.position.z}]}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.npccmd(list); }); return(re); }); api.addBeforeActListener(EventKey.onBlockCmd, x => { var a = BaseEvent.getFrom(x) as BlockCmdEvent; string list = $"{{\'cmd\':\'{a.cmd}\',\'dimensionid\':\'{a.dimensionid}\',\'postion\':[{a.position.x},{a.position.y},{a.position.z}],\'type\':\'{a.type}\',\'tickdelay\':\'{a.tickdelay}\'}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.blockcmd(list); }); return(re); }); api.addBeforeActListener(EventKey.onPistonPush, x => { var a = BaseEvent.getFrom(x) as PistonPushEvent; var re = true; string list = $"{{\'targetposition\':[{a.targetposition.x},{a.targetposition.y},{a.targetposition.z}],\'blockid\':\'{a.blockid}\',\'blockname\':\'{ a.blockname }\',\'dimensionid\':\'{ a.dimensionid }\',\'targetblockid\':\'{a.targetblockid}\',\'targetblockname\':\'{a.targetblockname}}}"; CallLuaFunc(LuaFun, func => { re = func.pistonpush(list); }); return(re); }); api.addBeforeActListener(EventKey.onStartOpenChest, x => { var a = BaseEvent.getFrom(x) as StartOpenChestEvent; string list = $"{{\'playername\':\'{a.playername}\',\'blockid\':\'{a.blockid}\',\'blockname\':\'{a.blockname}\',\'XYZ\':[{a.XYZ.x},{a.XYZ.y},{a.XYZ.z}],\'postion\':[{a.position.x},{a.position.y},{a.position.z}],\'dimensionid\':\'{a.dimensionid}\'}}"; var re = true; CallLuaFunc(LuaFun, func => { re = func.openchest(list); }); return(re); }); api.addBeforeActListener(EventKey.onStopOpenChest, x => { var a = BaseEvent.getFrom(x) as StopOpenChestEvent; string list = $"{{\'playername\':\'{a.playername}\',\'blockid\':\'{a.blockid}\',\'blockname\':\'{a.blockname}\',\'XYZ\':[{a.XYZ.x},{a.XYZ.y},{a.XYZ.z}],\'postion\':[{a.position.x},{a.position.y},{a.position.z}],\'dimensionid\':\'{a.dimensionid}\'}}"; CallLuaFunc(LuaFun, func => { var re = func.closechest(list); }); return(true); }); api.addBeforeActListener(EventKey.onServerCmdOutput, x => { var a = BaseEvent.getFrom(x) as ServerCmdOutputEvent; var re = true; string list = $"{{\'output\':\'{a.output.Replace("\n", null).Replace("\'", "\\\'")}\'}}"; CallLuaFunc(LuaFun, func => { re = func.server_cmdoutput(list); }); return(re); }); }