summaryrefslogtreecommitdiffstats
path: root/Network.cpp
blob: 8b25756d63249067c15b6f707a8aed7794b66309 (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
#include <iostream>
#include "Network.hpp"
#include "PacketBuilder.hpp"

Network::Network(std::string address, unsigned short port) : m_address(address), m_port(port) {
    std::cout << "Connecting to server " << m_address << ":" << m_port << std::endl;
    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) {
            std::cerr << "Can't connect to remote server" << std::endl;
            throw 14;
        } else {
            std::cerr << "Connection failed with unknown reason" << std::endl;
            throw 13;
        }
    }
    std::cout << "Connected." << std::endl;
}

Network::~Network() {
    std::cout << "Disconnecting..." << std::endl;
    m_socket.disconnect();
}

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 Network::SendPacket(Packet &packet) {
    m_socket.setBlocking(true);
    byte *packetData = new byte[packet.GetLength()];
    packet.CopyToBuff(packetData);
    m_socket.send(packetData, packet.GetLength());
    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(VarInt, bufLen);
    size_t packetLen = fLen.GetVarInt() + fLen.GetLength();
    if (packetLen > 1024 * 1024 * 30)
        std::cout << "OMG! SIZEOF PACKET IS " << packetLen << std::endl;
    if (packetLen < rec) {
        return Packet(bufLen);
    }
    byte *bufPack = new byte[packetLen];
    for (int i = 0; i < packetLen; i++)
        bufPack[i] = 'N';
    memcpy(bufPack, bufLen, rec);
    if (m_socket.receive(bufPack + rec, packetLen - rec, rec) != sf::Socket::Done) {
        delete[] bufPack;
        throw 93;
    }
    rec++;
    //Check for losted data
    int losted = 0;
    for (int i = packetLen - 2; i > 0; i--)
        if (bufPack[i] == 'N')
            losted++;
    if (losted > 100) {
        if (m_socket.receive(bufPack + rec, packetLen - rec, rec) != sf::Socket::Done) {
            throw 93;
        }
        std::cout << "Keep receiving!" << std::endl;
    }
    //One more time
    losted = 0;
    for (int i = packetLen - 2; i > 0; i--)
        if (bufPack[i] == 'N')
            losted++;
    if (losted > 100) {
        std::cout << "\x1b[31m" << "Losted " << losted << " bytes of " << packetLen << "\x1b[0m" << std::endl;
        delete[] bufPack;
        throw 93;
    }
    Packet p(bufPack);
    delete[] bufPack;
    return p;
}