summaryrefslogtreecommitdiff
path: root/src/network/network.cpp
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2019-01-28 11:10:59 +0100
committerNiels Martin Hansen <nielsm@indvikleren.dk>2019-02-03 18:00:16 +0100
commit5f8354f3585dd1fb852a097253e38cb91ee909d2 (patch)
tree82c3d6cd98127d1ee9671f60fed99731ffd64dd8 /src/network/network.cpp
parentc511b0e8017173bd9fee65a34dda23fc15c6644b (diff)
downloadopenttd-5f8354f3585dd1fb852a097253e38cb91ee909d2.tar.xz
Change: Make a shortened network revision string for use in server queries
Diffstat (limited to 'src/network/network.cpp')
-rw-r--r--src/network/network.cpp57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 0bbdd0d06..d70d800f9 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -1101,12 +1101,67 @@ void NetworkShutDown()
}
/**
+ * How many hex digits of the git hash to include in network revision string.
+ * Determined as 10 hex digits + 2 characters for -g/-u/-m prefix.
+ */
+static const uint GITHASH_SUFFIX_LEN = 12;
+
+/**
+ * Get the network version string used by this build.
+ * The returned string is guaranteed to be at most NETWORK_REVISON_LENGTH bytes.
+ */
+const char * GetNetworkRevisionString()
+{
+ /* This will be allocated on heap and never free'd, but only once so not a "real" leak. */
+ static char *network_revision = nullptr;
+
+ if (!network_revision) {
+ /* Start by taking a chance on the full revision string. */
+ network_revision = stredup(_openttd_revision);
+ /* Ensure it's not longer than the packet buffer length. */
+ if (strlen(network_revision) >= NETWORK_REVISION_LENGTH) network_revision[NETWORK_REVISION_LENGTH - 1] = '\0';
+
+ /* Release version names are not mangled further. */
+ if (IsReleasedVersion()) return network_revision;
+
+ /* Prepare a prefix of the git hash.
+ * Size is length + 1 for terminator, +2 for -g prefix. */
+ assert(_openttd_revision_modified < 3);
+ char githash_suffix[GITHASH_SUFFIX_LEN + 1] = "-";
+ githash_suffix[1] = "gum"[_openttd_revision_modified];
+ for (uint i = 2; i < GITHASH_SUFFIX_LEN; i++) {
+ githash_suffix[i] = _openttd_revision_hash[i-2];
+ }
+
+ /* Where did the hash start in the original string?
+ * Overwrite from that position, unless that would go past end of packet buffer length. */
+ ptrdiff_t hashofs = strrchr(_openttd_revision, '-') - _openttd_revision;
+ if (hashofs + strlen(githash_suffix) + 1 > NETWORK_REVISION_LENGTH) hashofs = strlen(network_revision) - strlen(githash_suffix);
+ /* Replace the git hash in revision string. */
+ strecpy(network_revision + hashofs, githash_suffix, network_revision + NETWORK_REVISION_LENGTH);
+ assert(strlen(network_revision) < NETWORK_REVISION_LENGTH); // strlen does not include terminator, constant does, hence strictly less than
+ }
+
+ return network_revision;
+}
+
+static const char *ExtractNetworkRevisionHash(const char *revstr)
+{
+ return strrchr(revstr, '-');
+}
+
+/**
* Checks whether the given version string is compatible with our version.
+ * First tries to match the full string, if that fails, attempts to compare just git hashes.
* @param other the version string to compare to
*/
bool IsNetworkCompatibleVersion(const char *other)
{
- return strncmp(_openttd_revision, other, NETWORK_REVISION_LENGTH - 1) == 0;
+ if (strncmp(GetNetworkRevisionString(), other, NETWORK_REVISION_LENGTH - 1) == 0) return true;
+
+ const char *hash1 = ExtractNetworkRevisionHash(GetNetworkRevisionString());
+ const char *hash2 = ExtractNetworkRevisionHash(other);
+ return hash1 && hash2 && (strncmp(hash1, hash2, GITHASH_SUFFIX_LEN) == 0);
}
#endif /* ENABLE_NETWORK */