//konstruktor gracza public Player(ulong _id, TcpClient userClient) { //ustawienie identyfikatora gracza id = _id; //wczytanie ustawień dla połączenia z serwerem host = Properties.Settings.Default.Host; port = Properties.Settings.Default.Port; //inicjalizacja gniazda połączenia z serwerem try { client = userClient; code = new UTF8Encoding(); Command request = new Command(ClientCmd.GET_PLAYER_DATA); request.Add(id.ToString()); string[] dane = request.Apply(client.Client, true); if (dane[0] == ServerCmd.PLAYER_DATA) { login = dane[1]; password = dane[2]; access = int.Parse(dane[3]); email = dane[4]; } } catch { //obsługa wyjątku } }
public CharacterEquipment(ulong characterId, TcpClient clientTcp) { id = characterId; client = clientTcp.Client; Command command = new Command(); command.Request(ClientCmd.GET_CHARACTER_EQUIPMENT); command.Add(id.ToString()); string[] dane = command.Apply(client, true); if (dane[0] == ServerCmd.CHARACTER_EQUIPMENT) { head = uint.Parse(dane[1]); chest = uint.Parse(dane[2]); legs = uint.Parse(dane[3]); weapon = uint.Parse(dane[4]); shield = uint.Parse(dane[5]); } }
public Character(ulong characterId, TcpClient clientTcp) { client = clientTcp.Client; id = characterId; Command command = new Command(); command.Request(ClientCmd.GET_CHARACTER_DATA); command.Add(id.ToString()); string[] dane = command.Apply(client, true); if (dane[0] == ServerCmd.CHARACTER_DATA) { name = dane[1]; level = uint.Parse(dane[2]); exp = uint.Parse(dane[3]); gold = uint.Parse(dane[4]); strength = uint.Parse(dane[5]); stamina = uint.Parse(dane[6]); dexterity = uint.Parse(dane[7]); luck = uint.Parse(dane[8]); status = dane[9]; lastDamage = UInt64.Parse(dane[10]); damage = UInt64.Parse(dane[11]); lastFatigue = UInt64.Parse(dane[12]); fatigue = UInt64.Parse(dane[13]); location = uint.Parse(dane[14]); travelEndTime = UInt64.Parse(dane[15]); travelDestination = UInt32.Parse(dane[16]); } equip = new CharacterEquipment(id, clientTcp); pointRegenerationTime = 30; fullRegenerationTime = 15 * 60; //przykładowa zmiana imienia postaci //this.Name = "updateTest"; }
//wysyłanie danych gracza private bool SendPlayerData(ulong playerId, Command response, Socket socket) { string[] dane = new string[3]; dane = GetPlayerData(playerId); //utworzenie odpowiedzi response.Request(ServerCmd.PLAYER_DATA); response.Add(dane); response.Apply(socket); AddLogAsynch("[" + GetServerDateTime() + "][ " + dane[0] + " ]: Pobrał dane gracza."); return true; }
//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."); } }
public Skills(TcpClient client) { skillList = new List<Skill>(); socket = client.Client; string[] result; Command request = new Command(); request.Request(ClientCmd.GET_SKILLS); result = request.Apply(socket, true); if (result[0] == ServerCmd.SKILLS) { for (int i = 1; i < result.Length; i += 6) { Skill skill = new Skill( uint.Parse(result[i]), uint.Parse(result[i+1]), uint.Parse(result[i+2]), uint.Parse(result[i+3]), uint.Parse(result[i+4]), uint.Parse(result[i+5]) ); skillList.Add(skill); } } }
public Map(TcpClient clientSocket) { socket = clientSocket.Client; uint citiesNumber = 0; string[] citiesData; Command request = new Command(); request.Request(ClientCmd.GET_CITIES); citiesData = request.Apply(socket, true); //obliczenie liczby miast citiesNumber = uint.Parse(citiesData[1]); for (int i = 2; i < citiesData.Length; i += 6) { City city = new City( uint.Parse(citiesData[i]), //id citiesData[i + 1], //name uint.Parse(citiesData[i + 2]), //accessLevel uint.Parse(citiesData[i + 3]), //leftCoordinate uint.Parse(citiesData[i + 4]), //topCoordinate citiesData[i + 5] //icon ); cityData.Add(city); } //tworzenie buttonów na podstawie danych z bazki foreach (City city in cityData) { //najpierw sam button Button btn = new Button(); //potem stackpanel przechowujący jego zawartość StackPanel btnContent = new StackPanel(); //obrazek, który będzie jego zawartością Image btnImage = new Image(); //i jego źródło btnImage.Source = new BitmapImage(new Uri("pack://application:,,,/Images/" + city.Icon + ".png")); btnImage.Width = 44; btnImage.Height = 60; //oraz textblock, który będzie wyświetlał nazwę miasta TextBlock btnText = new TextBlock(); //przypisanie do texblocka nazwy miasta btnText.Text = city.Name; //szerokość stała na 50 px btnText.Width = 50; //nazwa kontrolki aby można było dynamicznie zmieniać kolor tekstu w buttonie btnText.Name = "city" + city.Id + "Name"; //wyśrodkowanie tekstu btnText.TextAlignment = TextAlignment.Center; //ustawienie stackpanelu na 40 szerokości i 75 wysokości (obrazek wtedy sam się zeskaluje) btnContent.Width = 50; btnContent.Height = 75; btnContent.Margin = new Thickness(3, 3, 3, 3); //wyśrodkowanie zawartości w pionie do środka btnContent.VerticalAlignment = VerticalAlignment.Center; //dodanie obrazka i texblocka z nazwą miasta do stackpanelu btnContent.Children.Add(btnImage); btnContent.Children.Add(btnText); //nazwanie buttona miasta btn.Name = "city" + city.Id; //jego szerokość na 55 px btn.Width = 55; //cały content wyśrodkowany btn.HorizontalAlignment = HorizontalAlignment.Center; //przypisanie stackpanelu jako zawartości buttona btn.Content = btnContent; //dodanie tagu z identyfikatorem miasta btn.Tag = city.Id; //określenie położenia na mapie Canvas.SetLeft(btn, city.LeftCoordinate); Canvas.SetTop(btn, city.TopCoordinate); //dodanie do listy buttonów mapy cityButtons.Add(btn); } }
//logowanie do gry private void singin_Click(object sender, RoutedEventArgs e) { //inicjalizacja gniazda try { user = new TcpClient(host, port); //ustawienie czasu oczekiwania na odpowiedź serwera user.ReceiveTimeout = 5; } catch { MessageBox.Show("Czas oczekiwania na połączenie minął. Nie można było połączyć się z serwerem. Sprawdź połączenia z Internetami.", "Błąd połączenia!", MessageBoxButton.OK, MessageBoxImage.Warning); return; } //inicjalizacja kodera/dekodera code = new UTF8Encoding(); //inicjalizacja bufora przechowującego dane do wysłania byte[] buf; Command cmd = new Command(); cmd.Request(ClientCmd.LOGIN); cmd.Add(login.Text); cmd.Add(GetMD5Hash(password.Password)); Stopwatch watch = new Stopwatch(); watch.Start(); string[] args = cmd.Apply(user.Client, true); if (Convert.ToUInt64(args[1]) == 0) { MessageBox.Show("[Klient] Nie udało się zalogować."); user.Close(); singin.IsEnabled = true; return; } else { watch.Stop(); new Interface(Convert.ToUInt64(args[1]), user, (long.Parse(args[2]) + watch.ElapsedTicks) - DateTime.UtcNow.Ticks).Show(); this.Close(); } }