mirror of
https://github.com/glest/glest-source.git
synced 2025-08-23 08:22:50 +02:00
- added client side ping style packet for linux socket disconnect checking
This commit is contained in:
@@ -48,6 +48,8 @@ struct FormatString {
|
|||||||
MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainMenu,JoinMenu joinMenuInfo, bool openNetworkSlots):
|
MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainMenu,JoinMenu joinMenuInfo, bool openNetworkSlots):
|
||||||
MenuState(program, mainMenu, "connected-game") //← set on connected-game
|
MenuState(program, mainMenu, "connected-game") //← set on connected-game
|
||||||
{
|
{
|
||||||
|
lastNetworkSend = time(NULL);
|
||||||
|
|
||||||
returnMenuInfo=joinMenuInfo;
|
returnMenuInfo=joinMenuInfo;
|
||||||
Lang &lang= Lang::getInstance();
|
Lang &lang= Lang::getInstance();
|
||||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||||
@@ -360,6 +362,12 @@ void MenuStateConnectedGame::update()
|
|||||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||||
Lang &lang= Lang::getInstance();
|
Lang &lang= Lang::getInstance();
|
||||||
|
|
||||||
|
const int pingFrequency = 5;
|
||||||
|
if(difftime(time(NULL),lastNetworkSend) >= pingFrequency) {
|
||||||
|
lastNetworkSend = time(NULL);
|
||||||
|
clientInterface->sendPingMessage(pingFrequency, time(NULL));
|
||||||
|
}
|
||||||
|
|
||||||
//update status label
|
//update status label
|
||||||
if(clientInterface != NULL && clientInterface->isConnected()) {
|
if(clientInterface != NULL && clientInterface->isConnected()) {
|
||||||
buttonDisconnect.setText(lang.get("Disconnect"));
|
buttonDisconnect.setText(lang.get("Disconnect"));
|
||||||
|
@@ -71,6 +71,7 @@ private:
|
|||||||
string currentMap;
|
string currentMap;
|
||||||
JoinMenu returnMenuInfo;
|
JoinMenu returnMenuInfo;
|
||||||
bool settingsReceivedFromServer;
|
bool settingsReceivedFromServer;
|
||||||
|
time_t lastNetworkSend;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@@ -266,6 +266,17 @@ void ClientInterface::updateLobby()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nmtPing:
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
|
NetworkMessagePing networkMessagePing;
|
||||||
|
if(receiveMessage(&networkMessagePing)) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nmtSynchNetworkGameData:
|
case nmtSynchNetworkGameData:
|
||||||
{
|
{
|
||||||
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData;
|
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData;
|
||||||
@@ -540,6 +551,17 @@ void ClientInterface::updateKeyframe(int frameCount)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nmtPing:
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
|
NetworkMessagePing networkMessagePing;
|
||||||
|
if(receiveMessage(&networkMessagePing)) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nmtQuit:
|
case nmtQuit:
|
||||||
{
|
{
|
||||||
NetworkMessageQuit networkMessageQuit;
|
NetworkMessageQuit networkMessageQuit;
|
||||||
@@ -746,6 +768,11 @@ void ClientInterface::sendTextMessage(const string &text, int teamIndex, bool ec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientInterface::sendPingMessage(int32 pingFrequency, int64 pingTime) {
|
||||||
|
NetworkMessagePing networkMessagePing(pingFrequency,pingTime);
|
||||||
|
sendMessage(&networkMessagePing);
|
||||||
|
}
|
||||||
|
|
||||||
string ClientInterface::getNetworkStatus() {
|
string ClientInterface::getNetworkStatus() {
|
||||||
std::string label = Lang::getInstance().get("Server") + ": " + serverName;
|
std::string label = Lang::getInstance().get("Server") + ": " + serverName;
|
||||||
//float pingTime = getThreadedPingMS(getServerIpAddress().c_str());
|
//float pingTime = getThreadedPingMS(getServerIpAddress().c_str());
|
||||||
@@ -866,6 +893,13 @@ bool ClientInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
|
|||||||
this->receiveMessage(&msg);
|
this->receiveMessage(&msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case nmtPing:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessagePing msg = NetworkMessagePing();
|
||||||
|
this->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case nmtLaunch:
|
case nmtLaunch:
|
||||||
{
|
{
|
||||||
discard = true;
|
discard = true;
|
||||||
|
@@ -94,6 +94,8 @@ public:
|
|||||||
|
|
||||||
int getCurrentFrameCount() const { return currentFrameCount; }
|
int getCurrentFrameCount() const { return currentFrameCount; }
|
||||||
|
|
||||||
|
virtual void sendPingMessage(int32 pingFrequency, int64 pingTime);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Mutex * getServerSynchAccessor() { return NULL; }
|
Mutex * getServerSynchAccessor() { return NULL; }
|
||||||
|
@@ -170,11 +170,6 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex
|
|||||||
networkGameDataSynchCheckOkMap = false;
|
networkGameDataSynchCheckOkMap = false;
|
||||||
networkGameDataSynchCheckOkTile = false;
|
networkGameDataSynchCheckOkTile = false;
|
||||||
networkGameDataSynchCheckOkTech = false;
|
networkGameDataSynchCheckOkTech = false;
|
||||||
//networkGameDataSynchCheckOkFogOfWar = false;
|
|
||||||
|
|
||||||
//chatText.clear();
|
|
||||||
//chatSender.clear();
|
|
||||||
//chatTeamIndex= -1;
|
|
||||||
this->clearChatInfo();
|
this->clearChatInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,9 +224,6 @@ void ConnectionSlot::update(bool checkForNewClients) {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
|
||||||
connectedTime = time(NULL);
|
connectedTime = time(NULL);
|
||||||
|
|
||||||
//chatText.clear();
|
|
||||||
//chatSender.clear();
|
|
||||||
//chatTeamIndex= -1;
|
|
||||||
this->clearChatInfo();
|
this->clearChatInfo();
|
||||||
|
|
||||||
if(hasOpenSlots == false) {
|
if(hasOpenSlots == false) {
|
||||||
@@ -255,9 +247,6 @@ void ConnectionSlot::update(bool checkForNewClients) {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
if(socket->isConnected()) {
|
if(socket->isConnected()) {
|
||||||
//chatText.clear();
|
|
||||||
//chatSender.clear();
|
|
||||||
//chatTeamIndex= -1;
|
|
||||||
this->clearChatInfo();
|
this->clearChatInfo();
|
||||||
|
|
||||||
if(socket->hasDataToRead() == true) {
|
if(socket->hasDataToRead() == true) {
|
||||||
@@ -272,16 +261,23 @@ void ConnectionSlot::update(bool checkForNewClients) {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nmtPing:
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
|
NetworkMessagePing networkMessagePing;
|
||||||
|
if(receiveMessage(&networkMessagePing)) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nmtText:
|
case nmtText:
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
NetworkMessageText networkMessageText;
|
NetworkMessageText networkMessageText;
|
||||||
if(receiveMessage(&networkMessageText)) {
|
if(receiveMessage(&networkMessageText)) {
|
||||||
//chatText = networkMessageText.getText();
|
|
||||||
//chatSender = networkMessageText.getSender();
|
|
||||||
//chatTeamIndex = networkMessageText.getTeamIndex();
|
|
||||||
|
|
||||||
ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getSender().c_str(),networkMessageText.getTeamIndex());
|
ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getSender().c_str(),networkMessageText.getTeamIndex());
|
||||||
this->addChatInfo(msg);
|
this->addChatInfo(msg);
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ namespace Glest{ namespace Game{
|
|||||||
// class NetworkInterface
|
// class NetworkInterface
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
const int NetworkInterface::readyWaitTimeout= 120000; // 2 minutes
|
const int NetworkInterface::readyWaitTimeout= 180000; // 3 minutes
|
||||||
|
|
||||||
bool NetworkInterface::allowGameDataSynchCheck = false;
|
bool NetworkInterface::allowGameDataSynchCheck = false;
|
||||||
bool NetworkInterface::allowDownloadDataSynch = false;
|
bool NetworkInterface::allowDownloadDataSynch = false;
|
||||||
|
@@ -141,6 +141,29 @@ void NetworkMessageIntro::send(Socket* socket) const{
|
|||||||
NetworkMessage::send(socket, &data, sizeof(data));
|
NetworkMessage::send(socket, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class NetworkMessagePing
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
NetworkMessagePing::NetworkMessagePing(){
|
||||||
|
data.messageType= nmtPing;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkMessagePing::NetworkMessagePing(int32 pingFrequency, int64 pingTime){
|
||||||
|
data.messageType= nmtPing;
|
||||||
|
data.pingFrequency= pingFrequency;
|
||||||
|
data.pingTime= pingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkMessagePing::receive(Socket* socket){
|
||||||
|
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkMessagePing::send(Socket* socket) const{
|
||||||
|
assert(data.messageType==nmtPing);
|
||||||
|
NetworkMessage::send(socket, &data, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class NetworkMessageReady
|
// class NetworkMessageReady
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
@@ -106,10 +106,38 @@ public:
|
|||||||
virtual void send(Socket* socket) const;
|
virtual void send(Socket* socket) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class NetworkMessagePing
|
||||||
|
//
|
||||||
|
// Message sent at any time
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
class NetworkMessagePing: public NetworkMessage{
|
||||||
|
private:
|
||||||
|
struct Data{
|
||||||
|
int8 messageType;
|
||||||
|
int32 pingFrequency;
|
||||||
|
int64 pingTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Data data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NetworkMessagePing();
|
||||||
|
NetworkMessagePing(int32 pingFrequency, int64 pingTime);
|
||||||
|
|
||||||
|
int32 getPingFrequency() const {return data.pingFrequency;}
|
||||||
|
int64 getPingTime() const {return data.pingTime;}
|
||||||
|
|
||||||
|
virtual bool receive(Socket* socket);
|
||||||
|
virtual void send(Socket* socket) const;
|
||||||
|
};
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class NetworkMessageReady
|
// class NetworkMessageReady
|
||||||
//
|
//
|
||||||
// Message sent at the beggining of the game
|
// Message sent at the beginning of the game
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class NetworkMessageReady: public NetworkMessage{
|
class NetworkMessageReady: public NetworkMessage{
|
||||||
|
@@ -567,6 +567,7 @@ void ServerInterface::update() {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
//process text messages
|
//process text messages
|
||||||
|
/*
|
||||||
if(this->getChatTextList().empty() == true) {
|
if(this->getChatTextList().empty() == true) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
@@ -607,6 +608,7 @@ void ServerInterface::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,6 +685,14 @@ bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
|
|||||||
connectionSlot->receiveMessage(&msg);
|
connectionSlot->receiveMessage(&msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case nmtPing:
|
||||||
|
{
|
||||||
|
discard = true;
|
||||||
|
NetworkMessagePing msg = NetworkMessagePing();
|
||||||
|
connectionSlot->receiveMessage(&msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nmtLaunch:
|
case nmtLaunch:
|
||||||
{
|
{
|
||||||
discard = true;
|
discard = true;
|
||||||
|
@@ -117,7 +117,7 @@ public:
|
|||||||
|
|
||||||
PLATFORM_SOCKET getSocketId() const { return sock; }
|
PLATFORM_SOCKET getSocketId() const { return sock; }
|
||||||
|
|
||||||
int getDataToRead();
|
int getDataToRead(bool wantImmediateReply=false);
|
||||||
int send(const void *data, int dataSize);
|
int send(const void *data, int dataSize);
|
||||||
int receive(void *data, int dataSize);
|
int receive(void *data, int dataSize);
|
||||||
int peek(void *data, int dataSize);
|
int peek(void *data, int dataSize);
|
||||||
|
@@ -696,8 +696,7 @@ Socket::Socket()
|
|||||||
{
|
{
|
||||||
this->pingThread = NULL;
|
this->pingThread = NULL;
|
||||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if(isSocketValid() == false)
|
if(isSocketValid() == false) {
|
||||||
{
|
|
||||||
throwException("Error creating socket");
|
throwException("Error creating socket");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -877,7 +876,7 @@ bool Socket::hasDataToRead(PLATFORM_SOCKET socket)
|
|||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Socket::getDataToRead(){
|
int Socket::getDataToRead(bool wantImmediateReply) {
|
||||||
unsigned long size = 0;
|
unsigned long size = 0;
|
||||||
|
|
||||||
//fd_set rfds;
|
//fd_set rfds;
|
||||||
@@ -927,6 +926,10 @@ int Socket::getDataToRead(){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(wantImmediateReply == true) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
loopCount++;
|
loopCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1094,6 @@ bool Socket::isReadable() {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//return (i == 1 && FD_ISSET(sock, &set));
|
|
||||||
bool result = (i == 1);
|
bool result = (i == 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1153,24 +1155,12 @@ bool Socket::isConnected() {
|
|||||||
//if the socket is readable it is connected if we can read a byte from it
|
//if the socket is readable it is connected if we can read a byte from it
|
||||||
if(isReadable()) {
|
if(isReadable()) {
|
||||||
char tmp;
|
char tmp;
|
||||||
int err = peek(&tmp, sizeof(tmp));
|
int err = peek(&tmp, 1);
|
||||||
if(err <= 0) {
|
if(err <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
// Need this extra check for proper linux disconnect checking
|
|
||||||
struct sockaddr name;
|
|
||||||
socklen_t namelen = sizeof (name);
|
|
||||||
|
|
||||||
int peer_result = getpeername(sock, &name, &namelen);
|
|
||||||
if(peer_result != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//otherwise the socket is connected
|
//otherwise the socket is connected
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user