Exemplo n.º 1
0
        private void Writing()
        {
            NetworkStream ns     = m_client.GetStream();
            StreamWriter  writer = new StreamWriter(ns, Encoding.UTF8);
            bool          keepOn = true;

            while (keepOn)
            {
                //if (m_writingQueue.Count == 0)
                //{
                //    Thread.Sleep(1000);
                //}
                //else
                //{
                //    Message msg;
                //    lock(m_writingQueue)
                //    {
                //        msg = m_writingQueue.Dequeue();
                //    }
                //    if (msg == null)
                //    {
                //        break;
                //    }
                //    writer.Write(msg.ToString());
                //    writer.Flush(); // 尽快将数据通过网络发送给对方而不是缓存在缓冲区里
                //}

                /*
                 * 改进等待模式。从固定的Sleep 1秒,变成等待通知唤醒。
                 * 在PostMessage中,对附加在m_writingQueue上的等待线程唤醒。
                 * 这样消息发送将没有不得已的1秒延迟了。
                 * */
                Queue <Message> tmp = new Queue <Message>();
                lock (m_writingQueue)
                {
                    if (m_writingQueue.Count == 0)
                    {
                        Monitor.Wait(m_writingQueue);
                    }
                    while (m_writingQueue.Count > 0)
                    {
                        tmp.Enqueue(m_writingQueue.Dequeue());
                    }
                }
                while (tmp.Count > 0)
                {
                    Message msg = tmp.Dequeue();
                    if (msg == null)
                    {
                        keepOn = false;
                        break;
                    }
                    writer.Write(msg.ToString());
                    writer.Flush();
                }
            }
            m_client.Close();
            if (m_state == ClientState.Logined)
            {
                lock (ClientServant.m_onlineClients)
                {
                    ClientServant.m_onlineClients.Remove(m_id);
                }
                if (!string.IsNullOrEmpty(Location))
                {
                    Arena.PartArena(Location, this);
                }
                BroadcastMessage(new Message(m_id, "logout"));
            }
        }
Exemplo n.º 2
0
        private void ProcessMessage(Message msg)
        {
            switch (msg.Command)
            {
            case "verify":     // 版本验证
                if (m_state == ClientState.Initial && msg.Parameters.Length == 1 && ConfigManager.GetConfig("GameServer.ProtocolVersion") == msg.Parameters[0])
                {
                    m_state = ClientState.Verified;
                    Message response = new Message(null, "verify", "yes");
                    PostMessage(response);
                }
                else
                {
                    PostMessage(new Message(null, "verify", "no"));
                }
                break;

            case "login":     // 登录验证
                if (m_state != ClientState.Verified)
                {
                    break;
                }
                if (m_state == ClientState.Logined)
                {
                    break;
                }
                if (msg.Parameters.Length == 1)
                {
                    lock (ClientServant.m_onlineClients)
                    {
                        if (ClientServant.m_onlineClients.ContainsKey(msg.Parameters[0]))
                        {
                            PostMessage(new Message(null, "login", "no", "id in use"));
                        }
                        else
                        {
                            m_id = msg.Parameters[0];
                            ClientServant.m_onlineClients.Add(m_id, this);
                            ClientServant.BroadcastMessage(new Message(m_id, "login", "yes"));
                            m_state = ClientState.Logined;
                        }
                    }
                }
                break;

            case "speak":     // 世界范围喊话
                if (m_state != ClientState.Logined && m_state != ClientState.Matching)
                {
                    PostMessage(new Message(null, "speak", "no", "need logined"));
                }
                else
                {
                    if (msg.Parameters.Length == 1)
                    {
                        BroadcastMessage(new Message(m_id, "speak", msg.Parameters[0]));
                    }
                }
                break;

            case "whisper":     // 私聊密语
                if (m_state != ClientState.Logined && m_state != ClientState.Matching)
                {
                    PostMessage(new Message(null, "whisper", "no", "need logined"));
                }
                else
                {
                    if (msg.Parameters.Length == 2)
                    {
                        string        targetId = msg.Parameters[0];
                        ClientServant cs;
                        lock (ClientServant.m_onlineClients)
                        {
                            if (ClientServant.m_onlineClients.TryGetValue(targetId, out cs))
                            {
                                cs.PostMessage(new Message(m_id, "whisper", msg.Parameters[1]));
                            }
                            else
                            {
                                PostMessage(new Message(null, "whisper", "no", "user id not exist"));
                            }
                        }
                    }
                }
                break;

            case "match":     // 自动匹配
                if (m_state != ClientState.Logined)
                {
                    break;
                }
                if (string.IsNullOrEmpty(Location))
                {
                    // 注意两条语句顺序,因为执行AddMatchRequest方法有可能因为匹配上而清除ClientState.Matching状态
                    m_state = ClientState.Matching;
                    Arena.AddMatchRequest(new KeyValuePair <string, ClientServant>(ID, this));
                }
                break;

            case "join":     // 观众加入竞技场观战
                if (m_state != ClientState.Logined)
                {
                    break;
                }
                if (string.IsNullOrEmpty(Location))
                {
                    if (Arena.JoinArena(msg.Parameters[0], this))
                    {
                        PostMessage(new Message(ID, "join", msg.Parameters[0]));
                    }
                }
                break;

            case "part":     // 观众或者参战者离开竞技场
                if (m_state != ClientState.Logined)
                {
                    break;
                }
                if (string.IsNullOrEmpty(Location))
                {
                    break;
                }
                Arena.PartArena(msg.Parameters[0], this);
                break;

            case "list":     // 当前竞技场列表
                if (m_state == ClientState.Logined && string.IsNullOrEmpty(Location))
                {
                    Message response = new Message(null, "list", Arena.GetArenaList().ToArray());
                    PostMessage(response);
                }
                break;

            case "discuss":     // 在竞技场内的讨论
                if (m_state == ClientState.Logined && !string.IsNullOrEmpty(Location) && msg.Parameters.Length == 1)
                {
                    Arena.Discuss(Location, ID, msg.Parameters[0]);
                }
                break;

            case "layat":     // 放置棋子
                if (m_state == ClientState.Logined && !string.IsNullOrEmpty(Location) && msg.Parameters.Length == 2)
                {
                    int x = Convert.ToInt32(msg.Parameters[0]);
                    int y = Convert.ToInt32(msg.Parameters[1]);
                    Arena.LayAt(Location, ID, x, y);
                }
                break;
            }
        }