ddnet/src/engine/client/client.h

520 lines
18 KiB
C
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2010-05-29 07:25:38 +00:00
#ifndef ENGINE_CLIENT_CLIENT_H
#define ENGINE_CLIENT_CLIENT_H
2009-10-29 12:14:31 +00:00
#include <deque>
#include <memory>
#include <base/hash.h>
#include <engine/client.h>
#include <engine/client/checksum.h>
2020-09-10 18:14:47 +00:00
#include <engine/client/friends.h>
#include <engine/client/ghost.h>
#include <engine/client/serverbrowser.h>
#include <engine/client/updater.h>
#include <engine/editor.h>
#include <engine/graphics.h>
#include <engine/shared/config.h>
#include <engine/shared/demo.h>
#include <engine/shared/fifo.h>
#include <engine/shared/http.h>
#include <engine/shared/network.h>
2024-03-25 05:46:00 +00:00
#include <engine/textrender.h>
#include <engine/warning.h>
#include "graph.h"
#include "smooth_time.h"
2022-06-16 17:50:46 +00:00
class CDemoEdit;
class IDemoRecorder;
class CMsgPacker;
class CUnpacker;
class IConfigManager;
class IDiscord;
class IEngine;
2022-06-16 17:50:46 +00:00
class IEngineInput;
class IEngineMap;
class IEngineSound;
class IFriends;
class ILogger;
2022-06-16 17:50:46 +00:00
class ISteam;
class INotifications;
2022-06-16 17:50:46 +00:00
class IStorage;
class IUpdater;
2022-11-29 17:14:38 +00:00
#define CONNECTLINK_DOUBLE_SLASH "ddnet://"
#define CONNECTLINK_NO_SLASH "ddnet:"
class CServerCapabilities
{
public:
bool m_ChatTimeoutCode = false;
bool m_AnyPlayerFlag = false;
bool m_PingEx = false;
bool m_AllowDummy = false;
bool m_SyncWeaponInput = false;
};
class CClient : public IClient, public CDemoPlayer::IListener
2010-05-29 07:25:38 +00:00
{
// needed interfaces
IConfigManager *m_pConfigManager = nullptr;
CConfig *m_pConfig = nullptr;
IConsole *m_pConsole = nullptr;
IDiscord *m_pDiscord = nullptr;
IEditor *m_pEditor = nullptr;
IEngine *m_pEngine = nullptr;
IFavorites *m_pFavorites = nullptr;
IGameClient *m_pGameClient = nullptr;
IEngineGraphics *m_pGraphics = nullptr;
IEngineInput *m_pInput = nullptr;
IEngineMap *m_pMap = nullptr;
IEngineSound *m_pSound = nullptr;
ISteam *m_pSteam = nullptr;
INotifications *m_pNotifications = nullptr;
IStorage *m_pStorage = nullptr;
IEngineTextRender *m_pTextRender = nullptr;
IUpdater *m_pUpdater = nullptr;
2023-12-18 19:01:26 +00:00
CHttp m_Http;
2010-05-29 07:25:38 +00:00
CNetClient m_aNetClient[NUM_CONNS];
2022-06-16 17:50:46 +00:00
CDemoPlayer m_DemoPlayer;
CDemoRecorder m_aDemoRecorder[RECORDER_MAX];
2022-06-16 17:50:46 +00:00
CDemoEditor m_DemoEditor;
CGhostRecorder m_GhostRecorder;
CGhostLoader m_GhostLoader;
CServerBrowser m_ServerBrowser;
CUpdater m_Updater;
CFriends m_Friends;
CFriends m_Foes;
2010-05-29 07:25:38 +00:00
char m_aConnectAddressStr[MAX_SERVER_ADDRESSES * NETADDR_MAXSTRSIZE] = "";
2010-05-29 07:25:38 +00:00
CUuid m_ConnectionId = UUID_ZEROED;
bool m_HaveGlobalTcpAddr = false;
NETADDR m_GlobalTcpAddr = NETADDR_ZEROED;
uint64_t m_aSnapshotParts[NUM_DUMMIES] = {0, 0};
int64_t m_LocalStartTime = 0;
int64_t m_GlobalStartTime = 0;
2010-05-29 07:25:38 +00:00
IGraphics::CTextureHandle m_DebugFont;
2015-07-09 00:08:14 +00:00
2021-06-23 05:05:49 +00:00
int64_t m_LastRenderTime;
int m_SnapCrcErrors = 0;
bool m_AutoScreenshotRecycle = false;
bool m_AutoStatScreenshotRecycle = false;
bool m_AutoCSVRecycle = false;
bool m_EditorActive = false;
int m_aAckGameTick[NUM_DUMMIES] = {-1, -1};
int m_aCurrentRecvTick[NUM_DUMMIES] = {0, 0};
int m_aRconAuthed[NUM_DUMMIES] = {0, 0};
char m_aRconUsername[32] = "";
char m_aRconPassword[sizeof(g_Config.m_SvRconPassword)] = "";
int m_UseTempRconCommands = 0;
int m_ExpectedRconCommands = -1;
int m_GotRconCommands = 0;
char m_aPassword[sizeof(g_Config.m_Password)] = "";
bool m_SendPassword = false;
2010-05-29 07:25:38 +00:00
// version-checking
char m_aVersionStr[10] = "0";
2010-05-29 07:25:38 +00:00
// pinging
int64_t m_PingStartTime = 0;
2010-05-29 07:25:38 +00:00
char m_aCurrentMap[IO_MAX_PATH_LENGTH] = "";
char m_aCurrentMapPath[IO_MAX_PATH_LENGTH] = "";
2010-05-29 07:25:38 +00:00
char m_aTimeoutCodes[NUM_DUMMIES][32] = {"", ""};
bool m_aCodeRunAfterJoin[NUM_DUMMIES] = {false, false};
bool m_GenerateTimeoutSeed = true;
2014-08-17 17:19:40 +00:00
char m_aCmdConnect[256] = "";
char m_aCmdPlayDemo[IO_MAX_PATH_LENGTH] = "";
char m_aCmdEditMap[IO_MAX_PATH_LENGTH] = "";
2010-05-29 07:25:38 +00:00
// map download
char m_aMapDownloadUrl[256] = "";
std::shared_ptr<CHttpRequest> m_pMapdownloadTask = nullptr;
char m_aMapdownloadFilename[256] = "";
char m_aMapdownloadFilenameTemp[256] = "";
char m_aMapdownloadName[256] = "";
IOHANDLE m_MapdownloadFileTemp = 0;
int m_MapdownloadChunk = 0;
int m_MapdownloadCrc = 0;
int m_MapdownloadAmount = -1;
int m_MapdownloadTotalsize = -1;
bool m_MapdownloadSha256Present = false;
SHA256_DIGEST m_MapdownloadSha256 = SHA256_ZEROED;
bool m_MapDetailsPresent = false;
char m_aMapDetailsName[256] = "";
int m_MapDetailsCrc = 0;
SHA256_DIGEST m_MapDetailsSha256 = SHA256_ZEROED;
char m_aMapDetailsUrl[256] = "";
std::shared_ptr<CHttpRequest> m_pDDNetInfoTask = nullptr;
2010-05-29 07:25:38 +00:00
// time
CSmoothTime m_aGameTime[NUM_DUMMIES];
CSmoothTime m_PredictedTime;
2010-05-29 07:25:38 +00:00
// input
struct // TODO: handle input better
{
int m_aData[MAX_INPUT_SIZE]; // the input data
int m_Tick; // the tick that the input is for
2021-06-23 05:05:49 +00:00
int64_t m_PredictedTime; // prediction latency when we sent this input
2022-01-09 12:06:41 +00:00
int64_t m_PredictionMargin; // prediction margin when we sent this input
2021-06-23 05:05:49 +00:00
int64_t m_Time;
2020-10-18 14:51:26 +00:00
} m_aInputs[NUM_DUMMIES][200];
2010-05-29 07:25:38 +00:00
int m_aCurrentInput[NUM_DUMMIES] = {0, 0};
bool m_LastDummy = false;
bool m_DummySendConnInfo = false;
bool m_DummyConnecting = false;
bool m_DummyConnected = false;
float m_LastDummyConnectTime = 0.0f;
2010-05-29 07:25:38 +00:00
// graphs
CGraph m_InputtimeMarginGraph;
CGraph m_GametimeMarginGraph;
CGraph m_FpsGraph;
// the game snapshots are modifiable by the game
CSnapshotStorage m_aSnapshotStorage[NUM_DUMMIES];
CSnapshotStorage::CHolder *m_aapSnapshots[NUM_DUMMIES][NUM_SNAPSHOT_TYPES];
2010-05-29 07:25:38 +00:00
int m_aReceivedSnapshots[NUM_DUMMIES] = {0, 0};
char m_aaSnapshotIncomingData[NUM_DUMMIES][CSnapshot::MAX_SIZE];
int m_aSnapshotIncomingDataSize[NUM_DUMMIES] = {0, 0};
2010-05-29 07:25:38 +00:00
2022-06-16 17:50:46 +00:00
CSnapshotStorage::CHolder m_aDemorecSnapshotHolders[NUM_SNAPSHOT_TYPES];
Fix aliasing warnings in `CClient::DemoPlayer_Play` Fix warnings with `-fstrict-aliasing` and `-Wstrict-aliasing=2` by using char array instead of array of char pointers: ``` src/engine/client/client.cpp: In member function 'virtual const char* CClient::DemoPlayer_Play(const char*, int)': src/engine/client/client.cpp:3858:123: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 3858 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_CURRENT][0]; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ src/engine/client/client.cpp:3859:126: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 3859 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pAltSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_CURRENT][1]; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ src/engine/client/client.cpp:3864:117: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 3864 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_PREV][0]; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ src/engine/client/client.cpp:3865:120: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 3865 | m_aapSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pAltSnap = (CSnapshot *)m_aaapDemorecSnapshotData[SNAP_PREV][1]; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ ``` Snapshot data during demo playback was being stored in an array of `char *` instead of an array of `char`, which caused above aliasing warnings and used 8 times more memory for the snapshot storage than being necessary.
2022-11-12 19:12:24 +00:00
char m_aaaDemorecSnapshotData[NUM_SNAPSHOT_TYPES][2][CSnapshot::MAX_SIZE];
2010-05-29 07:25:38 +00:00
2022-06-16 17:50:46 +00:00
CSnapshotDelta m_SnapshotDelta;
2010-05-29 07:25:38 +00:00
std::deque<std::shared_ptr<CDemoEdit>> m_EditJobs;
2010-05-29 07:25:38 +00:00
//
bool m_CanReceiveServerCapabilities = false;
bool m_ServerSentCapabilities = false;
CServerCapabilities m_ServerCapabilities;
2022-06-16 17:50:46 +00:00
CServerInfo m_CurrentServerInfo;
int64_t m_CurrentServerInfoRequestTime = -1; // >= 0 should request, == -1 got info
2010-05-29 07:25:38 +00:00
int m_CurrentServerPingInfoType = -1;
int m_CurrentServerPingBasicToken = -1;
int m_CurrentServerPingToken = -1;
CUuid m_CurrentServerPingUuid = UUID_ZEROED;
int64_t m_CurrentServerCurrentPingTime = -1; // >= 0 request running
int64_t m_CurrentServerNextPingTime = -1; // >= 0 should request
2010-05-29 07:25:38 +00:00
// version info
struct CVersionInfo
2010-05-29 07:25:38 +00:00
{
enum
{
STATE_INIT = 0,
STATE_START,
STATE_READY,
};
int m_State = STATE_INIT;
2010-05-29 07:25:38 +00:00
} m_VersionInfo;
2011-02-27 14:03:57 +00:00
std::vector<SWarning> m_vWarnings;
std::vector<SWarning> m_vQuittingWarnings;
2016-05-02 21:36:21 +00:00
CFifo m_Fifo;
IOHANDLE m_BenchmarkFile = 0;
int64_t m_BenchmarkStopTime = 0;
2020-11-19 15:15:07 +00:00
CChecksum m_Checksum;
int m_OwnExecutableSize = 0;
IOHANDLE m_OwnExecutable = 0;
// favorite command handling
bool m_FavoritesGroup = false;
bool m_FavoritesGroupAllowPing = false;
int m_FavoritesGroupNum = 0;
NETADDR m_aFavoritesGroupAddresses[MAX_SERVER_ADDRESSES];
2021-07-19 18:14:12 +00:00
void UpdateDemoIntraTimers();
2022-01-09 12:06:41 +00:00
int MaxLatencyTicks() const;
int PredictionMargin() const;
2021-07-19 18:14:12 +00:00
std::shared_ptr<ILogger> m_pFileLogger = nullptr;
std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
2010-05-29 07:25:38 +00:00
public:
IConfigManager *ConfigManager() { return m_pConfigManager; }
CConfig *Config() { return m_pConfig; }
IDiscord *Discord() { return m_pDiscord; }
2011-02-27 14:03:57 +00:00
IEngine *Engine() { return m_pEngine; }
IGameClient *GameClient() { return m_pGameClient; }
2010-05-29 07:25:38 +00:00
IEngineGraphics *Graphics() { return m_pGraphics; }
IEngineInput *Input() { return m_pInput; }
IEngineSound *Sound() { return m_pSound; }
ISteam *Steam() { return m_pSteam; }
INotifications *Notifications() { return m_pNotifications; }
2010-05-29 07:25:38 +00:00
IStorage *Storage() { return m_pStorage; }
IEngineTextRender *TextRender() { return m_pTextRender; }
IUpdater *Updater() { return m_pUpdater; }
2023-12-18 19:01:26 +00:00
IHttp *Http() { return &m_Http; }
2010-05-29 07:25:38 +00:00
CClient();
// ----- send functions -----
int SendMsg(int Conn, CMsgPacker *pMsg, int Flags) override;
// Send via the currently active client (main/dummy)
int SendMsgActive(CMsgPacker *pMsg, int Flags) override;
2010-05-29 07:25:38 +00:00
void SendInfo(int Conn);
void SendEnterGame(int Conn);
void SendReady(int Conn);
void SendMapRequest();
2010-05-29 07:25:38 +00:00
bool RconAuthed() const override { return m_aRconAuthed[g_Config.m_ClDummy] != 0; }
bool UseTempRconCommands() const override { return m_UseTempRconCommands != 0; }
void RconAuth(const char *pName, const char *pPassword) override;
void Rcon(const char *pCmd) override;
bool ReceivingRconCommands() const override { return m_ExpectedRconCommands > 0; }
float GotRconCommandsPercentage() const override;
2010-05-29 07:25:38 +00:00
bool ConnectionProblems() const override;
2010-05-29 07:25:38 +00:00
IGraphics::CTextureHandle GetDebugFont() const override { return m_DebugFont; }
2010-05-29 07:25:38 +00:00
void SendInput();
2018-02-04 15:00:47 +00:00
// TODO: OPT: do this a lot smarter!
int *GetInput(int Tick, int IsDummy) const override;
2010-05-29 07:25:38 +00:00
const char *LatestVersion() const override;
2010-05-29 07:25:38 +00:00
// ------ state handling -----
void SetState(EClientState State);
2010-05-29 07:25:38 +00:00
// called when the map is loaded and we should init for a new round
void OnEnterGame(bool Dummy);
void EnterGame(int Conn) override;
2010-05-29 07:25:38 +00:00
void Connect(const char *pAddress, const char *pPassword = nullptr) override;
void DisconnectWithReason(const char *pReason);
void Disconnect() override;
2010-05-29 07:25:38 +00:00
void DummyDisconnect(const char *pReason) override;
void DummyConnect() override;
bool DummyConnected() const override;
bool DummyConnecting() const override;
bool DummyConnectingDelayed() const override;
bool DummyAllowed() const override;
2010-05-29 07:25:38 +00:00
void GetServerInfo(CServerInfo *pServerInfo) const override;
2010-05-29 07:25:38 +00:00
void ServerInfoRequest();
void LoadDebugFont();
2010-05-29 07:25:38 +00:00
// ---
int GetPredictionTime() override;
CSnapItem SnapGetItem(int SnapId, int Index) const override;
const void *SnapFindItem(int SnapId, int Type, int Id) const override;
int SnapNumItems(int SnapId) const override;
void SnapSetStaticsize(int ItemType, int Size) override;
2010-05-29 07:25:38 +00:00
void Render();
void DebugRender();
void Restart() override;
void Quit() override;
2010-05-29 07:25:38 +00:00
const char *PlayerName() const override;
const char *DummyName() const override;
const char *ErrorString() const override;
2010-05-29 07:25:38 +00:00
const char *LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc);
const char *LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedSha256, int WantedCrc);
2010-05-29 07:25:38 +00:00
void ProcessConnlessPacket(CNetChunk *pPacket);
void ProcessServerInfo(int Type, NETADDR *pFrom, const void *pData, int DataSize);
void ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy);
2010-05-29 07:25:38 +00:00
int UnpackAndValidateSnapshot(CSnapshot *pFrom, CSnapshot *pTo);
void ResetMapDownload();
void FinishMapDownload();
void RequestDDNetInfo() override;
void ResetDDNetInfoTask();
void FinishDDNetInfo();
void LoadDDNetInfo();
const NETADDR &ServerAddress() const override { return *m_aNetClient[CONN_MAIN].ServerAddress(); }
int ConnectNetTypes() const override;
const char *ConnectAddressString() const override { return m_aConnectAddressStr; }
const char *MapDownloadName() const override { return m_aMapdownloadName; }
int MapDownloadAmount() const override { return !m_pMapdownloadTask ? m_MapdownloadAmount : (int)m_pMapdownloadTask->Current(); }
int MapDownloadTotalsize() const override { return !m_pMapdownloadTask ? m_MapdownloadTotalsize : (int)m_pMapdownloadTask->Size(); }
2010-05-29 07:25:38 +00:00
void PumpNetwork();
void OnDemoPlayerSnapshot(void *pData, int Size) override;
void OnDemoPlayerMessage(void *pData, int Size) override;
2010-05-29 07:25:38 +00:00
void Update();
void RegisterInterfaces();
void InitInterfaces();
void Run();
bool InitNetworkClient(char *pError, size_t ErrorSize);
bool CtrlShiftKey(int Key, bool &Last);
2010-05-29 07:25:38 +00:00
static void Con_Connect(IConsole::IResult *pResult, void *pUserData);
static void Con_Disconnect(IConsole::IResult *pResult, void *pUserData);
static void Con_DummyConnect(IConsole::IResult *pResult, void *pUserData);
static void Con_DummyDisconnect(IConsole::IResult *pResult, void *pUserData);
2021-03-17 15:09:39 +00:00
static void Con_DummyResetInput(IConsole::IResult *pResult, void *pUserData);
static void Con_Quit(IConsole::IResult *pResult, void *pUserData);
2023-05-09 21:39:31 +00:00
static void Con_Restart(IConsole::IResult *pResult, void *pUserData);
static void Con_DemoPlay(IConsole::IResult *pResult, void *pUserData);
2016-04-27 15:21:40 +00:00
static void Con_DemoSpeed(IConsole::IResult *pResult, void *pUserData);
static void Con_Minimize(IConsole::IResult *pResult, void *pUserData);
static void Con_Ping(IConsole::IResult *pResult, void *pUserData);
static void Con_Screenshot(IConsole::IResult *pResult, void *pUserData);
2016-08-27 19:10:27 +00:00
#if defined(CONF_VIDEORECORDER)
void StartVideo(const char *pFilename, bool WithTimestamp);
2016-08-27 15:51:23 +00:00
static void Con_StartVideo(IConsole::IResult *pResult, void *pUserData);
static void Con_StopVideo(IConsole::IResult *pResult, void *pUserData);
const char *DemoPlayer_Render(const char *pFilename, int StorageType, const char *pVideoName, int SpeedIndex, bool StartPaused = false) override;
2016-08-27 19:10:27 +00:00
#endif
static void Con_Rcon(IConsole::IResult *pResult, void *pUserData);
static void Con_RconAuth(IConsole::IResult *pResult, void *pUserData);
2017-03-06 09:31:05 +00:00
static void Con_RconLogin(IConsole::IResult *pResult, void *pUserData);
static void Con_BeginFavoriteGroup(IConsole::IResult *pResult, void *pUserData);
static void Con_EndFavoriteGroup(IConsole::IResult *pResult, void *pUserData);
static void Con_AddFavorite(IConsole::IResult *pResult, void *pUserData);
static void Con_RemoveFavorite(IConsole::IResult *pResult, void *pUserData);
static void Con_Play(IConsole::IResult *pResult, void *pUserData);
static void Con_Record(IConsole::IResult *pResult, void *pUserData);
static void Con_StopRecord(IConsole::IResult *pResult, void *pUserData);
static void Con_AddDemoMarker(IConsole::IResult *pResult, void *pUserData);
2020-11-19 15:15:07 +00:00
static void Con_BenchmarkQuit(IConsole::IResult *pResult, void *pUserData);
static void ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainFullscreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainWindowBordered(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainWindowScreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainWindowVSync(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainWindowResize(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainTimeoutSeed(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2018-06-20 06:36:10 +00:00
static void ConchainPassword(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainReplays(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2019-04-21 16:20:53 +00:00
2014-08-12 14:21:06 +00:00
static void Con_DemoSlice(IConsole::IResult *pResult, void *pUserData);
static void Con_DemoSliceBegin(IConsole::IResult *pResult, void *pUserData);
2014-08-12 14:21:06 +00:00
static void Con_DemoSliceEnd(IConsole::IResult *pResult, void *pUserData);
2019-05-20 21:55:40 +00:00
static void Con_SaveReplay(IConsole::IResult *pResult, void *pUserData);
2014-08-12 14:21:06 +00:00
2010-05-29 07:25:38 +00:00
void RegisterCommands();
const char *DemoPlayer_Play(const char *pFilename, int StorageType) override;
void DemoRecorder_Start(const char *pFilename, bool WithTimestamp, int Recorder, bool Verbose = false) override;
void DemoRecorder_HandleAutoStart() override;
void DemoRecorder_UpdateReplayRecorder() override;
void DemoRecorder_AddDemoMarker(int Recorder);
2022-06-16 17:50:46 +00:00
IDemoRecorder *DemoRecorder(int Recorder) override;
2010-05-29 07:25:38 +00:00
void AutoScreenshot_Start() override;
void AutoStatScreenshot_Start() override;
void AutoScreenshot_Cleanup();
2015-05-19 22:51:02 +00:00
void AutoStatScreenshot_Cleanup();
void AutoCSV_Start() override;
void AutoCSV_Cleanup();
void ServerBrowserUpdate() override;
void HandleConnectAddress(const NETADDR *pAddr);
void HandleConnectLink(const char *pLink);
2019-04-10 06:56:20 +00:00
void HandleDemoPath(const char *pPath);
void HandleMapPath(const char *pPath);
virtual void InitChecksum();
virtual int HandleChecksum(int Conn, CUuid Uuid, CUnpacker *pUnpacker);
// gfx
void SwitchWindowScreen(int Index) override;
void SetWindowParams(int FullscreenMode, bool IsBorderless) override;
void ToggleWindowVSync() override;
void Notify(const char *pTitle, const char *pMessage) override;
void OnWindowResize() override;
2020-11-19 15:15:07 +00:00
void BenchmarkQuit(int Seconds, const char *pFilename);
void UpdateAndSwap() override;
// DDRace
void GenerateTimeoutSeed() override;
void GenerateTimeoutCodes(const NETADDR *pAddrs, int NumAddrs);
int GetCurrentRaceTime() override;
const char *GetCurrentMap() const override;
const char *GetCurrentMapPath() const override;
SHA256_DIGEST GetCurrentMapSha256() const override;
unsigned GetCurrentMapCrc() const override;
2017-09-09 21:10:42 +00:00
void RaceRecord_Start(const char *pFilename) override;
void RaceRecord_Stop() override;
bool RaceRecord_IsRecording() override;
void DemoSliceBegin() override;
void DemoSliceEnd() override;
void DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser) override;
2022-03-14 04:56:44 +00:00
virtual void SaveReplay(int Length, const char *pFilename = "");
2014-09-19 22:36:22 +00:00
bool EditorHasUnsavedData() const override { return m_pEditor->HasUnsavedData(); }
2015-07-22 20:16:49 +00:00
IFriends *Foes() override { return &m_Foes; }
void GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount) override;
void AddWarning(const SWarning &Warning) override;
SWarning *GetCurWarning() override;
std::vector<SWarning> &&QuittingWarnings() { return std::move(m_vQuittingWarnings); }
CChecksumData *ChecksumData() override { return &m_Checksum.m_Data; }
int UdpConnectivity(int NetType) override;
Use `SDL_OpenURL` to open links and files on Android Opening links and files with the `open_link` and `open_file` functions does not work on Android, as the `open_link` function uses `fork` which is not supported on Android. This also seems to cause a strange bug where client networking partially breaks. Currently, after trying to open any link, connecting to servers is not possible anymore but the server browser still works, with the connection getting stuck randomly in the connecting/loading state. SDL implements URL opening, including of file URIs, with the `SDL_OpenURL` function for most systems including Android. However, using `SDL_OpenURL` for all systems has several downsides: 1. The `SDL_OpenURL` function is only available since SDL 2.0.14, in particular not for the Ubuntu 20 CI runner. Hence, we would either have to conditionally compile the link opening function to a null-implementation or fallback to using the existing `open_link` function. 2. We would be undoing some additional fixes in the `open_link` function for Windows, which are not included in the Windows implementation of `SDL_OpenURL`. 3. This would also replace the use of `open` on UNIX with `xdg-open`. 4. This would move the functionality to open links and files from the base to the engine client, so we could not have tools or the server potentially making use of this functionality in the future (e.g. open a folder for convenience). Implementing link and file opening for Android ourselves is too much effort and potentially made even harder by SDL already managing all the unique JVM resources in the `SDLActivity`. Therefore, the `SDL_OpenURL` function is only used for Android, which is always based on the latest SDL2 version. The original `open_link` functionality is kept for the other systems. For this purpose, the `IClient::ViewLink` and `ViewFile` functions are added to wrap `open_link` and `open_file` for the client and also reduce some duplicate code for error logging. Unfortunately, testing also revealed that `SDL_OpenURL` does not currently support opening file URIs, at least not of files the internal storage location, which all the DDNet client's files would be located in. At least opening URLs works and neither breaks networking anymore.
2024-06-30 11:45:57 +00:00
bool ViewLink(const char *pLink) override;
bool ViewFile(const char *pFilename) override;
#if defined(CONF_FAMILY_WINDOWS)
void ShellRegister() override;
void ShellUnregister() override;
#endif
void ShowMessageBox(const char *pTitle, const char *pMessage, EMessageBoxType Type = MESSAGE_BOX_TYPE_ERROR) override;
void GetGpuInfoString(char (&aGpuInfo)[256]) override;
void SetLoggers(std::shared_ptr<ILogger> &&pFileLogger, std::shared_ptr<ILogger> &&pStdoutLogger);
2010-05-29 07:25:38 +00:00
};
2010-05-29 07:25:38 +00:00
#endif