summaryrefslogtreecommitdiffstats
path: root/src/network/Network.cpp
blob: 4ce424c13f3583cefe535f7b3933d0f020bd4505 (plain) (blame)
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
#include "Network.hpp"

Network::Network(std::string address, unsigned short port) : m_address(address), m_port(port) {
	LOG(INFO) << "Connecting to server " << m_address << ":" << m_port;
	sf::Socket::Status status = m_socket.connect(sf::IpAddress(m_address), m_port);
	m_socket.setBlocking(true);
	if (status != sf::Socket::Done) {
		if (status == sf::Socket::Error) {
			LOG(ERROR) << "Can't connect to remote server";
		} else {
			LOG(ERROR) << "Connection failed with unknown reason";
			throw std::runtime_error("Connection is failed");
			throw 13;
		}
	}
	LOG(INFO) << "Connected to server";
}

Network::~Network() {
	m_socket.disconnect();
	LOG(INFO) << "Disconnected";
}

void Network::SendHandshake(std::string username) {
	//Handshake packet
	Packet handshakePacket = PacketBuilder::CHandshaking0x00(316, m_address, m_port, 2);
	SendPacket(handshakePacket);

	//LoginStart packet
	Field fName;
	fName.SetString(username);
	Packet loginPacket(0);
	loginPacket.AddField(fName);
	SendPacket(loginPacket);
}

void DumpPacket(Packet &packet, std::string DumpName) {
	return;
	byte *buff = new byte[packet.GetLength()];
	packet.CopyToBuff(buff);
	std::ofstream fs(DumpName, std::ios::out | std::ios::binary);
	fs.write(reinterpret_cast<const char *>(buff), packet.GetLength());
	fs.close();
	delete buff;
}

static int pn = 0;

void Network::SendPacket(Packet &packet) {
	m_socket.setBlocking(true);
	byte *packetData = new byte[packet.GetLength()];
	packet.CopyToBuff(packetData);
	m_socket.send(packetData, packet.GetLength());
	std::ostringstream out;
	out << "s" << pn++ << "-";
	out << "0x" << (packet.GetId() < 15 ? "0" : "") << std::hex << packet.GetId() << std::dec;
	DumpPacket(packet, out.str());

	delete[] packetData;
}

Packet Network::ReceivePacket() {
	byte bufLen[5] = {0};
	size_t rec = 0;
	for (int i = 0; i < 5; i++) {
		byte buff = 0;
		size_t r = 0;
		m_socket.receive(&buff, 1, r);
		rec += r;
		bufLen[i] = buff;
		if ((buff & 0b10000000) == 0) {
			break;
		}
	}
	Field fLen = FieldParser::Parse(VarIntType, bufLen);
	size_t packetLen = fLen.GetVarInt() + fLen.GetLength();
	if (packetLen > 1024 * 1024 * 15)
		LOG(WARNING) << "OMG SIZEOF PACKAGE IS " << packetLen;
	if (packetLen < rec) {
		return Packet(bufLen);
	}
	byte *bufPack = new byte[packetLen];
	std::copy(bufLen, bufLen + rec, bufPack);
	size_t dataLen = rec;
	while (m_socket.receive(bufPack + dataLen, packetLen - dataLen, rec) == sf::Socket::Done && dataLen < packetLen) {
		dataLen += rec;
	}
	if (dataLen < packetLen) {
		LOG(ERROR) << "Received data is " << dataLen << " but " << packetLen << " is promoted";
		throw std::runtime_error("Data is losted");
	} else {
		Packet p(bufPack);
		delete[] bufPack;

		std::ostringstream out;
		out << "r" << pn++ << "-";
		out << "0x" << (p.GetId() < 15 ? "0" : "") << std::hex << p.GetId() << std::dec;
		DumpPacket(p, out.str());
		return p;
	}
}