public static Message Parse(string rawMessage) { Message msg = new Message(); if (rawMessage.StartsWith(":")) // has prefix { int indexOfSpace = rawMessage.IndexOf(" "); msg.m_prefix = rawMessage.Substring(1, indexOfSpace - 1); rawMessage = rawMessage.Substring(indexOfSpace + 1); } int indexOfCommandSpace = rawMessage.IndexOf(" "); if (indexOfCommandSpace != -1) { msg.m_command = rawMessage.Substring(0, indexOfCommandSpace); rawMessage = rawMessage.Substring(indexOfCommandSpace); // reserve this space int indexOfTrailing = rawMessage.IndexOf(" :"); // Space+Colon if (indexOfTrailing != -1) { if (indexOfTrailing == 0) { msg.m_parameters = new string[1]; msg.m_parameters[0] = rawMessage.Substring(2); } else { string beforeTrailing = rawMessage.Substring(0, indexOfTrailing); string trailing = rawMessage.Substring(indexOfTrailing + 2); string[] splits = beforeTrailing.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); msg.m_parameters = new string[splits.Length + 1]; Array.Copy(splits, msg.m_parameters, splits.Length); msg.m_parameters[msg.m_parameters.Length - 1] = trailing; } } else { string[] splits = rawMessage.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); msg.m_parameters = splits; } } else { msg.m_command = rawMessage; msg.m_parameters = new string[0]; } return msg; }
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; } }
public void PostMessage(Message response) { lock(m_writingQueue) { m_writingQueue.Enqueue(response); Program.Logger.DebugFormat("RESPONSE TO {0} WITH {1}", m_clientIPEndPoint, response); Monitor.Pulse(m_writingQueue); } }
private static void BroadcastMessage(Message message) { lock(m_onlineClients) { foreach(ClientServant c in m_onlineClients.Values) { c.PostMessage(message); } } }