forked from otland/forgottenserver
-
Notifications
You must be signed in to change notification settings - Fork 1
/
connection.h
125 lines (95 loc) · 3.12 KB
/
connection.h
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
// Copyright 2023 The Forgotten Server Authors. All rights reserved.
// Use of this source code is governed by the GPL-2.0 License that can be found in the LICENSE file.
#ifndef FS_CONNECTION_H
#define FS_CONNECTION_H
#include "networkmessage.h"
enum ConnectionState_t
{
CONNECTION_STATE_DISCONNECTED,
CONNECTION_STATE_REQUEST_CHARLIST,
CONNECTION_STATE_GAMEWORLD_AUTH,
CONNECTION_STATE_GAME,
CONNECTION_STATE_PENDING
};
enum checksumMode_t
{
CHECKSUM_DISABLED,
CHECKSUM_ADLER,
CHECKSUM_SEQUENCE
};
static constexpr int32_t CONNECTION_WRITE_TIMEOUT = 30;
static constexpr int32_t CONNECTION_READ_TIMEOUT = 30;
class Protocol;
using Protocol_ptr = std::shared_ptr<Protocol>;
class OutputMessage;
using OutputMessage_ptr = std::shared_ptr<OutputMessage>;
class Connection;
using Connection_ptr = std::shared_ptr<Connection>;
using ConnectionWeak_ptr = std::weak_ptr<Connection>;
class ServiceBase;
using Service_ptr = std::shared_ptr<ServiceBase>;
class ServicePort;
using ServicePort_ptr = std::shared_ptr<ServicePort>;
using ConstServicePort_ptr = std::shared_ptr<const ServicePort>;
class ConnectionManager
{
public:
static ConnectionManager& getInstance()
{
static ConnectionManager instance;
return instance;
}
Connection_ptr createConnection(boost::asio::io_context& io_context, ConstServicePort_ptr servicePort);
void releaseConnection(const Connection_ptr& connection);
void closeAll();
private:
ConnectionManager() = default;
std::unordered_set<Connection_ptr> connections;
std::mutex connectionManagerLock;
};
class Connection : public std::enable_shared_from_this<Connection>
{
public:
using Address = boost::asio::ip::address;
// non-copyable
Connection(const Connection&) = delete;
Connection& operator=(const Connection&) = delete;
enum
{
FORCE_CLOSE = true
};
Connection(boost::asio::io_context& io_context, ConstServicePort_ptr service_port);
~Connection();
friend class ConnectionManager;
void close(bool force = false);
// Used by protocols that require server to send first
void accept(Protocol_ptr protocol);
void accept();
void send(const OutputMessage_ptr& msg);
const Address& getIP() const { return remoteAddress; };
private:
void parseHeader(const boost::system::error_code& error);
void parsePacket(const boost::system::error_code& error);
void onWriteOperation(const boost::system::error_code& error);
static void handleTimeout(ConnectionWeak_ptr connectionWeak, const boost::system::error_code& error);
void closeSocket();
void internalSend(const OutputMessage_ptr& msg);
boost::asio::ip::tcp::socket& getSocket() { return socket; }
friend class ServicePort;
NetworkMessage msg;
boost::asio::steady_timer readTimer;
boost::asio::steady_timer writeTimer;
std::recursive_mutex connectionLock;
std::list<OutputMessage_ptr> messageQueue;
ConstServicePort_ptr service_port;
Protocol_ptr protocol;
boost::asio::ip::tcp::socket socket;
Address remoteAddress;
time_t timeConnected;
uint32_t packetsSent = 0;
ConnectionState_t connectionState = CONNECTION_STATE_PENDING;
bool receivedFirst = false;
bool receivedName = false;
bool receivedLastChar = false;
};
#endif // FS_CONNECTION_H