示例#1
0
        public void HandlePayload(IClient client, int opCode, byte[] payload, int length)
        {
            var handler = GetHandler(opCode);

            if (handler == null)
            {
                client.Disconnect();
                _log.Warn("Client {0} sent an unhandled opcode {1} - disconnected.", client, opCode.ToString("X8", CultureInfo.InvariantCulture));
                return;
            }

            var permission = handler.Permission;

            Contract.Assume(permission != null);

            if (!client.HasPermission(permission))
            {
                client.Disconnect();
                _log.Warn("Client {0} sent opcode {1} which requires permission {2} - disconnected.", client,
                          opCode.ToString("X8", CultureInfo.InvariantCulture), permission.Name);
                return;
            }

            // Invoke the packet handler. Exceptions are caught in the client actor's context.
            var packet = CreatePacket(opCode, payload, length);

            client.PostAsync(() => handler.Invoke(client, packet));
        }
示例#2
0
        private static void LoadSingleTypeCacheConfig(IEnumerable <XElement> types)
        {
            SingleTypeCacheConfig config;

            foreach (XElement el in types)
            {
                try
                {
                    string name = el.Attribute("name").Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        LogProxy.Warn(CACHETYPENAMEISNULL);
                        continue;
                    }

                    bool isFix = false;
                    if (el.Attribute("isfix") != null)
                    {
                        bool.TryParse(el.Attribute("isfix").Value.Trim(), out isFix);

                        if (isFix)
                        {
                            config = new SingleTypeCacheConfig(name, true, 0, 0);
                            MyCacheConfig[name] = config;

                            continue;
                        }
                    }

                    int second = 0;
                    if (el.Attribute("second") != null)
                    {
                        int.TryParse(el.Attribute("second").Value.Trim(), out second);

                        if (second < 0)
                        {
                            second = 0;
                        }
                    }

                    int size = 0;
                    if (el.Attribute("size") != null)
                    {
                        int.TryParse(el.Attribute("size").Value.Trim(), out size);

                        if (size < 0)
                        {
                            size = 0;
                        }
                    }

                    config = new SingleTypeCacheConfig(name, false, second, size);
                    MyCacheConfig[name] = config;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#3
0
        private static void LoadStorageContexts(IEnumerable <XElement> storageContexts)
        {
            StorageContext storageContext;
            bool           isFirst = true;

            foreach (XElement el in storageContexts)
            {
                storageContext = BuilderStorageContext(el);
                if (string.IsNullOrEmpty(storageContext.Name))
                {
                    LogProxy.Warn(STORAGECONTEXTNAMEISNULL);
                    continue;
                }

                StorageContexts[storageContext.Name] = storageContext;

                if (isFirst)
                {
                    DefaultStorageContext = storageContext;
                    isFirst = false;
                }
                else if (string.Equals(storageContext.Name, DEFAULTSTORAGECONTEXT, StringComparison.OrdinalIgnoreCase))
                {
                    DefaultStorageContext = storageContext;
                }
            }
        }
示例#4
0
        private static void LoadSynClientConfig(IEnumerable <XElement> excludedTypes, IEnumerable <XElement> synTypes)
        {
            SynClientConfig config;

            foreach (XElement el in excludedTypes)
            {
                try
                {
                    string name = el.Attribute("name").Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        LogProxy.Warn(SYNCLIENTTYPENAMEISNULL);
                        continue;
                    }

                    if (MySynClientConfig.ContainsKey(name))
                    {
                        continue;
                    }

                    config = new SynClientConfig(name, true, false);
                    MySynClientConfig[name] = config;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }

            foreach (XElement el in synTypes)
            {
                try
                {
                    string name = el.Attribute("name").Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        LogProxy.Warn(SYNCLIENTTYPENAMEISNULL);
                        continue;
                    }

                    if (MySynClientConfig.ContainsKey(name))
                    {
                        continue;
                    }

                    bool isLazy = false;
                    if (el.Attribute("islazy") != null)
                    {
                        bool.TryParse(el.Attribute("islazy").Value.Trim(), out isLazy);
                    }

                    config = new SynClientConfig(name, false, isLazy);
                    MySynClientConfig[name] = config;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#5
0
        private static Dictionary <string, string> LoadStorageContexts(IEnumerable <XElement> storageContextList)
        {
            Dictionary <string, string> storageContexts = new Dictionary <string, string>();

            string name;

            foreach (XElement el in storageContextList)
            {
                try
                {
                    name = el.Attribute("name").Value;
                    if (string.IsNullOrEmpty(name))
                    {
                        LogProxy.Warn(ALIASISNULL);
                        continue;
                    }

                    storageContexts[name] = el.Value;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
            return(storageContexts);
        }
示例#6
0
        public static void SaveObject(SRO obj)
        {
            if (obj == null)
            {
                LogProxy.Warn(OBJECTISNULL);
                return;
            }

            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    SaveSingleObject(obj);

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                obj.Reset();

                LogProxy.Error(ex, true);
            }

            obj.AfterSave();
        }
示例#7
0
        /// <summary>
        /// Called when a connection is accepted.
        /// </summary>
        private void OnAccept(object sender, SocketAsyncEventArgs args)
        {
            var sock = args.AcceptSocket;

            if (!sock.Connected)
            {
                return;
            }

            // Wrap stuff in a try block, in case the socket is disposed of.
            try
            {
                var accept = true;

                // Do we accept multiple connections from the same address?
                if (!AllowMultipleConnections)
                {
                    lock (_clients)
                        accept = _clients.All(cl => !cl.EndPoint.Equals(sock.RemoteEndPoint.ToIPEndPoint()));
                }

                if (!accept)
                {
                    _log.Warn("Disconnecting client from {0}; already connected.", sock.RemoteEndPoint);

                    sock.Shutdown(SocketShutdown.Both);
                    sock.Disconnect(false);
                    sock.Close();
                }
                else
                {
                    // Add the client and thus start receiving.
                    var client = new TcpClient(sock, this, _propagator);
                    client.AddPermission(new ConnectedPermission());
                    AddClient(client);
                }
            }
            catch (Exception ex)
            {
                if (ex is SocketException)
                {
                    ExceptionManager.RegisterException(ex);
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }

                throw;
            }

            // Continue accepting with the event args we were using before.
            Accept(args);
        }
示例#8
0
        public static void SaveObject(SRO[] objs)
        {
            if (objs == null || objs.Length == 0)
            {
                LogProxy.Warn(OBJECTSISNULL);
                return;
            }

            var objDistincted = objs.Distinct(new SROComparer());

            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    foreach (SRO obj in objDistincted)
                    {
                        if (obj == null)
                        {
                            LogProxy.Warn(OBJECTISNULL);
                            continue;
                        }

                        SaveSingleObject(obj);
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                foreach (SRO obj in objDistincted)
                {
                    if (obj != null)
                    {
                        obj.Reset();
                    }
                }

                LogProxy.Error(ex, true);
            }

            foreach (SRO obj in objDistincted)
            {
                if (obj != null)
                {
                    obj.AfterSave();
                }
            }
        }
示例#9
0
        private static void LogError(string message, IClient client, bool disconnect)
        {
            Contract.Requires(client != null);
            Contract.Requires(!string.IsNullOrEmpty(message));

            // If we have no client, we're running in library mode, and just throw an exception.
            if (client == null)
            {
                throw new ProtocolViolationException("Protocol violation: {0}".Interpolate(message));
            }

            // Otherwise, report an error, as we're serving actual clients.
            _log.Warn("Protocol violation by client {0}: {1}".Interpolate(client, message));

            if (disconnect)
            {
                client.Disconnect();
            }
        }
示例#10
0
        private static void LoadMappings(IEnumerable <XElement> mappings, AssemblyConfig assembly)
        {
            Mapping mapping;

            foreach (XElement el in mappings)
            {
                try
                {
                    mapping = MappingBuilder(el, assembly);
                    if (string.IsNullOrEmpty(mapping.Name))
                    {
                        LogProxy.Warn(MAPPINGSNAMEISNULL);
                        continue;
                    }

                    Mappings[mapping.Name] = mapping;
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#11
0
        private static void LoadAssemblies(IEnumerable <XElement> assemblies)
        {
            AssemblyConfig assembly;

            foreach (XElement el in assemblies)
            {
                try
                {
                    assembly = AssemblyConfigBuilder(el);
                    if (string.IsNullOrEmpty(assembly.Name))
                    {
                        LogProxy.Warn(ASSEMBLYNAMEISNULL);
                        continue;
                    }

                    Assemblies[assembly.Name] = assembly;
                    LoadMappings(el.Elements("Type"), assembly);
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#12
0
        public void SaveObject(SRO obj)
        {
            if (obj == null)
            {
                LogProxy.Warn(OBJECTISNULL);
                return;
            }

            try
            {
                if (BeforeSaveMothed != null)
                {
                    BeforeSaveMothed(new SRO[] { obj });
                }
            }
            catch (Exception ex)
            {
                LogProxy.Error(ex, false);
            }

            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    SaveSingleObject(obj);

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                obj.Reset();

                LogProxy.Error(ex, true);
            }

            AddCache(obj);

            if (!obj.IsNew && obj.SaveMode != SROSaveMode.NoChange && SynClientService != null)
            {
                SynClientService.Add(obj);
            }

            obj.IsNew = false;

            if (obj.SaveMode != SROSaveMode.NoChange)
            {
                try
                {
                    obj.AfterSave();
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }

                try
                {
                    if (AfterSaveMothed != null)
                    {
                        AfterSaveMothed(new SRO[] { obj });
                    }
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#13
0
        public void SaveObject(SRO[] objs)
        {
            if (objs == null || objs.Length == 0)
            {
                LogProxy.Warn(OBJECTSISNULL);
                return;
            }

            try
            {
                if (BeforeSaveMothed != null)
                {
                    BeforeSaveMothed(objs);
                }
            }
            catch (Exception ex)
            {
                LogProxy.Error(ex, false);
            }

            var objDistincted = objs.Distinct(new SROComparer());

            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    foreach (SRO obj in objDistincted)
                    {
                        if (obj == null)
                        {
                            LogProxy.Warn(OBJECTISNULL);
                            continue;
                        }

                        SaveSingleObject(obj);
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                foreach (SRO obj in objDistincted)
                {
                    if (obj != null)
                    {
                        obj.Reset();
                    }
                }

                LogProxy.Error(ex, true);
            }

            bool isChanged = false;

            foreach (SRO obj in objDistincted)
            {
                if (obj != null)
                {
                    AddCache(obj);

                    if (!obj.IsNew && obj.SaveMode != SROSaveMode.NoChange && SynClientService != null)
                    {
                        SynClientService.Add(obj);
                    }

                    obj.IsNew = false;

                    if (obj.SaveMode != SROSaveMode.NoChange)
                    {
                        isChanged = true;

                        try
                        {
                            obj.AfterSave();
                        }
                        catch (Exception ex)
                        {
                            LogProxy.Error(ex, false);
                        }
                    }
                }
            }

            if (isChanged)
            {
                try
                {
                    if (AfterSaveMothed != null)
                    {
                        AfterSaveMothed(objs);
                    }
                }
                catch (Exception ex)
                {
                    LogProxy.Error(ex, false);
                }
            }
        }
示例#14
0
        private void OnReceiveHeader(object sender, SocketAsyncEventArgs args)
        {
            args.Completed -= OnReceiveHeader;

            var error = args.SocketError;

            if (error != SocketError.Success)
            {
                _log.Warn("Client {0} triggered a socket error ({1}) when trying to fetch a header - disconnected.", this, error);
                Disconnect();
                return;
            }

            var bytesTransferred = args.BytesTransferred;

            Contract.Assume(bytesTransferred >= 0);

            if (bytesTransferred == 0)
            {
                _log.Info("Client {0} disconnected gracefully.", this);
                Disconnect();
                return;
            }

            var length = _propagator.IncomingHeaderLength;

            if (bytesTransferred > length)
            {
                _log.Warn("Client {0} sent an invalid-length header ({1} bytes, expected {2}) - disconnected.", this,
                          bytesTransferred, length);
                Disconnect();
                return;
            }

            _receivePosition += bytesTransferred;
            Contract.Assume(_receivePosition < _receiveBuffer.Length);

            if (_receivePosition != length)
            {
                // The header was split; continue receiving...
                args.Completed += OnReceiveHeader;
                args.SetBuffer(_headerBuffer, _receivePosition, length - _receivePosition);

                try
                {
                    if (!_socket.ReceiveAsync(args))
                    {
                        OnReceiveHeader(this, args);
                    }
                    else
                    {
                        return; // Call back once the rest of the header arrives.
                    }
                }
                catch (Exception ex)
                {
                    args.Completed -= OnReceiveHeader;
                    Disconnect();

                    if (ex is ObjectDisposedException)
                    {
                        return;
                    }

                    if (ex is SocketException)
                    {
                        ExceptionManager.RegisterException(ex);
                        return;
                    }

                    throw;
                }
            }

            // We have the full header; reset.
            _receivePosition = 0;

            // Decrypt if some sort of encryption scheme has been set.
            if (Crypt != null)
            {
                Crypt.Decrypt(_headerBuffer, 0, length);
            }

            // Try to extract header information; if anything goes wrong, it's definitely a malicious client.
            int recvLength;

            try
            {
                var header = _propagator.HandleHeader(this, _headerBuffer);
                recvLength     = header.Length;
                _receiveOpCode = header.OpCode;
            }
            catch (Exception ex)
            {
                ExceptionManager.RegisterException(ex);
                Disconnect();
                return;
            }

            if (_receiveLength > MaxReceiveBufferSize)
            {
                _log.Warn("Client {0} sent an invalid packet length in a header ({1} bytes) - disconnected.", this, _receiveLength);
                Disconnect();
                return;
            }

            if (_receiveLength == 0)
            {
                // For empty packets, we just return the buffer, but with no actual region.
                _propagator.HandlePayload(this, _receiveOpCode, _receiveBuffer, 0);
                Receive();
                return;
            }

            _receiveLength = recvLength;

            // If the client is trying to send a packet larger than our receive buffer, reallocate it.
            if (recvLength > _receiveBuffer.Length)
            {
                _receiveBuffer = new byte[recvLength];
            }

            _eventArgs.SetBuffer(_receiveBuffer, 0, recvLength);
            args.Completed += OnReceivePayload;

            try
            {
                if (!_socket.ReceiveAsync(args))
                {
                    OnReceivePayload(this, args);
                }
            }
            catch (Exception ex)
            {
                args.Completed -= OnReceivePayload;
                Disconnect();

                if (ex is ObjectDisposedException)
                {
                    return;
                }

                if (ex is SocketException)
                {
                    ExceptionManager.RegisterException(ex);
                    return;
                }

                throw;
            }

            Contract.Assume(_receiveLength < _receiveBuffer.Length);
            Contract.Assume(_headerBuffer.Length == _propagator.IncomingHeaderLength); // Make the static checker shut up.
        }