private static void RoomListRefresh(CustomProtocolManager.Header header, byte[] msg) { ClientInfo ci = ClientInfo.getInstance(); List <RoomCreateData> roomDatas = CustomProtocolManager.ParseRoomListPacket(msg, 0, msg.Length); ci.mainClientFrame.RoomListRefresh(roomDatas); }
private static void SendRoomList(CustomProtocolManager.Header header, byte[] msg, User target) { if (target.ChannelNumber == -1) { return; } List <RoomCreateData> list = new List <RoomCreateData>(); Channel c = ServerProperty.getInstance().channelsList[target.ChannelNumber]; RoomCreateData rcd; foreach (KeyValuePair <string, Room> data in c.rooms) { rcd = new RoomCreateData() { gameInfo = data.Value.gameInfo, gameParameters = data.Value.gameParameters, roomName = data.Value.roomName, HostNickName = data.Value.HostNickName, teamCount = data.Value.teamCount, maxCapacity = data.Value.maxCapacity, password = data.Value.password }; list.Add(rcd); } SendToUser(target, CustomProtocolManager.MakeRoomListPacket(list)); }
private static void UserListRefresh(CustomProtocolManager.Header header, byte[] msg) { ClientInfo ci = ClientInfo.getInstance(); List <string> list; bool isRoom; isRoom = CustomProtocolManager.ParseUserList(msg, 0, (int)header.size, out list); ci.mainClientFrame.UserListRefresh(isRoom, list); }
private static void ChannelChangeResultHandle(CustomProtocolManager.Header header, byte[] msg) { ClientInfo ci = ClientInfo.getInstance(); if (ci.channelSelect == null) { return; } ci.channelSelect.DialogResult = DialogResult.OK; }
private static void RoomChangeHandle(CustomProtocolManager.Header header, byte[] msg) { RoomCreateData roomData = CustomProtocolManager.ParseRoomResponsePacket(msg, 0, msg.Length); if (roomData == null) // 빠져나오는 반응이거나 실패의 의미 { ClientInfo.getInstance().mainClientFrame.ExitingRoomUIChanger(); return; } ClientInfo.getInstance().mainClientFrame.EnteringRoom(roomData); }
private static void RoomStateChangeHandle(CustomProtocolManager.Header header, byte[] msg, User target) { string arg; string[] tmp; ServerProperty sp = ServerProperty.getInstance(); Room targetRoom; User user; try { targetRoom = sp.channelsList[target.ChannelNumber].rooms[target.RoomID]; } catch { return; } switch (CustomProtocolManager.ParseRoomStateChangePacket(msg, 0, msg.Length, out arg)) { case CustomProtocolManager.RoomStateChangeOption.Start: try { if (!target.RoomID.Equals(target.Nickname)) { return; // 방장이 아니면 거부 } else if (targetRoom.members.Count < 2) { return; // 최소 실행 인원이 안되면 거부 } foreach (KeyValuePair <string, RoomMember> r in targetRoom.members) { user = sp.channelsList[target.ChannelNumber].users[r.Value.Nickname]; // 방장의 경우 if (r.Key.Equals(target.Nickname)) { arg = String.Format("NormalStart {0} {1} {2} {3}", "SERVER", targetRoom.members.Count - 1, r.Value.Nickname, r.Value.TeamNumber); } else // 그 외의 경우 { tmp = ("" + target.client.Client.RemoteEndPoint).Split(':'); arg = String.Format("NormalStart {0} {1} {2} {3}", "CLIENT", tmp[0], r.Value.Nickname, r.Value.TeamNumber); } SendToUser(user, CustomProtocolManager.MakeRoomStateChangePacket(CustomProtocolManager.RoomStateChangeOption.Start, arg)); } } catch { } break; default: break; } }
private static void ChannelInfoMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg) { ClientInfo ci = ClientInfo.getInstance(); ChannelInfo info; if (ci.channelSelect == null) { return; // 채널 선택창이 없으면 메세지의 의미가 없으므로 중단 } int index = CustomProtocolManager.ParseChannelInfoPacket(msg, 0, (int)header.size, out info); ci.channelSelect.AddChannelList(info, index); }
// 서버명 요청 및 클라이언트 프로그램 인증 패킷 처리. private static void MakeConnectionMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg, ref User target) {// 서버로 들어오는 MakeConnection 계 메세지는 000밖에 없다. ServerProperty sp = ServerProperty.getInstance(); // 0번 옵션이 아니거나 올바른 서버명 요청패킷이 아니라면 메세지는 처분한다. if (header.optNumber != 0 || !CustomProtocolManager.ParseConnectRequestPacket(msg, 0)) { return; } target.Id = CustomProtocolManager.AUTHORIZED_CLIENT_TEMP_NAME; byte[] packet = CustomProtocolManager.MakeClientReqInfoPacket(sp.serverName, sp.RSAparams, sp.gameInfoList); SendToUser(target, packet); }
/* * opt 0 - 내용; 채널에 채팅 * opt 1 - 내용; 게임방에 채팅 * TODO: opt 2 - 팀번호 + 내용; 팀 채팅 * TODO: opt 3 - 길이 + 유저명 + 길이 + 내용; 대상 유저에게 귓속말 */ private static void ChattingHandleFunction(CustomProtocolManager.Header header, byte[] msg, ref User target) { ServerProperty sp = ServerProperty.getInstance(); byte[] packet; string chat = target.Nickname + ": " + CustomProtocolManager.ParseGeneralChatting(msg, 0, msg.Length); switch ((CustomProtocolManager.ChattingOption)header.optNumber) { case CustomProtocolManager.ChattingOption.Channel: packet = CustomProtocolManager.MakeGeneralChatting(chat, CustomProtocolManager.NormalChatType.Channel); foreach (KeyValuePair <string, User> pair in sp.channelsList[target.ChannelNumber].users) { SendToUser(pair.Value, packet); } break; case CustomProtocolManager.ChattingOption.Room: if (target.RoomID == null) { return; } packet = CustomProtocolManager.MakeGeneralChatting(chat, CustomProtocolManager.NormalChatType.Room); foreach (KeyValuePair <string, RoomMember> pair in sp.channelsList[target.ChannelNumber].rooms[target.RoomID].members) { SendToUser(sp.channelsList[target.ChannelNumber].users[pair.Value.Nickname], packet); } break; /* 테스트버전 미사용 * case CustomProtocolManager.ChattingOption.Team: * * break; * * case CustomProtocolManager.ChattingOption.Whisper: * break; */ default: break; } }
// 옵션 분류 private static void InfoChangeMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg) { switch ((CustomProtocolManager.InfoChangeOption)header.optNumber) { case CustomProtocolManager.InfoChangeOption.Channel: ChannelChangeResultHandle(header, msg); break; case CustomProtocolManager.InfoChangeOption.RoomChangeResponse: RoomChangeHandle(header, msg); break; case CustomProtocolManager.InfoChangeOption.RoomStateChange: RoomStateChangeHandle(header, msg); break; default: break; } }
private static void RoomCreateHandle(CustomProtocolManager.Header header, byte[] msg, User target) { if (target.RoomID != null) { return; } target.RoomID = target.Nickname; RoomCreateData data = CustomProtocolManager.ParseRoomCreatePacket(msg, 0, msg.Length); ServerProperty sp = ServerProperty.getInstance(); data.HostNickName = target.Nickname; Room r = new Room(data); r.members.TryAdd(target.Nickname, new RoomMember(target.Nickname)); sp.channelsList[target.ChannelNumber].rooms.TryAdd(target.Nickname, r); SendToUser(target, CustomProtocolManager.MakeRoomResponsePacket(true, data)); }
private static void RoomStateChangeHandle(CustomProtocolManager.Header header, byte[] msg) { string arg; ClientInfo ci = ClientInfo.getInstance(); CustomProtocolManager.ParseRoomStateChangePacket(msg, 0, msg.Length, out arg); foreach (GameRegistry gr in ci.gameRegistries) { if (GameInfo.IsSameInfo(gr.gameInfo, ci.roomInfo.gameInfo)) { try { ci.gameProcess = Process.Start(gr.folderPath + @"\Game.exe ", arg); MessageBox.Show(arg); } catch { throw new Exception("게임을 찾을수 없었습니다. 실행파일을 Game.exe로 이름을 변경해주십시오."); } } } }
private static void SendUserInfo(CustomProtocolManager.Header header, byte[] msg, User target) { List <string> userList = new List <string>(); if (target.ChannelNumber != -1) { Channel channel = ServerProperty.getInstance().channelsList[target.ChannelNumber]; foreach (string nickname in channel.users.Keys) { userList.Add(nickname); } SendToUser(target, CustomProtocolManager.MakeUserList(userList, false)); } if (target.RoomID != null) { Room room; userList.Clear(); try { room = ServerProperty.getInstance().channelsList[target.ChannelNumber].rooms[target.RoomID]; } catch { target.RoomID = null; return; } foreach (KeyValuePair <string, RoomMember> pair in room.members) { if (pair.Value.TeamNumber != 0) { userList.Add(pair.Key + "(" + pair.Value.TeamNumber + ")"); } else { userList.Add(pair.Key); } } SendToUser(target, CustomProtocolManager.MakeUserList(userList, true)); } }
// 옵션타입 분류 함수 private static void AuthorizeMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg, ref User target) { switch ((CustomProtocolManager.AuthorizationOption)header.optNumber) { case CustomProtocolManager.AuthorizationOption.LoginPacket: LoginHandleFunction(msg, target); break; case CustomProtocolManager.AuthorizationOption.JoinDataPacket: AccountMakingHandler(msg, target); break; case CustomProtocolManager.AuthorizationOption.DuplicateCheck: AccountDuplicateCheckHandler(msg, target); break; case CustomProtocolManager.AuthorizationOption.Response: break; default: return; } }
/* * opt 0 - 004; 채널 정보 요청 * opt 0 - 인덱스 번호 + XML 직렬화 객체(ChannelInfo); * TODO: opt 2 - 방 리스트 요청 * TODO: opt 3 - 방 상세 정보 * TODO: opt 4 - 방 상세 정보 * TODO: opt 5 - 유저 정보 * TODO: opt 6 - 파일 정보 * TODO: opt 7 - 파일 전송 요청 */ // 옵션 분류 함수 private static void InfoTypeMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg, ref User target) { switch ((CustomProtocolManager.InfoReqOption)header.optNumber) { case CustomProtocolManager.InfoReqOption.ChannelInfo: SendChannelInfo(msg, ref target); break; case CustomProtocolManager.InfoReqOption.RoomList: SendRoomList(header, msg, target); break; case CustomProtocolManager.InfoReqOption.RoomInfo: break; case CustomProtocolManager.InfoReqOption.UserInfo: SendUserInfo(header, msg, target); break; default: break; } }
// 옵션 분류 함수 private static void InfoTypeMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg) { switch ((CustomProtocolManager.InfoReqOption)header.optNumber) { case CustomProtocolManager.InfoReqOption.ChannelInfo: ChannelInfoMsgHandleFunction(header, msg); break; case CustomProtocolManager.InfoReqOption.RoomList: RoomListRefresh(header, msg); break; case CustomProtocolManager.InfoReqOption.RoomInfo: break; case CustomProtocolManager.InfoReqOption.UserInfo: UserListRefresh(header, msg); break; default: break; } }
// 옵션 분류 함수 private static void InfoChangeMsgHandleFunction(CustomProtocolManager.Header header, byte[] msg, ref User target) { switch ((CustomProtocolManager.InfoChangeOption)header.optNumber) { case CustomProtocolManager.InfoChangeOption.Channel: ChannelChangeRequestHandler(header, msg, target); break; case CustomProtocolManager.InfoChangeOption.RoomCreate: RoomCreateHandle(header, msg, target); break; case CustomProtocolManager.InfoChangeOption.RoomEnter: RoomEnterHandle(header, msg, target); break; case CustomProtocolManager.InfoChangeOption.RoomStateChange: RoomStateChangeHandle(header, msg, target); break; default: break; } }
// 채팅 메세지 처리 private static void ChattingHandleFunction(CustomProtocolManager.Header header, byte[] msg) { string parsedMsg = CustomProtocolManager.ParseGeneralChatting(msg, 0, (int)header.size); ClientInfo.getInstance().mainClientFrame.ChatWriter(parsedMsg, (int)header.optNumber); }
private static void RoomEnterHandle(CustomProtocolManager.Header header, byte[] msg, User target) { ServerProperty sp = ServerProperty.getInstance(); string targetRoomHost = CustomProtocolManager.ParseRoomEnterPacket(msg, 0, msg.Length); try { if (targetRoomHost.Equals("") || targetRoomHost == null) { if (target.RoomID.Equals(target.Nickname)) { string str = target.RoomID; foreach (KeyValuePair <string, RoomMember> u in sp.channelsList[target.ChannelNumber].rooms[str].members) { sp.channelsList[target.ChannelNumber].users[u.Key].RoomID = null; SendToUser(sp.channelsList[target.ChannelNumber].users[u.Key], CustomProtocolManager.MakeRoomResponsePacket()); } Room rDummy; sp.channelsList[target.ChannelNumber].rooms.TryRemove(str, out rDummy); return; } RoomMember dummy; sp.channelsList[target.ChannelNumber].rooms[target.RoomID].members.TryRemove(target.Nickname, out dummy); target.RoomID = null; SendToUser(target, CustomProtocolManager.MakeRoomResponsePacket()); return; } } catch { } if (target.RoomID != null) { return; } Room targetRoom; try { targetRoom = sp.channelsList[target.ChannelNumber].rooms[targetRoomHost]; } catch { return; } if (targetRoom.members.Count < targetRoom.maxCapacity) { targetRoom.members.TryAdd(target.Nickname, new RoomMember(target.Nickname)); target.RoomID = targetRoom.HostNickName; SendToUser(target, CustomProtocolManager.MakeRoomResponsePacket(true, new RoomCreateData() { gameInfo = targetRoom.gameInfo, gameParameters = targetRoom.gameParameters, roomName = targetRoom.roomName, HostNickName = targetRoom.HostNickName, teamCount = targetRoom.teamCount, maxCapacity = targetRoom.maxCapacity, password = targetRoom.password }) ); } }
/// <summary> /// 서버명을 요청한 후 수신받아 기록합니다. 절차는 동기식으로 작동합니다. /// 이 함수를 사용하면 인증 가능한 상태라고 초기화 되기 때문에, /// 처음 접속시가 아니면 사용하지 마십시오. /// </summary> /// <returns>성공 여부를 나타냅니다.</returns> public static bool ReceiveDefaultInfo() { string serverName; System.Security.Cryptography.RSAParameters parameters; int index = 0; byte[] data; List <GameInfo> reqInfos; ConnectInfo ci = ConnectInfo.getInstance(); ClientInfo cInfo = ClientInfo.getInstance(); data = CustomProtocolManager.MakeConnectRequestPacket(); if (!SendingFunction(ci.tcpClient.Client, data)) { return(false); } // 헤더 수신 index = 0; data = new byte[CustomProtocolManager.HEADER_SIZE]; if (!ReceiveFunction(ci.tcpClient.Client, ref data, ref index, CustomProtocolManager.HEADER_SIZE)) { return(false); } // 수신된 헤더 확인 CustomProtocolManager.Header header = CustomProtocolManager.ParseHeader(ref data); // 데이터 수신 index = 0; data = new byte[header.size]; if (!ReceiveFunction(ci.tcpClient.Client, ref data, ref index, (int)header.size)) { return(false); } CustomProtocolManager.ParseClientReqInfoPacket(data, 0, (UInt32)data.Length, out serverName, out parameters, out reqInfos); ci.ServerName = serverName; ci.securityParameter = parameters; // 필요 게임들이 존재하는지 확인 DirectoryInfo di = new DirectoryInfo(ClientInfo.GAMEDATA_PATH); FileStream fs; XmlSerializer xs = new XmlSerializer(typeof(GameInfo)); GameInfo registry; foreach (DirectoryInfo sdi in di.GetDirectories()) { foreach (FileInfo fi in sdi.GetFiles()) { if (!fi.Extension.Equals(".info")) { continue; } fs = fi.OpenRead(); registry = (GameInfo)xs.Deserialize(fs); for (int i = 0; i < reqInfos.Count; ++i) { if (GameInfo.IsSameInfo(reqInfos[i], registry)) { cInfo.gameRegistries.Add(new GameRegistry { gameInfo = registry, folderPath = fi.DirectoryName }); reqInfos.RemoveAt(i); } } fs.Close(); } } // 필요 정보가 남아있으면 필요한 게임이 없으므로 서버 이용 불가 if (reqInfos.Count != 0) { string msg; foreach (GameInfo gi in reqInfos) { msg = "이 서버에 접속하기 위해서는 다음의 게임이 필요합니다." + "\n게임명: " + gi.name + "\n버전: " + gi.gameVersion + "\n제작자: " + gi.producer; MessageBox.Show(msg, "파일 누락"); } return(false); } return(true); }
// 채널 변경 요청에 대한 처리 private static void ChannelChangeRequestHandler(CustomProtocolManager.Header header, byte[] msg, User target) { ServerProperty sp = ServerProperty.getInstance(); int index = CustomProtocolManager.ParseChannelEnterRequestPacket(msg, 0); byte[] packet; if (index < sp.channelsList.Count) { if (sp.channelsList[index].CanEnter) { if (sp.channelsList[index].users.TryAdd(target.Nickname, target)) { User user; if (target.RoomID != null) { if (target.RoomID.Equals(target.Nickname)) { foreach (KeyValuePair <string, RoomMember> u in sp.channelsList[target.ChannelNumber].rooms[target.RoomID].members) { SendToUser( sp.channelsList[target.ChannelNumber].users[u.Value.Nickname], CustomProtocolManager.MakeRoomResponsePacket() ); } Room dummy; sp.channelsList[target.ChannelNumber].rooms.TryRemove(target.RoomID, out dummy); } else { RoomMember dummy; sp.channelsList[target.ChannelNumber].rooms[target.RoomID].members.TryRemove(target.Nickname, out dummy); } } if (target.ChannelNumber != -1) { sp.channelsList[target.ChannelNumber].users.TryRemove(target.Nickname, out user); } target.RoomID = null; target.ChannelNumber = index; packet = CustomProtocolManager.MakeChannelEnterResultPacket(CustomProtocolManager.GenericResponseType.Acknowledge); } else { packet = CustomProtocolManager.MakeChannelEnterResultPacket(CustomProtocolManager.GenericResponseType.Denied); } } else { packet = CustomProtocolManager.MakeChannelEnterResultPacket(CustomProtocolManager.GenericResponseType.Denied); } } else { packet = CustomProtocolManager.MakeChannelEnterResultPacket(CustomProtocolManager.GenericResponseType.Denied); } SendToUser(target, packet); }