[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