/// <summary> /// Textractor创建线程事件 /// </summary> /// <param name="threadId"></param> /// <param name="processId"></param> /// <param name="address"></param> /// <param name="context"></param> /// <param name="subcontext"></param> /// <param name="name"></param> /// <param name="hookCode"></param> public void CreateThreadHandle(long threadId, uint processId, long address, long context, long subcontext, string name, string hookCode) { TextHookData data = new TextHookData() { GamePID = (int)processId, HookCode = hookCode, HookAddress = "" + address, MisakaHookCode = "【" + address + ":" + context + ":" + subcontext + "】", HookFunc = name }; //ThreadID_RenewNum_List.Add(threadId,0); ThreadID_HookDataInfo_List.Add(threadId, data); }
/// <summary> /// 智能处理来自Textrator的输出并返回一个TextHookData用于下一步处理(TextHookData可为空) /// 具体的含义参见TextHookData定义 /// </summary> /// <param name="OutputText">来自Textrator的输出</param> /// <returns></returns> private TextHookData DealTextratorOutput(string OutputText) { if (OutputText == "" || OutputText == null) { return(null); } string Info = GetMiddleString(OutputText, "[", "]", 0); if (Info == null) { return(null); } string[] Infores = Info.Split(':'); if (Infores.Length >= 7) { TextHookData thd = new TextHookData(); string content = OutputText.Replace("[" + Info + "] ", ""); //删除信息头部分 thd.GamePID = Infores[1]; //游戏/本体进程ID(为0一般代表Textrator本体进程ID) thd.HookFunc = Infores[5]; //方法名:Textrator注入游戏进程获得文本时的方法名(为 Console 时代表Textrator本体控制台输出;为 Clipboard 时代表从剪贴板获取的文本) thd.HookCode = Infores[6]; //特殊码:Textrator注入游戏进程获得文本时的方法的特殊码,是一个唯一值,可用于判断 thd.Data = content; //实际获取到的内容 thd.HookAddress = Infores[2]; //Hook入口地址:可用于以后卸载Hook thd.MisakaHookCode = "【" + Infores[2] + ":" + Infores[3] + ":" + Infores[4] + "】"; //【值1:值2:值3】见上方格式说明 return(thd); } else { return(null); } }
/// <summary> /// Textractor输出事件 /// </summary> /// <param name="threadid"></param> /// <param name="opdata"></param> public void OutputHandle(long threadid, string opdata) { opdata = opdata.Replace("\r\n", "").Replace("\n", ""); AddTextractorHistory(threadid + ":" + opdata); if (Pause == false) { TextHookData thData = ThreadID_HookDataInfo_List[threadid]; if (thData != null) { TextHookData data = thData; data.Data = opdata; if (data.HookFunc != "Console" && data.HookFunc != "Clipboard" && data.HookFunc != "") { //Hook入口选择窗口处理 //if (ThreadID_RenewNum_List[threadid] < 150) //{ if (TextractorFun_Index_List.ContainsKey(threadid) == true) { HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = TextractorFun_Index_List[threadid]; e.Data = data; HFSevent?.Invoke(this, e); } else { TextractorFun_Index_List.Add(threadid, listIndex); HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = listIndex; e.Data = data; HFSevent?.Invoke(this, e); listIndex++; } //ThreadID_RenewNum_List[threadid]++; //} //else { // DetachProcessByHookAddress(data.GamePID, data.HookAddress); //} //Hook入口重复确认窗口处理 if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode)) { if (TextractorFun_Re_Index_List.ContainsKey(threadid) == true) { HookSelectRecvEventArgs hsre = new HookSelectRecvEventArgs { Index = TextractorFun_Index_List[threadid], Data = data }; HFRSevent?.Invoke(this, hsre); } else { TextractorFun_Re_Index_List.Add(threadid, listIndex_Re); HookSelectRecvEventArgs hsre = new HookSelectRecvEventArgs { Index = listIndex_Re, Data = data }; HFRSevent?.Invoke(this, hsre); listIndex_Re++; } } //使用了边Hook边卸载的情况 //纠错:注意不能删misakacode不同的,因为地址可能相同,仅根据Hook特殊码来删就行了 if (DetachUnrelatedHookWhenDataRecv == true) { if (HookCodeList[0] != data.HookCode) { DetachUnrelatedHookAsync(data.GamePID, data.MisakaHookCode); } } //文本去重窗口处理&游戏翻译窗口处理 //如果IsNeedReChooseHook=false则说明没有多重处理,不用再对比HookCodePlus if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode) && (MisakaCodeList == null || MisakaCodeList.Contains(data.MisakaHookCode))) { SolvedDataRecvEventArgs sdre = new SolvedDataRecvEventArgs { Data = data }; Sevent?.Invoke(this, sdre); } } } } }
/// <summary> /// 控制台输出事件,在这做内部消化处理 /// </summary> /// <param name="sendingProcess"></param> /// <param name="outLine"></param> void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { AddTextractorHistory(outLine.Data); if (Pause == false) { TextHookData thData = DealTextratorOutput(outLine.Data); if (thData != null) { TextHookData data = thData; if (data.HookFunc != "Console" && data.HookFunc != "Clipboard" && data.HookFunc != "") { //Hook入口选择窗口处理 if (TextractorFun_Index_List.ContainsKey(data.MisakaHookCode) == true) { HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = TextractorFun_Index_List[data.MisakaHookCode]; e.Data = data; HFSevent?.Invoke(this, e); } else { TextractorFun_Index_List.Add(data.MisakaHookCode, listIndex); HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = TextractorFun_Index_List[data.MisakaHookCode]; e.Data = data; HFSevent?.Invoke(this, e); listIndex++; } //Hook入口重复确认窗口处理 if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode)) { if (TextractorFun_Re_Index_List.ContainsKey(data.MisakaHookCode) == true) { HookSelectRecvEventArgs e = new HookSelectRecvEventArgs { Index = TextractorFun_Index_List[data.MisakaHookCode], Data = data }; HFRSevent?.Invoke(this, e); } else { TextractorFun_Re_Index_List.Add(data.MisakaHookCode, listIndex_Re); HookSelectRecvEventArgs e = new HookSelectRecvEventArgs { Index = TextractorFun_Index_List[data.MisakaHookCode], Data = data }; HFRSevent?.Invoke(this, e); listIndex_Re++; } } //使用了边Hook边卸载的情况 //纠错:注意不能删misakacode不同的,因为地址可能相同,仅根据Hook特殊码来删就行了 if (DetachUnrelatedHookWhenDataRecv == true) { if (HookCodeList[0] != data.HookCode) { DetachUnrelatedHookAsync(int.Parse(data.GamePID, System.Globalization.NumberStyles.HexNumber), data.MisakaHookCode); } } //文本去重窗口处理&游戏翻译窗口处理 //如果IsNeedReChooseHook=false则说明没有多重处理,不用再对比HookCodePlus if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode) && (MisakaCodeList == null || MisakaCodeList.Contains(data.MisakaHookCode))) { SolvedDataRecvEventArgs e = new SolvedDataRecvEventArgs { Data = data }; Sevent?.Invoke(this, e); } } } } }
/// <summary> /// 控制台输出事件,在这做内部消化处理 /// </summary> /// <param name="sendingProcess"></param> /// <param name="outLine"></param> void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { AddTextractorHistory(outLine.Data); if (Pause == false) { TextHookData?thData = DealTextratorOutput(outLine.Data); if (thData != null) { TextHookData data = thData.Value; if (data.HookFunc != "Console" && data.HookFunc != "") { //Hook入口选择窗口处理 if (TextractorFun_Index_List.ContainsKey(data.MisakaHookCode) == true) { HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = TextractorFun_Index_List[data.MisakaHookCode]; e.Data = data; HFSevent(this, e); } else { TextractorFun_Index_List.Add(data.MisakaHookCode, listIndex); HookSelectRecvEventArgs e = new HookSelectRecvEventArgs(); e.Index = TextractorFun_Index_List[data.MisakaHookCode]; e.Data = data; HFSevent(this, e); listIndex++; } //Hook入口重复确认窗口处理 if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode)) { if (TextractorFun_Re_Index_List.ContainsKey(data.MisakaHookCode) == true) { HookSelectRecvEventArgs e = new HookSelectRecvEventArgs { Index = TextractorFun_Index_List[data.MisakaHookCode], Data = data }; HFRSevent(this, e); } else { TextractorFun_Re_Index_List.Add(data.MisakaHookCode, listIndex_Re); HookSelectRecvEventArgs e = new HookSelectRecvEventArgs { Index = TextractorFun_Index_List[data.MisakaHookCode], Data = data }; HFRSevent(this, e); listIndex_Re++; } } //文本去重窗口处理&游戏翻译窗口处理 //如果MisakaCodeList为空则说明没有多重处理,不用再对比HookCodePlus if (HookCodeList.Count != 0 && HookCodeList.Contains(data.HookCode) && (MisakaCodeList == null || MisakaCodeList.Contains(data.MisakaHookCode))) { SolvedDataRecvEventArgs e = new SolvedDataRecvEventArgs { Data = data }; Sevent(this, e); } } } } }