Exemple #1
0
        /// <summary>
        /// Responsible for encoding and decoding packet information.
        /// </summary>
        //public class Interpreter

        /// <summary>
        /// Interpreter for converting byte input to a BitBuffer.
        /// </summary>
        //protected Interpreter Interpreter { get; } = new Interpreter();

        protected void ProcessPayload(Controller connection, Packet reusableIncoming, Func <T, bool> getSafeToExecute)
        {
            /// <summary>
            /// Records acknowledging information for the packet.
            /// </summary>
            // Connection.ProcessPacket
            connection.RemoteClock.UpdateLatest(reusableIncoming.SenderTick);
            foreach (var evnt in FilterIncomingEvents(reusableIncoming.Events))
            {
                /// <summary>
                /// Handles the execution of an incoming event.
                /// </summary>
                // private void ProcessEvent(Event evnt)
                {
                    if (evnt.EntityId.IsValid)
                    {
                        World_Entities.TryGetValue(evnt.EntityId, out var entity);

                        if (getSafeToExecute(entity))
                        {
                            Event_InvokeEntity(evnt, connection, entity);
                        }
                    }
                    else
                    {
                        Event_Invoke(evnt, connection);
                    }
                    connection.ProcessedEventHistory = connection.ProcessedEventHistory.Store(evnt.EventId);
                }
            }

            var ackedEventId = reusableIncoming.AckEventId;

            {
                /// <summary>
                /// Removes any acked or expired outgoing events.
                /// </summary>
                //void CleanOutgoingEvents(SequenceId ackedEventId)
                if (ackedEventId.IsValid != false)
                {
                    while (connection.OutgoingEvents.Count > 0)
                    {
                        var top = connection.OutgoingEvents.Peek();

                        // Stop if we hit an un-acked reliable event
                        if (top.IsReliable)
                        {
                            if (top.EventId > ackedEventId)
                            {
                                break;
                            }
                        }
                        // Stop if we hit an unreliable event with remaining attempts
                        else
                        {
                            if (top.Attempts > 0)
                            {
                                break;
                            }
                        }

                        var val = connection.OutgoingEvents.Dequeue();
                        val.Pool.Deallocate(val);
                    }
                }
            }

            /// <summary>
            /// Gets all events that we haven't processed yet, in order with no gaps.
            /// </summary>
            IEnumerable <Event> FilterIncomingEvents(IEnumerable <Event> events)
            {
                foreach (var evnt in events)
                {
                    if (connection.ProcessedEventHistory.IsNewId(evnt.EventId))
                    {
                        yield return(evnt);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Wraps an incoming connection in a peer and stores it.
        /// </summary>
        public void AddConnection(IConnection connection)
        {
            if (!clients.ContainsKey(connection))
            {
                var controller = new ServerController(connection);

                // ServerConnection.ctor
                controller.Connection.PayloadReceived += (data, length) =>
                {
                    //Console.WriteLine($"data {data.Length} length {length}"); // 253 245
                    var reusableIncoming = _protocol.Decode(data, length);
                    if (reusableIncoming != default)
                    {
                        ProcessPayload(controller, reusableIncoming, entity =>
                        {
                            // Entity events can only be executed on controlled entities
                            return(entity != null && entity.Controller == controller);
                        });
                        //onProcessPacket();
                        // Integrate
                        foreach (var pair in reusableIncoming.View.LatestUpdates)
                        {
                            controller.Scope.AckedByClient.RecordUpdate(pair.Key, pair.Value);
                        }

                        // client.PacketReceived.Invoke(client, clientPacket);
                        {
                            // client.PacketReceived += (_peer, clientPacket) =>
                            foreach (var update in reusableIncoming.ReceivedCommandUpdates)
                            {
                                {
                                    // ServerManager.ProcessCommandUpdate
                                    if (World_Entities.TryGetValue(update.EntityId, out var entity))
                                    {
                                        foreach (var command in update.Commands.GetValues())
                                        {
                                            if (entity.Controller == controller && entity.IncomingCommands.Store(command))
                                            {
                                                command.IsNewCommand = true;
                                            }
                                            else
                                            {
                                                command.Pool.Deallocate(command);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Bad packet read, discarding...");
                    }
                    reusableIncoming.Reset();
                };

                clients.Add(connection, controller);

                ControllerJoined.Invoke(controller);
            }
        }