File indexing completed on 2024-05-05 05:40:40
0001 /*************************************************************************** 0002 * Copyright (C) 2020 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "worker/playermessagehelper.h" 0021 0022 #include <QBuffer> 0023 #include <QCoreApplication> 0024 #include <QDebug> 0025 0026 #include "data/character.h" 0027 #include "data/player.h" 0028 #include "data/charactervision.h" 0029 0030 #include "network/networkmessagereader.h" 0031 #include "network/networkmessagewriter.h" 0032 0033 void PlayerMessageHelper::sendOffConnectionInfo(Player* player, const QByteArray& password) 0034 { 0035 if(player == nullptr) 0036 return; 0037 0038 NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::ConnectionInfo); 0039 msg.byteArray32(password); 0040 msg.string32(player->name()); 0041 msg.string32(player->uuid()); 0042 msg.sendToServer(); 0043 } 0044 0045 void PlayerMessageHelper::sendOffPlayerInformations(Player* player) 0046 { 0047 NetworkMessageWriter message(NetMsg::UserCategory, NetMsg::PlayerConnectionAction); 0048 writePlayerIntoMessage(message, player); 0049 message.sendToServer(); 0050 } 0051 0052 void PlayerMessageHelper::writePlayerIntoMessage(NetworkMessageWriter& msg, Player* player) 0053 { 0054 if(nullptr == player) 0055 return; 0056 0057 msg.string16(player->name()); 0058 msg.string8(player->uuid()); 0059 auto color= player->getColor(); 0060 msg.rgb(color.rgb()); 0061 msg.uint8(player->isGM() ? 1 : 0); 0062 msg.string16(QCoreApplication::instance()->applicationVersion()); 0063 0064 auto avatar= player->avatar(); 0065 0066 msg.uint8(static_cast<quint8>(!avatar.isNull())); 0067 if(!avatar.isNull()) 0068 { 0069 msg.byteArray32(avatar); 0070 } 0071 0072 const auto& characters= player->children(); 0073 // Characters 0074 msg.int32(static_cast<int>(characters.size())); 0075 0076 std::for_each(characters.begin(), characters.end(), 0077 [&msg](const std::unique_ptr<Character>& character) 0078 { writeCharacterIntoMessage(msg, character.get()); }); 0079 0080 /*QByteArray array; 0081 QDataStream out(&array, QIODevice::WriteOnly); 0082 out.setVersion(QDataStream::Qt_5_7); 0083 out << player->features(); 0084 0085 msg.byteArray32(array);*/ 0086 } 0087 0088 void PlayerMessageHelper::writeVisionIntoMessage(NetworkMessageWriter& msg, CharacterVision* vision) 0089 { 0090 if(nullptr == vision) 0091 { 0092 qWarning() << "Vision can't be serialized into network message"; 0093 return; 0094 } 0095 0096 auto pos = vision->position(); 0097 msg.real(pos.x()); 0098 msg.real(pos.y()); 0099 msg.real(vision->angle()); 0100 msg.uint8(vision->shape()); 0101 msg.uint8(static_cast<quint8>(vision->visible())); 0102 msg.real(vision->radius()); 0103 } 0104 0105 void PlayerMessageHelper::writeCharacterIntoMessage(NetworkMessageWriter& msg, Character* character) 0106 { 0107 if(nullptr == character) 0108 return; 0109 0110 auto parent= character->parentPerson(); 0111 msg.string8(nullptr != parent ? parent->uuid() : QStringLiteral("nullptr")); 0112 msg.string8(character->uuid()); 0113 msg.string16(character->name()); 0114 msg.string16(character->stateId()); 0115 msg.uint8(static_cast<quint8>(character->isNpc())); 0116 msg.int32(character->number()); 0117 auto color= character->getColor(); 0118 msg.rgb(color.rgb()); 0119 auto lifeColor = character->getLifeColor(); 0120 msg.rgb(lifeColor.rgb()); 0121 msg.int32(character->getHealthPointsCurrent()); 0122 msg.int32(character->getHealthPointsMin()); 0123 msg.int32(character->getHealthPointsMax()); 0124 msg.int32(character->getInitiativeScore()); 0125 msg.string32(character->initCommand()); 0126 msg.real(character->getDistancePerTurn()); 0127 msg.uint8(static_cast<quint8>(character->hasInitScore())); 0128 0129 auto avatar= character->avatar(); 0130 0131 msg.uint8(static_cast<quint8>(!avatar.isNull())); 0132 if(!avatar.isNull()) 0133 msg.byteArray32(avatar); 0134 } 0135 0136 bool PlayerMessageHelper::readPlayer(NetworkMessageReader& msg, Player* player) 0137 { 0138 if(!msg.isValid() || nullptr == player) 0139 { 0140 qWarning() << "Network message OUT OF MEMORY player"; 0141 return false; 0142 } 0143 0144 auto name= msg.string16(); 0145 auto uuid= msg.string8(); 0146 auto color= QColor(msg.rgb()); 0147 auto gameMaster= (msg.uint8() != 0); 0148 auto softVersion= msg.string16(); 0149 0150 // auto player= new Player(uuid, name, color, gameMaster); 0151 qDebug() << player->name() << "new player name" << name; 0152 player->setUuid(uuid); 0153 player->setName(name); 0154 player->setColor(color); 0155 player->setGM(gameMaster); 0156 player->setUserVersion(softVersion); 0157 0158 bool hasAvatar= static_cast<bool>(msg.uint8()); 0159 if(hasAvatar) 0160 { 0161 player->setAvatar(msg.byteArray32()); 0162 } 0163 0164 int childCount= msg.int32(); 0165 qDebug() << "character count: " << childCount; 0166 for(int i= 0; (i < childCount && msg.isValid()); ++i) 0167 { 0168 try 0169 { 0170 QString parentId; 0171 Character* child= readCharacter(msg,parentId); 0172 player->addCharacter(child); 0173 } 0174 catch(std::bad_alloc&) 0175 { 0176 qWarning() << "Bad alloc"; 0177 return false; 0178 } 0179 } 0180 if(!msg.isValid()) 0181 { 0182 qWarning() << "Network message OUT OF MEMORY player after character"; 0183 return false; 0184 } 0185 /*QByteArray array= msg.byteArray32(); 0186 QDataStream in(&array, QIODevice::ReadOnly); 0187 in.setVersion(QDataStream::Qt_5_7); 0188 QMap<QString, quint8> features; 0189 in >> features; 0190 for(auto key : features.keys()) 0191 { 0192 auto value= features.value(key); 0193 player->setFeature(key, value); 0194 }*/ 0195 return true; 0196 } 0197 0198 Character* PlayerMessageHelper::readCharacter(NetworkMessageReader& msg, QString& parentId) 0199 { 0200 if(!msg.isValid()) 0201 return {}; 0202 auto character= new Character(); 0203 parentId= msg.string8(); 0204 character->setUuid(msg.string8()); 0205 character->setName(msg.string16()); 0206 character->setStateId(msg.string16()); 0207 character->setNpc(static_cast<bool>(msg.uint8())); 0208 character->setNumber(msg.int32()); 0209 character->setColor(QColor(msg.rgb())); 0210 character->setLifeColor(QColor(msg.rgb())); 0211 character->setHealthPointsCurrent(msg.int32()); 0212 character->setHealthPointsMin(msg.int32()); 0213 character->setHealthPointsMax(msg.int32()); 0214 character->setInitiativeScore(msg.int32()); 0215 character->setInitCommand(msg.string32()); 0216 character->setDistancePerTurn(msg.real()); 0217 character->setHasInitiative(static_cast<bool>(msg.uint8())); 0218 0219 bool hasAvatar= static_cast<bool>(msg.uint8()); 0220 0221 if(hasAvatar) 0222 { 0223 auto byte= msg.byteArray32(); 0224 character->setAvatar(byte); 0225 } 0226 0227 return character; 0228 }