55using System . Linq ;
66using System . Runtime . InteropServices ;
77using System . Text ;
8+ using System . Text . RegularExpressions ;
89using System . Threading . Tasks ;
910using System . Windows . Forms ;
1011using GameAnalyticsSDK . Net ;
@@ -24,16 +25,16 @@ public enum CrashType {
2425
2526 public static class CrashReportHelper
2627 {
27- private const string TruncatedString = "------- TRUNCATED -------" ;
2828 private const int MaxInfologSize = 62000 ;
29+ private const string InfoLogLineStartPattern = @"(^\[t=\d+:\d+:\d+\.\d+\]\[f=-?\d+\] )" ;
30+ private const string InfoLogLineEndPattern = @"(\r?\n|\Z)" ;
2931 public static Issue ReportCrash ( string infolog , CrashType type , string engine , string bugReportTitle , string bugReportDescription )
3032 {
3133 try
3234 {
3335 var client = new GitHubClient ( new ProductHeaderValue ( "chobbyla" ) ) ;
3436 client . Credentials = new Credentials ( GlobalConst . CrashReportGithubToken ) ;
3537
36-
3738 infolog = Truncate ( infolog , MaxInfologSize ) ;
3839
3940 var createdIssue =
@@ -48,86 +49,47 @@ public static Issue ReportCrash(string infolog, CrashType type, string engine, s
4849 }
4950 return null ;
5051 }
51-
52- public static bool IsDesyncMessage ( string msg )
52+ public static int FindFirstDesyncMessage ( string logStr )
5353 {
54- return ! string . IsNullOrEmpty ( msg ) && msg . Contains ( " Sync error for " ) && msg . Contains ( " in frame " ) && msg . Contains ( " correct is " ) ;
54+ //[t=00:22:43.533864][f=0003461] Sync error for mankarse in frame 3451 (got 927a6f33, correct is 6b550dd1)
55+ try
56+ {
57+ //See ZkData.Account.IsValidLobbyName
58+ var accountNamePattern = @"[_[\]a-zA-Z0-9]{1,25}" ;
59+ var match =
60+ Regex . Match (
61+ logStr ,
62+ $@ "Sync error for(?<={ InfoLogLineStartPattern } Sync error for) { accountNamePattern } in frame \d+ \(got [a-z0-9]+, correct is [a-z0-9]+\){ InfoLogLineEndPattern } ",
63+ RegexOptions . CultureInvariant | RegexOptions . Compiled | RegexOptions . ExplicitCapture | RegexOptions . Multiline ,
64+ TimeSpan . FromSeconds ( 30 ) ) ;
65+
66+ return match . Success ? match . Index : - 1 ;
67+ }
68+ catch ( RegexMatchTimeoutException )
69+ {
70+ Trace . TraceError ( "[CrashReportHelper] RegexMatchTimeoutException in FindFirstDesyncMessage" ) ;
71+ return - 1 ;
72+ }
5573 }
5674
57-
5875 private static string Truncate ( string infolog , int maxSize )
5976 {
60- if ( infolog . Length > maxSize ) // truncate infolog in middle
61- {
62- var lines = infolog . Lines ( ) ;
63- var firstPart = new List < string > ( ) ;
64- var lastPart = new List < string > ( ) ;
65- int desyncFirst = - 1 ;
66-
67- for ( int a = 0 ; a < lines . Length ; a ++ )
68- if ( IsDesyncMessage ( lines [ a ] ) )
69- {
70- desyncFirst = a ;
71- break ;
72- }
73-
74- if ( desyncFirst != - 1 )
75- {
76- var sumSize = 0 ;
77- var firstIndex = desyncFirst ;
78- var lastIndex = desyncFirst + 1 ;
79- do
80- {
81- if ( firstIndex >= 0 )
82- {
83- firstPart . Add ( lines [ firstIndex ] ) ;
84- sumSize += lines [ firstIndex ] . Length ;
85- }
86- if ( lastIndex < lines . Length )
87- {
88- lastPart . Add ( lines [ lastIndex ] ) ;
89- sumSize += lines [ lastIndex ] . Length ;
90- }
77+ var firstDesync = FindFirstDesyncMessage ( infolog ) ;
78+ var regionsOfInterest = new List < TextTruncator . RegionOfInterest > ( firstDesync == - 1 ? 2 : 3 ) ;
9179
92- firstIndex -- ;
93- lastIndex ++ ;
94-
95- } while ( sumSize < MaxInfologSize && ( firstIndex > 0 || lastIndex < lines . Length ) ) ;
96- if ( lastIndex < lines . Length ) lastPart . Add ( TruncatedString ) ;
97- if ( firstIndex > 0 ) firstPart . Add ( TruncatedString ) ;
98- firstPart . Reverse ( ) ;
99- }
100- else
101- {
102-
103- var sumSize = 0 ;
104-
105- for ( int i = 0 ; i < lines . Length ; i ++ )
106- {
107- int index = i % 2 == 0 ? i / 2 : lines . Length - i / 2 - 1 ;
108- if ( sumSize + lines [ index ] . Length < maxSize )
109- {
110- if ( i % 2 == 0 ) firstPart . Add ( lines [ index ] ) ;
111- else lastPart . Add ( lines [ index ] ) ;
112- }
113- else
114- {
115- firstPart . Add ( TruncatedString ) ;
116- break ;
117- }
118- sumSize += lines [ index ] . Length ;
119- }
120- lastPart . Reverse ( ) ;
121- }
122-
123- infolog = string . Join ( "\r \n " , firstPart ) + "\r \n " + string . Join ( "\r \n " , lastPart ) ;
80+ regionsOfInterest . Add ( new TextTruncator . RegionOfInterest { PointOfInterest = 0 , StartLimit = 0 , EndLimit = infolog . Length } ) ;
81+ if ( firstDesync != - 1 )
82+ {
83+ regionsOfInterest . Add ( new TextTruncator . RegionOfInterest { PointOfInterest = firstDesync , StartLimit = 0 , EndLimit = infolog . Length } ) ;
12484 }
125- return infolog ;
85+ regionsOfInterest . Add ( new TextTruncator . RegionOfInterest { PointOfInterest = infolog . Length , StartLimit = 0 , EndLimit = infolog . Length } ) ;
86+
87+ return TextTruncator . Truncate ( infolog , maxSize , regionsOfInterest ) ;
12688 }
127-
89+
12890 public static void CheckAndReportErrors ( string logStr , bool springRunOk , string bugReportTitle , string bugReportDescription , string engineVersion )
12991 {
130- var syncError = CrashReportHelper . IsDesyncMessage ( logStr ) ;
92+ var syncError = FindFirstDesyncMessage ( logStr ) != - 1 ;
13193 if ( syncError ) Trace . TraceWarning ( "Sync error detected" ) ;
13294
13395 var openGlFail = logStr . Contains ( "No OpenGL drivers installed." ) ||
0 commit comments