Ejemplo n.º 1
0
        private void ProcessEvent(MyPacket packet)
        {
            if (_networkHandlers.Count == 0)
            {
                //pass the message back to the game server
                try
                {
                    ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
                }
                catch (Exception ex)
                {
                    ApplicationLog.Error(ex, "~Error processing event!");
                    //crash after logging, bad things could happen if we continue on with bad data
                    throw;
                }
                return;
            }

            //magic: DO NOT TOUCH
            BitStream stream = new BitStream();

            stream.ResetRead(packet);

            NetworkId networkId = stream.ReadNetworkId();
            //this value is unused, but removing this line corrupts the rest of the stream
            NetworkId blockedNetworkId = stream.ReadNetworkId();
            uint      eventId          = (uint)stream.ReadUInt16();


            CallSite     site;
            IMyNetObject sendAs;
            object       obj;

            if (networkId.IsInvalid)     // Static event
            {
                site   = m_typeTable.StaticEventTable.Get(eventId);
                sendAs = null;
                obj    = null;
            }
            else     // Instance event
            {
                sendAs = ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).GetObjectByNetworkId(networkId);
                if (sendAs == null)
                {
                    return;
                }
                var typeInfo   = m_typeTable.Get(sendAs.GetType());
                int eventCount = typeInfo.EventTable.Count;
                if (eventId < eventCount)     // Directly
                {
                    obj  = sendAs;
                    site = typeInfo.EventTable.Get(eventId);
                }
                else     // Through proxy
                {
                    obj      = ((IMyProxyTarget)sendAs).Target;
                    typeInfo = m_typeTable.Get(obj.GetType());
                    site     = typeInfo.EventTable.Get(eventId - (uint)eventCount); // Subtract max id of Proxy
                }
            }

#if DEBUG
            if (ExtenderOptions.IsDebugging)
            {
                if (!site.MethodInfo.Name.Contains("SyncPropertyChanged"))    // && !site.MethodInfo.Name.Contains( "OnSimulationInfo" ) )
                {
                    ApplicationLog.Error($"Caught event {site.MethodInfo.Name} from user {PlayerMap.Instance.GetFastPlayerNameFromSteamId( packet.Sender.Id.Value )}:{packet.Sender.Id.Value}. Length {stream.ByteLength}B");
                }
            }
#endif
            //we're handling the network live in the game thread, this needs to go as fast as possible
            bool handled = false;
            Parallel.ForEach(_networkHandlers, handler =>
            {
                try
                {
                    if (handler.CanHandle(site))
                    {
                        handled |= handler.Handle(packet.Sender.Id.Value, site, stream, obj);
                    }
                }
                catch (Exception ex)
                {
                    ApplicationLog.Error(ex.ToString());
                }
            });

            //one of the handlers wants us to discard this packet
            if (handled)
            {
                return;
            }

            //pass the message back to the game server
            try
            {
                ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
            }
            catch (Exception ex)
            {
                ApplicationLog.Error(ex, "Error when returning control to game server!");
                //crash after logging, bad things could happen if we continue on with bad data
                throw;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This is the main body of the network intercept system. When messages come in from clients, they are processed here
        /// before being passed on to the game server.
        ///
        /// DO NOT modify this method unless you're absolutely sure of what you're doing. This can very easily destabilize the game!
        /// </summary>
        /// <param name="packet"></param>
        private void OnEvent(MyPacket packet)
        {
            if (_networkHandlers.Count == 0)
            {
                //pass the message back to the game server
                try
                {
                    ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
                }
                catch (Exception ex)
                {
                    _log.Fatal(ex);
                    _log.Fatal(ex, "~Error processing event!");
                    //crash after logging, bad things could happen if we continue on with bad data
                    throw;
                }
                return;
            }

            var stream = new BitStream();

            stream.ResetRead(packet);

            var networkId = stream.ReadNetworkId();
            //this value is unused, but removing this line corrupts the rest of the stream
            var blockedNetworkId = stream.ReadNetworkId();
            var eventId          = (uint)stream.ReadInt16();


            CallSite site;
            object   obj;

            if (networkId.IsInvalid) // Static event
            {
                site = m_typeTable.StaticEventTable.Get(eventId);
                obj  = null;
            }
            else // Instance event
            {
                var sendAs = ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).GetObjectByNetworkId(networkId);
                if (sendAs == null)
                {
                    return;
                }
                var typeInfo   = m_typeTable.Get(sendAs.GetType());
                var eventCount = typeInfo.EventTable.Count;
                if (eventId < eventCount) // Directly
                {
                    obj  = sendAs;
                    site = typeInfo.EventTable.Get(eventId);
                }
                else // Through proxy
                {
                    obj      = ((IMyProxyTarget)sendAs).Target;
                    typeInfo = m_typeTable.Get(obj.GetType());
                    site     = typeInfo.EventTable.Get(eventId - (uint)eventCount); // Subtract max id of Proxy
                }
            }

            //we're handling the network live in the game thread, this needs to go as fast as possible
            var discard = false;

            foreach (var handler in _networkHandlers)
            //Parallel.ForEach(_networkHandlers, handler =>
            {
                try
                {
                    if (handler.CanHandle(site))
                    {
                        discard |= handler.Handle(packet.Sender.Id.Value, site, stream, obj, packet);
                    }
                }
                catch (Exception ex)
                {
                    //ApplicationLog.Error(ex.ToString());
                    _log.Error(ex);
                }
            }

            //one of the handlers wants us to discard this packet
            if (discard)
            {
                return;
            }

            //pass the message back to the game server
            try
            {
                ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
            }
            catch (Exception ex)
            {
                _log.Fatal(ex);
                _log.Fatal(ex, "Error when returning control to game server!");
                //crash after logging, bad things could happen if we continue on with bad data
                throw;
            }
        }