summaryrefslogtreecommitdiff
path: root/csgo-loader/csgo-server/Networking/TCPServer.hpp
blob: 9459136c6bca3d74b1097de0d1517d824cc51023 (plain)
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
#pragma once

// For encryption wrappers.
#include <Security/Encryption.hpp>

// WinSocks
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

// std::function
#include <functional>

// std::min
#include <algorithm>

// std::thread
#include <thread>

namespace Networking
{
	// Base connection class, used to handle multiple connections in a thread-based model.
	class TCPConnection
	{
		SOCKET				m_Socket;
		Wrapper::Encryption m_Encryption;
		char				m_IpAddress[32];

	public:
		// Initialiser for TCPConnection class.
		TCPConnection(SOCKET Connection, const char *IpAddress, Wrapper::Encryption &RSA) :
			m_Encryption(RSA), m_Socket(Connection)
		{
			strcpy_s<32>(m_IpAddress, IpAddress);
			printf("[ => ] %s connected!\n", m_IpAddress);
		}

		// Release the connection once it goes out of scope.
		void Close();

		// Wrappers for sending/receiving data.
		void SendRawBytes(ByteArray &Bytes);
		ByteArray ReceiveRawBytes();

		void SendBytes(ByteArray &Bytes);
		ByteArray ReceiveBytes();

		// Overload for getting the socket, in case we need to expose it.
		SOCKET operator()()
		{
			return m_Socket;
		}

		// Expose the encryption key for the connection.
		ByteArray GetEncryptionKey()
		{
			return m_Encryption.GetKey();
		}

		char *GetIpAddress() { return m_IpAddress; }
	};

	// Basic TCP server. Supports custom connection handling (pass a lambda to the handler list).
	using ConnectionHandler = std::function<void(TCPConnection &)>;

	class TCPServer
	{
		WSADATA		m_WinSocks;
		SOCKET		m_Socket;
		sockaddr_in m_Context;

		// Connection handlers, will be called sequentially upon connection.
		ConnectionHandler m_ConnectionHandler;

	public:
		// Default constructor, nothing needed for now.
		TCPServer() = default;

		// Handle destruction of server once it goes out of scope.
		~TCPServer()
		{
			// If we have a socket, close it.
			if(m_Socket)
				closesocket(m_Socket);

			// Close WSA context.
			WSACleanup();
		}

		// Handle the creation and handling of TCPServer connections.
		bool Start(uint16_t ServerPort);
		void AcceptConnection();

		// Overload for adding connection handlers, C# style support for events.
		void operator+=(std::function<void(TCPConnection &)> Function)
		{
			m_ConnectionHandler = Function;
		}
	};
}