Skip to content

Commit 71cf169

Browse files
committed
Merge pull request #457 from asarium/feature/versionCheck
Add "$Minimum version" to game settings table
2 parents 184a583 + 0bb6002 commit 71cf169

File tree

4 files changed

+131
-155
lines changed

4 files changed

+131
-155
lines changed

code/globalincs/version.cpp

Lines changed: 73 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -7,126 +7,85 @@
77
*
88
*/
99

10-
11-
12-
#include <stdio.h>
13-
#include <string.h>
1410
#include "globalincs/pstypes.h"
1511
#include "globalincs/version.h"
16-
#include "osapi/osregistry.h"
17-
18-
19-
// ----------------------------------------------------------------------------------------------------------------
20-
// VERSION DEFINES/VARS
21-
//
22-
23-
// Defines
24-
// NB: for compatibility reasons, this must not include the SVN revision
25-
#define VER(major, minor, build) (100*100*major+100*minor+build)
26-
#define MAX_LINE_LENGTH 512
27-
28-
29-
// ----------------------------------------------------------------------------------------------------------------
30-
// VERSION FUNCTIONS
31-
//
32-
33-
// compare version against the passed version file
34-
// returns -1 on error
35-
// 0 if we are an earlier version
36-
// 1 if same version
37-
// 2 if higher version
38-
// fills in user version and latest version values if non-NULL
39-
//
40-
// NB: since this function is only used for multiplayer (in multi_update.cpp - and actually commented out), and since multiplayer
41-
// doesn't care about SVN revisions, this function doesn't need to check the SVN revision
42-
int version_compare(char *filename, int *u_major, int *u_minor, int *u_build, int *l_major, int *l_minor, int *l_build)
43-
{
44-
int usr_major, usr_minor, usr_build;
45-
int latest_major, latest_minor, latest_build;
46-
47-
// open file and try backup, if needed
48-
FILE *f = fopen(filename, "rt");
49-
if (f == NULL) {
50-
return -1;
51-
}
5212

53-
// grab the last line in file which isn't empty and isn't a comment
54-
char buffer[MAX_LINE_LENGTH+1] = {0};
55-
char verbuffer[MAX_LINE_LENGTH+1] = {0};
13+
#include <sstream>
5614

57-
while ( !feof(f) ) {
58-
// Read the line into a temporary buffer or break if there is nothing
59-
if (fgets(buffer, MAX_LINE_LENGTH, f) == nullptr) {
60-
break;
15+
namespace version
16+
{
17+
bool check_at_least(int major, int minor, int build, int revision)
18+
{
19+
if (FS_VERSION_MAJOR < major)
20+
{
21+
return false;
6122
}
62-
63-
// take the \n off the end of it
64-
if (buffer[0] != '\0' && buffer[strlen(buffer) - 1] == '\n')
65-
buffer[strlen(buffer) - 1] = 0;
66-
67-
// If the line is empty, go get another one
68-
if (buffer[0] == '\0') continue;
69-
70-
// If the line is a comment, go get another one
71-
if (buffer[0] == VERSION_FILE_COMMENT_CHAR) continue;
72-
73-
// Line is a good one, so save it...
74-
strcpy_s(verbuffer, buffer);
75-
}
76-
fclose(f);
77-
78-
// Make sure a version line was found
79-
if (verbuffer[0] == '\0') {
80-
// MessageBox(XSTR("Couldn't parse Version file!", 1205), XSTR("Error!", 1185), MB_OK|MB_ICONERROR);
81-
return -1;
82-
}
83-
84-
// Get the most up to date Version number
85-
latest_major = 0;
86-
latest_minor = 0;
87-
latest_build = 0;
88-
89-
if (sscanf(verbuffer, "%i %i %i", &latest_major, &latest_minor, &latest_build) != 3) {
90-
// MessageBox(XSTR("Couldn't parse Version file!", 1205), XSTR("Error!", 1185), MB_OK|MB_ICONERROR);
91-
return -1;
23+
if (FS_VERSION_MAJOR > major)
24+
{
25+
// Major is greater than the given version => the rest doesn't matter
26+
return true;
27+
}
28+
// major is now equal to our major version
29+
30+
if (FS_VERSION_MINOR < minor)
31+
{
32+
return false;
33+
}
34+
if (FS_VERSION_MINOR > minor)
35+
{
36+
// Minor is greater than the given version => the rest doesn't matter
37+
return true;
38+
}
39+
// minor is now equal to our minor version
40+
41+
if (FS_VERSION_BUILD < build)
42+
{
43+
return false;
44+
}
45+
if (FS_VERSION_BUILD > build)
46+
{
47+
// build is greater than the given version => the rest doesn't matter
48+
return true;
49+
}
50+
// build is now equal to our build version
51+
52+
if (revision == 0)
53+
{
54+
// Special case, if there is no revision info, skip it
55+
return true;
56+
}
57+
if (FS_VERSION_REVIS == 0)
58+
{
59+
// Special case, when there is no revision ignore it
60+
return true;
61+
}
62+
63+
if (FS_VERSION_REVIS < revision)
64+
{
65+
return false;
66+
}
67+
if (FS_VERSION_REVIS > revision)
68+
{
69+
// build is greater than the given version => the rest doesn't matter
70+
return true;
71+
}
72+
73+
// revision is now equal to our revision version
74+
return true;
9275
}
93-
94-
// retrieve the user's current version
95-
usr_major = os_config_read_uint("Version", "Major", 0);
96-
usr_minor = os_config_read_uint("Version", "Minor", 0);
97-
usr_build = os_config_read_uint("Version", "Build", 0);
9876

99-
// Make sure the user's Version was found!
100-
if ( VER(usr_major, usr_minor, usr_build) == 0 ) {
101-
// MessageBox(XSTR("The FreeSpace 2 Auto-Update program could not find your current game Version in the system registry.\n\nThis should be corrected by starting up the game, exiting the game, and then running the Auto-Update program.", 1206), XSTR("Unable to Determine User's Version", 1207), MB_OK|MB_ICONERROR);
102-
return NO_VERSION_IN_REGISTRY;
103-
}
104-
105-
// stuff outgoing values
106-
if(u_major != NULL){
107-
*u_major = usr_major;
108-
}
109-
if(u_minor != NULL){
110-
*u_minor = usr_minor;
111-
}
112-
if(u_build != NULL){
113-
*u_build = usr_build;
114-
}
115-
if(l_major != NULL){
116-
*l_major = latest_major;
117-
}
118-
if(l_minor != NULL){
119-
*l_minor = latest_minor;
120-
}
121-
if(l_build != NULL){
122-
*l_build = latest_build;
123-
}
124-
125-
// check to see if the user's version is up to date
126-
if (VER(usr_major, usr_minor, usr_build) < VER(latest_major, latest_minor, latest_build)) {
127-
return 0;
77+
SCP_string format_version(int major, int minor, int build, int revision)
78+
{
79+
SCP_stringstream ss;
80+
81+
ss << major << "." << minor << "." << build;
82+
83+
if (revision != 0)
84+
{
85+
ss << "." << revision;
86+
}
87+
88+
return ss.str();
12889
}
129-
130-
// same version
131-
return 1;
13290
}
91+

code/globalincs/version.h

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#ifndef __FS2_VERSIONING_HEADER_FILE
1313
#define __FS2_VERSIONING_HEADER_FILE
1414

15+
#include "globalincs/vmallocator.h"
16+
1517
// ----------------------------------------------------------------------------------------------------------------
1618
// VERSION DEFINES/VARS
1719
//
@@ -38,25 +40,29 @@
3840
#define FS_VERSION_REVIS 000000 // SVN revision
3941
//#define FS_VERSION_IDENT NOX("custom") // special build release identifier, must be a string (don't define unless it's supposed to be used!!)
4042

41-
#define VERSION_LOC_FNAME "version.nfo"
42-
#define MOTD_LOC_FNAME "motd.txt"
43-
44-
#define MOTD_URL "http://www.pxo.net/files/fs2/motd.txt"
45-
#define VERSION_URL "http://www.pxo.net/files/fs2/version.nfo"
46-
47-
#define VERSION_FILE_COMMENT_CHAR ';'
48-
#define NO_VERSION_IN_REGISTRY -2
49-
50-
// ----------------------------------------------------------------------------------------------------------------
51-
// VERSION FUNCTIONS
52-
//
53-
54-
// compare version against the passed version file
55-
// returns -1 on error
56-
// 0 if we are an earlier version
57-
// 1 if same version
58-
// 2 if higher version
59-
// fills in user version and latest version values if non-NULL
60-
int version_compare(char *filename, int *u_major, int *u_minor, int *u_build, int *l_major, int *l_minor, int *l_build);
43+
namespace version
44+
{
45+
/**
46+
* @brief Checks if the current version is at least the given version
47+
*
48+
* @param major The major version to check
49+
* @param minor The minor version to check
50+
* @param build The build version to check
51+
* @param revision The revision version to check
52+
*
53+
* @returns @c true when we are at least the given version, @c false otherwise
54+
*/
55+
bool check_at_least(int major, int minor, int build, int revision);
56+
57+
/**
58+
* @brief Returns the string representation of the passed version
59+
* @param major The major version to format
60+
* @param minor The minor version to format
61+
* @param build The build version to format
62+
* @param revision The revision version to format
63+
* @returns A string representation of the version number
64+
*/
65+
SCP_string format_version(int major, int minor, int build, int revision);
66+
}
6167

6268
#endif

code/mod_table/mod_table.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "gamesnd/eventmusic.h"
88
#include "globalincs/def_files.h"
9+
#include "globalincs/version.h"
910
#include "localization/localize.h"
1011
#include "mission/missioncampaign.h"
1112
#include "mission/missionmessage.h"
@@ -51,6 +52,36 @@ void parse_mod_table(const char *filename)
5152
reset_parse();
5253

5354
// start parsing
55+
optional_string("#GAME SETTINGS");
56+
57+
if (optional_string("$Minimum version:")) {
58+
int major = 0;
59+
int minor = 0;
60+
int build = 0;
61+
int revision = 0;
62+
63+
required_string("+Major:");
64+
stuff_int(&major);
65+
66+
required_string("+Minor:");
67+
stuff_int(&minor);
68+
69+
required_string("+Build:");
70+
stuff_int(&build);
71+
72+
if (optional_string("+Revision:")) {
73+
stuff_int(&revision);
74+
}
75+
76+
mprintf(("Game Settings Table: Parsed minimum version of %s\n", version::format_version(major, minor, build, revision).c_str()));
77+
78+
if (!version::check_at_least(major, minor, build, revision)) {
79+
Error(LOCATION, "This modification needs at least version %s of FreeSpace Open. However, the current is only %s!",
80+
version::format_version(major, minor, build, revision).c_str(),
81+
version::format_version(FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD, FS_VERSION_REVIS).c_str());
82+
}
83+
}
84+
5485
optional_string("#CAMPAIGN SETTINGS");
5586

5687
if (optional_string("$Default Campaign File Name:")) {

code/network/multi_update.cpp

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,7 @@ char Multi_update_error_string[512];
4040
// initialize the http xfer of the version info file, return 1 on success
4141
int multi_update_http_init()
4242
{
43-
char url_file[512] = "";
44-
char local_file[512] = "";
45-
46-
// url
47-
strcpy_s(url_file, VERSION_URL);
48-
49-
// local file
50-
strcpy_s(local_file, Cfile_root_dir);
51-
strcat_s(local_file, DIR_SEPARATOR_STR);
52-
strcat_s(local_file, VERSION_LOC_FNAME);
53-
54-
// new file
55-
Multi_update_get = new InetGetFile(url_file, local_file);
56-
if(Multi_update_get == NULL){
57-
// error string
58-
strcpy_s(Multi_update_error_string, XSTR("Could not get data from website", 977));
59-
60-
return 0;
61-
}
62-
63-
return 1;
43+
return 0;
6444
}
6545

6646
// do frame for the popup. returns 0 if not done yet, 1 if succeeded, 2 on error

0 commit comments

Comments
 (0)