⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formmain.cs

📁 kuiMsg是一款用.net C# 开发的即时消息开源软件,适合.net即时消息软件开发者用。 主要功能: 支持文件传输(p2p); 支持GIF动画表情( 彻底消除闪屏 :) );
💻 CS
📖 第 1 页 / 共 4 页
字号:

                if (tUser == null)//如果用户没有在集合里查找到,则添加到集合
                {
                    exUser user = new exUser();
                    user.UserID = tempUser.UserID;
                    user.userName = tempUser.userName;
                    user.depId = tempUser.depId;
                    user.State = tempUser.State;
                    user.IP = tempUser.IP;
                    user.Port = tempUser.Port;

                    FormAccess.Users.add(user);
                }
                else
                {
                    tUser.ID = tempUser.ID;
                    tUser.userName = tempUser.userName;
                    tUser.State = tempUser.State;
                    tUser.IP = tempUser.IP;
                    tUser.Port = tempUser.Port;
                }

                FormAccess.CurrGetOnlineUserCount++;//当前获得的用户信息加1
                LanMsg.dataAccess.insertUserToDB(tempUser, FormAccess.selfInfo.UserID);//将下载的最新组织机构表存入数据库
            }

            //MessageBox.Show("获得用户:" + FormAccess.CurrGetOnlineUserCount);
            if (FormAccess.CurrGetOnlineUserCount != FormAccess.ServerDepAndUserVersion.usersCount)
                FormAccess.requestUserCollections();//如果还没有获得服务器上全部用户在线信息,则继续从服务器下载在线用户信息

        }
        #endregion

        #region 获得服务器返回的部分组织机构信息
        /// <summary>
        /// 获得服务器返回的部分组织机构信息
        /// </summary>
        /// <param name="e"></param>
        private  void onGetDepartmentCollections(DataArrivalEventArgs e)
        {

            IMLibrary.DepartmentCollections   tempDeps = IMLibrary.Serializers.ByteToObj(e.Data) as DepartmentCollections;//获得组织机构部门集合
            if (tempDeps == null) { return; }// 非法数据则退出

            foreach (Department tempDep in tempDeps)
            {
                if (FormAccess.findDep(tempDep.depId) == null)//如果部门没有在集合里查找到,则添加到集合
                {
                    exDepartment dep = new exDepartment();
                    dep.depId = tempDep.depId;
                    dep.depName = tempDep.depName;
                    dep.superiorId = tempDep.superiorId;

                    dep.Node.Text = dep.depName;// + "(0/0)";
                    dep.Node.ToolTipText = dep.depName;
                    dep.Node.Name = dep.depId.ToString();
                    dep.Node.Tag = "0";
                    FormAccess.deps.add(dep);
                }

                FormAccess.CurrGetDepCount  ++;
                LanMsg.dataAccess.insertDepToDB(tempDep, FormAccess.selfInfo.UserID); //将下载的最新组织机构表存入数据库
                
            }

            if (FormAccess.CurrGetDepCount != FormAccess.ServerDepAndUserVersion.departmentCount)//如果没有全部获得全部组织机构信息
               FormAccess.requestDepartmentCollections();//则继续从服务器下载第FormAccess.CurrGetDepCount个开始的组织机构表

          // MessageBox.Show("收到" + FormAccess.deps.Count.ToString() + "个部门");


        }
        #endregion

        #region 服务器返回用户登录密码错误消息
        /// <summary>
        /// 服务器返回用户登录密码错误消息
        /// </summary>
        /// <param name="e"></param>
        private void onErrorPassword(DataArrivalEventArgs e)
        {
            timerLogin.Enabled = false;//停止检测登录
            this.NotifyIcon.ContextMenuStrip = null ;//关联菜单设为空
            FormAccess.selfPassword = null;//登录密码设为空
            this.Close();//关闭主窗口

            MessageBox.Show("密码错误,请重新登录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.readyLogin(false);//重新登录
        }
        #endregion

        #region 登录函数 Login
        /// <summary>
        /// 用户登录
        /// </summary>
        private void Login()//用户登录
        {
            this.tabSelfInfo.Text = "正在登录...";
            this.tabSelfInfo.Refresh();
            string loginInfo = string.Format("{0}|{1}|{2}|{3}", FormAccess.selfInfo.UserID, FormAccess.selfPassword, LanMsg.dataAccess.getDepVersion().ToString(), LanMsg.dataAccess.getUserVersion().ToString());
            IMLibrary.ServerMsg msg = new IMLibrary.ServerMsg(0, IMLibrary.TextEncoder.textToBytes(loginInfo));
            FormAccess.sendMsgToServer(0, msg );
        }
        #endregion

        #region  timerCheckOnlinState_Tick  检测自己的在线状态事件
        int timerToServerInc = 0;//时间计数器,以分为单位,每三分钟向服务器询问一次是否在线
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerCheckOnlinState_Tick(object sender, EventArgs e)
        {
            this.CheckOnlineState();

            byte[] buf = new byte[1];//打洞数据空包
            foreach (exUser user in FormAccess.Users)//向对方打洞
                if (user.State != 0)//如果用户在线则向对方UDP打洞
                    FormAccess.sendMsgToOneUser(255, buf, user.IP, user.Port);//

            System.Threading.Thread.Sleep(500);

            timerToServerInc++;//时间读数器自增一分

            if (timerToServerInc ==2)//每2分钟检测自己的在线情况
            {
                if (FormAccess.selfInfo.tempState == 0)//如果已经掉线,则停止相应程序
                {
                    this.timerCheckOnlinState.Enabled = false;//停止检测自己的在线状态
                    FormAccess.setUsersNoOnline();
                }
                else//如果已经登录在线,则将自己假设为脱机状态,然后向服务器发送消息告之自已在线状态
                    FormAccess.selfInfo.tempState = 0;

                timerToServerInc = 0;
            }


            //if (user.State != 0 && user.IP == FormAccess.selfInfo.IP && user.UserID != FormAccess.selfInfo.UserID && !user.isInLan)//如果用户与自己同在一局域网内
            //{
            //    IMLibrary.UserInfo LocalUser = new UserInfo();
            //    LocalUser.UserID = FormAccess.selfInfo.UserID;
            //    LocalUser.IP = FormAccess.LocalIp;
            //    LocalUser.Port = FormAccess.LocalPort;

            //    byte[] buffer = IMLibrary.Serializers.ObjToByte(LocalUser);

            //    FormAccess.sendMsgToOneUser(18, buffer, user);
            //}   else 
        }


        /// <summary>
        /// 当前用户每隔一分钟向服务器发送自己的在线状态,并检测自己是否已经与服务器断开联接 
        /// </summary>
        private void CheckOnlineState()
        {
            byte[] buffer = new byte[1];
            buffer[0] = FormAccess.selfInfo.State;
            IMLibrary.ServerMsg msg = new IMLibrary.ServerMsg(FormAccess.selfInfo.ID, buffer);
            ///连续发送2次,也免数据包丢失
            FormAccess.sendMsgToServer(2, msg);
            System.Threading.Thread.Sleep(50);
            FormAccess.sendMsgToServer(2, msg);
        }
        #endregion 

        #region 触发用户状态为联机事件onUserOnlineChanageState(DataArrivalEventArgs e)
        /// <summary>
        /// 用户状态为联机事件
        /// </summary>
        /// <param name="e">数据到达事件</param>
        private void onUserOnlineChanageState(DataArrivalEventArgs e)
        {
            FormAccess.selfInfo.tempState = FormAccess.selfInfo.State;
        }
        #endregion

        #region 成功登录事件过程onUserScuccessLogin
        /// <summary>
        /// 服务器返回用户成功登录消息,处理成功登录事件过程
        /// </summary>
        /// <param name="e">数据到达事件参数列表</param>
        private void onUserScuccessLogin(DataArrivalEventArgs e)
        {
            try
            {
                this.tabSelfInfo.Text = "(联机)";
                this.tabSelfInfo.Refresh();
                FormAccess.selfInfo.State = 1;//将用户自己的状态设置为1,表示联机
                FormAccess.selfInfo.tempState = 1;//将用户自己的临时状态设置为1,表示联机
                this.StartButton.Icon = this.loginIcon;
                this.timerLogin.Enabled = false;//停止登录检测
                this.timerCheckOnlinState.Enabled = true;//一旦登录成功就开始检测用户与服务器之间的联接状态

                this.NotifyIcon.BalloonTipText = "您已经成功登录到LanMsg服务器。";
                this.NotifyIcon.BalloonTipTitle = "LanMsg登录成功";
                this.NotifyIcon.ShowBalloonTip(5000);

                if (this.TreeUsers.Nodes.Count == 0)//如果用户成功用新密码登录,但组织机构与用户未添加到树图,则添加
                {
                    FormAccess.usersToTreeView(this.TreeUsers);//将用户表填充至TreeView控件
                    FormAccess.depsToTreeView(this.TreeUsers);//将组织机构填充至TreeView控件
                }

                FormAccess.palySound(FormAccess.resourceManager.GetStream("Global"));///播放声音

                FormAccess.ServerDepAndUserVersion = (IMLibrary.Serializers.ByteToObj(e.Data)) as IMLibrary.versionDepAndUser;//获得消息类
                 

                System.DateTime currDate = System.DateTime.Now;

                if (FormAccess.ServerDepAndUserVersion.departmentVersion != LanMsg.dataAccess.getDepVersion())//如果服务器组织机构版本与本地数据库的版本不同则下载
                {
                   // MessageBox.Show("组织机构版本改变!");

                    FormAccess.deps.Clear();//清除部门集合,重新下载
                    this.TreeUsers.Nodes.Clear(); this.TreeUsers.Refresh();

                    LanMsg.dataAccess.delDepsFromDB(FormAccess.selfInfo.UserID);//删除数据库中组织机构信息

                    FormAccess.requestDepartmentCollections();//从服务器下载第FormAccess.CurrGetDepCount个开始的组织机构表

                    bool depsIsDownLoad = true;//标识组织机构信息是否下载完成
                    while (depsIsDownLoad)//循环,直到获得全部组织机构部门信息为止
                    {
                        if (FormAccess.CurrGetDepCount == FormAccess.ServerDepAndUserVersion.departmentCount)
                            break;//如果已经获得全部组织机构信息,则退出循环

                        Application.DoEvents();

                        if (FormAccess.CurrGetDepCount != FormAccess.ServerDepAndUserVersion.departmentCount && FormAccess.DateDiff(currDate, System.DateTime.Now) > 30)// 设置一个超时为半分钟
                        {
                            if (MessageBox.Show("获取组织机构信息超时(请检查网络是否有问题)!是否需要重试?", "提示", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel)
                                break;//退出
                            currDate = System.DateTime.Now;
                            FormAccess.requestDepartmentCollections();//从服务器下载第FormAccess.CurrGetDepCount个开始的组织机构表
                        }
                    }
                    FormAccess.depsToTreeView(this.TreeUsers);//将部门集合在邦定到treeView控件
                }

                if (FormAccess.ServerDepAndUserVersion.departmentVersion != LanMsg.dataAccess.getDepVersion() || FormAccess.ServerDepAndUserVersion.usersVersion != dataAccess.getUserVersion())//如果用户版本号不一样,则清空用户表,重新下载
                {
                    FormAccess.clearTreeViewUser();
                    this.TreeUsers.Refresh();
                    FormAccess.Users.Clear();//清除用户集合,重新下载
                    LanMsg.dataAccess.delUsersFromDB (FormAccess.selfInfo.UserID);//删除数据库中组织机构信息

                    FormAccess.requestUserCollections();//从服务器下载在线用户信息
                    currDate = System.DateTime.Now;//当前时间
                    bool usersIsDownLoad = true;
                    while (usersIsDownLoad)
                    {
                        if (FormAccess.ServerDepAndUserVersion.usersCount == FormAccess.CurrGetOnlineUserCount)
                            goto Break;//如果所有用户在线信息已经下载完成,则退出请求

                        Application.DoEvents();

                        if (FormAccess.CurrGetOnlineUserCount != FormAccess.ServerDepAndUserVersion.usersCount && FormAccess.DateDiff(currDate, System.DateTime.Now) > 60)// 设置一个超时为半分钟
                        {
                            if (MessageBox.Show("获取用户信息超时(请检查网络是否有问题),当前从服务器获得 " + FormAccess.CurrGetOnlineUserCount.ToString() + "个用户的数据!是否需要重试?", "提示", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel)
                                goto Break;//退出
                            currDate = System.DateTime.Now;
                            FormAccess.requestUserCollections();//从服务器下载第FormAccess.CurrGetOnlineUserCount个开始的用户信息
                        }
                    }

                Break:

                    LanMsg.dataAccess.updateDepVersion();//更新本地数据库中的组织机构版本号
                    LanMsg.dataAccess.updateUserVersion();//更新本地数据库中的用户版本号

                    FormAccess.usersToTreeView(this.TreeUsers);//将用户集合帮定到treeView
                }


                LanMsg.dataAccess.wirteUserOrPassword(FormAccess.selfInfo.UserID, FormAccess.selfPassword, FormAccess.selfPassword, this.selfAutoLogin);//向数据库写入新用户或更改也存在的用户密码

                FormAccess.udpPenToUser(true, null);//慢速算法实现向所有用户UDP打洞

            }
            catch { return; }//收到非法消息,退出程序

        }
        #endregion
         
        #region FormMain_FormClosing窗口关闭事件过程
        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.isExitApp)
            {
                //this.TopMost = false;
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
                this.Hide();
            }
        }
        #endregion

        # region  NotifyIcon双击事件
        private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (FormAccess.selfPassword != null)
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                //this.TopMost = true;
            }
        }
        #endregion

        #region MenuItemExit_Click菜单退出程序事件
        /// <summary>
        /// 菜单退出程序事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItemExit_Click(object sender, EventArgs e)
        {
            this.ExitApp();
        }
        #endregion

        #region 登录timer

        private  int loginCount = 0;
        private int loginTimerCount = 0;

        private void timerLogin_Tick(object sender, EventArgs e)
        {
            loginTimerCount++;

            if (FormAccess.selfInfo.State != 0)
            {
                ((Timer)sender).Enabled = false;
                return;
            }
            if (loginTimerCount % 10 == 0 && FormAccess.selfInfo.State == 0)//如果5秒内登录不成功,则重新登录
            {
                this.Login();
                loginCount++;
            }

            if (loginCount > 5 && FormAccess.selfInfo.State == 0)//如果30秒后登录不成功,则退出登录
            {
                loginCount = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -