Version Checking System¶
Client/server version comparison using git hashes at connection time.
Architecture¶
[Client: LoginScene] ←TCP→ [TCPAuthServer]
↓ ↓
Version.hpp VersionHistoryManager
(getClientVersion) (loadFromFile)
↓ ↓
VersionInfo ←────→ VersionHistory
(13 bytes) (451 bytes)
Wire Structures¶
// VersionInfo (13 bytes) - Sent in AuthResponseWithToken
struct VersionInfo {
uint8_t major, minor, patch;
uint8_t flags; // Bit 0: isDev
char gitHash[9]; // 8 chars + null
};
// VersionHistory (451 bytes) - Last 50 commits
struct VersionHistory {
uint8_t count;
char hashes[50][9]; // Newest first
};
Verification Flow¶
- Login - Client sends credentials
- Auth Success - Server responds with
serverVersion+versionHistory - Client compares -
isVersionCompatible(client, server) - If mismatch - Popup shows commits behind + JENKINS button
Version Compatibility¶
The client performs an exact hash match with the server version:
// Version.hpp - Actual implementation
inline bool isVersionCompatible(const VersionInfo& client, const VersionInfo& server) {
if (client.isDev()) {
return true; // Dev mode bypasses check
}
return client.isExactMatch(server); // Exact hash comparison
}
The history is used separately to calculate how many commits behind:
// TCPClient.cpp - After receiving auth response
int commitsBehind = response.versionHistory.findPosition(clientVersion.gitHash);
if (!isVersionCompatible(clientVersion, response.serverVersion)) {
emit(TCPVersionMismatchEvent{clientVersion, response.serverVersion, commitsBehind});
}
Development Mode¶
Create a version.dev file at project root to bypass version checking:
In dev mode: - Version mismatch warnings are suppressed - Useful for local development against production server
Test Environment Variable¶
Simulate a different git hash for testing:
Key Files¶
| File | Description |
|---|---|
src/client/include/core/Version.hpp |
getClientVersion(), isDevMode(), formatVersion() |
src/server/include/infrastructure/version/VersionHistoryManager.hpp |
Singleton, loadFromFile(), getCommitsBehind() |
src/common/protocol/Protocol.hpp |
VersionInfo, VersionHistory structs |
src/client/src/scenes/LoginScene.cpp |
Mismatch popup, JENKINS button |
scripts/generate_version_history.sh |
Helper script to generate history |
CI/CD Integration¶
Jenkinsfile¶
Generates version_history.txt at checkout:
deploy-service.py¶
Regenerates history at each VPS deployment:
def generate_version_history():
result = subprocess.run(
['git', 'log', '--format=%h', '-n', '50'],
capture_output=True, text=True
)
with open('version_history.txt', 'w') as f:
f.write(result.stdout)
Version History File Format¶
Simple text file with one short hash per line (newest first):
The server loads this file at startup via VersionHistoryManager::loadFromFile().
Client Mismatch UI¶
When version mismatch is detected:
- Warning popup displays:
- "Version mismatch detected"
- Number of commits behind (if calculable)
-
Current client hash vs server hash
-
Actions available:
- JENKINS button - Opens CI/CD to download latest build
- CONTINUE button - Proceed anyway (may cause issues)
- QUIT button - Exit client
Troubleshooting¶
"Version mismatch" on every connection¶
- Rebuild client from latest main branch
- Check if
version.devexists (should bypass) - Verify server's
version_history.txtis up to date
Client shows wrong hash¶
- Ensure clean git state (
git status) - Check
RTYPE_TEST_HASHenv var isn't set - Rebuild client after
git pull
Server history not loading¶
- Check
version_history.txtexists in server directory - Verify file permissions
- Check server logs for load errors