public void OnAck(MyClientStateBase forClient, byte packetId, bool delivered)
        {
            Console.WriteLine(String.Format("delivery: {0}, {1}", packetId, delivered));
            InventoryClientData clientData = m_clientInventoryUpdate[forClient.EndpointId.Value];
            InventoryPartInfo   packetInfo;

            if (clientData.SendPackets.TryGetValue(packetId, out packetInfo))
            {
                if (delivered == false)
                {
                    if (packetInfo.AllItemsSend)
                    {
                        clientData.Dirty = true;
                        clientData.MainSendingInfo.StartItemIndex = 0;
                        clientData.MainSendingInfo.NumItems       = 0;
                        clientData.SendPackets.Clear();
                        clientData.FailedIncompletePackets.Clear();
                    }
                    else
                    {
                        clientData.FailedIncompletePackets.Add(packetInfo);
                    }
                }

                clientData.SendPackets.Remove(packetId);
            }
        }
Exemple #2
0
        void CreateClientData(Endpoint clientEndpoint)
        {
            if (!_serverData.TryGetValue(clientEndpoint, out var clientData))
            {
                clientData = new InventoryClientData();
                _serverData[clientEndpoint] = clientData;
            }

            clientData.Dirty     = false;
            clientData.HasRights = !Plugin.StaticConfig.InventoryPreventSharing ||
                                   (Owner as InventoryReplicable).HasRights(clientEndpoint.Id, ValidationType.Access | ValidationType.Ownership) ==
                                   ValidationResult.Passed;

            foreach (var item in Inventory.GetItems())
            {
                var amount = item.Amount;
                if (item.Content is MyObjectBuilder_GasContainerObject gas)
                {
                    amount = (MyFixedPoint)gas.GasLevel;
                }

                var data = new ClientInvetoryData
                {
                    Item   = item,
                    Amount = amount
                };
                clientData.ClientItemsSorted[item.ItemId] = data;
                clientData.ClientItems.Add(data);
            }
        }
        public void Serialize(BitStream stream, MyClientStateBase forClient, byte packetId, int maxBitPosition)
        {
            if (stream.Writing)
            {
                InventoryClientData clientData = m_clientInventoryUpdate[forClient.EndpointId.Value];
                if (clientData.FailedIncompletePackets.Count > 0)
                {
                    InventoryPartInfo failedPacket = clientData.FailedIncompletePackets[0];
                    clientData.FailedIncompletePackets.RemoveAtFast(0);

                    InventoryPartInfo reSendPacket = WriteInventory(ref failedPacket, stream, packetId, maxBitPosition, true);
                    clientData.SendPackets[packetId] = reSendPacket;
                }
                else
                {
                    clientData.MainSendingInfo       = WriteInventory(ref clientData.MainSendingInfo, stream, packetId, maxBitPosition);
                    clientData.SendPackets[packetId] = clientData.MainSendingInfo;

                    List <MyPhysicalInventoryItem> items = Inventory.GetItems();

                    if (clientData.MainSendingInfo.StartItemIndex + clientData.MainSendingInfo.NumItems >= items.Count)
                    {
                        clientData.MainSendingInfo.StartItemIndex = 0;
                        clientData.MainSendingInfo.NumItems       = 0;
                        clientData.Dirty = false;
                    }
                }
            }
            else
            {
                ReadInventory(stream);
            }
        }
Exemple #4
0
        public float GetGroupPriority(int frameCountWithoutSync, MyClientInfo client)
        {
            ProfilerShort.Begin("MyEntityInventoryStateGroup::GetGroupPriority");
            InventoryClientData            clientData = m_clientInventoryUpdate[client.EndpointId.Value];
            List <MyPhysicalInventoryItem> items      = Inventory.GetItems();

            if (clientData.Dirty == false && clientData.FailedIncompletePackets.Count == 0)
            {
                ProfilerShort.End();
                return(-1);
            }

            if (clientData.FailedIncompletePackets.Count > 0)
            {
                ProfilerShort.End();
                return(1.0f * frameCountWithoutSync);
            }

            MyClientState state = (MyClientState)client.State;

            if (Inventory.Owner is MyCharacter)
            {
                MyCharacter character = Inventory.Owner as MyCharacter;
                MyPlayer    player    = MyPlayer.GetPlayerFromCharacter(character);

                if (player == null && character.IsUsing != null)
                {
                    MyShipController cockpit = (character.IsUsing as MyShipController);
                    if (cockpit != null && cockpit.ControllerInfo.Controller != null)
                    {
                        player = cockpit.ControllerInfo.Controller.Player;
                    }
                }

                if (player != null && player.Id.SteamId == client.EndpointId.Value)
                {
                    ProfilerShort.End();
                    return(1.0f * frameCountWithoutSync);
                }
            }

            if (state.ContextEntity is MyCharacter && state.ContextEntity == Inventory.Owner)
            {
                ProfilerShort.End();
                return(1.0f * frameCountWithoutSync);
            }

            if (state.Context == MyClientState.MyContextKind.Inventory || state.Context == MyClientState.MyContextKind.Building ||
                (state.Context == MyClientState.MyContextKind.Production && Inventory.Owner is MyAssembler))
            {
                ProfilerShort.End();
                return(GetPriorityStateGroup(client) * frameCountWithoutSync);
            }

            ProfilerShort.End();
            return(0);
        }
        public bool Serialize(BitStream stream, EndpointId forClient, uint timestamp, byte packetId, int maxBitPosition)
        {
            if (stream.Writing)
            {
                InventoryClientData clientData = m_clientInventoryUpdate[forClient.Value];
                bool needsSplit = false;
                if (clientData.FailedIncompletePackets.Count > 0)
                {
                    InventoryDeltaInformation failedPacket = clientData.FailedIncompletePackets[0];
                    clientData.FailedIncompletePackets.RemoveAtFast(0);

                    InventoryDeltaInformation reSendPacket = WriteInventory(ref failedPacket, stream, packetId, maxBitPosition, out needsSplit);

                    if (needsSplit)
                    {
                        //resend split doesnt generate new id becaose it was part of allreadt sent message
                        clientData.FailedIncompletePackets.Add(CreateSplit(ref failedPacket, ref reSendPacket));
                    }

                    if (reSendPacket.HasChanges)
                    {
                        clientData.SendPackets[packetId] = reSendPacket;
                    }
                }
                else
                {
                    InventoryDeltaInformation difference = CalculateInventoryDiff(ref clientData);
                    difference.MessageId = clientData.CurrentMessageId;

                    clientData.MainSendingInfo = WriteInventory(ref difference, stream, packetId, maxBitPosition, out needsSplit);
                    if (needsSplit)
                    {
                        //split generate new id becaose its different message
                        clientData.CurrentMessageId++;
                        InventoryDeltaInformation split = CreateSplit(ref difference, ref clientData.MainSendingInfo);
                        split.MessageId = clientData.CurrentMessageId;
                        clientData.FailedIncompletePackets.Add(split);
                    }

                    if (clientData.MainSendingInfo.HasChanges)
                    {
                        clientData.SendPackets[packetId] = clientData.MainSendingInfo;
                        clientData.CurrentMessageId++;
                    }

                    clientData.Dirty = false;
                }
            }
            else
            {
                ReadInventory(stream);
            }

            return(true);
        }
Exemple #6
0
        public void OnAck(MyClientStateBase forClient, byte packetId, bool delivered)
        {
            Console.WriteLine(String.Format("delivery: {0}, {1}", packetId, delivered));
            InventoryClientData       clientData = m_clientInventoryUpdate[forClient.EndpointId.Value];
            InventoryDeltaInformation packetInfo;

            if (clientData.SendPackets.TryGetValue(packetId, out packetInfo))
            {
                if (delivered == false)
                {
                    clientData.FailedIncompletePackets.Add(packetInfo);
                }

                clientData.SendPackets.Remove(packetId);
            }
        }
Exemple #7
0
        static void ApplyChangesToClientItems(InventoryClientData clientData, ref InventoryDeltaInformation delta)
        {
            if (delta.RemovedItems != null)
            {
                foreach (var num in delta.RemovedItems)
                {
                    var num2 = -1;
                    for (var i = 0; i < clientData.ClientItems.Count; i++)
                    {
                        if (clientData.ClientItems[i].Item.ItemId == num)
                        {
                            num2 = i;
                            break;
                        }
                    }

                    if (num2 != -1)
                    {
                        clientData.ClientItems.RemoveAt(num2);
                    }
                }
            }

            if (delta.NewItems != null)
            {
                foreach (var keyValuePair in delta.NewItems)
                {
                    var item = new ClientInvetoryData
                    {
                        Item   = keyValuePair.Value,
                        Amount = keyValuePair.Value.Amount
                    };
                    if (keyValuePair.Key >= clientData.ClientItems.Count)
                    {
                        clientData.ClientItems.Add(item);
                    }
                    else
                    {
                        clientData.ClientItems.Insert(keyValuePair.Key, item);
                    }
                }
            }
        }
        private void ApplyChangesToClientItems(InventoryClientData clientData, ref InventoryDeltaInformation delta)
        {
            if (delta.RemovedItems != null)
            {
                foreach (var item in delta.RemovedItems)
                {
                    int index = -1;
                    for (int i = 0; i < clientData.ClientItems.Count; ++i)
                    {
                        if (clientData.ClientItems[i].Item.ItemId == item)
                        {
                            index = i;
                            break;
                        }
                    }

                    if (index != -1)
                    {
                        clientData.ClientItems.RemoveAt(index);
                    }
                }
            }

            if (delta.NewItems != null)
            {
                foreach (var item in delta.NewItems)
                {
                    ClientInvetoryData newitem = new ClientInvetoryData()
                    {
                        Item = item.Value, Amount = item.Value.Amount
                    };
                    if (item.Key >= clientData.ClientItems.Count)
                    {
                        clientData.ClientItems.Add(newitem);
                    }
                    else
                    {
                        clientData.ClientItems.Insert(item.Key, newitem);
                    }
                }
            }
        }
        public float GetGroupPriority(int frameCountWithoutSync, MyClientStateBase client)
        {
            InventoryClientData clientData = m_clientInventoryUpdate[client.EndpointId.Value];

            MyClientState state = client as MyClientState;

            if (Inventory.Owner is MyCharacter && m_clientInventoryUpdate[client.EndpointId.Value].Dirty)
            {
                MyPlayer player = MyPlayer.GetPlayerFromCharacter(Inventory.Owner as MyCharacter);
                if (player != null && player.Id.SteamId == client.EndpointId.Value)
                {
                    return(1.0f);
                }
            }

            if (m_clientInventoryUpdate[client.EndpointId.Value].Dirty && (state.Context == MyClientState.MyContextKind.Inventory ||
                                                                           (state.Context == MyClientState.MyContextKind.Production && Inventory.Owner is MyAssembler)))
            {
                return(Inventory.GetPriorityStateGroup(client));
            }
            return(0);
        }
        InventoryDeltaInformation CalculateInventoryDiff(ref InventoryClientData clientData)
        {
            if (m_itemsToSend == null)
            {
                m_itemsToSend = new List <MyPhysicalInventoryItem>();
            }

            if (m_foundDeltaItems == null)
            {
                m_foundDeltaItems = new HashSet <uint>();
            }
            m_foundDeltaItems.Clear();


            InventoryDeltaInformation      delta;
            List <MyPhysicalInventoryItem> items = Inventory.GetItems();

            //this is two step algoritm

            //first check for adds/removals
            //this part can find removed and added items
            //but cannot find swapped items
            CalculateAddsAndRemovals(clientData, out delta, items);

            //apply changes to client items (only add and remove)

            if (delta.HasChanges)
            {
                ApplyChangesToClientItems(clientData, ref delta);
            }
            //then check client data for changed items
            for (int i = 0; i < items.Count; ++i)
            {
                if (clientData.ClientItems.Count < i && clientData.ClientItems[i].Item.ItemId != items[i].ItemId)
                {
                    if (delta.SwappedItems == null)
                    {
                        delta.SwappedItems = new Dictionary <int, int>();
                    }
                    if (delta.SwappedItems.ContainsKey(i))
                    {
                        continue;
                    }

                    for (int j = 0; j < clientData.ClientItems.Count; ++j)
                    {
                        if (clientData.ClientItems[j].Item.ItemId == items[i].ItemId)
                        {
                            delta.SwappedItems[j] = i;
                        }
                    }
                }
            }

            clientData.ClientItemsSorted.Clear();
            clientData.ClientItems.Clear();

            foreach (var serverItem in items)
            {
                MyFixedPoint amount = serverItem.Amount;

                var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                if (gasItem != null)
                {
                    amount = (MyFixedPoint)gasItem.GasLevel;
                }
                ClientInvetoryData item = new ClientInvetoryData()
                {
                    Item = serverItem, Amount = amount
                };
                clientData.ClientItemsSorted[serverItem.ItemId] = item;
                clientData.ClientItems.Add(item);
            }
            return(delta);
        }
Exemple #11
0
        void CalculateAddsAndRemovals(InventoryClientData clientData, out InventoryDeltaInformation delta, List <MyPhysicalInventoryItem> items)
        {
            delta = new InventoryDeltaInformation
            {
                HasChanges = false
            };
            var num = 0;

            foreach (var myPhysicalInventoryItem in items)
            {
                if (clientData.ClientItemsSorted.TryGetValue(myPhysicalInventoryItem.ItemId, out var data))
                {
                    if (data.Item.Content.TypeId == myPhysicalInventoryItem.Content.TypeId &&
                        data.Item.Content.SubtypeId == myPhysicalInventoryItem.Content.SubtypeId)
                    {
                        m_foundDeltaItems.Add(myPhysicalInventoryItem.ItemId);
                        var myFixedPoint = myPhysicalInventoryItem.Amount;
                        var obj          = myPhysicalInventoryItem.Content as MyObjectBuilder_GasContainerObject;
                        if (obj != null)
                        {
                            myFixedPoint = (MyFixedPoint)obj.GasLevel;
                        }

                        if (data.Amount != myFixedPoint)
                        {
                            var value = myFixedPoint - data.Amount;
                            if (delta.ChangedItems == null)
                            {
                                delta.ChangedItems = new Dictionary <uint, MyFixedPoint>();
                            }

                            delta.ChangedItems[myPhysicalInventoryItem.ItemId] = value;
                            delta.HasChanges = true;
                        }
                    }
                }
                else
                {
                    delta.NewItems ??= new SortedDictionary <int, MyPhysicalInventoryItem>();
                    delta.NewItems[num] = myPhysicalInventoryItem;
                    delta.HasChanges    = true;
                }

                num++;
            }

            foreach (var keyValuePair in clientData.ClientItemsSorted)
            {
                if (delta.RemovedItems == null)
                {
                    delta.RemovedItems = new List <uint>();
                }

                if (m_foundDeltaItems.Contains(keyValuePair.Key))
                {
                    continue;
                }
                delta.RemovedItems.Add(keyValuePair.Key);
                delta.HasChanges = true;
            }
        }
Exemple #12
0
        InventoryDeltaInformation CalculateInventoryDiff(ref InventoryClientData clientData)
        {
            if (m_itemsToSend == null)
            {
                m_itemsToSend = new List <MyPhysicalInventoryItem>();
            }

            if (m_foundDeltaItems == null)
            {
                m_foundDeltaItems = new HashSet <uint>();
            }

            m_foundDeltaItems.Clear();
            var items = Inventory.GetItems();

            CalculateAddsAndRemovals(clientData, out var delta, items);
            if (delta.HasChanges)
            {
                ApplyChangesToClientItems(clientData, ref delta);
            }

            for (var i = 0; i < items.Count; i++)
            {
                if (i < clientData.ClientItems.Count)
                {
                    var itemId = clientData.ClientItems[i].Item.ItemId;
                    if (itemId != items[i].ItemId)
                    {
                        if (delta.SwappedItems == null)
                        {
                            delta.SwappedItems = new Dictionary <uint, int>();
                        }

                        for (var j = 0; j < items.Count; j++)
                        {
                            if (itemId == items[j].ItemId)
                            {
                                delta.SwappedItems[itemId] = j;
                            }
                        }
                    }
                }
            }

            clientData.ClientItemsSorted.Clear();
            clientData.ClientItems.Clear();
            foreach (var item in items)
            {
                var amount = item.Amount;
                var obj    = item.Content as MyObjectBuilder_GasContainerObject;
                if (obj != null)
                {
                    amount = (MyFixedPoint)obj.GasLevel;
                }

                var data = new ClientInvetoryData
                {
                    Item   = item,
                    Amount = amount
                };
                clientData.ClientItemsSorted[item.ItemId] = data;
                clientData.ClientItems.Add(data);
            }

            return(delta);
        }
        private void ApplyChangesToClientItems(InventoryClientData clientData,ref  InventoryDeltaInformation delta)
        {
            if (delta.RemovedItems != null)
            {
                foreach (var item in delta.RemovedItems)
                {
                    int index = -1;
                    for (int i = 0; i < clientData.ClientItems.Count; ++i)
                    {
                        if (clientData.ClientItems[i].Item.ItemId == item)
                        {
                            index = i;
                            break;
                        }
                    }

                    if (index != -1)
                    {
                        clientData.ClientItems.RemoveAt(index);
                    }
                }
            }

            if (delta.NewItems != null)
            {
                foreach (var item in delta.NewItems)
                {
                    ClientInvetoryData newitem = new ClientInvetoryData() { Item = item.Value, Amount = item.Value.Amount };
                    if (item.Key >= clientData.ClientItems.Count)
                    {
                        clientData.ClientItems.Add(newitem);
                    }
                    else
                    {
                        clientData.ClientItems.Insert(item.Key, newitem);
                    }
                }
            }
        }
        InventoryDeltaInformation CalculateInventoryDiff(ref InventoryClientData clientData)
        {
            if (m_itemsToSend == null)
            {
                m_itemsToSend = new List<MyPhysicalInventoryItem>();
            }

            if(m_foundDeltaItems == null )
            {
                m_foundDeltaItems = new HashSet<uint>();
            }
            m_foundDeltaItems.Clear();
           
            
            InventoryDeltaInformation delta;
            List<MyPhysicalInventoryItem> items = Inventory.GetItems();
            //this is two step algoritm 

            //first check for adds/removals
            //this part can find removed and added items
            //but cannot find swapped items
            CalculateAddsAndRemovals(clientData, out delta, items);

            //apply changes to client items (only add and remove)

            if(delta.HasChanges)
            {
                ApplyChangesToClientItems(clientData,ref delta);
            }
            //then check client data for changed items
            for (int i = 0; i < items.Count; ++i)
            {
                if(clientData.ClientItems.Count < i && clientData.ClientItems[i].Item.ItemId !=  items[i].ItemId)
                {    
                    if(delta.SwappedItems == null)
                    {
                        delta.SwappedItems = new Dictionary<int, int>();
                    }
                    if(delta.SwappedItems.ContainsKey(i))
                    {
                        continue;
                    }

                    for (int j = 0; j < clientData.ClientItems.Count;++j)
                    {
                        if(clientData.ClientItems[j].Item.ItemId == items[i].ItemId)
                        {
                            delta.SwappedItems[j] = i;
                        }
                    }             
                }
            }

            clientData.ClientItemsSorted.Clear();
            clientData.ClientItems.Clear();

            foreach (var serverItem in items)
            {
                MyFixedPoint amount = serverItem.Amount;

                var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                if (gasItem != null)
                {
                    amount = (MyFixedPoint)gasItem.GasLevel;
                }
                ClientInvetoryData item = new ClientInvetoryData() { Item = serverItem, Amount = amount };
                clientData.ClientItemsSorted[serverItem.ItemId] = item;
                clientData.ClientItems.Add(item);
            }
            return delta;
        }
Exemple #15
0
        InventoryDeltaInformation CalculateInventoryDiff(ref InventoryClientData clientData)
        {
            if (m_itemsToSend == null)
            {
                m_itemsToSend = new List <MyPhysicalInventoryItem>();
            }

            if (m_foundDeltaItems == null)
            {
                m_foundDeltaItems = new HashSet <uint>();
            }
            m_foundDeltaItems.Clear();

            InventoryDeltaInformation delta = new InventoryDeltaInformation();

            delta.HasChanges = false;

            List <MyPhysicalInventoryItem> items = Inventory.GetItems();

            int serverPos = 0;

            foreach (var serverItem in items)
            {
                ClientInvetoryData clientItem;

                if (clientData.ClientItems.TryGetValue(serverItem.ItemId, out clientItem))
                {
                    if (clientItem.Item.Content.TypeId == serverItem.Content.TypeId &&
                        clientItem.Item.Content.SubtypeId == serverItem.Content.SubtypeId)
                    {
                        m_foundDeltaItems.Add(serverItem.ItemId);
                        delta.HasChanges = true;

                        MyFixedPoint serverAmount = serverItem.Amount;

                        var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                        if (gasItem != null)
                        {
                            serverAmount = (MyFixedPoint)gasItem.GasLevel;
                        }

                        if (clientItem.Amount != serverAmount)
                        {
                            MyFixedPoint contentDelta = serverAmount - clientItem.Amount;
                            if (delta.ChangedItems == null)
                            {
                                delta.ChangedItems = new Dictionary <uint, MyFixedPoint>();
                            }
                            delta.ChangedItems[serverItem.ItemId] = contentDelta;
                        }
                    }
                }
                else
                {
                    if (delta.NewItems == null)
                    {
                        delta.NewItems = new SortedDictionary <int, MyPhysicalInventoryItem>();
                    }
                    delta.NewItems[serverPos] = serverItem;
                    delta.HasChanges          = true;
                }

                serverPos++;
            }

            foreach (var clientItem in clientData.ClientItems)
            {
                if (delta.RemovedItems == null)
                {
                    delta.RemovedItems = new List <uint>();
                }
                if (m_foundDeltaItems.Contains(clientItem.Key) == false)
                {
                    delta.RemovedItems.Add(clientItem.Key);
                    delta.HasChanges = true;
                }
            }

            clientData.ClientItems.Clear();
            foreach (var serverItem in items)
            {
                MyFixedPoint amount = serverItem.Amount;

                var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                if (gasItem != null)
                {
                    amount = (MyFixedPoint)gasItem.GasLevel;
                }

                clientData.ClientItems[serverItem.ItemId] = new ClientInvetoryData()
                {
                    Item = serverItem, Amount = amount
                };
            }
            return(delta);
        }
        private void CalculateAddsAndRemovals(InventoryClientData clientData, out InventoryDeltaInformation delta, List<MyPhysicalInventoryItem> items)
        {
            delta = new InventoryDeltaInformation();
            delta.HasChanges = false;

            int serverPos = 0;
            foreach (var serverItem in items)
            {
                ClientInvetoryData clientItem;

                if (clientData.ClientItemsSorted.TryGetValue(serverItem.ItemId, out clientItem))
                {
                    if (clientItem.Item.Content.TypeId == serverItem.Content.TypeId &&
                        clientItem.Item.Content.SubtypeId == serverItem.Content.SubtypeId)
                    {
                        m_foundDeltaItems.Add(serverItem.ItemId);
                        MyFixedPoint serverAmount = serverItem.Amount;

                        var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                        if (gasItem != null)
                        {
                            serverAmount = (MyFixedPoint)gasItem.GasLevel;
                        }

                        if (clientItem.Amount != serverAmount)
                        {
                            MyFixedPoint contentDelta = serverAmount - clientItem.Amount;
                            if (delta.ChangedItems == null)
                            {
                                delta.ChangedItems = new Dictionary<uint, MyFixedPoint>();
                            }
                            delta.ChangedItems[serverItem.ItemId] = contentDelta;
                            delta.HasChanges = true;
                        }
                    }
                }
                else
                {
                    if (delta.NewItems == null)
                    {
                        delta.NewItems = new SortedDictionary<int, MyPhysicalInventoryItem>();
                    }
                    delta.NewItems[serverPos] = serverItem;
                    delta.HasChanges = true;
                }

                serverPos++;
            }

            foreach (var clientItem in clientData.ClientItemsSorted)
            {
                if (delta.RemovedItems == null)
                {
                    delta.RemovedItems = new List<uint>();
                }
                if (m_foundDeltaItems.Contains(clientItem.Key) == false)
                {
                    delta.RemovedItems.Add(clientItem.Key);
                    delta.HasChanges = true;
                }
            }
        }
        private void CalculateAddsAndRemovals(InventoryClientData clientData, out InventoryDeltaInformation delta, List <MyPhysicalInventoryItem> items)
        {
            delta            = new InventoryDeltaInformation();
            delta.HasChanges = false;

            int serverPos = 0;

            foreach (var serverItem in items)
            {
                ClientInvetoryData clientItem;

                if (clientData.ClientItemsSorted.TryGetValue(serverItem.ItemId, out clientItem))
                {
                    if (clientItem.Item.Content.TypeId == serverItem.Content.TypeId &&
                        clientItem.Item.Content.SubtypeId == serverItem.Content.SubtypeId)
                    {
                        m_foundDeltaItems.Add(serverItem.ItemId);
                        MyFixedPoint serverAmount = serverItem.Amount;

                        var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                        if (gasItem != null)
                        {
                            serverAmount = (MyFixedPoint)gasItem.GasLevel;
                        }

                        if (clientItem.Amount != serverAmount)
                        {
                            MyFixedPoint contentDelta = serverAmount - clientItem.Amount;
                            if (delta.ChangedItems == null)
                            {
                                delta.ChangedItems = new Dictionary <uint, MyFixedPoint>();
                            }
                            delta.ChangedItems[serverItem.ItemId] = contentDelta;
                            delta.HasChanges = true;
                        }
                    }
                }
                else
                {
                    if (delta.NewItems == null)
                    {
                        delta.NewItems = new SortedDictionary <int, MyPhysicalInventoryItem>();
                    }
                    delta.NewItems[serverPos] = serverItem;
                    delta.HasChanges          = true;
                }

                serverPos++;
            }

            foreach (var clientItem in clientData.ClientItemsSorted)
            {
                if (delta.RemovedItems == null)
                {
                    delta.RemovedItems = new List <uint>();
                }
                if (m_foundDeltaItems.Contains(clientItem.Key) == false)
                {
                    delta.RemovedItems.Add(clientItem.Key);
                    delta.HasChanges = true;
                }
            }
        }
        InventoryDeltaInformation CalculateInventoryDiff(ref InventoryClientData clientData)
        {
            if (m_itemsToSend == null)
            {
                m_itemsToSend = new List<MyPhysicalInventoryItem>();
            }

            if(m_foundDeltaItems == null )
            {
                m_foundDeltaItems = new HashSet<uint>();
            }
            m_foundDeltaItems.Clear();

            InventoryDeltaInformation delta = new InventoryDeltaInformation();
            delta.HasChanges = false;

            List<MyPhysicalInventoryItem> items = Inventory.GetItems();

            int serverPos = 0;
            foreach (var serverItem in items)
            {

                ClientInvetoryData clientItem;

                if (clientData.ClientItems.TryGetValue(serverItem.ItemId,out clientItem))
                {
                    if (clientItem.Item.Content.TypeId == serverItem.Content.TypeId &&
                        clientItem.Item.Content.SubtypeId == serverItem.Content.SubtypeId)
                    {
                        m_foundDeltaItems.Add(serverItem.ItemId);
                        delta.HasChanges = true;

                        MyFixedPoint serverAmount = serverItem.Amount;

                        var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                        if (gasItem != null)
                        {
                            serverAmount = (MyFixedPoint)gasItem.GasLevel;
                        }

                        if (clientItem.Amount != serverAmount)
                        {
                            MyFixedPoint contentDelta = serverAmount - clientItem.Amount;
                            if (delta.ChangedItems == null)
                            {
                                delta.ChangedItems = new Dictionary<uint, MyFixedPoint>();
                            }
                            delta.ChangedItems[serverItem.ItemId] = contentDelta;
                        }                      
                    }
                }
                else
                {
                    if (delta.NewItems == null)
                    {
                        delta.NewItems = new SortedDictionary<int, MyPhysicalInventoryItem>();
                    }
                    delta.NewItems[serverPos] = serverItem;
                    delta.HasChanges = true;
                }

                serverPos++;
            }

            foreach (var clientItem in clientData.ClientItems)
            {
                if (delta.RemovedItems == null)
                {
                    delta.RemovedItems = new List<uint>();
                }
                if (m_foundDeltaItems.Contains(clientItem.Key) == false)
                {
                    delta.RemovedItems.Add(clientItem.Key);
                    delta.HasChanges = true;
                }
            }

            clientData.ClientItems.Clear();
            foreach (var serverItem in items)
            {
                MyFixedPoint amount = serverItem.Amount;

                var gasItem = serverItem.Content as MyObjectBuilder_GasContainerObject;
                if (gasItem != null)
                {
                    amount = (MyFixedPoint)gasItem.GasLevel;
                }

                clientData.ClientItems[serverItem.ItemId] = new ClientInvetoryData() { Item = serverItem, Amount = amount };
            }
            return delta;
        }