void Listen_Clients() { //Создание лог. файла //DateTime dt = DateTime.Now; //string writePath = @"Logs ["+dt.Hour.ToString()+"h "+dt.Minute.ToString()+"m] ["+dt.ToLongDateString()+"].txt"; //StreamWriter sw = new StreamWriter(writePath, false, Encoding.Default); string name = ""; byte[] costyl = new byte[512]; byte[] pack = new byte[512]; Console.WriteLine("Game server: Started listen"); try { while (game_up) { pack = game_listener.Receive(ref remoteIp); //Запись логов //sw.WriteLine("[" + dt.DayOfWeek + " " + dt.ToLongTimeString() + "]: " +pack[0].ToString()+"::"+Cons.GetData(pack)); //Console.WriteLine("Pack len = " + pack.Length + " " + Cons.GetData(pack) + "name=" + Cons.GetName13b(pack) + "|"); //Проверка легитимности пакета if (!clients_iport.ContainsKey(Cons.ToIport(remoteIp))) { Console.WriteLine("Packet from unregistred IP:Port"); continue; } switch (pack[0]) { //END case 3: name = Cons.GetData(pack); if (obj._Char.ContainsKey(name) && (remoteIp.ToString() == obj._Char[name].Addr.ToString() && remoteIp.Port == obj._Char[name].Addr.Port)) { Array.Copy(pack, 1, obj._Char[name].packet.END.data, 0, pack.Length - 1); obj._Char[name].packet.END.changed = true; } break; //SET_XYD case 4: name = Cons.GetName14b(pack); if (obj._Char.ContainsKey(name) && (remoteIp.ToString() == obj._Char[name].Addr.ToString() && remoteIp.Port == obj._Char[name].Addr.Port)) { Cons.SetPlayer_XYD(ref obj, pack); Array.Copy(pack, 1, costyl, 0, pack.Length - 1); //Записывается с пустотами obj._Char[name].packet.SET_XYD.data = costyl; obj._Char[name].packet.SET_XYD.changed = true; } break; //PLAYER_END_OK case 6: clients_iport[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; //HIT: 1[type of attack] 2-5[x] 6-9[y] 10[npc or player] 11-end[id or name] case 7: foreach (var item in obj._Char.Keys) { if (obj._Char[item].port == remoteIp.Port && obj._Char[item].IP == remoteIp.Address.ToString()) { var entrance = obj.players.First(p => p.Name == obj._Char[item].name); entrance.AttackFunc(obj.mobs); } } break; //DROP_TAKEN | 1-4[id] 5-8[ex_id] case 8: if (drop_Handle[Cons.ToIport(remoteIp)] != null) { continue; } drop_Handle[Cons.ToIport(remoteIp)] = pack; break; //INV_UPDATED | 1 - 4[items_updated] case 9: if (clients_iport[Cons.ToIport(remoteIp)] != null) { continue; } clients_iport[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; //ITEM_USED | 1-4[id] 5-8[id_ex] case 10: if (item_Used[Cons.ToIport(remoteIp)] != null) { continue; } item_Used[Cons.ToIport(remoteIp)] = pack; break; //11 GROCERY_BUY | 1-4[id] case 11: if (grocery_buy[Cons.ToIport(remoteIp)] != null) { continue; } grocery_buy[Cons.ToIport(remoteIp)] = pack; break; //12 TAKE_QUEST | 1-4[Q_ID] 5-8[NPC_ID] case 12: if (quest_Handle[Cons.ToIport(remoteIp)] != null) { continue; } quest_Handle[Cons.ToIport(remoteIp)] = pack; break; //13 QUESTS_ALL | 1-end[same_data] case 13: if (clients_iport[Cons.ToIport(remoteIp)] != null) { continue; } clients_iport[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; //14 QUEST_UPDATED | 1-end[same_data] case 14: if (clients_iport[Cons.ToIport(remoteIp)] != null) { continue; } clients_iport[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; //15 NPCxyd_REQUEST | 1 - end[same_data] case 15: //Console.WriteLine("15: " + Cons.GetData(pack)); if (clients_iport[Cons.ToIport(remoteIp)] != null) { continue; } clients_iport[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; } } } catch (SocketException e) { Console.WriteLine("Game catch: Listner:: while[" + remoteIp + "]" + e.ToString() + "code:" + e.ErrorCode); if (game_up) { Listen_Clients(); } } }
//Для каждого игрока создается отдельный поток с сессией void Session(object char_name) { string name = (string)char_name; IPEndPoint addr = new IPEndPoint(IPAddress.Parse(obj._Char[name].IP), obj._Char[name].port); bool IsExit = false; bool CharsXYD = false; bool MyXYD = false; bool MobsTH = false; bool DroppedTH = false; bool DropHandle = false; bool Inventory = false; bool Quests = false; bool NpcTH = false; try { List <Player> players = new List <Player>(obj.players); var entrance = players.Find(r => r.Name == name); //Цикл обновления инфы на клиенте while (obj._Char.ContainsKey(name) && obj._Char[name].online == true) { if (obj._Char[name].packet.END.changedP == true) { //Указываем что происходит выход, //Чтобы при повторных пакетах о выходе не вызывать функцию выхода еще раз if (!IsExit) { IsExit = true; Send(252, new byte[] { 0 }, addr); Disconnect(name); } } //Отправка координат всех игроков, после того как были обновлены свои координаты игрока if (CharsXYD == false) { CharsXYD = true; Task.Run(() => { Console.WriteLine("Started CharsXYD Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { players = new List <Player>(obj.players); foreach (var player in players) { if (player == null || player.Name == name) { continue; } float X = player.X - entrance.X; float Y = player.Y - entrance.Y; if (Math.Sqrt(X * X + Y * Y) < 12d) { Send_CHXYD(player.X, player.Y, player.Rotation, player.Direction, player.Hp, player.Name, addr);//CH_XYD } } Thread.Sleep(10); } }); } //Передача своих координат if (MyXYD == false) { MyXYD = true; Task.Run(() => { Console.WriteLine(" Started MyXYD Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { entrance.CheckDeath(); switch (entrance.Direction) { case 0: break; case 1: entrance.MovedByControl(false, false, false, true, obj.collision_map); break; case 2: entrance.MovedByControl(true, false, false, true, obj.collision_map); break; case 3: entrance.MovedByControl(true, false, false, false, obj.collision_map); break; case 4: entrance.MovedByControl(true, true, false, false, obj.collision_map); break; case 5: entrance.MovedByControl(false, true, false, false, obj.collision_map); break; case 6: entrance.MovedByControl(false, true, true, false, obj.collision_map); break; case 7: entrance.MovedByControl(false, false, true, false, obj.collision_map); break; case 8: entrance.MovedByControl(false, false, true, true, obj.collision_map); break; } try { if (item_Used[Cons.ToIport(addr)] != null) { Cons.UseItem(ref entrance, item_Used[Cons.ToIport(remoteIp)]); item_Used[Cons.ToIport(addr)] = null; entrance.Inventory.Changed = true; } } catch (Exception e) { Console.WriteLine(e.ToString()); } SendMyXYD(entrance.X, entrance.Y, entrance.Rotation, entrance.Direction, entrance.Hp, name, addr); Thread.Sleep(10); } }); } //Передача координат мобов if (MobsTH == false) { MobsTH = true; Task.Run(() => { Console.WriteLine(" Started mobs Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { for (int i = 0; i < obj.mobs.Length; i++) { if (entrance == null || obj.mobs[i] == null) { continue; } float X = obj.mobs[i].X - entrance.X; float Y = obj.mobs[i].Y - entrance.Y; if (Math.Sqrt(X * X + Y * Y) < 12d) { Send_MobXYD(obj.mobs[i].X, obj.mobs[i].Y, 0, 0, obj.mobs[i].HP, obj.mobs[i].Id, i, addr);//CH_XYD } // Thread.Sleep(1); } Thread.Sleep(150); } }); } //Передача координат NPC if (NpcTH == false) { NpcTH = true; Task.Run(() => { bool[] NPCsent = new bool[100]; for (int i = 0; i < 100; i++) { NPCsent[i] = false; } try { Console.WriteLine(" Started NPC Thread, id thread: " + Task.CurrentId); while (obj._Char.ContainsKey(name) && obj._Char[name].online == true) { for (int i = 0; i < obj.NPCs.Length; i++) { if (entrance == null || obj.NPCs[i] == null) { continue; } float X = obj.NPCs[i].X - entrance.X; float Y = obj.NPCs[i].Y - entrance.Y; if (NPCsent[i] == false && (Math.Sqrt(X * X + Y * Y) < 12d)) { Send_NPCXYDs(obj.NPCs[i].X, obj.NPCs[i].Y, 0, 0, obj.NPCs[i].Id, obj.NPCs[i].Name, addr); NPCsent[i] = true; } else { if (!(Math.Sqrt(X * X + Y * Y) < 12d)) { NPCsent[i] = false; } } } Thread.Sleep(150); } } catch (Exception e) { Console.WriteLine(e.ToString()); } }); } //Передача дропа if (DroppedTH == false) { DroppedTH = true; Task.Run(() => { Console.WriteLine(" Started drop sender Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { for (int i = 0; i < obj.items.Count; i++) { if (entrance == null || obj.items[i] == null) { continue; } float X = obj.items[i].X - entrance.X; float Y = obj.items[i].Y - entrance.Y; if ((Math.Sqrt(X * X + Y * Y) < 12d)) { if (obj.items[i].Dropped) { Send_Drop(obj.items[i].X, obj.items[i].Y, obj.items[i].Id, obj.items[i].Quantity, obj.items[i].ID_EX, addr); } else if (obj.items[i].Taken) { Del_Drop(obj.items[i].ID_EX, addr); } } } Thread.Sleep(100); } }); } //Обработка запросов на лут персонажа if (DropHandle == false) { DropHandle = true; Task.Run(() => { Console.WriteLine(" Started drop handler Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { if (drop_Handle[Cons.ToIport(addr)] != null) { try { //Console.WriteLine("Item handling"); byte[] id = new byte[4]; byte[] ex = new byte[4]; Array.Copy(drop_Handle[Cons.ToIport(addr)], 1, id, 0, 4); Array.Copy(drop_Handle[Cons.ToIport(addr)], 5, ex, 0, 4); int ID = BitConverter.ToInt32(id, 0); int EX = BitConverter.ToInt32(ex, 0); Item item = obj.items.Find(i => (i.Id == ID && i.ID_EX == EX)); if (item == null) { //Console.WriteLine("Item not found"); Send(245, "NO" + Cons.GetData(drop_Handle[Cons.ToIport(addr)]), remoteIp); drop_Handle[Cons.ToIport(addr)] = null; continue; } if (item.Dropped == false) { //Console.WriteLine("Item not dropped"); Send(245, "NO" + Cons.GetData(drop_Handle[Cons.ToIport(addr)]), remoteIp); drop_Handle[Cons.ToIport(addr)] = null; continue; } if (entrance.Inventory.Items.Contains(item) == true) { //Console.WriteLine("Item is in Inventory"); Send(245, "NO" + Cons.GetData(drop_Handle[Cons.ToIport(addr)]), remoteIp); drop_Handle[Cons.ToIport(addr)] = null; continue; } float X = item.X - entrance.X; float Y = item.Y - entrance.Y; if (Math.Sqrt(X * X + Y * Y) < 1.5d) { item.Dropped = false; item.Taken = true; entrance.Inventory.Add(item); obj.items.Remove(item); //Console.WriteLine("DROP_TAKEN:: To:" + remoteIp + "Data:" + Cons.GetData(drop_Handle[Cons.ToIport(addr)])); Send(245, Cons.GetData(drop_Handle[Cons.ToIport(addr)]), remoteIp); drop_Handle[Cons.ToIport(addr)] = null; } else { //Console.WriteLine("Far distance"); drop_Handle[Cons.ToIport(addr)] = null; } } catch (Exception e) { Console.WriteLine(e.ToString()); } } Thread.Sleep(1); } }); } //Обработка инвентаря if (Inventory == false) { Inventory = true; Task.Run(() => { Console.WriteLine(" Started Inventory handler Thread, id thread: " + Task.CurrentId); while (obj._Char[name].online == true) { if (entrance.Inventory.Changed == true) { List <int> Id = new List <int>(); List <int> Ex = new List <int>(); List <int> Quantity = new List <int>(); int total = 0; for (int i = 0; i < entrance.Inventory.Items.Length; i++, total++) { if (entrance.Inventory.Items[i] == null) { break; } //Console.WriteLine("Adding: Item_" + i + ", ID = " + entrance.Inventory.Items[i].Id + ", EX = "+ entrance.Inventory.Items[i].ID_EX +", Q = " + entrance.Inventory.Items[i].Quantity); Id.Add(entrance.Inventory.Items[i].Id); Ex.Add(entrance.Inventory.Items[i].ID_EX); Quantity.Add(entrance.Inventory.Items[i].Quantity); } UpdateInv(total, Id, Ex, Quantity, addr); entrance.Inventory.Changed = false; } if (grocery_buy[Cons.ToIport(addr)] != null) { Cons.Buy(ref entrance, grocery_buy[Cons.ToIport(addr)]); grocery_buy[Cons.ToIport(addr)] = null; } Thread.Sleep(50); } }); } if (Quests == false) { Quests = true; Task.Run(() => { Console.WriteLine(" Started Quests handler Thread, id thread: " + Task.CurrentId); List <int> Id = new List <int>(); List <int> St = new List <int>(); List <int> Quantity = new List <int>(); int total = entrance.Quests.Count; for (int i = 0; i < total; i++) { Id.Add(entrance.Quests[i].Id); St.Add(entrance.Quests[i].State); Quantity.Add(entrance.Quests[i].Counter); } Initialize_Quests(total, Id, St, Quantity, addr); while (obj._Char[name].online == true) { entrance.CheckQuests(); try { if (quest_Handle[Cons.ToIport(addr)] != null) { Cons.QuestHandle(ref entrance, quest_Handle[Cons.ToIport(addr)]); quest_Handle[Cons.ToIport(addr)] = null; } for (int i = 0; i < entrance.Quests.Count; i++) { if (entrance.Quests[i].UpdClient) { Quest_Update(entrance.Quests[i].Id, entrance.Quests[i].State, entrance.Quests[i].Counter, addr); entrance.Quests[i].UpdClient = false; } } Thread.Sleep(100); } catch (Exception e) { Console.WriteLine(e.ToString()); } } }); } Thread.Sleep(1); } } catch (SocketException e) { Console.WriteLine(" Game catch: Socket ex in session [" + char_name + "]" + ":: " + e.Message + "code:" + e.ErrorCode); if (obj._Char[name].online == true) { Session(char_name); } } catch (Exception e) { //Console.WriteLine(e.ToString()); } }
public void Listen_Connections() { string name = ""; Console.WriteLine("Login server: started"); try { while (login_UP) { byte[] pack = log_listen.Receive(ref remoteIp); Console.WriteLine("Login server: [" + Encoding.UTF8.GetString(pack) + "] from:" + remoteIp.Address + "::" + remoteIp.Port); if (!clients_iport_login.ContainsKey(Cons.ToIport(remoteIp))) { clients_iport_login.Add(Cons.ToIport(remoteIp), null); } switch (pack[0]) { //1 CHECK | -- case 1: Send(255, "ALIVE", remoteIp); break; //2 BEGIN | 1-end[char_name] case 2: name = Cons.GetData(pack); //Если содержится игрок с таким именем и он онлайн if (game_Obj._Char.ContainsKey(name) && game_Obj._Char[name].online == true) { if (game_Obj._Char[name].finding_thread == false && game_Obj._Char[name].client_informed == true) { Send(253, "Session is active", remoteIp); } //Если отключили игрока, то ставиться флаг онлайна - false. //game_Obj._Char[name].online = !game_Serv.Disconnect(name); } else { //Запускаем поток-сессию для нового клиента int result = game_Serv.Find_thSpace(name, remoteIp); switch (result) { case 0: //Успешно SendS(254, game_Obj._Char[name].ID.ToString(), remoteIp, name); game_Obj._Char[name].name = name; break; case 1: Send(253, "Char is disconnecting, " + game_Serv.total_players.ToString(), remoteIp); //Удалил вариант с этой ошибкой break; case 2: Send(253, "Max online= " + game_Serv.total_players.ToString(), remoteIp); break; case 3: Send(253, "Game server is down, " + game_Serv.total_players.ToString(), remoteIp); break; } } break; //5 BEGIN_OK | 1[id] case 5: //Записывается дата сюда, надо для механизма важных сообщений Console.WriteLine("BEGIN_OK: " + clients_iport_login[Cons.ToIport(remoteIp)]); clients_iport_login[Cons.ToIport(remoteIp)] = Cons.GetData(pack); break; } } } catch (SocketException ex) { Console.WriteLine("Login server: socket ex in listener:: " + ex.Message); if (login_UP) { Listen_Connections(); } } }