コード例 #1
0
ファイル: MainForm.cs プロジェクト: Bejusek/GameServer
        //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.");
            }
        }