Ejemplo n.º 1
0
    private static void GenerateLogPdb()
    {
        //搜索指定目录,得到所有匹配文件路径
        string[] subPaths = SearchFiles.SearchAllFilesWithSpecifiedSuffixs(baseDir, searchPath, ".cs,.lua");
        //新建LogPdb映射
        LogTrackPdbFile pdb = new LogTrackPdbFile();

        //处理所有子文件
        foreach (var subPath in subPaths)
        {
            //剔除所有屏蔽文件
            bool ignoreSign = false;
            foreach (var ignorePath in ignorePaths)
            {
                if (subPath == ignorePath)
                {
                    ignoreSign = true;
                    break;
                }
            }
            if (ignoreSign == false)
            {
                //编码手动插入的代码
                HashLogTrackCode(baseDir, subPath, pdb);
            }
        }
        //生成新LogPdb
        pdb.CreateLogPdb(newLogPdbFolderPath + "/newLogPdb.json");
    }
Ejemplo n.º 2
0
    //编码手动插入的代码
    private static void HashLogTrackCode(string baseDir, string subPath, LogTrackPdbFile pdb)
    {
        #region 正则表达式拆分
        //第1组,匹配权限标识符
        string identifier = @"(public|private|protected)*";
        //第2,3,4组,匹配修饰符(括号从左往右顺序)
        string qualifier = @"((\s+(static|override|virtual)*\s+)|\s+)";
        //第5组,匹配返回值中的泛型(注意,因为有逗号,所以不支持多个返回值,即元组)
        string genericity = @"\w+(<\w+>)*";
        //第6组,匹配返回值中的数组标记
        string arraySign = @"(\[\])*\s+";
        //第7组,匹配函数名和泛型(格式同第5组)
        //第8组,匹配函数参数列表
        string paramList = @"\s*\(([^\)]+\s*)?\)";
        //标记函数体第1个左大括号及后面的内容,直到遇到第2个左大括号
        string leftBraceAndContent = @"\s*\{[^\{\}]*";
        //第9,10,11,12,13组,以成对的方式匹配从第2个左大括号起的所有相应的右大括号,直到第2个左大括号被匹配掉
        //第11组,平衡组,匹配第2个左大括号
        //第10组,包含第11组,额外匹配第2个左大括号后的非{}字符
        //第13组,反平衡组,匹配第1个右大括号
        //第12组,包含第13组,额外匹配第1个右大括号后的非{}字符
        //第9组,包含第10,11,12,13组,匹配除第1对外的成对括号对
        string mainText = @"(((?'Open'\{)[^\{\}]*)+((?'-Open'\})[^\{\}]*)+)*";
        //第14,15,16组,检测括号不成对的情况,还有没匹配掉的Open标签则匹配失败,随后匹配掉最后一个右大括号
        string check = @"(?(Open)(?!))\}";
        #endregion
        //重置需要写入标记
        bool hasChanged = false;
        var  fullPath   = baseDir + subPath;
        if (!File.Exists(fullPath))
        {
            return;
        }
        var text = File.ReadAllText(fullPath);
        //识别类
        Regex regexClassAll = new Regex(identifier + qualifier + @"class\s+\w+" + leftBraceAndContent + mainText + check);
        //识别类名
        Regex regexClassName = new Regex(@"(?<=class\s+)\w+(?=[\s\n]*{)");
        //识别函数体
        Regex regexFuncAll = new Regex(identifier + qualifier + genericity + arraySign + genericity + paramList + leftBraceAndContent + mainText + check);
        //识别函数头
        Regex regexFuncHead = new Regex(identifier + qualifier + genericity + arraySign + genericity + paramList);
        //识别函数名,左侧有空格,右侧有左括号或<>加左括号)
        Regex regexFuncName = new Regex(@"(?<=\s+)\w+?(?=\(|<\w*>\()");
        //识别左大括号
        Regex regexLeftBrace = new Regex(@"\{");
        //识别日志代码
        Regex regexLogTrackCode = new Regex(@"FSPDebuger\.LogTrack.*((;)|(\*/))");
        //识别日志代码(提取/**/间的输出内容)
        //Regex regexLogTrackCodeBetweenStars = new Regex(@"(?<=/\*)[^/\*]+(?=\*/)");
        Regex regexLogTrackCodeBetweenStars = new Regex(@"(?<=/\*).*(?=\*/)");
        //识别日志代码(提取+号)
        Regex regexLogTrackCodePlus = new Regex(@"\+");
        //识别日志代码(提取逗号)
        Regex regexLogTrackCodeComma = new Regex(@",");
        //识别日志代码(提取""间的输出内容)
        //Regex regexLogTrackCodeBetweenDoubleQuotation = new Regex(@"(?<="")[^""]+(?="")");
        Regex regexLogTrackCodeBetweenDoubleQuotation = new Regex(@"(?<="").*(?="")");

        //识别日志ID
        Regex regexLogHash = new Regex(@"(?<=\(.*?)\d+?(?=\s*[,\)])");

        //获取所有类
        var matchesClassAll = regexClassAll.Matches(text);
        //逐个类操作(至少要有一个类)
        for (int i = matchesClassAll.Count - 1; i >= 0; i--)
        {
            //获取类名
            var matchClassName = regexClassName.Match(text, matchesClassAll[i].Index, matchesClassAll[i].Length);
            //获取该类下的所有函数
            var matchesFuncAll = regexFuncAll.Matches(matchesClassAll[i].Value);
            //逐个函数操作
            for (int j = matchesFuncAll.Count - 1; j >= 0; j--)
            {
                //获取函数头
                var matchFuncHead = regexFuncHead.Match(text, matchesClassAll[i].Index + matchesFuncAll[j].Index, matchesFuncAll[j].Length);
                //获取函数名
                var matchFuncName = regexFuncName.Match(text, matchFuncHead.Index, matchFuncHead.Length);
                //匹配左大括号
                var matchLeftBrace = regexLeftBrace.Match(text, matchesClassAll[i].Index + matchesFuncAll[j].Index, matchesFuncAll[j].Length);
                //没找到左大括号,函数不完整,不打印日志
                if (matchLeftBrace.Success)
                {
                    //获取该函数下对应的日志代码
                    var matchesLogTrackCode = regexLogTrackCode.Matches(matchesFuncAll[j].Value);
                    //逐条日志代码操作
                    for (int k = matchesLogTrackCode.Count - 1; k >= 0; k--)
                    {
                        hasChanged = true;
                        //获取所有+号(输出内容中不能有+号和逗号)
                        var matchesLogTrackCodePlus = regexLogTrackCodePlus.Matches(matchesLogTrackCode[k].Value);
                        //逐个+号操作(+号操作完后不会影响Index,因为逗号也是1位,因此可以把插入/**/的操作放后面)
                        for (int m = matchesLogTrackCodePlus.Count - 1; m >= 0; m--)
                        {
                            //移除+号
                            text = text.Remove(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchesLogTrackCodePlus[m].Index, 1);
                            //插入逗号
                            text = text.Insert(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchesLogTrackCodePlus[m].Index, ",");
                        }
                        //获取参数个数
                        int argsCount = matchesLogTrackCodePlus.Count;
                        //获取双引号间的输出内容
                        var matchLogTrackCodeBetweenDoubleQuotation = regexLogTrackCodeBetweenDoubleQuotation.Match(matchesLogTrackCode[k].Value);
                        //若双引号间无输出内容,说明是之前编码的日志代码,从/**/间寻找
                        if (matchLogTrackCodeBetweenDoubleQuotation.Success == false)
                        {
                            var matchLogTrackCodeBetweenStars = regexLogTrackCodeBetweenStars.Match(matchesLogTrackCode[k].Value);
                            //找到就提取输出内容
                            if (matchLogTrackCodeBetweenStars.Success == true)
                            {
                                //更新参数个数为逗号的个数
                                var matchesLogTrackCodeComma = regexLogTrackCodeComma.Matches(matchesLogTrackCode[k].Value);
                                argsCount = matchesLogTrackCodeComma.Count;
                                //构建条目并添加到LogPdb,并获取合法ID
                                ushort validID = pdb.AddItem(subPath, matchClassName.Value, matchFuncName.Value, matchLogTrackCodeBetweenStars.Value, argsCount);
                                //匹配日志ID
                                var matchLogHash = regexLogHash.Match(matchesLogTrackCode[k].Value);
                                //移除原ID
                                text = text.Remove(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchLogHash.Index, matchLogHash.Value.Length);
                                //插入新ID
                                text = text.Insert(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchLogHash.Index, validID.ToString());
                            }
                        }
                        //否则是新添加的日志代码,提取输出内容,在日志末尾创建/**/并放入其中
                        else
                        {
                            //必须/**/匹配不到才插入
                            if (regexLogTrackCodeBetweenStars.IsMatch(matchesLogTrackCode[k].Value) == false)
                            {
                                //插入输出内容到/**/
                                text = text.Insert(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchesLogTrackCode[k].Length, "/*" + matchLogTrackCodeBetweenDoubleQuotation.Value + "*/");
                                //构建条目并添加到LogPdb,并获取合法ID
                                ushort validID = pdb.AddItem(subPath, matchClassName.Value, matchFuncName.Value, matchLogTrackCodeBetweenDoubleQuotation.Value, argsCount);
                                //移除双引号中的输出内容
                                text = text.Remove(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchLogTrackCodeBetweenDoubleQuotation.Index - 1, matchLogTrackCodeBetweenDoubleQuotation.Value.Length + 2);
                                //添加ID实现替换
                                text = text.Insert(matchesClassAll[i].Index + matchesFuncAll[j].Index + matchesLogTrackCode[k].Index + matchLogTrackCodeBetweenDoubleQuotation.Index - 1, validID.ToString());
                            }
                        }
                    }
                }
            }
            //所有函数处理完后,若有手动插入的代码,需重新写入文件
            if (hasChanged)
            {
                File.WriteAllText(baseDir + subPath, text);
            }
        }
    }