//właściwa obsługa klienta private void ClientService(object s) { //gniazdo klienta, którego obsługujemy Socket socket = s as Socket; //dekoder UTF-8 code = new UTF8Encoding(); //zdefiniowanie nazwy klienta - potem zamieniana na nazwę użytkownika string clientName = socket.RemoteEndPoint.ToString(); //informacja o tym czy klientowi udało się zalogować bool successLog = false; //bufor do pobierania danych od klienta byte[] buf; //inicjalizacja wielkości paczki z żądaniem int packageSize = 0; /* -------------- INICJALIZACJA OBIEKTÓW DLA GRACZA -------------- */ //obiekt postaci Character character = null; /* --------------------------------------------------------------- */ while (socket.Connected && isRunning && IsConnected(socket)) { if (socket.Available > 0) { //jeżeli ostatnia paczka została odczytana if (packageSize == 0) { //to ustaw bufor na 4 bajty = int32 buf = new byte[4]; //i odczytaj wielkość nowej paczki socket.Receive(buf); packageSize = BitConverter.ToInt32(buf, 0); } else { //jeżeli wielkość paczki jest ustalona //to ustaw bufor na wielkość jej odpowiadającą buf = new byte[packageSize]; //komenda wczytana z bufora string cmd = code.GetString(buf, 0, socket.Receive(buf)); //po wczytaniu ustaw wielkość paczki na 0 zgłaszając tym samym gotowość do przyjęcia następnej packageSize = 0; //utworzenie obiektu komendy Command response = new Command(); //zamiana lini komendy na nazwę akcji args[0] i argumenty - reszta tablicy string[] args = CommandsToArguments(cmd); switch (args[0]) { /* * LOGOWANIE */ case ClientCmd.LOGIN: ulong userID = Login(args[1], args[2]); if (userID == 0) { AddLogAsynch("[" + GetServerDateTime() + "][Klient]: Nieudana próba logowania (Login: "******")"); } else { AddLogAsynch("[" + GetServerDateTime() + "][ " + args[1] + " ]: Udane logowanie. ID = " + userID); clientName = args[1]; successLog = true; //utworzenie obiektu postaci dla zalogowanego gracza character = new Character(userID, dataBase); //uaktualnienie w bazie danych daty ostatniego logowania ExecuteQuery("UPDATE `" + dataBase.MySqlBase + "`.`player` SET `lastlogin` = '" + GetServerDateTime() + "' WHERE `player`.`id` =" + userID + ";", dataBase); } //utworzenie odpowiedzi response.Request(ClientCmd.LOGIN); response.Add(userID.ToString()); response.Add(DateTime.UtcNow.Ticks.ToString()); response.Apply(socket); break; /* * WYSYŁANIE DANYCH GRACZA * kolejność danych: komenda, Login, hasło, dostęp, email */ case ClientCmd.GET_PLAYER_DATA: Thread sendPlayerDataTh = new Thread(unused => SendPlayerData(ulong.Parse(args[1]), response, socket)); sendPlayerDataTh.Priority = ThreadPriority.BelowNormal; sendPlayerDataTh.IsBackground = true; sendPlayerDataTh.Start(); break; /* * WYSŁANIE DANYCH POSTACI * kolejność danych: komenda, imie, poziom, doświadczenie, złoto, siła, wytrzymałość, zręczność, szczęście */ case ClientCmd.GET_CHARACTER_DATA: response.Request(ServerCmd.CHARACTER_DATA); response.Add(character.Name); response.Add(character.Level.ToString()); response.Add(character.Experience.ToString()); response.Add(character.Gold.ToString()); response.Add(character.Strength.ToString()); response.Add(character.Stamina.ToString()); response.Add(character.Dexterity.ToString()); response.Add(character.Luck.ToString()); response.Add(character.Status); response.Add(character.LastDamage.ToString()); response.Add(character.Damage.ToString()); response.Add(character.LastFatigue.ToString()); response.Add(character.Fatigue.ToString()); response.Add(character.Location.ToString()); response.Add(character.TravelEndTime.ToString()); response.Add(character.TravelDestination.ToString()); response.Apply(socket); break; /* * UAKTUALNIANIE PÓL BAZY DANYCH * kolejność danych: komenda, tabela, pola, wartości, pole warunku, wartość pola warunku */ case ClientCmd.UPDATE_DATA_BASE: string log = ""; string UpdateQuery = CreateMySqlUpdateQuery(args, ref log); AddLogAsynch("[" + GetServerDateTime() + "][ " + clientName + " ]: " + log); ExecuteQuery(UpdateQuery, dataBase); //utworzenie odpowiedzi response.Request(ServerCmd.DATA_BASE_UPDATED); response.Apply(socket); break; case ClientCmd.GET_CHARACTER_EQUIPMENT: response.Request(ServerCmd.CHARACTER_EQUIPMENT); response.Add(character.Equipment.Head.ToString()); response.Add(character.Equipment.Chest.ToString()); response.Add(character.Equipment.Legs.ToString()); response.Add(character.Equipment.Weapon.ToString()); response.Add(character.Equipment.Shield.ToString()); response.Apply(socket); break; case ClientCmd.GET_CITIES: response.Request(ServerCmd.CITIES); response.Add(map.CitiesNumber.ToString()); foreach (City city in map.CityData) { response.Add(city.Id.ToString()); response.Add(city.Name); response.Add(city.AccessLevel.ToString()); response.Add(city.LeftCoordinate.ToString()); response.Add(city.TopCoordinate.ToString()); response.Add(city.Icon); } response.Apply(socket); break; case ClientCmd.GET_SKILLS: response.Request(ServerCmd.SKILLS); //AddLogAsynch("Pobiernie umiejętności"); foreach (Skill skill in skills.SkillList) { response.Add(skill.Id.ToString()); response.Add(skill.AccessLevel.ToString()); response.Add(skill.Strength.ToString()); response.Add(skill.Stamina.ToString()); response.Add(skill.Dexterity.ToString()); response.Add(skill.Luck.ToString()); } response.Apply(socket); break; default: AddLogAsynch("[" + GetServerDateTime() + "][Klient]: Odebrano nieznaną komendę!"); break; } response.Clear(); } } } if (successLog) { AddLogAsynch("[" + GetServerDateTime() + "][ " + clientName + " ]: Gracz rozłączył się z serwerem."); } }