Snake/SnakeServer/ClientProtocol/clientprotocol.cpp

210 lines
4.5 KiB
C++
Raw Normal View History

2019-02-12 13:12:11 +03:00
#include "clientprotocol.h"
2019-02-13 13:03:40 +03:00
2019-02-25 21:38:37 +03:00
#include <QDataStream>
2019-02-13 13:03:40 +03:00
#include <QVariantMap>
2019-02-25 21:38:37 +03:00
#include <networkobjects.h>
#include <streamers.h>
2019-02-13 13:03:40 +03:00
#define DEFAULT_GAME_PORT 7777
namespace ClientProtocol {
Header::Header() {
reset();
}
bool Header::isValid() const {
2019-03-05 00:48:32 +03:00
if (sizeof (*this) != 8) {
2019-02-13 13:03:40 +03:00
return false;
}
2019-03-05 00:48:32 +03:00
return isValidSize(static_cast<NetworkClasses::Type>(command) , size);
2019-02-13 13:03:40 +03:00
2019-03-05 00:48:32 +03:00
// switch (command) {
// case Ping: {
2019-02-13 13:03:40 +03:00
2019-03-05 00:48:32 +03:00
// if (type > 1 || size > 0)
// return false;
2019-02-13 13:03:40 +03:00
2019-03-05 00:48:32 +03:00
// return true;
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// case Item: {
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// switch (type) {
// case Request: return size == 36; // key sha256 (32byte) + id item 4
// case Responke: return true;
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// return false;
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// case Login: {
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// switch (type) {
// case Request: return size > 36; // key sha256 (32byte) + 4 size array + maxsize of name of gmail (64)
// case Responke: return isValidSize(NetworkClasses::Player, size);
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// return false;
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// case PlayerData: {
2019-03-05 00:48:32 +03:00
// switch (type) {
// case Request: return size == 36; // key sha256 (32byte + size of array)
// case Responke: return isValidSize(NetworkClasses::Player, size);
// }
2019-03-05 00:48:32 +03:00
// return false;
// }
2019-03-05 00:48:32 +03:00
// case SaveData: {
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// switch (type) {
// case Request: return isValidSize(NetworkClasses::Game, size);; // key sha256 (32byte) + maxsize of name of gmail (64)
// case Responke: return isValidSize(NetworkClasses::Player, size);
// }
2019-02-13 22:03:29 +03:00
2019-03-05 00:48:32 +03:00
// return false;
// }
// default: return false;
// }
2019-02-13 13:03:40 +03:00
}
void Header::reset() {
size = 0;
2019-02-15 23:36:59 +03:00
command = Undefined;
2019-02-13 13:03:40 +03:00
type = Responke;
}
Package::Package() {
reset();
}
bool Package::isValid() const {
if (!hdr.isValid()) {
return false;
}
2019-03-05 00:48:32 +03:00
return hdr.size == static_cast<unsigned int> (data.size());
2019-02-13 13:03:40 +03:00
}
2019-02-15 23:36:59 +03:00
bool Package::parse(QVariantMap& res) const {
2019-02-13 13:03:40 +03:00
if (!isValid())
2019-02-15 23:36:59 +03:00
return false;
2019-02-13 13:03:40 +03:00
res["command"] = hdr.command;
res["type"] = hdr.type;
2019-03-02 13:29:21 +03:00
res["sig"] = hdr.sig;
2019-03-05 00:48:32 +03:00
QDataStream stream(data);
2019-03-05 00:48:32 +03:00
if (!Streamers::read(stream, res, static_cast<NetworkClasses::Type>(hdr.command))) {
2019-02-15 23:36:59 +03:00
return false;
2019-02-13 13:03:40 +03:00
}
2019-02-15 23:36:59 +03:00
return true;
}
2019-02-26 20:24:05 +03:00
2019-03-05 00:48:32 +03:00
bool Package::create(const QVariantMap &map, Type type) {
2019-02-15 23:36:59 +03:00
auto command = static_cast<unsigned char>(map.value("command", 0xff).toInt());
2019-03-05 00:48:32 +03:00
if (!(command & NetworkClasses::CustomType) || type == Type::Undefined) {
2019-02-15 23:36:59 +03:00
return false;
}
2019-03-05 00:48:32 +03:00
QDataStream stream(&data, QIODevice::ReadWrite);
2019-02-15 23:36:59 +03:00
2019-03-05 00:48:32 +03:00
if (!Streamers::write(stream, map)) {
return false;
2019-02-15 23:36:59 +03:00
}
hdr.command = command;
hdr.type = type;
hdr.size = static_cast<unsigned int>(data.size());
2019-02-15 23:36:59 +03:00
return isValid();
2019-02-13 13:03:40 +03:00
}
QByteArray Package::toBytes() const {
QByteArray res;
res.append(reinterpret_cast<char*>(const_cast<Header*>(&hdr)),
sizeof (hdr));
res.append(data);
return res;
}
void Package::reset() {
hdr.reset();
data.clear();
}
2019-03-05 00:48:32 +03:00
unsigned int getSize(NetworkClasses::Type type, bool isMax) {
2019-02-28 10:42:36 +03:00
auto size = NetworkClasses::getSizeType(type);
2019-02-25 21:38:37 +03:00
if (size) {
return size;
}
2019-02-28 10:42:36 +03:00
if (type == NetworkClasses::String) {
2019-03-05 00:48:32 +03:00
return (isMax)? 255: 5;
2019-02-28 10:42:36 +03:00
} else if (type == NetworkClasses::Variant) {
2019-03-05 00:48:32 +03:00
return (isMax)? 16 : 6;
2019-02-25 21:38:37 +03:00
}
2019-03-05 00:48:32 +03:00
if (NetworkClasses::isArray(type)) {
NetworkClasses::Type arrayType = static_cast<NetworkClasses::Type>(type & ~NetworkClasses::Array);
2019-02-25 21:38:37 +03:00
2019-03-05 00:48:32 +03:00
auto sizeItem = NetworkClasses::getSizeType(arrayType);
2019-02-25 21:38:37 +03:00
2019-03-05 00:48:32 +03:00
if (arrayType == NetworkClasses::String) {
sizeItem = (isMax)? 255: 5;
} else if (arrayType == NetworkClasses::Variant) {
sizeItem = (isMax)? 16 : 6;
}
2019-02-25 21:38:37 +03:00
2019-03-05 00:48:32 +03:00
constexpr int description = sizeof(int);
2019-02-25 21:38:37 +03:00
2019-03-05 00:48:32 +03:00
size += description + sizeItem * ((isMax)? MAX_SIZE: MIN_SIZE);
return size;
}
if (type & NetworkClasses::CustomType) {
constexpr auto baseSize = sizeof (short) + sizeof (int);
size += baseSize;
}
2019-02-25 21:38:37 +03:00
2019-03-05 00:48:32 +03:00
auto listPropertyes = networkObjects.value(type);
for (auto &&i : listPropertyes) {
2019-02-25 21:38:37 +03:00
size += getSize(i, isMax);
}
return size;
}
2019-03-05 00:48:32 +03:00
bool isStaticObject(NetworkClasses::Type type, unsigned int &max, unsigned int &min) {
max = getSize(type, true);
min = getSize(type);
2019-02-25 21:38:37 +03:00
return max == min;
}
2019-03-05 00:48:32 +03:00
bool isValidSize(NetworkClasses::Type type, unsigned int size) {
unsigned int max;
unsigned int min;
2019-02-25 21:38:37 +03:00
if (isStaticObject(type, max, min)) {
return size == max;
}
return size <= max && size >= min;
}
2019-02-13 13:03:40 +03:00
}