File: NetProtocol.h

package info (click to toggle)
spring 106.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,316 kB
  • sloc: cpp: 543,954; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (132 lines) | stat: -rw-r--r-- 3,540 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef NET_PROTOCOL_H
#define NET_PROTOCOL_H

#include <atomic>
#include <string>

#include "BaseNetProtocol.h" // not used in here, but in all files including this one
#include "System/Threading/SpringThreading.h"

class ClientSetup;
class CDemoRecorder;

namespace netcode
{
	class RawPacket;
	class CConnection;
}

/**
 * @brief Client interface for handling communication with the game server.
 *
 * Even when playing singleplayer, this is the way of communicating
 * with the server. It keeps the connection alive,
 * and is able to send and receive raw binary packets transparently
 * over the network.
*/
class CNetProtocol
{
public:
	CNetProtocol();
	~CNetProtocol();

	/**
	 * @brief Initialise in client mode (remote server)
	*/
	void InitClient(std::shared_ptr<ClientSetup> clientSetup, const std::string& clientVersion, const std::string& clientPlatform);

	/**
	 * @brief Initialise in client mode (local server)
	 */
	void InitLocalClient();

	/// Are we still connected (or did the connection time-out)?
	bool CheckTimeout(int nsecs = 0, bool initial = false) const;

	void AttemptReconnect(const std::string& myVersion, const std::string& myPlatform);

	bool NeedsReconnect();

	/// This checks if any data has been received yet
	bool Connected() const;

	std::string ConnectionStr() const;

	/**
	 * @brief Take a look at the messages in the recieve buffer (read-only)
	 * @return A RawPacket holding the data, or 0 if no data
	 * @param ahead How many packets to look ahead. A typical usage would be:
	 * for (int ahead = 0; (packet = clientNet->Peek(ahead)) != NULL; ++ahead) {}
	 */
	std::shared_ptr<const netcode::RawPacket> Peek(unsigned ahead) const;

	/**
	 * @brief Deletes a packet from the buffer
	 * @param index queue index number
	 * useful for messages that skips queuing and needs to be processed immediately
	 */
	void DeleteBufferPacketAt(unsigned index);

	float GetPacketTime(int frameNum) const;

	/**
	 * @brief Receive a single message (and remove it from the recieve buffer)
	 * @return The first data packet from the buffer, or 0 if there is no data
	 *
	 * Receives only one message at a time
	 * (even if there are more in the recieve buffer),
	 * so call this until you get a 0 in return.
	 * When a demo recorder is present it will be recorded.
	 */
	std::shared_ptr<const netcode::RawPacket> GetData(int framenum);

	/**
	 * @brief Send a message to the server
	 */
	void Send(std::shared_ptr<const netcode::RawPacket> pkt);
	/// @overload
	void Send(const netcode::RawPacket* pkt);

	/**
	 * Updates our network while the game loads to prevent timeouts.
	 * Runs until \a keepUpdating is false.
	 */
	void UpdateLoop();

	/// Must be called to send / recieve packets
	void Update();

	void Close(bool flush = false);

	void KeepUpdating(bool b) { keepUpdating = b; }

	void SetDemoRecorder(CDemoRecorder&& r);
	void ResetDemoRecorder();

	netcode::CConnection* GetServerConnection() { return serverConnPtr; }
	CDemoRecorder* GetDemoRecorder() { return demoRecordPtr; }

	unsigned int GetNumWaitingServerPackets() const;
	unsigned int GetNumWaitingPingPackets() const;

private:
	std::atomic<bool> keepUpdating;

	spring::spinlock serverConnMutex;

	uint8_t serverConnMem[1024];
	uint8_t demoRecordMem[ 512];

	netcode::CConnection* serverConnPtr = nullptr;
	CDemoRecorder* demoRecordPtr = nullptr;

	std::string userName;
	std::string userPasswd;
};

extern CNetProtocol* clientNet;

#endif // NET_PROTOCOL_H