コード例 #1
0
ファイル: MiscHandlers.cs プロジェクト: Bankst/DragonFiesta
        internal static void NC_MISC_S2SCONNECTION_REQ(NetworkMessage message, NetworkConnection connection)
        {
            var from        = message.ReadByte();
            var to          = message.ReadByte();
            var worldNumber = message.ReadByte();
            var worldName   = message.ReadString(20);
            var unused      = message.ReadByte();
            var ip          = message.ReadString(16);
            var port        = message.ReadUInt16();
            var key         = message.ReadUInt16();

            if (key != from + to)
            {
                SocketLog.Write(SocketLogLevel.Warning, "Invalid key used with S2S connection.");
                connection.Disconnect();
                return;
            }

            if ((NetworkConnectionType)@from != NetworkConnectionType.NCT_WORLDMANAGER)
            {
                return;
            }
            if (ServerMain.Worlds.Exists(world => world.Connection == connection || world.Number == worldNumber))
            {
                return;
            }

            ServerMain.Worlds.Add(new World(connection, worldName, worldNumber, ip, port));
            new PROTO_NC_MISC_S2SCONNECTION_ACK().Send(connection);
        }
コード例 #2
0
 protected void Log(string info, LogLevel logLevel)
 {
     // 必须要加锁保证Log文件写时不被占用
     lock (LoggerLock)
     {
         SocketLog?.Invoke(this, new SocketLogEventArgs(info, logLevel));
     }
 }
コード例 #3
0
        /// <summary>
        /// Invokes the message handler.
        /// </summary>
        public static void Invoke(NetworkMessageHandlerMethod method, NetworkMessage message, NetworkConnection connection)
        {
            if (method == null || !connection.IsConnected)
            {
                return;
            }

            SocketLog.Write(SocketLogLevel.Debug, $"Calling handler for {message.Command}");

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var cancelSource = new CancellationTokenSource();
            var token        = cancelSource.Token;

            var task = HandlerFactory.StartNew(() =>
            {
                method.Invoke(message, connection);
                token.ThrowIfCancellationRequested();
            }, token);

            RunningHandlers.TryAdd(task.Id, task);

            try
            {
                if (!task.Wait(MaxTaskRuntime * 1000, token))
                {
                    cancelSource.Cancel();
                }
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.Flatten().InnerExceptions)
                {
                    SocketLog.Write(SocketLogLevel.Exception, $"Unhandled exception: {e.Message} - {e.StackTrace}");
                }

                connection.Disconnect();
            }
            catch (OperationCanceledException)
            {
                connection.Disconnect();
            }
            finally
            {
                stopwatch.Stop();
                RunningHandlers.TryRemove(task.Id, out var unused);
                cancelSource.Dispose();
                Object.Destroy(message);

                SocketLog.Write(SocketLogLevel.Debug, $"Handler took {stopwatch.ElapsedMilliseconds}ms to complete.");
            }
        }
コード例 #4
0
ファイル: NetworkServer.cs プロジェクト: Bankst/DragonFiesta
        /// <summary>
        /// Places the server in the listening state.
        /// </summary>
        /// <param name="ipAddress">The IP address to listen for connection on.</param>
        /// <param name="port">The port to listen for connections on.</param>
        /// <param name="backlog">The maximum number of pending connections in the queue.</param>
        public void Listen(string ipAddress, ushort port, int backlog = BacklogSize)
        {
            if (!IPAddress.TryParse(ipAddress, out var address))
            {
                SocketLog.Write(SocketLogLevel.Exception, $"The IPAddress {ipAddress} is invalid.");
                return;
            }

            _socket.Bind(new IPEndPoint(address, port));
            _socket.Listen(backlog);
            _socket.BeginAccept(AcceptConnection, _socket);
        }
コード例 #5
0
ファイル: UserHandlers.cs プロジェクト: Bankst/DragonFiesta
        internal static void NC_USER_CLIENT_VERSION_CHECK_REQ(NetworkMessage message, NetworkConnection connection)
        {
            var versionKey = message.ReadString(64);

            if (versionKey != LoginConfiguration.Instance.ClientVersion && ServerMain.LoginConfig.CheckVersion)
            {
                SocketLog.Write(SocketLogLevel.Exception, $"Wrong version key used - {versionKey}");

                new PROTO_NC_USER_CLIENT_WRONGVERSION_CHECK_ACK().Send(connection);
                return;
            }

            new PROTO_NC_USER_CLIENT_RIGHTVERSION_CHECK_ACK((byte)XTrapKey.Length, XTrapKey).Send(connection);
        }
コード例 #6
0
ファイル: UserHandlers.cs プロジェクト: Bankst/DragonFiesta
        internal static void NC_USER_WILLLOGIN_ACK(NetworkMessage message, NetworkConnection connection)
        {
            var guid = message.ReadString(32);
            var ok   = message.ReadBoolean();

            var transfer = ServerMain.Transfers.First(t => t.Guid == guid);

            ServerMain.Transfers.RemoveSafe(transfer);

            if (!ok || !transfer)
            {
                SocketLog.Write(SocketLogLevel.Exception, $"Process transfer failed for - {transfer}");
                new PROTO_NC_USER_LOGINFAIL_ACK(0x49).Send(transfer?.Connection);

                return;
            }

            ServerMain.CachedAccounts.AddSafe(guid, transfer.Account);
            new PROTO_NC_USER_WORLDSELECT_ACK(transfer.World, guid).Send(transfer.Connection);

            Object.Destroy(transfer);
        }
コード例 #7
0
ファイル: NetworkServer.cs プロジェクト: Bankst/DragonFiesta
        /// <summary>
        /// Accepts a pending connection.
        /// </summary>
        /// <param name="e">The status of the operation.</param>
        private void AcceptConnection(IAsyncResult e)
        {
            if (e.AsyncState == null)
            {
                SocketLog.Write(SocketLogLevel.Exception, "NetworkServer::AcceptConnection : AsyncState is null");
                return;
            }

            var serverSocket = (Socket)e.AsyncState;
            var clientSocket = serverSocket.EndAccept(e);

            if (clientSocket != null)
            {
                var connection = new NetworkConnection(this, clientSocket, _connectionType);
                if (connection.IsConnected)
                {
                    Connections.Add(connection);
                }
            }

            // Begin accepting connections again.
            serverSocket.BeginAccept(AcceptConnection, serverSocket);
        }
コード例 #8
0
ファイル: UserHandlers.cs プロジェクト: Bankst/DragonFiesta
        internal static void NC_USER_US_LOGIN_REQ(NetworkMessage message, NetworkConnection connection)
        {
            var userName = message.ReadString(260);
            var password = message.ReadString(36);

            AccountService.Login(userName, password, out var userNo, out var blocked, out var canLogin);

            if (userNo == -1)
            {
                SocketLog.Write(SocketLogLevel.Warning, $"[{connection}] Invalid credentials");

                new PROTO_NC_USER_LOGINFAIL_ACK(0x45).Send(connection);
                new PROTO_NC_LOG_USER_LOGINFAIL(userName, password, connection.GetRemoteIP, 0x45).Send(ServerMain.GameLogServer);
                return;
            }

            if (blocked)
            {
                SocketLog.Write(SocketLogLevel.Warning, $"[{connection}] Logging in while banned");

                new PROTO_NC_USER_LOGINFAIL_ACK(0x47).Send(connection);
                new PROTO_NC_LOG_USER_LOGINFAIL(userName, password, connection.GetRemoteIP, 0x47).Send(ServerMain.GameLogServer);
                return;
            }

            if (!canLogin)
            {
                SocketLog.Write(SocketLogLevel.Warning, $"[{connection}] Logging in during maintenance");

                new PROTO_NC_USER_LOGINFAIL_ACK(0x48).Send(connection);
                new PROTO_NC_LOG_USER_LOGINFAIL(userName, password, connection.GetRemoteIP, 0x48).Send(ServerMain.GameLogServer);
                return;
            }

            connection.Account = new Account(userNo, userName);
            new PROTO_NC_USER_LOGIN_ACK(ServerMain.Worlds).Send(connection);
        }