[Scummvm-git-logs] scummvm master -> 871d7dc7d3187526f6c43e69b8995ac6f7aea032

LittleToonCat noreply at scummvm.org
Thu Aug 10 02:45:03 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
871d7dc7d3 SCUMM HE: Implement realiable net message types.


Commit: 871d7dc7d3187526f6c43e69b8995ac6f7aea032
    https://github.com/scummvm/scummvm/commit/871d7dc7d3187526f6c43e69b8995ac6f7aea032
Author: Little Cat (toontownlittlecat at gmail.com)
Date: 2023-08-09T23:44:44-03:00

Commit Message:
SCUMM HE: Implement realiable net message types.

Changed paths:
    engines/scumm/dialog-sessionselector.cpp
    engines/scumm/he/intern_he.h
    engines/scumm/he/logic/baseball2001.cpp
    engines/scumm/he/logic/football.cpp
    engines/scumm/he/net/net_defines.h
    engines/scumm/he/net/net_main.cpp
    engines/scumm/he/net/net_main.h
    engines/scumm/vars.cpp


diff --git a/engines/scumm/dialog-sessionselector.cpp b/engines/scumm/dialog-sessionselector.cpp
index 8e2cf3bb32a..ad5f0176161 100644
--- a/engines/scumm/dialog-sessionselector.cpp
+++ b/engines/scumm/dialog-sessionselector.cpp
@@ -96,7 +96,7 @@ void SessionSelectorDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd
 
 void SessionSelectorDialog::handleTickle() {
 	// Keep the connection active.
-	_vm->_net->doNetworkOnceAFrame(12);
+	_vm->_net->doNetworkOnceAFrame(15);
 
 	// Query for new sessions every 5 seconds.
 	if (!_timestamp || g_system->getMillis() - _timestamp > 5000) {
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 8a92860d2c5..30eaa379fa4 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -738,6 +738,7 @@ protected:
 	byte VAR_REMOTE_START_SCRIPT;
 	byte VAR_NETWORK_AVAILABLE;
 	byte VAR_NETWORK_RECEIVE_ARRAY_SCRIPT;
+	byte VAR_NETWORK_NET_LAG;
 
 public:
 	int networkSessionDialog();
@@ -1046,6 +1047,7 @@ protected:
 	byte VAR_REMOTE_START_SCRIPT;
 	byte VAR_NETWORK_AVAILABLE;
 	byte VAR_NETWORK_RECEIVE_ARRAY_SCRIPT;
+	byte VAR_NETWORK_NET_LAG;
 };
 
 class ScummEngine_vCUPhe : public Engine {
diff --git a/engines/scumm/he/logic/baseball2001.cpp b/engines/scumm/he/logic/baseball2001.cpp
index 68a20429ecc..935a6372279 100644
--- a/engines/scumm/he/logic/baseball2001.cpp
+++ b/engines/scumm/he/logic/baseball2001.cpp
@@ -81,7 +81,7 @@ int LogicHEbaseball2001::startOfFrame() {
 #ifdef USE_LIBCURL
 	_vm->_lobby->doNetworkOnceAFrame();
 #endif
-	_vm->_net->doNetworkOnceAFrame(0);
+	_vm->_net->doNetworkOnceAFrame(15);
 #endif
 	return 0;
 }
@@ -178,27 +178,11 @@ case OP_NET_INIT:
 
 #ifdef USE_ENET
 void LogicHEbaseball2001::netRemoteStartScript(int numArgs, int32 *args) {
-	int priority = PN_PRIORITY_HIGH;
-
-	int targetUserId;
-	if (_vm->_net->_isHost)
-		targetUserId = 2;
-	else
-		targetUserId = 1;
-
-	_vm->_net->remoteStartScript(PN_SENDTYPE_INDIVIDUAL, targetUserId, priority, numArgs - 3, &args[3]);
+	_vm->_net->remoteStartScript(args[0], args[1], args[2], numArgs - 3, &args[3]);
 }
 
 void LogicHEbaseball2001::netRemoteSendArray(int32 *args) {
-	int priority = PN_PRIORITY_HIGH;
-
-	int targetUserId;
-	if (_vm->_net->_isHost)
-		targetUserId = 2;
-	else
-		targetUserId = 1;
-
-	_vm->_net->remoteSendArray(PN_SENDTYPE_INDIVIDUAL, targetUserId, priority, args[3]);
+	_vm->_net->remoteSendArray(args[0], args[1], args[2], args[3]);
 }
 #endif // USE_ENET
 
diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp
index fec3d2fca94..b5c897efcf9 100644
--- a/engines/scumm/he/logic/football.cpp
+++ b/engines/scumm/he/logic/football.cpp
@@ -97,7 +97,7 @@ int LogicHEfootball::startOfFrame() {
 	if (_vm->_lobby)
 		_vm->_lobby->doNetworkOnceAFrame();
 #endif
-	_vm->_net->doNetworkOnceAFrame(0);
+	_vm->_net->doNetworkOnceAFrame(15);
 #endif
 	return 0;
 }
@@ -404,27 +404,11 @@ int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) {
 
 #ifdef USE_ENET
 void LogicHEfootball::netRemoteStartScript(int numArgs, int32 *args) {
-	int priority = PN_PRIORITY_HIGH;
-
-	int targetUserId;
-	if (_vm->_net->_isHost)
-		targetUserId = 2;
-	else
-		targetUserId = 1;
-
-	_vm->_net->remoteStartScript(PN_SENDTYPE_INDIVIDUAL, targetUserId, priority, numArgs - 3, &args[3]);
+	_vm->_net->remoteStartScript(args[0], args[1], args[2], numArgs - 3, &args[3]);
 }
 
 void LogicHEfootball::netRemoteSendArray(int32 *args) {
-	int priority = PN_PRIORITY_HIGH;
-
-	int targetUserId;
-	if (_vm->_net->_isHost)
-		targetUserId = 2;
-	else
-		targetUserId = 1;
-
-	_vm->_net->remoteSendArray(PN_SENDTYPE_INDIVIDUAL, targetUserId, priority, args[3]);
+	_vm->_net->remoteSendArray(args[0], args[1], args[2], args[3]);
 }
 #endif // USE_ENET
 
diff --git a/engines/scumm/he/net/net_defines.h b/engines/scumm/he/net/net_defines.h
index c3efea18036..3044d723c08 100644
--- a/engines/scumm/he/net/net_defines.h
+++ b/engines/scumm/he/net/net_defines.h
@@ -32,6 +32,8 @@ namespace Scumm {
 #define PN_SENDTYPE_GROUP							2
 #define PN_SENDTYPE_HOST							3
 #define PN_SENDTYPE_ALL								4
+#define PN_SENDTYPE_ALL_RELIABLE					14
+#define PN_SENDTYPE_ALL_RELIABLE_TIMED				24
 
 #define MAX_GAME_NAME								128				/* Used for the multiplayer networking code */
 #define MAX_PLAYER_NAME								128				/* Used for the multiplayer networking code */
@@ -45,6 +47,9 @@ namespace Scumm {
 #define PACKETTYPE_REMOTESTARTSCRIPTRETURN			2
 #define PACKETTYPE_REMOTESTARTSCRIPTRESULT			3
 #define PACKETTYPE_REMOTESENDSCUMMARRAY				4
+// ScummVM specific type, used for determine
+// net lag
+#define PACKETTYPE_RELIABLETIMEDRESP				5
 
 const int MAX_PACKET_SIZE = 4096;	// bytes
 const int MAX_HOSTNAME_SIZE = 256;
diff --git a/engines/scumm/he/net/net_main.cpp b/engines/scumm/he/net/net_main.cpp
index 85709b0cc5b..6c8adf3e643 100644
--- a/engines/scumm/he/net/net_main.cpp
+++ b/engines/scumm/he/net/net_main.cpp
@@ -71,6 +71,8 @@ Net::Net(ScummEngine_v90he *vm) : _latencyTime(1), _fakeLatency(false), _vm(vm)
 
 	_hostDataQueue = Common::Queue<Common::JSONValue *>();
 	_peerIndexQueue = Common::Queue<int>();
+
+	_waitForTimedResp = false;
 }
 
 Net::~Net() {
@@ -154,7 +156,7 @@ int Net::joinGame(Common::String IP, char *userName) {
 			uint tickCount = 0;
 			while (!_sessions.size()) {
 				serviceBroadcast();
-				// Wait for one minute for response before giving up
+				// Wait for one second for response before giving up
 				tickCount += 5;
 				g_system->delayMillis(5);
 				if (tickCount >= 1000)
@@ -520,7 +522,7 @@ int32 Net::setProviderByName(int32 parameter1, int32 parameter2) {
 
 void Net::setFakeLatency(int time) {
 	_latencyTime = time;
-	debug("NETWORK: Setting Fake Latency to %d ms", _latencyTime);
+	debugC(DEBUG_NETWORK, "NETWORK: Setting Fake Latency to %d ms", _latencyTime);
 	_fakeLatency = true;
 }
 
@@ -741,22 +743,32 @@ int Net::remoteSendData(int typeOfSend, int sendTypeParam, int type, Common::Str
 		// sooo, send all.
 		typeOfSend = PN_SENDTYPE_ALL;
 
+	bool reliable = false;
+	if (priority == PN_PRIORITY_HIGH || typeOfSend == PN_SENDTYPE_ALL_RELIABLE ||
+		typeOfSend == PN_SENDTYPE_ALL_RELIABLE_TIMED)
+		reliable = true;
+
 	// Since I am lazy, instead of constructing the JSON object manually
 	// I'd rather parse it
 	Common::String res = Common::String::format(
 		"{\"cmd\":\"game\",\"from\":%d,\"to\":%d,\"toparam\":%d,"
 		"\"type\":%d, \"reliable\":%s, \"data\":{%s}}",
 		_myUserId, typeOfSend, sendTypeParam, type,
-		priority == PN_PRIORITY_HIGH ? "true" : "false", data.c_str());
+		reliable == true ? "true" : "false", data.c_str());
 
 	debugC(DEBUG_NETWORK, "NETWORK: Sending data: %s", res.c_str());
 	Common::JSONValue *str = Common::JSON::parse(res.c_str());
 	if (_isHost) {
-		// handleGameDataHost(str, sendTypeParam - 1);
 		_hostDataQueue.push(str);
 		_peerIndexQueue.push(sendTypeParam - 1);
-	} else
-		_sessionHost->send(res.c_str(), 0, 0, priority == PN_PRIORITY_HIGH);
+	} else {
+		_sessionHost->send(res.c_str(), 0, 0, reliable);
+		if (typeOfSend == PN_SENDTYPE_ALL_RELIABLE_TIMED) {
+			// Wait for a response to determine net lag.
+			_savedTime = g_system->getMillis();
+			_waitForTimedResp = true;
+		}
+	}
 	return defaultRes;
 }
 
@@ -1129,11 +1141,20 @@ void Net::remoteReceiveData() {
 			int userId = -1;
 			if (_addressToUserId.contains(address))
 				userId = _addressToUserId[address];
-			if (userId > -1)
+			if (userId > -1) {
 				debugC(DEBUG_NETWORK, "NETWORK: User %s (%d) has disconnected.", _userIdToName[userId].c_str(), userId);
+				if (_isHost)
+					destroyPlayer(userId);
+			}
 			else
 				debugC(DEBUG_NETWORK, "NETWORK: Connection from %s has disconnected.", address.c_str());
 
+			if (!_isHost) {
+				// Since we've lost connect to our host, it's safe
+				// to shut everything down.
+				closeProvider();
+			}
+
 			if (_gameName == "moonbase") {
 				// TODO: Host migration
 				if (!_isHost && _vm->_currentRoom == 2) {
@@ -1141,6 +1162,11 @@ void Net::remoteReceiveData() {
 					_vm->VAR(253) = 26; // gGameMode = GAME-OVER
 					_vm->runScript(2104, 1, 0, 0); // leave-game
 				}
+			} else {
+				// Football/Baseball
+
+				// We have lost our only other opponent, do not wait for a timed response.
+				_waitForTimedResp = false;
 			}
 			break;
 		}
@@ -1241,6 +1267,9 @@ void Net::doNetworkOnceAFrame(int msecs) {
 	if (!_enet || !_sessionHost)
 		return;
 
+	uint tickCount = 0;
+
+receiveData:
 	remoteReceiveData();
 
 	if (_sessionServerHost)
@@ -1256,12 +1285,26 @@ void Net::doNetworkOnceAFrame(int msecs) {
 		int peerIndex = _peerIndexQueue.pop();
 		handleGameDataHost(json, peerIndex);
 	}
+
+	if (_waitForTimedResp) {
+		g_system->delayMillis(msecs);
+
+		// Wait for 3 seconds for a response before giving up.
+		tickCount += msecs;
+		if (tickCount >= 3000) {
+			_savedTime = 0;
+			_waitForTimedResp = false;
+			return;
+		}
+		goto receiveData;
+	}
 }
 
 void Net::handleGameData(Common::JSONValue *json, int peerIndex) {
 	if (!_enet || !_sessionHost)
 		return;
 	_fromUserId = json->child("from")->asIntegerNumber();
+	uint to = json->child("to")->asIntegerNumber();
 	uint type = json->child("type")->asIntegerNumber();
 
 	uint32 *params;
@@ -1377,11 +1420,25 @@ void Net::handleGameData(Common::JSONValue *json, int peerIndex) {
 			_vm->runScript(_vm->VAR(_vm->VAR_NETWORK_RECEIVE_ARRAY_SCRIPT), 1, 0, (int *)_tmpbuffer);
 		}
 		break;
+	case PACKETTYPE_RELIABLETIMEDRESP:
+		{
+			int savedTime = ((g_system->getMillis() - _savedTime) / 2) ;	//div by 2 for one-way lag.
+			_vm->VAR(_vm->VAR_NETWORK_NET_LAG) = savedTime;
+			_waitForTimedResp = false;
+		}
+		break;
 
 	default:
 		warning("NETWORK: Received unknown network command %d", type);
 	}
 
+	if (to == PN_SENDTYPE_ALL_RELIABLE_TIMED) {
+		if (_fromUserId != _myUserId) {
+			// Send a response
+			remoteSendData(PN_SENDTYPE_INDIVIDUAL, _fromUserId, PACKETTYPE_RELIABLETIMEDRESP, "", PN_PRIORITY_HIGH);
+		}
+	}
+
 }
 
 void Net::handleGameDataHost(Common::JSONValue *json, int peerIndex) {
@@ -1418,6 +1475,8 @@ void Net::handleGameDataHost(Common::JSONValue *json, int peerIndex) {
 		}
 		break;
 	case PN_SENDTYPE_ALL:
+	case PN_SENDTYPE_ALL_RELIABLE:
+	case PN_SENDTYPE_ALL_RELIABLE_TIMED:
 		{
 			// It's for all of us, including the host.
 			// Don't handle data if we're shutting down, or the game will crash.
@@ -1438,6 +1497,17 @@ void Net::handleGameDataHost(Common::JSONValue *json, int peerIndex) {
 						_sessionHost->send(str.c_str(), i, 0, reliable);
 				}
 			}
+
+			if (to == PN_SENDTYPE_ALL_RELIABLE_TIMED) {
+				if (from == _myUserId) {
+					// That's us, wait for a response to determine net lag.
+					// Don't wait if we're the only ones here (our opponent disconnected).
+					if (getTotalPlayers() > 1) {
+						_savedTime = g_system->getMillis();
+						_waitForTimedResp = true;
+					}
+				}
+			}
 		}
 		break;
 	default:
diff --git a/engines/scumm/he/net/net_main.h b/engines/scumm/he/net/net_main.h
index 7433feaf122..37209fae331 100644
--- a/engines/scumm/he/net/net_main.h
+++ b/engines/scumm/he/net/net_main.h
@@ -552,6 +552,10 @@ private:
 	bool _gotSessions;
 	int _sessionServerPeer;
 	bool _isRelayingGame; ///< If we're relaying in-game data over the session server or not.
+
+	// Used to determine net lag between players.
+	int _savedTime;
+	bool _waitForTimedResp;
 };
 
 } // End of namespace Scumm
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 4f344da5305..781e82a9a15 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -341,6 +341,7 @@ void ScummEngine_v90he::setupScummVars() {
 			VAR_REMOTE_START_SCRIPT = 98;
 			VAR_NETWORK_AVAILABLE = 100;
 			VAR_NETWORK_RECEIVE_ARRAY_SCRIPT = 101;
+			VAR_NETWORK_NET_LAG = 136;
 		}
 #endif
 		VAR_MAIN_SCRIPT = 127;
@@ -362,6 +363,8 @@ void ScummEngine_v100he::setupScummVars() {
 		VAR_U32_USER_VAR_D = 111;
 		VAR_U32_USER_VAR_E = 112;
 		VAR_U32_USER_VAR_F = 113;
+		VAR_NETWORK_NET_LAG = 136;
+
 	}
 }
 #endif




More information about the Scummvm-git-logs mailing list