@@ -29,69 +29,42 @@ namespace ORTS.Common
29
29
public static class VersionInfo
30
30
{
31
31
static readonly string ApplicationPath = Path . GetDirectoryName ( Process . GetCurrentProcess ( ) . MainModule . FileName ) ;
32
- // GetRevision() must come before GetVersion()
33
- /// <summary>Revision number , e.g. Release : "1648 ", experimental : "1649 ", local: ""</summary>
34
- public static readonly string Revision = GetRevision ( "Revision.txt ") ;
35
- /// <summary>Full version number, e.g. Release: "0.9.0.1648", experimental: "X.1649", local: ""</summary>
36
- public static readonly string Version = GetVersion ( "Version.txt" ) ;
37
- /// <summary>Full build number, e.g. "0.0.5223.24629 (2014-04-20 13:40:58Z)"</summary>
38
- public static readonly string Build = GetBuild ( "ORTS.Common.dll" , "OpenRails.exe" , "Menu.exe" , "RunActivity.exe" ) ;
32
+
33
+ /// <summary>Full version , e.g. stable : "1.4 ", testing : "T1.4-1-g1234567 ", unstable: "U2021.01.01-0000", local: ""</summary>
34
+ public static readonly string Version = GetVersion ( "OpenRails.exe ") ;
35
+
36
+ /// <summary>Full build, e.g. "0.0.5223.24629 (2014-04-20 13:40:58Z)"</summary>
37
+ public static readonly string Build = GetBuild ( "OpenRails.exe" ) ;
38
+
39
39
/// <summary>Version, but if "", returns Build</summary>
40
40
public static readonly string VersionOrBuild = GetVersionOrBuild ( ) ;
41
41
42
- static string GetRevision ( string fileName )
43
- {
44
- try
45
- {
46
- using ( var f = new StreamReader ( Path . Combine ( ApplicationPath , fileName ) ) )
47
- {
48
- var revision = f . ReadLine ( ) . Trim ( ) ;
49
- if ( revision . StartsWith ( "$Revision:" ) && revision . EndsWith ( "$" ) && ! revision . Contains ( " 000 " ) )
50
- return revision . Substring ( 10 , revision . Length - 11 ) . Trim ( ) ;
51
- }
52
- }
53
- catch
54
- {
55
- }
56
- return "" ;
57
- }
58
-
59
42
static string GetVersion ( string fileName )
60
43
{
61
44
try
62
45
{
63
- using ( var f = new StreamReader ( Path . Combine ( ApplicationPath , fileName ) ) )
64
- {
65
- var version = f . ReadLine ( ) . Trim ( ) ;
66
- if ( ! String . IsNullOrEmpty ( Revision ) )
67
- return version + Revision ;
68
- }
46
+ var version = FileVersionInfo . GetVersionInfo ( Path . Combine ( ApplicationPath , fileName ) ) ;
47
+ if ( version . ProductVersion != version . FileVersion )
48
+ return version . ProductVersion ;
69
49
}
70
50
catch
71
51
{
72
52
}
73
53
return "" ;
74
54
}
75
55
76
- static string GetBuild ( params string [ ] fileNames )
56
+ static string GetBuild ( string fileName )
77
57
{
78
58
var builds = new Dictionary < TimeSpan , string > ( ) ;
79
- foreach ( var fileName in fileNames )
59
+ try
80
60
{
81
- try
82
- {
83
- var version = FileVersionInfo . GetVersionInfo ( Path . Combine ( ApplicationPath , fileName ) ) ;
84
- builds . Add ( new TimeSpan ( version . ProductBuildPart , 0 , 0 , version . ProductPrivatePart * 2 ) , version . ProductVersion ) ;
85
- }
86
- catch
87
- {
88
- }
61
+ var version = FileVersionInfo . GetVersionInfo ( Path . Combine ( ApplicationPath , fileName ) ) ;
62
+ var datetime = new DateTime ( 2000 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
63
+ var timespan = new TimeSpan ( version . FileBuildPart , 0 , 0 , version . FilePrivatePart * 2 ) ;
64
+ return String . Format ( "{0} ({1:u})" , version . FileVersion , datetime + timespan ) ;
89
65
}
90
- if ( builds . Count > 0 )
66
+ catch
91
67
{
92
- var datetime = new DateTime ( 2000 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
93
- var timespan = builds . Keys . OrderBy ( ts => ts ) . Last ( ) ;
94
- return String . Format ( "{0} ({1:u})" , builds [ timespan ] , datetime + timespan ) ;
95
68
}
96
69
return "" ;
97
70
}
@@ -102,70 +75,62 @@ static string GetVersionOrBuild()
102
75
}
103
76
104
77
/// <summary>
105
- /// Find whether a requested version and build are valid for this build
78
+ /// Compares a version and build with the youngest version which failed to restore, to see if that version/ build is likely to restore successfully
106
79
/// </summary>
107
- /// <param name="version">version to test again </param>
108
- /// <param name="build">build to test again </param>
109
- /// <param name="youngestFailedToResume ">youngest build that failed to resume </param>
80
+ /// <param name="version">version to test</param>
81
+ /// <param name="build">build to test</param>
82
+ /// <param name="youngestVersionFailedToRestore ">youngest version that failed to restore </param>
110
83
/// <returns>true or false when able to determine validity, null otherwise</returns>
111
- public static bool ? GetValidity ( string version , string build , int youngestFailedToResume )
84
+ public static bool ? GetValidity ( string version , string build , string youngestVersionFailedToRestore )
112
85
{
113
- int revision = GetRevisionFromVersion ( version ) ;
114
- int programRevision = 0 ;
115
- try // as Convert.ToInt32() can fail and version may be ""
116
- {
117
- programRevision = Convert . ToInt32 ( VersionInfo . Revision ) ;
118
- }
119
- catch { } // ignore errors
120
- //MessageBox.Show(String.Format("VersionInfo.Build = {0}, build = {1}, version = {2}, youngestFailedToResume = {3}", VersionInfo.Build, build, Version, youngestFailedToResume));
121
- if ( revision != 0 ) // compiled remotely by Open Rails
122
- {
123
- if ( revision == programRevision )
124
- {
125
- return true ;
126
- }
127
- else
128
- {
129
- if ( revision > youngestFailedToResume // 1. Normal situation
130
- || programRevision < youngestFailedToResume ) // 2. If an old version of OR is used, then attempt to load Saves
131
- // which would be blocked by the current version of OR
132
- {
133
- return null ;
134
- }
135
- }
136
- }
137
- else // compiled locally
138
- {
139
- if ( build . EndsWith ( VersionInfo . Build ) )
140
- {
141
- return true ;
142
- }
143
- else
144
- {
145
- return null ;
146
- }
147
- }
148
- return false ; // default validity
86
+ // Validity rules:
87
+ // - Same version and build --> yes
88
+ // - Same non-empty version --> yes
89
+ // - Unable to parse save or program version --> maybe
90
+ // - Save version > setting --> maybe
91
+ // - Program version < setting --> maybe
92
+ // - Default --> no
93
+
94
+ if ( Version == version && Build == build ) return true ;
95
+ if ( Version . Length > 0 && version . Length > 0 && Version == version ) return true ;
96
+ var saveVersion = ParseVersion ( version ) ;
97
+ var programVersion = ParseVersion ( Version ) ;
98
+ var settingVersion = ParseVersion ( youngestVersionFailedToRestore ) ;
99
+ if ( saveVersion . Major == 0 || programVersion . Major == 0 ) return null ;
100
+ if ( saveVersion > settingVersion ) return null ;
101
+ if ( programVersion < settingVersion ) return null ;
102
+ return false ;
149
103
}
150
104
151
105
/// <summary>
152
- /// Find the revision number (e.g. 1648) from the full version (e.g. 0.9.0.1648 or X.1648 or X1648)
106
+ /// Converts many possible Open Rails versions into a standard Version struct
153
107
/// </summary>
154
- /// <param name="version">full version</param>
155
- public static int GetRevisionFromVersion ( string fullVersion )
108
+ /// <param name="version">text version to parse </param>
109
+ public static Version ParseVersion ( string version )
156
110
{
157
- var versionParts = fullVersion . Split ( '.' ) ;
158
- var revision = 0 ;
159
- try
160
- {
161
- var version = versionParts [ versionParts . Length - 1 ] ;
162
- if ( version . StartsWith ( "X" ) )
163
- version = version . Substring ( 1 ) ;
164
- // Might throw an error if it isn't a number like we expect.
165
- revision = Convert . ToInt32 ( version ) ;
166
- }
167
- catch { }
168
- return revision ;
111
+ // Version numbers which we do parse:
112
+ // - 0.9.0.1648 --> 0.9
113
+ // - 1.3.1.4328 --> 1.3.1
114
+ // - T1.3.1-241-g6ff150c21 --> 1.3.1.241
115
+ // - X1.3.1-370-g7df5318c2 --> 1.3.1.370
116
+ // - 1.4 --> 1.4
117
+ // - 1.4-rc1 --> 1.4
118
+ // - T1.4-2-g7db094316 --> 1.4.0.2
119
+ // Version numbers which we do NOT parse:
120
+ // - U2019.07.25-2200
121
+ // - U2021.06.25-0406
122
+ // - X.1648
123
+ // - X1648
124
+
125
+ if ( version . StartsWith ( "T" ) || version . StartsWith ( "X" ) ) version = version . Substring ( 1 ) ;
126
+
127
+ var versionParts = version . Split ( '-' ) ;
128
+ if ( ! System . Version . TryParse ( versionParts [ 0 ] , out var parsedVersion ) ) return new Version ( ) ;
129
+
130
+ var commits = 0 ;
131
+ if ( versionParts . Length > 1 ) int . TryParse ( versionParts [ 1 ] , out commits ) ;
132
+ // parsedVersion.Build will be -1 if the version only has major and minor, but we need the build number >= 0 here
133
+ return new Version ( parsedVersion . Major , parsedVersion . Minor , Math . Max ( 0 , parsedVersion . Build ) , commits ) ;
169
134
}
170
135
}
171
136
}
0 commit comments