mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-27 07:57:21 +00:00
272 lines
7.1 KiB
C++
272 lines
7.1 KiB
C++
|
#include "AMFFormat_BitStream.h"
|
||
|
|
||
|
// Writes an AMFValue pointer to a RakNet::BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value) {
|
||
|
if (value != nullptr) {
|
||
|
AMFValueType type = value->GetValueType();
|
||
|
|
||
|
switch (type) {
|
||
|
case AMFUndefined: {
|
||
|
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFNull: {
|
||
|
AMFNullValue* v = (AMFNullValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFFalse: {
|
||
|
AMFFalseValue* v = (AMFFalseValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFTrue: {
|
||
|
AMFTrueValue* v = (AMFTrueValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFInteger: {
|
||
|
AMFIntegerValue* v = (AMFIntegerValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFString: {
|
||
|
AMFStringValue* v = (AMFStringValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFXMLDoc: {
|
||
|
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFDate: {
|
||
|
AMFDateValue* v = (AMFDateValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case AMFArray: {
|
||
|
AMFArrayValue* v = (AMFArrayValue*)value;
|
||
|
this->Write(*v);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// A private function to write an value to a RakNet::BitStream
|
||
|
void WriteUInt29(RakNet::BitStream* bs, uint32_t v) {
|
||
|
unsigned char b4 = (unsigned char)v;
|
||
|
if (v < 0x00200000) {
|
||
|
b4 = b4 & 0x7F;
|
||
|
if (v > 0x7F) {
|
||
|
unsigned char b3;
|
||
|
v = v >> 7;
|
||
|
b3 = ((unsigned char)(v)) | 0x80;
|
||
|
if (v > 0x7F) {
|
||
|
unsigned char b2;
|
||
|
v = v >> 7;
|
||
|
b2 = ((unsigned char)(v)) | 0x80;
|
||
|
bs->Write(b2);
|
||
|
}
|
||
|
|
||
|
bs->Write(b3);
|
||
|
}
|
||
|
} else {
|
||
|
unsigned char b1;
|
||
|
unsigned char b2;
|
||
|
unsigned char b3;
|
||
|
|
||
|
v = v >> 8;
|
||
|
b3 = ((unsigned char)(v)) | 0x80;
|
||
|
v = v >> 7;
|
||
|
b2 = ((unsigned char)(v)) | 0x80;
|
||
|
v = v >> 7;
|
||
|
b1 = ((unsigned char)(v)) | 0x80;
|
||
|
|
||
|
bs->Write(b1);
|
||
|
bs->Write(b2);
|
||
|
bs->Write(b3);
|
||
|
}
|
||
|
|
||
|
bs->Write(b4);
|
||
|
}
|
||
|
|
||
|
// Writes a flag number to a RakNet::BitStream
|
||
|
void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) {
|
||
|
v = (v << 1) | 0x01;
|
||
|
WriteUInt29(bs, v);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFString to a RakNet::BitStream
|
||
|
void WriteAMFString(RakNet::BitStream* bs, const std::string& str) {
|
||
|
WriteFlagNumber(bs, (uint32_t)str.size());
|
||
|
bs->Write(str.c_str(), (uint32_t)str.size());
|
||
|
}
|
||
|
|
||
|
// Writes an AMF U16 to a RakNet::BitStream
|
||
|
void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) {
|
||
|
unsigned char b2;
|
||
|
b2 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
bs->Write((unsigned char)value);
|
||
|
bs->Write(b2);
|
||
|
}
|
||
|
|
||
|
// Writes an AMF U32 to RakNet::BitStream
|
||
|
void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) {
|
||
|
unsigned char b2;
|
||
|
unsigned char b3;
|
||
|
unsigned char b4;
|
||
|
|
||
|
b4 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b3 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b2 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
|
||
|
bs->Write((unsigned char)value);
|
||
|
bs->Write(b2);
|
||
|
bs->Write(b3);
|
||
|
bs->Write(b4);
|
||
|
}
|
||
|
|
||
|
// Writes an AMF U64 to RakNet::BitStream
|
||
|
void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) {
|
||
|
unsigned char b2;
|
||
|
unsigned char b3;
|
||
|
unsigned char b4;
|
||
|
unsigned char b5;
|
||
|
unsigned char b6;
|
||
|
unsigned char b7;
|
||
|
unsigned char b8;
|
||
|
|
||
|
b8 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b7 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b6 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b5 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b4 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b3 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
b2 = (unsigned char)value;
|
||
|
value = value >> 8;
|
||
|
|
||
|
bs->Write((unsigned char)value);
|
||
|
bs->Write(b2);
|
||
|
bs->Write(b3);
|
||
|
bs->Write(b4);
|
||
|
bs->Write(b5);
|
||
|
bs->Write(b6);
|
||
|
bs->Write(b7);
|
||
|
bs->Write(b8);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Writes an AMFUndefinedValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value) {
|
||
|
this->Write(AMFUndefined);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFNullValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value) {
|
||
|
this->Write(AMFNull);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFFalseValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value) {
|
||
|
this->Write(AMFFalse);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFTrueValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value) {
|
||
|
this->Write(AMFTrue);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFIntegerValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value) {
|
||
|
this->Write(AMFInteger);
|
||
|
WriteUInt29(this, value.GetIntegerValue());
|
||
|
}
|
||
|
|
||
|
// Writes an AMFDoubleValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value) {
|
||
|
this->Write(AMFDouble);
|
||
|
double d = value.GetDoubleValue();
|
||
|
WriteAMFU64(this, *((unsigned long long*)&d));
|
||
|
}
|
||
|
|
||
|
// Writes an AMFStringValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value) {
|
||
|
this->Write(AMFString);
|
||
|
std::string v = value.GetStringValue();
|
||
|
WriteAMFString(this, v);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFXMLDocValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value) {
|
||
|
this->Write(AMFXMLDoc);
|
||
|
std::string v = value.GetXMLDocValue();
|
||
|
WriteAMFString(this, v);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFDateValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value) {
|
||
|
this->Write(AMFDate);
|
||
|
uint64_t date = value.GetDateValue();
|
||
|
WriteAMFU64(this, date);
|
||
|
}
|
||
|
|
||
|
// Writes an AMFArrayValue to BitStream
|
||
|
template<>
|
||
|
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value) {
|
||
|
this->Write(AMFArray);
|
||
|
uint32_t denseSize = value.GetDenseValueSize();
|
||
|
WriteFlagNumber(this, denseSize);
|
||
|
|
||
|
_AMFArrayMap_::iterator it = value.GetAssociativeIteratorValueBegin();
|
||
|
_AMFArrayMap_::iterator end = value.GetAssociativeIteratorValueEnd();
|
||
|
|
||
|
while (it != end) {
|
||
|
WriteAMFString(this, it->first);
|
||
|
this->Write(it->second);
|
||
|
it++;
|
||
|
}
|
||
|
|
||
|
this->Write(AMFNull);
|
||
|
|
||
|
if (denseSize > 0) {
|
||
|
_AMFArrayList_::iterator it2 = value.GetDenseIteratorBegin();
|
||
|
_AMFArrayList_::iterator end2 = value.GetDenseIteratorEnd();
|
||
|
|
||
|
while (it2 != end2) {
|
||
|
this->Write(*it2);
|
||
|
it2++;
|
||
|
}
|
||
|
}
|
||
|
}
|