/// <inheritdoc /> public override void Write([NotNull] BitArray value, IWireStreamWriterStrategy dest) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //The size must be equal to the length divided by 8 bits (1 byte) but we do not include the //remainder from a modular division. The reason for this is it's always sent as 4 byte chunks from //Trinitycore and the size is always in terms of an int array byte[] bitmask = new byte[value.Length / 8]; ((ICollection)value).CopyTo(bitmask, 0); byte size = (byte)(bitmask.Length / sizeof(int)); //Write the size as if it were an int array first dest.Write(size); dest.Write(bitmask); }
protected void WriteMemberData(TType obj, [NotNull] IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } try { //replaced for perf /*foreach (IMemberSerializationMediator<TType> serializerInfo in orderedMemberInfos) * { * serializerInfo.WriteMember(obj, dest); * }*/ for (int i = 0; i < orderedMemberInfos.Length; i++) { orderedMemberInfos[i].WriteMember(obj, dest); } } catch (Exception e) { Console.WriteLine(e); throw; } }
/// <inheritdoc /> public override void WriteMember(TContainingType obj, IWireStreamWriterStrategy dest) { WriteCollectionSizeToField(obj); //TODO: Should we spend CPU cycles to reset the original value? This kind of changes the state of the DTO DecoratedMediator.WriteMember(obj, dest); }
/// <inheritdoc /> public override void Write(string value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //Review the source for Trinitycore's string reading for their ByteBuffer (payload/packet) Type. //(ctr+f << for std::string): http://www.trinitycore.net/d1/d17/ByteBuffer_8h_source.html //They use 0 byte to terminate the string in the stream //We should check this so we don't try to decode //or write null. Null should be considered empty. if (!String.IsNullOrEmpty(value)) { //TODO: Pointer hack for speed //Convert the string to bytes //Not sure about encoding yet byte[] stringBytes = EncodingStrategy.GetBytes(value); dest.Write(stringBytes); } //Write the null terminator; Client expects it. for (int i = 0; i < CharacterSize; i++) { dest.Write(0); } }
/// <inheritdoc /> public override void Write([NotNull] string value, IWireStreamWriterStrategy dest) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (dest == null) { throw new ArgumentNullException(nameof(dest)); } int size = sizeProvider.Size(value, dest); //Now that we know the size, and the header will be written if it was needed, we can write it //Don't write the size. Leave it up to the strategy above decoratedSerializer.Write(value, dest); //the tricky part here is that the serializer just wrote the string plus the null terminator //So, if the length of the string was less than the expected size write some more 0s. //However, DO NOT write another null terminator either way because we already have one. if (value.Length < size) { dest.Write(new byte[(CharacterSize * (size - value.Length))]); } }
//From jackpoz's bot: https://github.com/jackpoz/BotFarm/blob/592dbc9dbb58c06175bffecfced56eba42107c9a/Client/World/Network/OutPacket.cs#L47 /// <inheritdoc /> public override void Write(PackedGuid value, IWireStreamWriterStrategy dest) { //TODO: Can we use span or stackalloc? Or maybe shared buffer? byte[] packGuid = GeneratePackedGuid(value, out int size); dest.Write(packGuid, 0, size); }
/// <inheritdoc /> public override void Write(TObjectType[] value, IWireStreamWriterStrategy dest) { for (int i = 0; i < value.Length; i++) { ElementSerializer.Write(value[i], dest); } }
/// <inheritdoc /> public byte[] Serialize <TTypeToSerialize>(TTypeToSerialize data, IWireStreamWriterStrategy writer) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } //Conditional compile this because it's not really very efficient anymore to lookup if a type is serialized. #if DEBUG || DEBUGBUILD if (!serializerStorageService.HasSerializerFor(data.GetType())) { throw new InvalidOperationException($"Serializer cannot serialize Type: {typeof(TTypeToSerialize).FullName} because it's not registered."); } #endif if (!isCompiled) { throw new InvalidOperationException($"You cannot serialize before compiling the serializer."); } GetLeastDerivedSerializer(data.GetType()).Write(data, writer); return(writer.GetBytes()); }
//TODO: Error handling /// <inheritdoc /> public override void Write(TComplexType value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //invoke before serialization if it's available (value as ISerializationEventListener)?.OnBeforeSerialization(); //Writes base members first and goes down the inheritance line //WARNING: This caused HUGE perf probleems. Several orders of magnitude slower than Protobuf //We MUST not check if the serializer exists and we must precache the gets. if (reversedInheritanceHierarchy.Count() != 0) { foreach (Type t in reversedInheritanceHierarchy) { if (serializerProviderService.HasSerializerFor(t)) //TODO: Should we remove this check for perf? { serializerProviderService.Get(t).ObjectIntoWriter(value, dest); } } } WriteMemberData(value, dest); }
/// <inheritdoc /> public override void Write(bool value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } dest.Write(ConvertFromBool(value)); }
public override void WriteMember(object obj, [NotNull] IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } WriteMember((TContainingType)obj, dest); }
/// <inheritdoc /> public void ObjectIntoWriter(object obj, IWireStreamWriterStrategy dest) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } ObjectIntoWriter((TType)obj, dest); }
/// <inheritdoc /> public override void Write(string value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } decoratedSerializer.Write(new string(value.Reverse().ToArray()), dest); }
/// <inheritdoc /> public override void Write(TEnumType value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } serializerStrategy.Write(GenericMath.Convert <TEnumType, TBaseType>(value), dest); }
/// <inheritdoc /> public override void Write(TEnumType value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //Just write the string to the stream decoratedSerializer.Write(value.ToString(), dest); }
/// <inheritdoc /> public void WriteMember(TContainingType obj, IWireStreamWriterStrategy dest) { //Check if we should read if (!(bool)isReadWriteEnabledGetter.Getter(obj)) { return; } DecoratedMediator.WriteMember(obj, dest); }
/// <inheritdoc /> public override void Write(byte[] value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //MUST copy or it will modify the external objects byte[] bytes = value.ToArray(); Array.Reverse(bytes); dest.Write(bytes); }
/// <inheritdoc /> public override void Write(string value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //TODO: Pointer hack for speed byte[] stringBytes = EncodingStrategy.GetBytes(value); dest.Write(stringBytes); //Just don't write terminator. Very simple. }
/// <summary> /// Creates a realtime crypto stream reader. /// </summary> /// <param name="dest">The <see cref="IWireStreamWriterStrategy"/> to decorate.</param> /// <param name="sessionCrypto"></param> protected CryptoStreamWriter([NotNull] IWireStreamWriterStrategy dest, [NotNull] ISessionPacketCryptoService sessionCrypto) : base(sessionCrypto) { //We don't implement the writing ourselves because it could be a default behavior //our we may need network stream reading, which may block, or anything under the sun if (dest == null) { throw new ArgumentNullException(nameof(dest)); } Dest = dest; }
/// <inheritdoc /> public override void Write(DateTime value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //Based on ByteBuffer.h from the Trinitycore Project as well as Jackpoz's 3.3.5 packet bot. //Trinitycore: append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min); //pass to decorated serializer decoratedSerializer.Write(ConvertDateTimeToIntegerRepresentation(ref value), dest); }
/// <inheritdoc /> public override void Write(TType[] value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } int size = SizeStrategyService.Size <TType[], TType>(value, dest); //We no longer verify size thanks to PHANTASY STAR ONLINE. Thanks Sega. Sometimes we have to fake the size dest.Write(value.Reinterpret()); }
/// <inheritdoc /> public virtual void ObjectIntoWriter(TType obj, IWireStreamWriterStrategy dest) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //This is a simple type so the only way to write it is to just write the value this.Write(obj, dest); }
/// <inheritdoc /> public SkipSomeBytesWireStreamWriterStrategyDecorator([NotNull] IWireStreamWriterStrategy decoratedWriter, int byteNumberToSkip) { if (decoratedWriter == null) { throw new ArgumentNullException(nameof(decoratedWriter)); } if (byteNumberToSkip < 0) { throw new ArgumentOutOfRangeException(nameof(byteNumberToSkip)); } DecoratedWriter = decoratedWriter; ByteNumberToSkip = byteNumberToSkip; }
public OneTimeCryptoStreamWriter([NotNull] IWireStreamWriterStrategy dest, [NotNull] ISessionPacketCryptoService sessionCrypto) : base(dest, sessionCrypto) { //The starting state is default //The writer can only write when it's in default state. WriterState = State.Default; //Lazily encrypt the stream's bytes. //This means it can ONLY be done once. CryptoByteRepresentation = new Lazy <byte[]>(() => { WriterState = State.Crypted; return(sessionCrypto.ProcessBytes(dest.GetBytes(), 0)); }, true); }
/// <inheritdoc /> public void Write(int value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //If the key shouldn't be written then we avoid writing it //It may be that the data is needed to be left in the stream to indicate //something about the type later down the line. if (!typeHandlingFlags.HasFlag(InformationHandlingFlags.DontWrite)) { KeyTypeSerializerStrategy.Write(GenericMath.Convert <int, TKeyType>(value), dest); } }
public override void ObjectIntoWriter(TType obj, IWireStreamWriterStrategy dest) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (dest == null) { throw new ArgumentNullException(nameof(dest)); } //This method is only responsible for writing the members //Even if we're suppose to write type data for this type we don't //Just members WriteMemberData(obj, dest); }
/// <inheritdoc /> public int Size <TCollectionType, TElementType>(TCollectionType collection, IWireStreamWriterStrategy writer) where TCollectionType : IEnumerable, IEnumerable <TElementType> { if (collection == null) { throw new ArgumentNullException(nameof(collection)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } //This is a fixed size stragey. Don't look at the collection //Don't write anything to the stream either. Consumers know the size too return(FixedSize); }
/// <inheritdoc /> public override void Write(TType value, [NotNull] IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } bool isPopulated = PopulateSharedBufferWith(value); if (!isPopulated) { throw new InvalidOperationException($"Failed to populate {nameof(SharedByteBuffer)} in {nameof(SharedBufferTypeSerializer<TType>)} for Type: {typeof(TType)} with Value: {value}."); } //At this point the SharedBuffer contains the serialized representation of the value //DO NOT RELEASE LOCK UNTIL WRITTEN dest.Write(SharedByteBuffer.Value); }
/// <inheritdoc /> public override void Write(TObjectType[] value, IWireStreamWriterStrategy dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } int size = sizeStrategyService.Size <TObjectType[], TObjectType>(value, dest); //We no longer verify size thanks to PHANTASY STAR ONLINE. Thanks Sega. Sometimes we have to fake the size //We can't use Size because sometimes the offset might may force this to go out of bounds. //only write what we have, the size is not relevant here and may be written differently in the stream. for (int i = 0; i < value.Length; i++) { decoratedSerializer.Write(value[i], dest); } }
/// <inheritdoc /> public override void Write(LinearPathMoveInfo value, IWireStreamWriterStrategy dest) { if (value == null) { return; } dest.Write(value.LastIndex.Reinterpret()); dest.Write(value.FinalPosition.X.Reinterpret()); dest.Write(value.FinalPosition.Y.Reinterpret()); dest.Write(value.FinalPosition.Z.Reinterpret()); if (value.LastIndex > 1 && value.SplineMiddlePoints != null) { dest.Write(value.SplineMiddlePoints); } }