-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathNetworkClient.h
More file actions
270 lines (202 loc) · 9.16 KB
/
NetworkClient.h
File metadata and controls
270 lines (202 loc) · 9.16 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#pragma once
// TODO: Figure out how to deal with anything that is defined by these and include them in implementation only to remove Windows.h macro pollution from our headers.
#include "RakPeerInterface.h"
#include "NatPunchthroughClient.h"
// RakNet includes Windows.h so we need to undefine macros that conflict with our method names.
#undef GetClassName
#include "Singleton.h"
#include "NetworkMessages.h"
#include "PostProcessMan.h"
#include "Vector.h"
#define g_NetworkClient NetworkClient::Instance()
/////////////////////////////////////////////////////////////////////////
// TODO: Get Weegee to comment all these because I don't even.
/////////////////////////////////////////////////////////////////////////
namespace RTE {
class SoundContainer;
/// The centralized singleton manager of the network multiplayer client.
class NetworkClient : public Singleton<NetworkClient> {
friend class SettingsMan;
public:
#pragma region Creation
/// Constructor method used to instantiate a NetworkClient object in system memory. Create() should be called before using the object.
NetworkClient();
/// Makes the NetworkClient object ready for use.
/// @return An error return value signaling success or any particular failure. Anything below 0 is an error signal.
int Initialize();
#pragma endregion
#pragma region Destruction
/// Destructor method used to clean up a NetworkClient object before deletion from system memory.
~NetworkClient();
/// Destroys and resets (through Clear()) the NetworkClient object.
void Destroy() { Clear(); }
#pragma endregion
#pragma region Getters
/// Gets whether the client is connected and registered to a server.
/// @return Whether the client is connected and registered to a server.
bool IsConnectedAndRegistered() const { return m_IsConnected && m_IsRegistered; }
/// Gets scene width for network client.
/// @return Current scene width.
int GetSceneWidth() const { return m_SceneWidth; }
/// Gets scene height for network client.
/// @return Current scene height.
int GetSceneHeight() const { return m_SceneHeight; }
/// Indicates whether the scene wraps its scrolling around the X axis for network client.
/// @return Whether the scene wraps around the X axis or not.
bool SceneWrapsX() const { return m_SceneWrapsX; }
/// Get the coordinates of the center of the current frame.
/// @return A vector containing the X/Y coordinates of the frame target.
const Vector& GetFrameTarget() const { return m_TargetPos[m_CurrentFrameNum]; }
#pragma endregion
#pragma region Concrete Methods
/// Updates the state of this NetworkClient. Supposed to be done every frame.
void Update();
#pragma endregion
#pragma region Connection Handling
/// Connects the client to a server.
/// @param serverName Server name (or address) to connect to.
/// @param serverPort Server port.
/// @param playerName Player name to be used in network game.
void Connect(std::string serverName, unsigned short serverPort, std::string playerName);
/// Connects the client to a server through a NAT service.
/// @param address The NAT service address.
void ConnectNAT(RakNet::SystemAddress address);
/// Disconnects the client from the currently connected server.
void Disconnect();
/// Connects to a NAT service and performs punch-through.
/// @param serviceServerName NAT service server name (or address) to use for punch-through.
/// @param serviceServerPort NAT service server port.
/// @param playerName Player name to be used in network game.
/// @param serverName Server name (or address) to connect to.
/// @param serverPassword Server password.
void PerformNATPunchThrough(std::string serviceServerName, unsigned short serviceServerPort, std::string playerName, std::string serverName, std::string serverPassword);
///
/// @param rakPeer
/// @param address
/// @param port
/// @return
RakNet::SystemAddress ConnectBlocking(RakNet::RakPeerInterface* rakPeer, const char* address, unsigned short port);
#pragma endregion
protected:
static constexpr unsigned short c_PlayerNameCharLimit = 15; //!< Maximum length of the player name.
std::string m_PlayerName; //!< The player name the will be used by the client in network games.
RakNet::RakPeerInterface* m_Client; //!< The client RakPeerInterface.
RakNet::SystemAddress m_ClientID; //!< The client's identifier.
RakNet::SystemAddress m_ServerID; //!< The server's identifier.
RakNet::RakNetGUID m_ServerGUID; //!< The server's Globally Unique Identifier.
RakNet::NatPunchthroughClient m_NATPunchthroughClient; //!< The NAT punch-through client.
RakNet::SystemAddress m_NATServiceServerID; //!< The NAT server's identifier.
bool m_UseNATPunchThroughService; //!< Whether to use NAT service for connecting to server.
bool m_IsConnected; //!< Is client connected to server.
bool m_IsRegistered; //!< Is client registered at server.
bool m_IsNATPunched; //!< Is client connected through NAT service.
unsigned char m_PixelLineBuffer[c_MaxPixelLineBufferSize]; //!<
long int m_ReceivedData; //!<
long int m_CompressedData; //!<
int m_ClientInputFps; //!< The rate (in FPS) the client input is sent to the server.
long long m_LastInputSentTime; //!< The last time input was sent in real time ticks.
int m_CurrentFrameNum; //!< The received frame number.
int m_CurrentBoxWidth; //!< The received frame box width.
int m_CurrentBoxHeight; //!< The received frame box height.
bool m_CurrentFrameInterlaced; //!< Whether the received frame data is interlaced.
bool m_CurrentFrameDeltaCompressed; //!< Whether the received frame data is delta compressed.
bool m_ShowFillRate; //!<
Vector m_TargetPos[c_FramesToRemember]; //!<
std::list<PostEffect> m_PostEffects[c_FramesToRemember]; //!< List of post-effects received from server.
std::unordered_map<int, SoundContainer*> m_ServerSounds; //!< Unordered map of SoundContainers received from server. OWNED!!!
unsigned char m_SceneID; //!<
int m_CurrentSceneLayerReceived; //!<
BITMAP* m_SceneBackgroundBitmap; //!<
BITMAP* m_SceneForegroundBitmap; //!<
BITMAP* m_BackgroundBitmaps[c_MaxLayersStoredForNetwork]; //!<
LightweightSceneLayer m_BackgroundLayers[c_FramesToRemember][c_MaxLayersStoredForNetwork]; //!<
int m_ActiveBackgroundLayers; //!<
bool m_SceneWrapsX; //!<
int m_SceneWidth; //!<
int m_SceneHeight; //!<
int m_MouseButtonPressedState[MAX_MOUSE_BUTTONS]; //!<
int m_MouseButtonReleasedState[MAX_MOUSE_BUTTONS]; //!<
int m_MouseWheelMoved; //!< Whether the mouse wheel was moved this Update. Used to make mouse wheel detection better.
private:
#pragma region Update Breakdown
///
void HandleNetworkPackets();
#pragma endregion
#pragma region Network Event Handling
///
/// @param packet
/// @return
unsigned char GetPacketIdentifier(RakNet::Packet* packet) const;
///
void SendRegisterMsg();
///
void ReceiveAcceptedMsg();
///
void SendDisconnectMsg();
///
/// @param address
/// @param serverName
/// @param serverPassword
void SendServerGUIDRequest(RakNet::SystemAddress address, std::string serverName, std::string serverPassword);
///
/// @param packet
void ReceiveServerGUIDAnswer(RakNet::Packet* packet);
///
void SendInputMsg();
///
/// @param packet
void ReceiveFrameSetupMsg(RakNet::Packet* packet);
///
/// @param packet
void ReceiveFrameLineMsg(RakNet::Packet* packet);
///
/// @param packet
void ReceiveFrameBoxMsg(RakNet::Packet* packet);
///
void SendSceneAcceptedMsg();
///
/// @param packet
void ReceiveSceneMsg(RakNet::Packet* packet);
///
void ReceiveSceneEndMsg();
///
/// @param packet
void ReceiveSceneSetupMsg(RakNet::Packet* packet);
///
void SendSceneSetupAcceptedMsg();
/// Receive and handle a packet of terrain change data.
/// @param packet The packet to handle.
void ReceiveTerrainChangeMsg(RakNet::Packet* packet);
/// Receive and handle a packet of post-effect data.
/// @param packet The packet to handle.
void ReceivePostEffectsMsg(RakNet::Packet* packet);
/// Receive and handle a packet of sound event data.
/// @param packet The packet to handle.
void ReceiveSoundEventsMsg(RakNet::Packet* packet);
/// Receive and handle a packet of music event data.
/// @param packet The packet to handle.
void ReceiveMusicEventsMsg(RakNet::Packet* packet);
#pragma endregion
#pragma region Drawing
///
/// @param targetBitmap
void DrawBackgrounds(BITMAP* targetBitmap);
///
/// @param frame
void DrawPostEffects(int frame);
///
/// @param frameNumber
/// @param useInterlacing
/// @param clearFramebuffer
void DrawFrame(int frameNumber, bool useInterlacing, bool clearFramebuffer);
#pragma endregion
/// Gets the ping time between the client and the server.
/// @return The ping time between the client and the server.
int GetPing() const { return IsConnectedAndRegistered() ? m_Client->GetLastPing(m_ServerID) : 0; }
/// Clears all the member variables of this NetworkClient, effectively resetting the members of this abstraction level only.
void Clear();
// Disallow the use of some implicit methods.
NetworkClient(const NetworkClient& reference) = delete;
NetworkClient& operator=(const NetworkClient& rhs) = delete;
};
} // namespace RTE