protected void CreateMeta(string name, EncodingOptions options, ushort sequenceNumber) { m_MetaFrame = new MetaFrame(options); ExtendedFlags1 extendedFlags1 = new ExtendedFlags1 { RawValue = 0x84 }; ExtendedFlags2 extendedFlags2 = new ExtendedFlags2 { RawValue = 8 }; NetworkMessageHeader networkMessageHeader = new NetworkMessageHeader { VersionAndFlags = 0x91, ExtendedFlags1 = extendedFlags1, ExtendedFlags2 = extendedFlags2, PublisherID = new String(PublisherId) }; m_MetaFrame.NetworkMessageHeader = networkMessageHeader; m_MetaFrame.SequenceNumber = sequenceNumber; DateTime time = DateTime.UtcNow; m_MetaFrame.ConfigurationVersion.Minor = (uint)(time.Ticks & uint.MaxValue); m_MetaFrame.ConfigurationVersion.Major = (uint)(time.Ticks >> 32); m_MetaFrame.Name = new String(name); m_MetaFrame.DataSetWriterID = m_WriterId; m_MetaFrame.Description = Description; foreach (DataPointEntry entry in m_ProcessValues.Values) { CreateFieldMetaDataList(entry, m_MetaFrame, options); AddDataPointMeta(entry.DataPoint); } }
public void HandleLobbyCharacter(NetworkMessageHeader header, IResult message) { var dat = (LobbyCharacterResult)message; if (_lpBuffer.Contains(dat.MessageCounter)) { return; } _lpBuffer.Add(dat.MessageCounter); _lcBuffer.AddRange(dat.CharacterItems); if (dat.MessageCounter % 4 == 0) { return; } OnDataReady?.Invoke(new PackedResult(PackedResultType.LobbyCharacter, new LobbyCharacterResult { CharacterItems = new List <LobbyCharacterItem>(_lcBuffer), MessageCount = (byte)_lcBuffer.Count, MessageCounter = dat.MessageCounter, })); _lpBuffer.Clear(); _lcBuffer.Clear(); }
public override void Encode(Stream outputStream, bool withHeader = true) { if (outputStream == null || !outputStream.CanWrite) { return; } if (withHeader) { NetworkMessageHeader.Encode(outputStream); } PayloadHeader.Encode(outputStream); BaseType.WriteToStream(outputStream, BitConverter.GetBytes(MessageSequenceNumber)); BaseType.WriteToStream(outputStream, BitConverter.GetBytes(ChunkOffset)); BaseType.WriteToStream(outputStream, BitConverter.GetBytes(TotalSize)); int length = -1; if (ChunkData != null) { length = ChunkData.Length; } BaseType.WriteToStream(outputStream, BitConverter.GetBytes(length)); for (int i = 0; i < length; i++) { // ReSharper disable once PossibleNullReferenceException outputStream.WriteByte(ChunkData[i]); } }
public void HandleNetworkItemInfo(NetworkMessageHeader header, IResult message) { if (_retainerCountdown <= 0) { return; } var dat = (NetworkItemInfo)message; if (!_irBuffer.ContainsKey(dat.ContainerId)) { _irBuffer[dat.ContainerId] = new InventoryContainer(InventoryContainerTypeConverter.ToOffset(dat.ContainerId), (InventoryContainerId)dat.ContainerId); } var item = new InventoryItem(dat.Quantity, dat.Condition, dat.GlamourItemId, dat.ItemId, dat.IsHq, dat.SpiritBond, dat.ContainerSlot, dat.ArtisanId, dat.DyeId, dat.Materia1, dat.Materia2, dat.Materia3, dat.Materia4, dat.Materia5); if (_ipBuffer.ContainsKey(dat.ContainerId * PrimeForInventorySlot + dat.ContainerSlot)) // max slot is 240, also 241 is a prime { item.UnitPrice = _ipBuffer[dat.ContainerId * PrimeForInventorySlot + dat.ContainerSlot]; } _irBuffer[dat.ContainerId].InventoryItems.Add(item); }
public RoutedMessage(NetworkMessageHeader header, int len, byte[] msg, MessageConsumerDelegate consumer, MessageDecoded listener) { Header = header; HeaderLength = len; Message = msg; Consumer = consumer; Listener = listener; }
public void HandleNetworkItemInfoEnd(NetworkMessageHeader header, IResult message) { _retainerCountdown--; if (_retainerCountdown != 0) { return; } OnDataReady?.Invoke(new PackedResult(PackedResultType.InventoryNetwork, new InventoryResult(_irBuffer.Select(x => x.Value).ToList(), _retainerId))); }
public void HandleNetworkMarketListingCount(NetworkMessageHeader header, IResult message) { var dat = (NetworkMarketListingCount)message; _listingPacketCount = dat.Quantity / 10; if (dat.Quantity % 10 != 0) { _listingPacketCount++; } OnDataReady?.Invoke(new PackedResult(PackedResultType.MarketRequest, new MarketRequestResult { ItemId = dat.ItemId })); }
public void HandleNetworkPlayerSpawn(NetworkMessageHeader header, IResult message) { var dat = (NetworkPlayerSpawn)message; if (_worldId == dat.CurrentWorldId) { return; } _worldId = dat.CurrentWorldId; OnDataReady?.Invoke(new PackedResult(PackedResultType.CurrentWorld, new CurrentWorldResult(dat.CurrentWorldId))); }
public void HandleRequestRetainer(NetworkMessageHeader header, IResult message) { if (message == null) { return; } var dat = (NetworkRequestRetainer)message; _retainerId = dat.RetainerId; _retainerCountdown = 1; _irBuffer.Clear(); _ipBuffer.Clear(); }
public override void Encode(Stream outputStream, bool withHeader = true) { if (outputStream == null || !outputStream.CanWrite) { return; } if (withHeader) { NetworkMessageHeader.Encode(outputStream); } EncodeChunk(outputStream); }
public void HandleNetworkCharacterName(NetworkMessageHeader header, IResult message) { var dat = (NetworkCharacterName)message; _crBuffer.Add(new ArtisanInfo(dat.CharacterId, dat.Name, false)); if (_crBuffer.Count < 5) { return; } OnDataReady?.Invoke(new PackedResult(PackedResultType.Artisan, new ArtisanResult(new List <ArtisanInfo>(_crBuffer)))); _crBuffer.Clear(); }
protected NetworkMessageHeader GetChunkedMetaNetworkHeader() { NetworkMessageHeader networkHeader = new NetworkMessageHeader(); networkHeader.PublisherID = new String(m_PublisherID); networkHeader.VersionAndFlags = 0x91; networkHeader.ExtendedFlags1 = new ExtendedFlags1 { RawValue = 0x84 }; networkHeader.ExtendedFlags2 = new ExtendedFlags2 { RawValue = 0x09 }; return(networkHeader); }
public void HandleNetworkMarketResult(NetworkMessageHeader header, IResult message) { _blocked = false; var dat = (MarketOverviewResult)message; if (dat.RequestId != _overviewReqId) { ceOverview.Reset(0); _overviewReqId = dat.RequestId; } ceOverview.Reset(2); _loBuffer.AddRange(dat.ResultItems); }
protected NetworkMessageHeader GetChunkedNetworkHeader(bool isMetaMessage = false) { NetworkMessageHeader networkHeader = new NetworkMessageHeader(); networkHeader.PublisherID = new String(PublisherId); networkHeader.VersionAndFlags = 0xD1; networkHeader.ExtendedFlags1 = new ExtendedFlags1 { RawValue = 0x84 }; networkHeader.ExtendedFlags2 = new ExtendedFlags2 { RawValue = isMetaMessage ? (byte)0x09 : (byte)0x01 }; return(networkHeader); }
/// <summary> /// Returns a specific instance e.g. a MetaFrame, Key- or DeltaFrame. /// </summary> /// <param name="networkMessageHeader">The NetworkMessageHeader which was already parsed from the input stream.</param> /// <param name="inputStream">The input stream which should be parsed.</param> /// <param name="writerID"> /// Optionally the original WriterID. This is only required when a chunked DataFrame is parsed, /// because it does not contain the real WriterID. /// </param> /// <returns> /// Either a <c>MetaFrame</c>, <c>KeyFrame</c> or <c>DeltaFrame</c> if the message could be parsed successfully or /// <c>null</c> if the binary message could not be parsed. /// </returns> private NetworkMessage GetSpecificMessage(NetworkMessageHeader networkMessageHeader, Stream inputStream, ushort?writerID = null) { NetworkMessage parsedMessage = null; switch (networkMessageHeader.ExtendedFlags2.MessageType) { case MessageType.DiscoveryResponse: Logger.Debug("ParsePayload - Discovery Response"); parsedMessage = ParseMetaFrame(inputStream, networkMessageHeader, Options); break; case MessageType.DataSetMessage: Logger.Debug("ParsePayload - DataSetMessage"); DataFrame dataFrame = null; if (writerID != null) { // If a writeID is present we have a chunked message, // and we must not try to parse the Header, because there's no // header in case of a chunked DataSetMessage. dataFrame = new DataFrame(); if (!DataFrame.DecodeChunk(inputStream, ref dataFrame)) { Logger.Error($"Unable to decode chunked DataFrame: {dataFrame}."); return(null); } dataFrame.PayloadHeader.DataSetWriterID = new[] { writerID.Value }; } else { dataFrame = DataFrame.Decode(inputStream); if (dataFrame == null) { Logger.Error($"Unable to decode DataFrame: {networkMessageHeader}."); return(null); } } dataFrame.NetworkMessageHeader = networkMessageHeader; parsedMessage = ParseDataSetFrame(inputStream, dataFrame); break; default: Logger.Warn($"ParsePayload - Not supported message type: {networkMessageHeader.ExtendedFlags2.MessageType}"); break; } return(parsedMessage); }
public override void Encode(Stream outputStream, bool withHeader = true) { if (outputStream == null || !outputStream.CanWrite) { return; } if (withHeader) { // 1. Network Message Header NetworkMessageHeader.Encode(outputStream); } // 2. DataSet Payload Header PayloadHeader.Encode(outputStream); EncodeChunk(outputStream); }
private List <byte[]> GetChunkedFrame(uint chunkSize, DataFrame dataFrame) { byte[] rawData; using (MemoryStream stream = new MemoryStream()) { dataFrame.EncodeChunk(stream); rawData = stream.ToArray(); } List <byte[]> rawChunks = new List <byte[]>(); if (chunkSize == 0) { using (MemoryStream completeOutputStream = new MemoryStream()) { dataFrame.NetworkMessageHeader.Encode(completeOutputStream); dataFrame.PayloadHeader.Encode(completeOutputStream); completeOutputStream.Write(rawData, 0, rawData.Length); rawChunks.Add(completeOutputStream.ToArray()); } } else { for (uint i = 0; i < rawData.LongLength; i += chunkSize) { NetworkMessageHeader networkHeader = GetChunkedNetworkHeader(); ChunkedMessage chunkedMessage = new ChunkedMessage(); chunkedMessage.PayloadHeader = new ChunkedPayloadHeader(); chunkedMessage.PayloadHeader.DataSetWriterID = dataFrame.PayloadHeader.DataSetWriterID[0]; chunkedMessage.NetworkMessageHeader = networkHeader; chunkedMessage.TotalSize = (uint)rawData.LongLength; chunkedMessage.ChunkOffset = i; chunkedMessage.MessageSequenceNumber = dataFrame.DataSetMessageSequenceNumber; // Check if can copy a "full" chunk or just the remaining elements of the array. long length = Math.Min(chunkSize, rawData.LongLength - chunkedMessage.ChunkOffset); chunkedMessage.ChunkData = new byte[length]; Array.Copy(rawData, i, chunkedMessage.ChunkData, 0, length); using (MemoryStream stream = new MemoryStream()) { chunkedMessage.Encode(stream); rawChunks.Add(stream.ToArray()); } } } return(rawChunks); }
public void HandleInventoryModify(NetworkMessageHeader header, IResult message) { if (message == null) { return; } var msg = (NetworkInventoryModify)message; if (msg.FromContainer == InventoryContainerId.HIRE_LISTING) { if (_irBuffer.TryGetValue((int)msg.FromContainer, out var items)) { items.InventoryItems.RemoveAll(x => x.Slot == msg.FromSlot); } var dat = new RetainerUpdateItem(); dat.ContainerId = InventoryContainerId.HIRE_LISTING; dat.ContainerSlot = msg.FromSlot; dat.IsRemove = true; OnDataReady?.Invoke(new PackedResult(PackedResultType.RetainerUpdate, new RetainerUpdateResult { UpdateItems = new List <RetainerUpdateItem> { dat } })); // delete } else if (msg.ToContainer == InventoryContainerId.HIRE_LISTING) { var result = OnRequestScan?.Invoke(InventoryContainerId.HIRE_LISTING); if (result == null) { return; } if (!_irBuffer.TryGetValue((int)msg.ToContainer, out var items)) { _irBuffer[(int)msg.ToContainer] = new InventoryContainer( InventoryContainerTypeConverter.ToOffset((int)InventoryContainerId.HIRE_LISTING), InventoryContainerId.HIRE_LISTING); } items.InventoryItems.AddRange(result.InventoryContainers.First().InventoryItems.Where(x => x.Slot == msg.ToSlot)); // always a ClientTrigger follows add operation, so we do not need to forge request here. } }
public void HandleNetworkRetainerSummary(NetworkMessageHeader header, IResult message) { var dat = (NetworkRetainerSummary)message; if (dat.RetainerId == 0) { return; } _riBuffer.Add(new RetainerInfoItem { RetainerId = dat.RetainerId, RetainerOrder = dat.RetainerOrder, ItemsInSell = dat.ItemInSell, RetainerLocation = dat.RetainerLocation, ListingDueDate = dat.ListingDueDate, RetainerName = dat.RetainerName, }); }
private MetaFrame ParseMetaFrame(Stream inputStream, NetworkMessageHeader networkMessageHeader, EncodingOptions options) { MetaFrame metaFrame = MetaFrame.Decode(inputStream, options); if (metaFrame == null) { Logger.Error("Could not parse Meta Message."); } if (metaFrame != null) { metaFrame.NetworkMessageHeader = networkMessageHeader; m_LocalMetaStorage.StoreMetaMessageLocally(metaFrame); if (Logger.IsDebugEnabled) { Logger.Debug($"Meta Message decoded with Configuration Version: {metaFrame.ConfigurationVersion}"); Logger.Debug(metaFrame.ToString()); } } return(metaFrame); }
public List <byte[]> GetChunkedMetaFrame(uint chunkSize, EncodingOptions options, ushort sequenceNumber) { byte[] rawMessage = GetEncodedMetaFrame(options, sequenceNumber, false); List <byte[]> rawChunks = new List <byte[]>(); if (chunkSize == 0) { using (MemoryStream completeOutputStream = new MemoryStream()) { m_MetaFrame.NetworkMessageHeader.Encode(completeOutputStream); completeOutputStream.Write(rawMessage, 0, rawMessage.Length); rawChunks.Add(completeOutputStream.ToArray()); } } else { for (uint i = 0; i < rawMessage.LongLength; i += chunkSize) { NetworkMessageHeader networkHeader = GetChunkedNetworkHeader(true); ChunkedMessage chunkedMessage = new ChunkedMessage(); chunkedMessage.PayloadHeader = new ChunkedPayloadHeader(); //chunkedMessage.PayloadHeader.DataSetWriterID = m_MetaFrame.DataSetWriterID; chunkedMessage.NetworkMessageHeader = networkHeader; chunkedMessage.TotalSize = (uint)rawMessage.LongLength; chunkedMessage.ChunkOffset = i; chunkedMessage.MessageSequenceNumber = m_MetaFrame.SequenceNumber; // Check if can copy a "full" chunk or just the remaining elements of the array. long length = Math.Min(chunkSize, rawMessage.LongLength - chunkedMessage.ChunkOffset); chunkedMessage.ChunkData = new byte[length]; Array.Copy(rawMessage, i, chunkedMessage.ChunkData, 0, length); using (MemoryStream stream = new MemoryStream()) { chunkedMessage.Encode(stream); rawChunks.Add(stream.ToArray()); } } } return(rawChunks); }
public void HandleNetworkMarketListing(NetworkMessageHeader header, IResult message) { var dat = (MarketListingResult)message; _listingReqId = dat.RequestId; _mlBuffer.AddRange(dat.ListingItems); _listingPacketCount--; if (_listingPacketCount > 0) { return; } OnDataReady?.Invoke(new PackedResult(PackedResultType.MarketListing, new MarketListingResult { ListingItems = new List <MarketListingItem>(_mlBuffer), RequestId = _listingReqId })); _listingReqId = -1; _mlBuffer.Clear(); }
public void HandleClientTrigger(NetworkMessageHeader header, IResult message) { if (message == null) { return; } var msg = (NetworkClientTrigger)message; var dat = new RetainerUpdateItem(); dat.ContainerId = InventoryContainerId.HIRE_LISTING; dat.NewPrice = msg.Param12; dat.ContainerSlot = msg.Param11; dat.IsRemove = false; try { dat.RetainerId = _retainerId; dat.ItemInfo = _irBuffer[(int)dat.ContainerId].InventoryItems.First(x => x.Slot == dat.ContainerSlot); dat.OldPrice = _ipBuffer.TryGetValue((int)dat.ContainerId * PrimeForInventorySlot + dat.ContainerSlot, out var old) ? old : dat.ItemInfo.UnitPrice; dat.ItemInfo.UnitPrice = dat.NewPrice; } catch { dat.RetainerId = -1; dat.ItemInfo = null; dat.OldPrice = -1; } OnDataReady?.Invoke(new PackedResult(PackedResultType.RetainerUpdate, new RetainerUpdateResult { UpdateItems = new List <RetainerUpdateItem> { dat } })); // add or change }
public virtual List <byte[]> GetChunkedMetaFrame(uint chunkSize) { if (m_MetaFrame == null || chunkSize == 0) { return(null); } byte[] rawMessage = null; using (MemoryStream outputStream = new MemoryStream()) { m_MetaFrame.EncodeChunk(outputStream); rawMessage = outputStream.ToArray(); } List <byte[]> rawChunks = new List <byte[]>(); for (uint i = 0; i < rawMessage.LongLength; i += chunkSize) { NetworkMessageHeader networkHeader = GetChunkedMetaNetworkHeader(); ChunkedMessage chunkedMessage = new ChunkedMessage(); chunkedMessage.PayloadHeader = new ChunkedPayloadHeader(); //chunkedMessage.PayloadHeader.DataSetWriterID = m_MetaFrame.DataSetWriterID; chunkedMessage.NetworkMessageHeader = networkHeader; chunkedMessage.TotalSize = (uint)rawMessage.LongLength; chunkedMessage.ChunkOffset = i; chunkedMessage.MessageSequenceNumber = m_MetaFrame.SequenceNumber; // Check if can copy a "full" chunk or just the remaining elements of the array. long length = Math.Min(chunkSize, rawMessage.LongLength - chunkedMessage.ChunkOffset); chunkedMessage.ChunkData = new byte[length]; Array.Copy(rawMessage, i, chunkedMessage.ChunkData, 0, length); using (MemoryStream stream = new MemoryStream()) { chunkedMessage.Encode(stream); rawChunks.Add(stream.ToArray()); } } return(rawChunks); }
public void HandleNetworkItemPriceInfo(NetworkMessageHeader header, IResult message) { if (_retainerCountdown <= 0) { return; } var dat = (NetworkItemPriceInfo)message; if (!_irBuffer.ContainsKey(dat.ContainerId)) { _ipBuffer[dat.ContainerId * PrimeForInventorySlot + dat.ContainerSlot] = dat.UnitPrice; return; } if (!_irBuffer[dat.ContainerId].InventoryItems.Exists(x => x.Slot == dat.ContainerSlot)) { _ipBuffer[dat.ContainerId * PrimeForInventorySlot + dat.ContainerSlot] = dat.UnitPrice; return; } _irBuffer[dat.ContainerId].InventoryItems.Where(x => x.Slot == dat.ContainerSlot).ToList() .ForEach(x => x.UnitPrice = dat.UnitPrice); }
public void HandleNetworkRetainerSumEnd(NetworkMessageHeader header, IResult message) { OnDataReady?.Invoke(new PackedResult(PackedResultType.RetainerList, new RetainerInfoResult(new List <RetainerInfoItem>(_riBuffer)))); _riBuffer.Clear(); }
public void HandleNetworkLogout(NetworkMessageHeader header, IResult message) { OnGameLoggingOut?.Invoke(); }
public void HandleNetworkRetainerHistory(NetworkMessageHeader header, IResult message) { OnDataReady?.Invoke(new PackedResult(PackedResultType.RetainerHistory, (RetainerHistoryResult)message)); }
/// <summary> /// Parses a binary encoded OPC UA PubSub message. /// In case a message was decoded successfully a <see cref="MessageDecoded" /> event is raised. /// </summary> /// <param name="payload">Binary payload which should be decoded.</param> /// <returns><see cref="NetworkMessage" />The decoded message or <c>null</c> if the decoding failed for any reason.</returns> public NetworkMessage ParseBinaryMessage(byte[] payload) { if (payload == null) { Logger.Warn("ParsePayload - payload == null"); return(null); } if (payload.Length == 0) { Logger.Warn("ParsePayload - payload.Length == 0"); return(null); } NetworkMessage parsedMessage = null; using (MemoryStream memoryStream = new MemoryStream(payload, false)) { NetworkMessageHeader networkMessageHeader = NetworkMessageHeader.Decode(memoryStream); byte version = networkMessageHeader.ProtocolVersion; if (version != 1) { Logger.Warn($"Not supported protocol version: {version}. Skipping message."); return(null); } if (Logger.IsDebugEnabled) { Logger.Debug($"Message\t\t[{networkMessageHeader.ExtendedFlags2.MessageType}]\t\tfrom: {networkMessageHeader.PublisherID}"); } bool isChunkMessage = networkMessageHeader.ExtendedFlags2.Chunk; if (Logger.IsDebugEnabled) { Logger.Debug($"Chunked Message: {isChunkMessage}"); } if (isChunkMessage) { ChunkedMessage chunkedMessage = ChunkedMessage.Decode(memoryStream); if (chunkedMessage == null) { Logger.Error("Unable to parse chunked message."); } else { chunkedMessage.NetworkMessageHeader = networkMessageHeader; if (m_ChunkManager.Store(chunkedMessage)) { if (Logger.IsDebugEnabled) { Logger.Debug("All chunks received. Starting decoding of message."); } byte[] completeMessage = m_ChunkManager.GetPayload(chunkedMessage); using (MemoryStream chunkedStream = new MemoryStream(completeMessage, false)) { parsedMessage = GetSpecificMessage(networkMessageHeader, chunkedStream, chunkedMessage.PayloadHeader.DataSetWriterID); } if (Logger.IsDebugEnabled) { Logger.Debug(parsedMessage != null ? "Chunked message successfully decoded." : "Failed to decode chunked message."); } } else { if (Logger.IsDebugEnabled) { Logger.Debug("Not all chunked received yet. Cannot decode message."); } parsedMessage = chunkedMessage; } } } else { parsedMessage = GetSpecificMessage(networkMessageHeader, memoryStream); } // Ensure that we have at least the Network Message Header available. if (parsedMessage == null) { parsedMessage = new NetworkMessage { NetworkMessageHeader = networkMessageHeader }; } else { if (parsedMessage.NetworkMessageHeader == null) { parsedMessage.NetworkMessageHeader = networkMessageHeader; } } // Because we might have modified the PublisherID, // the RawPayload is set to null to avoid inconsistencies. parsedMessage.RawPayload = null; } return(parsedMessage); }
public void HandleLobbyService(NetworkMessageHeader header, IResult message) { OnDataReady?.Invoke(new PackedResult(PackedResultType.LobbyService, (LobbyServiceResult)message)); }