void DirEntity::PackDataObjects(BaseMessage& theMsgR, const DataObjectTypeSet& theSetR, unsigned long theFlags) { WTRACE("DirEntity::PackDataObjects"); WDBG_LL("DirEntity::PackDataObject Packing data objects, size=" << theSetR.size()); theMsgR.AppendShort(theSetR.size()); bool packType = ((theFlags & WONMsg::GF_ADDDOTYPE) != 0); bool packData = ((theFlags & WONMsg::GF_ADDDODATA) != 0); DataObjectTypeSet::const_iterator anItr(theSetR.begin()); for (; anItr != theSetR.end(); anItr++) { if (packType) { unsigned char aTypeLen = anItr->GetDataType().size(); theMsgR.AppendByte(aTypeLen); theMsgR.AppendBytes(aTypeLen, anItr->GetDataType().data()); } if (packData) { unsigned short aDataLen = anItr->GetData().size(); theMsgR.AppendShort(aDataLen); theMsgR.AppendBytes(aDataLen, anItr->GetData().data()); } } }
void DirEntity::UnpackDataObjects(BaseMessage& theMsgR, DataObjectTypeSet& theSetR, unsigned long theFlags) { WTRACE("DirEntity::UnpackDataObjects"); unsigned short aCt = theMsgR.ReadShort(); WDBG_LL("DirEntity::UnpackDataObjects Unpacking data objects, size=" << aCt); theSetR.clear(); bool unpackType = ((theFlags & WONMsg::GF_ADDDOTYPE) != 0); bool unpackData = ((theFlags & WONMsg::GF_ADDDODATA) != 0); for (int i=0; i < aCt; i++) { DataObject anObj; if (unpackType) { unsigned char aLen = theMsgR.ReadByte(); anObj.GetDataType().assign(reinterpret_cast<const unsigned char*>(theMsgR.ReadBytes(aLen)), aLen); } else anObj.GetDataType().assign(reinterpret_cast<const unsigned char*>(&i), sizeof(i)); if (unpackData) { unsigned short aLen = theMsgR.ReadShort(); anObj.GetData().assign(reinterpret_cast<const unsigned char*>(theMsgR.ReadBytes(aLen)), aLen); } theSetR.insert(anObj); } }
void DirEntity::UnpackACLs(BaseMessage& theMsgR) { WTRACE("DirEntity::UnpackACLs"); unsigned short anACLCt = theMsgR.ReadShort(); WDBG_LL("DirEntity::UnpackACLs Unpacking ACLs, size=" << anACLCt); mACLs.clear(); for (int i=0; i < anACLCt; i++) { DirACL anACL; anACL.mType = static_cast<WONMsg::DirG2ACLType>(theMsgR.ReadByte()); unsigned short aPermCt = theMsgR.ReadShort(); for (int j=0; j < aPermCt; j++) { Permission aPerm; aPerm.mUserId = theMsgR.ReadLong(); aPerm.mCommunityId = theMsgR.ReadLong(); aPerm.mTrustLevel = theMsgR.ReadShort(); anACL.mACL.insert(aPerm); } mACLs.push_back(anACL); } }
void ObjectController::doEnqueueCommand(uint32 command, const UnicodeString& arguments) { PlayerCreature* object = zone->getSelfPlayer(); Locker _locker(object); BaseMessage* message = new ObjectControllerMessage(object->getObjectID(), 0x23, 0x116); message->insertInt(object->getNewActionCount()); message->insertInt(command); message->insertLong(0); message->insertUnicode(arguments); object->getClient()->sendMessage(message); }
bool ObservationClientBase::FillMsgFromResult(BaseMessage& theMsg, const TMsgSocket::RecvBaseMsgResult& result) { bool aReturn = true; theMsg.AppendBytes(result.msg->GetDataLen(), result.msg->GetDataPtr()); try { theMsg.Unpack(); } catch (WONMsg::BadMsgException&) { // Might want to log a message here.. aReturn = false; } return aReturn; }
void ObjectController::doSayCommand(const UnicodeString& msg) { PlayerCreature* object = zone->getSelfPlayer(); Locker _locker(object); StringBuffer full; full << "0 " << "0 " << "0 " << "0 " << "0 " << msg.toString(); BaseMessage* message = new ObjectControllerMessage(object->getObjectID(), 0x23, 0x116); message->insertInt(object->getNewActionCount()); message->insertInt(String("spatialchatinternal").hashCode()); message->insertLong(0); message->insertUnicode(full.toString()); object->getClient()->sendMessage(message); }
BaseMessage* TMsgSocket::ExtractMessage(unsigned char* msg, unsigned long msgLength) { BaseMessage* theMsg = NULL; if (msgLength) { unsigned char headerType = *(msg); switch (headerType) { case 2: // Encrypted TMessage case 4: // Encrypted MiniMessage case 6: // Encrypted SmallMessage case 8: // Encrypted LargeMessage // Disallowed on non-AuthSocket break; case 3: // MiniMessage theMsg = new MiniMessage(msgLength, msg); break; case 5: // SmallMessage theMsg = new SmallMessage(msgLength, msg); break; case 7: // LargeMessage theMsg = new LargeMessage(msgLength, msg); break; default: // old TMessage theMsg = new TMessage(msgLength, msg); break; } if (theMsg) { try { theMsg->Unpack(); } catch (...) { delete theMsg; theMsg = NULL; } } } return theMsg; }
// TMessage ctor from WONException BadMsgException::BadMsgException(const BaseMessage& theMsgR, int theLine, const char* theFileP, const char* addTextP) throw() : WONException(WONCommon::ExBadTitanMessage, theLine, theFileP) { WTRACE("BadMsgException::ctor(TMessage)"); // Add header type info or header corrupt message if (theMsgR.GetDataLen() >= theMsgR.GetHeaderLength()) { WDBG_LL("BadMsgException::ctor(TMessage) Add header info."); GetStream() << "MessageClass=" << (int)theMsgR.GetMessageClass() << " MessageType=" << theMsgR.GetMessageType() << " ServiceType=" << theMsgR.GetServiceType(); } else { WDBG_LH("BadMsgException::ctor(TMessage) Corrupt header!"); GetStream() << HDRCORRUPT_MSG; } // Add message length and data length WDBG_LL("BadMsgException::ctor(TMessage) Add length info."); GetStream() << " DataLength=" << theMsgR.GetDataLen(); // Add additional text if defined if (addTextP) GetStream() << " " << addTextP; }
// Send Titan message to Observation Server Error ObservationClientBase::SendMMsgToServer(BaseMessage& theMsgR, const CompletionContainerBase* theCompletionP, const void* theReplyResultP) { ReplyCompletionData aReplyCompletionData; aReplyCompletionData.mReplyId = GetReplyMsgType(theMsgR.GetMessageType()); aReplyCompletionData.mCompletionP = const_cast<CompletionContainerBase*>(theCompletionP); aReplyCompletionData.mReplyResultP = const_cast<void*>(theReplyResultP); mCriticalSection.Enter(); mReplyCompletionList.push_back(aReplyCompletionData); mCriticalSection.Leave(); return mSocketMgrP->SendMMsgToServer(theMsgR); }
bool TMsgSocket::SendBaseMsg(BaseMessage& msg, long timeout, bool async, bool copyData, const CompletionContainer<const SendBaseMsgResult&>& completion) { SendBaseMsgData* sendBaseMsgData = new SendBaseMsgData; if (!sendBaseMsgData) { completion.Complete(SendBaseMsgResult(this, &msg, false, false)); return false; } sendBaseMsgData->msg = &msg; sendBaseMsgData->completion = completion; try { msg.Pack(); } catch (...) { delete sendBaseMsgData; completion.Complete(SendBaseMsgResult(this, &msg, false, false)); return false; } return SendRawMsgEx(msg.GetDataLen(), msg.GetDataPtr(), timeout, async, copyData, DoneSendBaseMsg, sendBaseMsgData); }
void PlayerCreature::updatePosition(float x, float z, float y) { if (client == NULL) return; setPosition(x, z, y); BaseMessage* message = new ObjectControllerMessage(objectID, 0x23, 0x71); message->insertInt(++movementCounter); message->insertFloat(direction.getX()); message->insertFloat(direction.getY()); message->insertFloat(direction.getZ()); message->insertFloat(direction.getW()); message->insertFloat(x); message->insertFloat(z); message->insertFloat(y); message->insertInt(0); client->sendMessage(message); }
void DirEntity::PackACLs(BaseMessage& theMsgR) const { WTRACE("DirEntity::PackACLs"); WDBG_LL("DirEntity::PackACLs Packing ACLs, size=" << mACLs.size()); theMsgR.AppendShort(mACLs.size()); DirACLList::const_iterator anACLItr(mACLs.begin()); for (; anACLItr != mACLs.end(); anACLItr++) { theMsgR.AppendByte(anACLItr->mType); theMsgR.AppendShort(anACLItr->mACL.size()); PermissionACL::const_iterator aPermItr(anACLItr->mACL.begin()); for (; aPermItr != anACLItr->mACL.end(); aPermItr++) { theMsgR.AppendLong(aPermItr->mUserId); theMsgR.AppendLong(aPermItr->mCommunityId); theMsgR.AppendShort(aPermItr->mTrustLevel); } } }
void BaseClientInterface::sendMessage(const BaseMessage &message) { sendData(message.toData()); }
bool TopicFilter::Matches(const BaseMessage &message) const { return (message.GetTopic() == topic); }
void DirEntity::Unpack(BaseMessage& theMsgR, unsigned long theGetFlags) { WTRACE("DirEntity::Unpack"); WDBG_LL("DirEntity::Unpack Unpacking entity"); // Read type if needed if (theGetFlags & WONMsg::GF_ADDTYPE) mType = theMsgR.ReadByte(); // Entity specific fields switch (mType) { case ET_DIRECTORY: // Read dir path if needed if (theGetFlags & WONMsg::GF_DIRADDPATH) theMsgR.ReadWString(mPath); //Read dir name if needed if (theGetFlags & WONMsg::GF_DIRADDNAME) theMsgR.ReadWString(mName); // Read dir visibility if needed if (theGetFlags & WONMsg::GF_DIRADDVISIBLE) mVisible = theMsgR.ReadByte(); break; case ET_SERVICE: // Read serv path if needed if (theGetFlags & WONMsg::GF_SERVADDPATH) theMsgR.ReadWString(mPath); // Read serv name if needed if (theGetFlags & WONMsg::GF_SERVADDNAME) theMsgR.ReadWString(mName); // Read serv netaddress if needed if (theGetFlags & WONMsg::GF_SERVADDNETADDR) { unsigned char aCt = theMsgR.ReadByte(); mNetAddress.assign(reinterpret_cast<const unsigned char*>(theMsgR.ReadBytes(aCt)), aCt); } break; } // Read displayName if needed if (theGetFlags & WONMsg::GF_ADDDISPLAYNAME) theMsgR.ReadWString(mDisplayName); // Read lifespan if needed if (theGetFlags & WONMsg::GF_ADDLIFESPAN) mLifespan = theMsgR.ReadLong(); // Read create date if needed if (theGetFlags & WONMsg::GF_ADDCREATED) mCreated = theMsgR.ReadLong(); // Read touched date if needed if (theGetFlags & WONMsg::GF_ADDTOUCHED) mTouched = theMsgR.ReadLong(); // Read CRC if needed if (theGetFlags & WONMsg::GF_ADDCRC) mCRC = theMsgR.ReadLong(); // Add UserIds if needed if (theGetFlags & WONMsg::GF_ADDUIDS) { mCreateId = theMsgR.ReadLong(); mTouchId = theMsgR.ReadLong(); } // Read Data Objects if needed if (theGetFlags & WONMsg::GF_ADDDATAOBJECTS) UnpackDataObjects(theMsgR, mDataObjects, theGetFlags); // Read ACLs if needed (deferred) if (theGetFlags & WONMsg::GF_ADDACLS) UnpackACLs(theMsgR); }
void DirEntity::Pack(BaseMessage& theMsgR, unsigned long theGetFlags, const DataObjectTypeSet& theSetR) const { WTRACE("DirEntity::Pack"); WDBG_LL("DirEntity::Pack Packing entity, type=" << mType); // Add type if needed if (theGetFlags & WONMsg::GF_ADDTYPE) theMsgR.AppendByte(mType); // Entity specific fields switch (mType) { case DirEntity::ET_DIRECTORY: // Add dir path if needed if (theGetFlags & WONMsg::GF_DIRADDPATH) theMsgR.Append_PW_STRING(mPath); // Add dir name if needed if (theGetFlags & WONMsg::GF_DIRADDNAME) theMsgR.Append_PW_STRING(mName); // Add dir visibility if needed if (theGetFlags & WONMsg::GF_DIRADDVISIBLE) theMsgR.AppendByte(mVisible); break; case DirEntity::ET_SERVICE: // Add serv path if needed if (theGetFlags & WONMsg::GF_SERVADDPATH) theMsgR.Append_PW_STRING(mPath); // Add serv name if needed if (theGetFlags & WONMsg::GF_SERVADDNAME) theMsgR.Append_PW_STRING(mName); // Add serv netaddress if needed if (theGetFlags & WONMsg::GF_SERVADDNETADDR) { theMsgR.AppendByte(mNetAddress.size()); theMsgR.AppendBytes(mNetAddress.size(), mNetAddress.data()); } break; } // Add displayName if needed if (theGetFlags & WONMsg::GF_ADDDISPLAYNAME) theMsgR.Append_PW_STRING(mDisplayName); // Add lifespan if needed if (theGetFlags & WONMsg::GF_ADDLIFESPAN) theMsgR.AppendLong(mLifespan); // Add create date if needed if (theGetFlags & WONMsg::GF_ADDCREATED) theMsgR.AppendLong(mCreated); // Add touched date if needed if (theGetFlags & WONMsg::GF_ADDTOUCHED) theMsgR.AppendLong(mTouched); // Add CRC if needed if (theGetFlags & WONMsg::GF_ADDCRC) theMsgR.AppendLong(mCRC); // Add UserIds if needed if (theGetFlags & WONMsg::GF_ADDUIDS) { theMsgR.AppendLong(mCreateId); theMsgR.AppendLong(mTouchId); } // Add all data objects if needed if (theGetFlags & WONMsg::GF_ADDDATAOBJECTS) PackDataObjects(theMsgR, mDataObjects, theGetFlags); // Otherwise, add requested data objects (if any) else if (theSetR.size() > 0) { DataObjectTypeSet aPackSet; DataObjectTypeSet::const_iterator anItr(theSetR.begin()); for (; anItr != theSetR.end(); anItr++) { DataObjectTypeSet::const_iterator aSrch(mDataObjects.find(*anItr)); if (aSrch != mDataObjects.end()) aPackSet.insert(*aSrch); } PackDataObjects(theMsgR, aPackSet, theGetFlags); } // Add ACLs if needed (deferred) if (theGetFlags & WONMsg::GF_ADDACLS) PackACLs(theMsgR); }
void MessageReadThread::Run() { // Read messages from our session, and dispatch them try { while (!session->ShuttingDown()) { MessageBuffer *in_msg = session->ReadMessage(); in_msg->Mark(); unsigned char msg_code = in_msg->ReadByte(); switch (msg_code) { case SUBSCRIBE: std::cerr << "Got subscribe message from server" << std::endl; delete in_msg; break; case UNSUBSCRIBE: std::cerr << "Got unsubscribe message from server" << std::endl; delete in_msg; break; case SUBSCRIBE_RESPONSE: { // Sub response int sub_id = in_msg->ReadInt32(); bool success = in_msg->ReadBool(); delete in_msg; std::cout << "Got subscription response: " << sub_id << ", " << success << std::endl; session->subscription_monitor.Enter(); try { if (success && session->pending_subscribes.find(sub_id) != session->pending_subscribes.end()) { // We added the subscription Subscription *sub = session->pending_subscribes[sub_id]; sub->sub_id = sub_id; session->pending_subscribes.erase(sub_id); session->subscriptions[sub_id] = sub; session->subscription_monitor.PulseAll(); } else if (!success && session->pending_unsubscribes.find(sub_id) != session->pending_unsubscribes.end()) { session->pending_unsubscribes.erase(sub_id); Subscription *sub = session->subscriptions[sub_id]; session->subscriptions.erase(sub_id); delete sub; session->subscription_monitor.PulseAll(); } else { std::cerr << "Invalid combination of success and states" << std::endl; } } catch (...) { session->subscription_monitor.Exit(); throw; } session->subscription_monitor.Exit(); } break; case SERVER_MESSAGE: { // Ideally, I could use the response_subscription filter // to check to see if the message matches, but since I // don't yet have enough information to generate the // BaseMessage object from the MessageBuffer object, I // have to pull the topic out directly. std::string topic = in_msg->ReadString(); // Move back to the beginning of the message (right before message type); in_msg->Reset(); if (topic == ResponseMessage::GetMessageType()) { BaseMessage *message = NULL; if (session->request_topic == ObjInfoReqMessage::GetMessageType()) message = new ObjInfoRespMessage(); else if (session->request_topic == SetPropertyMessage::GetMessageType()) message = new PropertyRespMessage(); else if (session->request_topic == GetPropertyMessage::GetMessageType()) message = new PropertyRespMessage(); else std::cerr << "Error: Got invalid response message: session->request_topic is " << session->request_topic << std::endl; message->ParseMessageBuffer(*in_msg); delete in_msg; session->response_monitor.Enter(); if (session->response_message != NULL) { std::cerr << "Warning, got response while there is one pending" << std::endl; delete message; } session->response_message = message; session->response_monitor.PulseAll(); session->response_monitor.Exit(); } else { // Message to be handled by the user thread session->message_queue_monitor.Enter(); session->message_queue.push_back(in_msg); session->message_queue_monitor.PulseAll(); //std::cout << "After adding message '" << topic << "' in Run, queue size is " << // session->message_queue.size() << std::endl; session->message_queue_monitor.Exit(); } } break; default: std::cerr << "Got unknown message code from server" << std::endl; delete in_msg; break; } } } catch (const MessageException &e) { std::cerr << "Message Exception: " << e.Message() << std::endl; } }