@@ -29,76 +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 ( "$" ) )
50
- {
51
- if ( ! revision . Contains ( " 000 " ) )
52
- return revision . Substring ( 10 , revision . Length - 11 ) . Trim ( ) ;
53
- }
54
- else
55
- {
56
- return revision ;
57
- }
58
- }
59
- }
60
- catch
61
- {
62
- }
63
- return "" ;
64
- }
65
-
66
42
static string GetVersion ( string fileName )
67
43
{
68
44
try
69
45
{
70
- using ( var f = new StreamReader ( Path . Combine ( ApplicationPath , fileName ) ) )
71
- {
72
- var version = f . ReadLine ( ) . Trim ( ) ;
73
- if ( ! String . IsNullOrEmpty ( Revision ) )
74
- return version + "-" + Revision ;
75
- }
46
+ var version = FileVersionInfo . GetVersionInfo ( Path . Combine ( ApplicationPath , fileName ) ) ;
47
+ if ( version . ProductVersion != version . FileVersion )
48
+ return version . ProductVersion ;
76
49
}
77
50
catch
78
51
{
79
52
}
80
53
return "" ;
81
54
}
82
55
83
- static string GetBuild ( params string [ ] fileNames )
56
+ static string GetBuild ( string fileName )
84
57
{
85
58
var builds = new Dictionary < TimeSpan , string > ( ) ;
86
- foreach ( var fileName in fileNames )
59
+ try
87
60
{
88
- try
89
- {
90
- var version = FileVersionInfo . GetVersionInfo ( Path . Combine ( ApplicationPath , fileName ) ) ;
91
- builds . Add ( new TimeSpan ( version . ProductBuildPart , 0 , 0 , version . ProductPrivatePart * 2 ) , version . ProductVersion ) ;
92
- }
93
- catch
94
- {
95
- }
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 ) ;
96
65
}
97
- if ( builds . Count > 0 )
66
+ catch
98
67
{
99
- var datetime = new DateTime ( 2000 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
100
- var timespan = builds . Keys . OrderBy ( ts => ts ) . Last ( ) ;
101
- return String . Format ( "{0} ({1:u})" , builds [ timespan ] , datetime + timespan ) ;
102
68
}
103
69
return "" ;
104
70
}
@@ -109,70 +75,62 @@ static string GetVersionOrBuild()
109
75
}
110
76
111
77
/// <summary>
112
- /// 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
113
79
/// </summary>
114
- /// <param name="version">version to test again </param>
115
- /// <param name="build">build to test again </param>
116
- /// <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>
117
83
/// <returns>true or false when able to determine validity, null otherwise</returns>
118
- public static bool ? GetValidity ( string version , string build , int youngestFailedToResume )
84
+ public static bool ? GetValidity ( string version , string build , string youngestVersionFailedToRestore )
119
85
{
120
- int revision = GetRevisionFromVersion ( version ) ;
121
- int programRevision = 0 ;
122
- try // as Convert.ToInt32() can fail and version may be ""
123
- {
124
- programRevision = Convert . ToInt32 ( VersionInfo . Revision ) ;
125
- }
126
- catch { } // ignore errors
127
- //MessageBox.Show(String.Format("VersionInfo.Build = {0}, build = {1}, version = {2}, youngestFailedToResume = {3}", VersionInfo.Build, build, Version, youngestFailedToResume));
128
- if ( revision != 0 ) // compiled remotely by Open Rails
129
- {
130
- if ( revision == programRevision )
131
- {
132
- return true ;
133
- }
134
- else
135
- {
136
- if ( revision > youngestFailedToResume // 1. Normal situation
137
- || programRevision < youngestFailedToResume ) // 2. If an old version of OR is used, then attempt to load Saves
138
- // which would be blocked by the current version of OR
139
- {
140
- return null ;
141
- }
142
- }
143
- }
144
- else // compiled locally
145
- {
146
- if ( build . EndsWith ( VersionInfo . Build ) )
147
- {
148
- return true ;
149
- }
150
- else
151
- {
152
- return null ;
153
- }
154
- }
155
- 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 ;
156
103
}
157
104
158
105
/// <summary>
159
- /// 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
160
107
/// </summary>
161
- /// <param name="version">full version</param>
162
- public static int GetRevisionFromVersion ( string fullVersion )
108
+ /// <param name="version">text version to parse </param>
109
+ public static Version ParseVersion ( string version )
163
110
{
164
- var versionParts = fullVersion . Split ( '.' ) ;
165
- var revision = 0 ;
166
- try
167
- {
168
- var version = versionParts [ versionParts . Length - 1 ] ;
169
- if ( version . StartsWith ( "X" ) )
170
- version = version . Substring ( 1 ) ;
171
- // Might throw an error if it isn't a number like we expect.
172
- revision = Convert . ToInt32 ( version ) ;
173
- }
174
- catch { }
175
- 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 ) ;
176
134
}
177
135
}
178
136
}
0 commit comments