glest-source/source/glest_game/network/client_interface.h
2018-05-06 00:01:36 +02:00

253 lines
6.6 KiB
C++

//
// client_interface.h:
//
// This file is part of ZetaGlest <https://github.com/ZetaGlest>
//
// Copyright (C) 2018 The ZetaGlest team
//
// ZetaGlest is a fork of MegaGlest <https://megaglest.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>
#ifndef _GLEST_GAME_CLIENTINTERFACE_H_
#define _GLEST_GAME_CLIENTINTERFACE_H_
#ifdef WIN32
#include <winsock2.h>
#include <winsock.h>
#endif
#include <vector>
#include "network_interface.h"
#include "socket.h"
#include "leak_dumper.h"
using Shared::Platform::Ip;
using Shared::Platform::ClientSocket;
using std::vector;
namespace Glest {
namespace Game {
class ClientInterface;
class ClientInterfaceThread : public BaseThread, public SlaveThreadControllerInterface {
protected:
ClientInterface * clientInterface;
virtual void setQuitStatus(bool value);
public:
explicit ClientInterfaceThread(ClientInterface *client);
virtual ~ClientInterfaceThread();
virtual void execute();
virtual void setMasterController(MasterSlaveThreadController *master) {
}
virtual void signalSlave(void *userdata) {
}
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false);
};
// =====================================================
// class ClientInterface
// =====================================================
class ClientInterface : public GameNetworkInterface {
private:
static const int messageWaitTimeout;
static const int waitSleepTime;
static const int maxNetworkCommandListSendTimeWait;
private:
ClientSocket * clientSocket;
string serverName;
bool introDone;
bool launchGame;
int playerIndex;
bool gameSettingsReceived;
int gameSettingsReceivedCount;
time_t connectedTime;
bool gotIntro;
Ip ip;
int port;
int currentFrameCount;
int lastSentFrameCount;
time_t lastNetworkCommandListSendTime;
time_t clientSimulationLagStartTime;
string versionString;
int sessionKey;
int serverFTPPort;
string serverUUID;
string serverPlatform;
ClientInterfaceThread *networkCommandListThread;
Mutex *networkCommandListThreadAccessor;
std::map<int, Commands> cachedPendingCommands; //commands ready to be given
std::map<int, vector<uint32> > cachedPendingCommandCRCs; //commands ready to be given
uint64 cachedPendingCommandsIndex;
uint64 cachedLastPendingFrameCount;
int64 timeClientWaitedForLastMessage;
Mutex *flagAccessor;
bool joinGameInProgress;
bool joinGameInProgressLaunch;
bool readyForInGameJoin;
bool resumeInGameJoin;
Mutex *quitThreadAccessor;
bool quitThread;
bool getQuitThread();
void setQuitThread(bool value);
bool getQuit();
void setQuit(bool value);
public:
ClientInterface();
virtual ~ClientInterface();
virtual std::string getIpAddress(bool mutexLock = true);
virtual Socket* getSocket(bool mutexLock = true) {
return clientSocket;
}
virtual void close();
bool getJoinGameInProgress();
bool getJoinGameInProgressLaunch();
bool getReadyForInGameJoin();
bool getResumeInGameJoin();
void sendResumeGameMessage();
uint64 getCachedLastPendingFrameCount();
int64 getTimeClientWaitedForLastMessage();
//message processing
virtual void update();
virtual void updateLobby();
virtual void updateKeyframe(int frameCount);
virtual void setKeyframe(int frameCount) {
currentFrameCount = frameCount;
}
virtual void waitUntilReady(Checksum* checksum);
// message sending
virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal,
string targetLanguage);
virtual void quitGame(bool userManuallyQuit);
virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex);
virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex);
virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex);
//misc
virtual string getNetworkStatus();
//accessors
string getServerName() const {
return serverName;
}
bool getLaunchGame() const {
return launchGame;
}
bool getIntroDone() const {
return introDone;
}
bool getGameSettingsReceived() const {
return gameSettingsReceived;
}
void setGameSettingsReceived(bool value);
int getGameSettingsReceivedCount() const {
return gameSettingsReceivedCount;
}
int getPlayerIndex() const {
return playerIndex;
}
void connect(const Ip &ip, int port);
void reset();
void discoverServers(DiscoveredServersInterface *cb);
void stopServerDiscovery();
void sendSwitchSetupRequest(string selectedFactionName, int8 currentSlotIndex,
int8 toSlotIndex, int8 toTeam, string networkPlayerName,
int8 networkPlayerStatus, int8 flags,
string language);
virtual bool getConnectHasHandshaked() const {
return gotIntro;
}
std::string getServerIpAddress();
int getCurrentFrameCount() const {
return currentFrameCount;
}
virtual void sendPingMessage(int32 pingFrequency, int64 pingTime);
const string &getVersionString() const {
return versionString;
}
virtual string getHumanPlayerName(int index = -1);
virtual int getHumanPlayerIndex() const {
return playerIndex;
}
int getServerFTPPort() const {
return serverFTPPort;
}
int getSessionKey() const {
return sessionKey;
}
bool isMasterServerAdminOverride();
void setGameSettings(GameSettings *serverGameSettings);
void broadcastGameSetup(const GameSettings *gameSettings);
void broadcastGameStart(const GameSettings *gameSettings);
void updateNetworkFrame();
virtual void saveGame(XmlNode *rootNode) {
};
protected:
Mutex * getServerSynchAccessor() {
return NULL;
}
NetworkMessageType waitForMessage(int waitMicroseconds = 0);
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType);
void updateFrame(int *checkFrame);
void shutdownNetworkCommandListThread(MutexSafeWrapper &safeMutexWrapper);
bool getNetworkCommand(int frameCount, int currentCachedPendingCommandsIndex);
void close(bool lockMutex);
};
}
}//end namespace
#endif