Opened 12 years ago

Last modified 3 years ago

#1602 new enhancement

Do engine- and mod version checks when connecting to direct MP games

Reported by: Pureon Owned by:
Priority: Must Have Milestone: Backlog
Component: Network Keywords: simple
Cc: Patch:

Description (last modified by Itms)

When setting up a multiplayer game, those who have connected should be checked for OOS on the match setup screen.

Currently only after the map loads do the OOS errors appear, so the match setup has to be restarted.

Change History (8)

comment:1 by historic_bruno, 12 years ago

Just want to mention that an OOS could still occur if it's a bug in the engine or random map generator and probably in other ways. The best we could do is probably some kind of checksum of the relevant data files, #161 hints at that (in the context of auto-updating). Not sure how we could verify engine compatibility since everyone could have a slightly different though compatible binary.

comment:2 by elexis, 9 years ago

Summary: Check connected players for OOS on the match setup screenDo engine- and mod version checks when connecting

Why I am not in favor of a full OOS check:

1) There already is a version check: There is a PS_PROTOCOL_VERSION defined in NetMessages.h, which changes like every release. If you are not playing the SVN version which changes daily, then you can't even connect to hosts which have a different version of the game - even if you try to connect by IP.

As we can see in CNetServerWorker::OnClientHandshake, the server requires that clients have the correct version and disconnects them otherwise:

	if (message->m_ProtocolVersion != PS_PROTOCOL_VERSION)
	{
		session->Disconnect(NDR_INCORRECT_PROTOCOL_VERSION);
		return false;
	}

(2) If you want to be more certain that no OOS will occur: If you want to verify that all players have a 100% compatible version, you would need to verify that all of the simulation-relevant files are identical. This includes the simulation-directory (1700 files, 3MB), the selected map (up to 10MB), the GUI code (250 files, 1,5mb) and basically the whole C++ source code (18MB, 2200 files).

This means that all of that data would have to be loaded and hashed, which takes quite a while (but not longer than the loading screen when starting the game, as you don't need to load the art files).

Also notice that usually bugs cause OOS and it is impossible to detect all of them in advance (See https://en.wikipedia.org/wiki/Halting_problem).


Here is what we should really do:

(A) Engine version check: The engine_version is saved in Pyrogenesis.cpp:

const char engine_version[] = "0.0.19";

The server and clients should send it in the m_SoftwareVersion field, since that one currently contains the PS_PROTOCOL_VERSION, which we already send in the m_ProtocolVersion field: From NetServer.cpp:

	// Send handshake challenge
	CSrvHandshakeMessage handshake;
	handshake.m_Magic = PS_PROTOCOL_MAGIC;
	handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
	handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
	return session->SendMessage(&handshake);

From NetClient.cpp:

	CCliHandshakeMessage handshake;
	handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
	handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
	handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
	client->SendMessage(&handshake);

(B) Mod version check: People might have enabled a different set of custom modificiations (mods). This would definitely lead to an OOS. Doing a mod check in the lobby as in #3370 doesn't fix this issue for non-lobby multiplayer games. Every mod has a mod.json file, which we could either serialize or hash and send in the handshake messages:

{
	"name": "0ad",
	"version": "0.0.19",
	"label": "0 A.D. Empires Ascendant",
	"url": "play0ad.com",
	"description": "A free, open-source, historical RTS game.",
	"dependencies": [],
	"type": "game"
}

Notice that currently the version string of the "public" mod is identical to the string saved in engine_version. However we should fix (A), as the software version isn't the protocol version and maybe we decide to change the version string in only one of those files at some point.

comment:3 by Itms, 5 years ago

Component: UI & SimulationUI – Game setup
Description: modified (diff)
Keywords: simple added
Priority: Should HaveMust Have
Summary: Do engine- and mod version checks when connectingDo engine- and mod version checks when connecting to direct MP games

Now that #3370 is in, I believe most of the foundation is here to do that in the gamesetup screen for direct MP games.

It is not really trivial, but it can be a good starting task for someone wanting to dive into the game setup.

comment:4 by elexis, 5 years ago

Not sure that it's better to do it in the gamesetup rather than in the handshake stage of the network protocol, see comment:2. If it's done in the gamesetup, it also has to be done for rejoins, and all of the currently existing JS and C++ would have to be delayed for the handshake stage in javascript to test for mods prior to receiving the initial gamesetup attributes (i.e. before the GUI gamesetup page is even rendered for the first time) / prior to receiving the simulation state for rejoin.

comment:5 by Itms, 5 years ago

Component: UI – Game setupNetwork

Ah yes, there is indeed a better component for that.

comment:6 by elexis, 5 years ago

And it's indeed considerably simple, involved files are probably only NetServer.cpp, NetClient.cpp, Mod.cpp (and the one network file with the disconnect reasons).

It got a bit simpler in a23b as we now have g_LoadedModVersions from Mod.cpp that stores currently enabled mod versions as a std::vector and can be accessed by a new getter.

comment:7 by Silier, 3 years ago

Keywords: simple removed
severity: simple

comment:8 by Silier, 3 years ago

Keywords: simple added
Note: See TracTickets for help on using tickets.