-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPacket.cpp
167 lines (142 loc) · 5.02 KB
/
Packet.cpp
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
#include "Packet.h"
enum struct DATA_TYPE {
BYTE = 0,
SHORT = 1,
INTEGER = 2,
FLOAT = 3,
STRING = 4,
FILE = 5
};
Packet::Packet() {
p = new ENetPacket();
}
Packet::Packet(ENetPacket* pac, int id) {
p = pac;
originalID = id;
}
Packet::~Packet() {
if (p)
enet_packet_destroy(p);
}
Packet::Packet(const void* data, size_t size, int sender) {
p = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
originalID = sender;
}
void Packet::append(int type, sol::object data) {
DATA_TYPE t = (DATA_TYPE)type;
switch (t) {
case DATA_TYPE::BYTE: {
uint8_t value = data.as<uint8_t>();
enet_packet_resize(p, p->dataLength + sizeof(value));
memcpy(p->data + p->dataLength - sizeof(value), &value, sizeof(value));
break;
}
case DATA_TYPE::SHORT: {
uint16_t value = data.as<uint16_t>();
enet_packet_resize(p, p->dataLength + sizeof(value));
memcpy(p->data + p->dataLength - sizeof(value), &value, sizeof(value));
break;
}
case DATA_TYPE::INTEGER: {
int32_t value = data.as<int32_t>();
enet_packet_resize(p, p->dataLength + sizeof(value));
memcpy(p->data + p->dataLength - sizeof(value), &value, sizeof(value));
break;
}
case DATA_TYPE::FLOAT: {
float value = data.as<float>();
enet_packet_resize(p, p->dataLength + sizeof(value));
memcpy(p->data + p->dataLength - sizeof(value), &value, sizeof(value));
break;
}
case DATA_TYPE::STRING: {
std::string value = data.as<std::string>();
uint16_t length = static_cast<uint16_t>(value.size());
enet_packet_resize(p, p->dataLength + sizeof(length) + length);
memcpy(p->data + p->dataLength - (sizeof(length) + length), &length, sizeof(length));
memcpy(p->data + p->dataLength - length, value.data(), length);
break;
}
case DATA_TYPE::FILE: {
std::string filePath = data.as<std::string>();
std::ifstream file(filePath, std::ios::binary);
if (!file.is_open()) return;
std::stringstream buffer;
buffer << file.rdbuf();
std::string fileContent = buffer.str();
uint32_t fileSize = static_cast<uint32_t>(fileContent.size());
enet_packet_resize(p, p->dataLength + sizeof(fileSize) + fileSize);
memcpy(p->data + p->dataLength - (sizeof(fileSize) + fileSize), &fileSize, sizeof(fileSize));
memcpy(p->data + p->dataLength - fileSize, fileContent.data(), fileSize);
break;
}
}
}
void Packet::clear() {
if (p) enet_packet_destroy(p);
}
int Packet::getSize() {
return p ? p->dataLength : 0;
}
int Packet::getSenderID() {
return p ? originalID : -1;
}
sol::object Packet::get(int type, size_t bytePos) {
DATA_TYPE t = (DATA_TYPE)type;
sol::object result;
switch (t) {
case DATA_TYPE::BYTE: {
uint8_t value;
memcpy(&value, p->data + bytePos, sizeof(value));
result = sol::make_object((*lua), value); // LuaState should be the current Lua state object
break;
}
case DATA_TYPE::SHORT: {
uint16_t value;
memcpy(&value, p->data + bytePos, sizeof(value));
result = sol::make_object((*lua), value);
break;
}
case DATA_TYPE::INTEGER: {
int32_t value;
memcpy(&value, p->data + bytePos, sizeof(value));
result = sol::make_object((*lua), value);
break;
}
case DATA_TYPE::FLOAT: {
float value;
memcpy(&value, p->data + bytePos, sizeof(value));
result = sol::make_object((*lua), value);
break;
}
case DATA_TYPE::STRING: {
uint16_t length;
memcpy(&length, p->data + bytePos, sizeof(length));
bytePos += sizeof(length);
std::string value(reinterpret_cast<char*>(p->data + bytePos), length);
result = sol::make_object((*lua), value);
break;
}
}
return result;
}
bool Packet::writeToFile(int bytePos, std::string path) {
if (bytePos < 0 || bytePos >= p->dataLength) return false;
size_t dataSize = p->dataLength - bytePos - 4;
std::string dataBuffer(reinterpret_cast<char*>(p->data + bytePos + 4), dataSize);
std::ofstream outFile(path, std::ios::binary);
if (!outFile.is_open()) return false;
outFile.write(dataBuffer.c_str(), dataSize);
outFile.close();
return true;
}
void bindPacket() {
sol::usertype<Packet> bind_type = lua->new_usertype<Packet>("Packet",
sol::constructors<Packet()>(),
"ID", &Packet::originalID);
bind_type["append"] = &Packet::append;
bind_type["get"] = &Packet::get;
bind_type["getSize"] = &Packet::getSize;
bind_type["destroy"] = &Packet::clear;
bind_type["writeToFile"] = &Packet::writeToFile;
}