Exemple #1
0
 public async Task SendChangeInfo()
 {
     if (IsEnd) return;
     var buffer = new byte[(byte)MessageSize.Change];
     buffer[0] = (byte)Message.m_newInfos;
     buffer[1] = (byte)bot.Energy;
     buffer[2] = (byte)(bot.Energy >> 8);
     buffer[3] = (byte)bot.ShieldLevel;
     buffer[4] = (byte)(bot.ShieldLevel >> 8);
     buffer[5] = (byte)bot.CloakLevel;
     buffer[6] = (byte)(bot.CloakLevel >> 8);
     buffer[7] = (byte)bot.Score;
     buffer[8] = (byte)(bot.Score >> 8);
     try
     {
         System.Diagnostics.Debug.WriteLine($"Sending 'C' to {bot.GUID}");
         await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);
         MainGame.SendCockpitInfo(bot.GUID, new ArraySegment<byte>(buffer, 0, buffer.Length));
     }
     catch (Exception err)
     {
         if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
             MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
         Console.WriteLine($"[ERROR] {err.Message}");
         State = BotState.Error;
     }
 }
Exemple #2
0
        public async Task SendDead()
        {
            if (IsEnd)
            {
                return;
            }
            State = BotState.IsDead;
            var buffer = new byte[(byte)MessageSize.Dead];

            buffer[0] = System.Text.Encoding.ASCII.GetBytes("D")[0];
            try
            {
                Console.WriteLine($"Bot {bot.Name} is dead!");
                await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);

                MainGame.ViewerRemovePlayer(bot.X, bot.Y);
            }
            catch (Exception err)
            {
                Console.WriteLine($"[ERROR] {err.Message}");
                State = BotState.Error;
            }
            if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
            {
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Energy;
            }
            MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
        }
Exemple #3
0
        public void SendPositionToCockpit()
        {
            if (IsEnd)
            {
                return;
            }
            var buffer = new byte[(byte)MessageSize.Position];

            buffer[0] = (byte)Message.m_Position;
            buffer[1] = (byte)bot.X;
            buffer[2] = (byte)bot.Y;
            MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
        }
Exemple #4
0
        public void SendPositionToCockpit()
        {
            if (IsEnd)
            {
                return;
            }
            var buffer = new byte[(byte)MessageSize.Position];

            buffer[0] = System.Text.Encoding.ASCII.GetBytes("P")[0];
            buffer[1] = (byte)bot.X;
            buffer[2] = (byte)bot.Y;
            MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
        }
Exemple #5
0
        public async Task SendDead()
        {
            if (IsEnd)
            {
                return;
            }
            var rnd = new Random();

            var buffer = new byte[1];

            try
            {
                if (!MainGame.Settings.autoRespawn)
                {
                    State     = BotState.IsDead;
                    buffer[0] = (byte)Message.m_dead;
                    BattleLogger.logger.info($"Bot {bot.Name} is dead!");
                    await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);
                }
                else
                {
                    bot.Energy = MainGame.Settings.EnergyStart;
                    BattleLogger.logger.info($"Bot {bot.Name} will respawn soon!");
                    buffer[0] = (byte)Message.m_Respawn;
                    await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);

                    byte  oldx = bot.X;
                    byte  oldy = bot.Y;
                    MapXY xy   = MainGame.SearchRespawnCase();
                    bot.X = xy.X;
                    bot.Y = xy.Y;
                    MainGame.TheMap[oldx, oldy] = CaseState.Empty;
                    State = BotState.Ready;
                    MainGame.ViewerMovePlayer(oldx, oldy, bot.X, bot.Y);
                    MainGame.RefreshViewer();
                    SendChangeInfo();
                }
            }
            catch (Exception err)
            {
                Console.WriteLine($"[ERROR] {err.Message}");
                State = BotState.Error;
            }
            if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
            {
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Energy;
            }
            MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
        }
Exemple #6
0
        public async Task SendDead()
        {
            var rnd = new Random();

            if (IsEnd)
            {
                return;
            }
            var buffer = new byte[1];

            try
            {
                if (!MainGame.Settings.autoRespawn)
                {
                    State     = BotState.IsDead;
                    buffer[0] = (byte)Message.m_dead;
                    Console.WriteLine($"Bot {bot.Name} is dead!");
                    await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);
                }
                else
                {
                    var rand_number = rnd.Next(MainGame.respawnList_X.Count - 1);
                    bot.Energy = MainGame.Settings.EnergyStart;
                    buffer[0]  = (byte)Message.m_Respawn;
                    BattleLogger.logger.info($"Bot {bot.Name} will respawn soon!");
                    await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);

                    MapXY xy = MainGame.SearchEmptyCase();
                    if (MainGame.respawnList_X[rand_number] == xy.X && MainGame.respawnList_Y[rand_number] == xy.Y)
                    {
                        bot.X = (byte)MainGame.respawnList_X[rand_number];
                        bot.Y = (byte)MainGame.respawnList_Y[rand_number];
                        State = BotState.IsRespawned;
                    }
                }
            }
            catch (Exception err)
            {
                Console.WriteLine($"[ERROR] {err.Message}");
                State = BotState.Error;
            }
            if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
            {
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Energy;
            }
            MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
        }
Exemple #7
0
        public async Task DoScan(byte size)
        {
            if (IsEnd)
            {
                return;
            }
            int distance = 2 * size + 1;
            var buffer   = new byte[2 + distance * distance];

            buffer[0] = (byte)Message.m_mapInfos;
            buffer[1] = (byte)(distance);
            UInt16 posByte = 2;
            int    posY    = bot.Y + size;

            for (UInt16 j = 0; j < (2 * size + 1); j++)
            {
                int posX = bot.X - size;
                for (UInt16 i = 0; i < (2 * size + 1); i++)
                {
                    if (posX < 0 || posX >= MainGame.Settings.MapWidth || posY < 0 || posY >= MainGame.Settings.MapHeight)
                    {
                        buffer[posByte++] = (byte)CaseState.Wall;
                    }
                    else
                    {
                        CaseState cs = MainGame.TheMap[posX, posY];
                        switch (cs)
                        {
                        case CaseState.Empty:
                        case CaseState.Wall:
                        case CaseState.Energy:
                            buffer[posByte++] = (byte)cs;
                            break;

                        case CaseState.Ennemy:
                            buffer[posByte++] = (byte)MainGame.IsEnnemyVisible(bot.X, bot.Y, posX, posY);
                            break;

                        default:
                            buffer[posByte++] = (byte)cs;
                            break;
                        }
                    }
                    posX++;
                }
                posY--;
            }
            try
            {
                State = BotState.WaitingAction;
                Console.WriteLine($"Sending 'I' to {bot.GUID}");
                if (size > 0)
                {
                    MainGame.SendCockpitInfo(bot.GUID, new ArraySegment <byte>(buffer, 0, buffer.Length));
                }
                await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);
            }
            catch (Exception err)
            {
                if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
                {
                    MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                }
                Console.WriteLine($"[ERROR] {err.Message}");
                State = BotState.Error;
            }
        }
Exemple #8
0
        /// <summary>
        /// réception des messages
        /// fin si le client se déconnecte
        /// </summary>
        /// <returns></returns>
        public async Task WaitReceive()
        {
            //Console.WriteLine("First, listen for GUID");
            // 1 - on attend la première data du client
            // qui doit etre son GUID

            var buffer = new byte[1024 * 4];
            WebSocketReceiveResult result = null;

            try
            {
                result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);

                Console.WriteLine($"[DEBUG] {result}");
            }
            catch (Exception err)
            {
                Console.WriteLine($"[ERROR] {err.Message}");
                //Console.WriteLine($"[ERROR] {err.Message}");
                IsEnd = true;
                State = BotState.Disconnect;
                try
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Error waiting data", CancellationToken.None);
                }
                catch (Exception) { }
                return;
            }
            while (!result.CloseStatus.HasValue)
            {
                // 2 - réception du GUID

                if (State == BotState.WaitingGUID)
                {
                    if (result.Count != 38 && result.Count != 36 && result.Count != 32) // pas de GUID ?
                    {
                        IsEnd = true;
                        State = BotState.Disconnect;
                        if (result.Count > 0)
                        {
                            var temp = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
                            Console.WriteLine($"[ERROR GUID] {temp}");
                        }
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "No GUID", CancellationToken.None);

                        return;
                    }
                    var text = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
                    // check que l'on a reçu un GUID
                    if (Guid.TryParse(text, out bot.GUID))
                    {
                        // et qu'il soit ok !
                        bot.Name = bot.GUID.ToString();
                        MapXY xy = MainGame.SearchEmptyCase();
                        MainGame.TheMap[xy.X, xy.Y] = CaseState.Ennemy;
                        bot.X      = xy.X;
                        bot.Y      = xy.Y;
                        bot.Energy = MainGame.Settings.EnergyStart;
                        bot.Score  = 0;
                        Console.WriteLine($"[NEW BOT] {bot.GUID} @ {xy.X}/{xy.Y}");

                        State = BotState.Ready;
                        await SendMessage("OK");

                        //MainGame.RefreshViewer();

                        SendPositionToCockpit();
                        //await StartNewTurn();
                    }
                    else
                    {
                        IsEnd = true;
                        State = BotState.Disconnect;
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[{text}] is not a GUID", CancellationToken.None);

                        return;
                    }
                } // réception GUID
                else
                { // exécute une action
                    if (result.Count < 1)
                    {
                        MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                        IsEnd = true;
                        State = BotState.Disconnect;
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer", CancellationToken.None);

                        return;
                    }
                    Console.WriteLine($"State {State}");
                    // On reçoit une commande du BOT
                    switch (State)
                    {
                    case BotState.WaitingAnswerD:     // le niveau de détection désiré pour ce tour
                        string command = System.Text.Encoding.UTF8.GetString(buffer, 0, 1);
                        if (command != "D")
                        {
                            MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                            IsEnd = true;
                            State = BotState.Disconnect;
                            await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[ERROR] Not the right answer, waiting D#, receive {command}", CancellationToken.None);

                            return;
                        }
                        // commande D sans niveau...
                        if (result.Count < 1)
                        {
                            MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                            IsEnd = true;
                            State = BotState.Disconnect;
                            await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'D'", CancellationToken.None);

                            return;
                        }
                        // do a scan of size value and send answer
                        byte distance = buffer[1];
                        Console.WriteLine($"{bot.Name}: scan distance={distance}");
                        if (distance > 0)
                        {
                            if (distance < bot.Energy)
                            {
                                bot.Energy -= distance;
                                await SendChangeInfo();
                                await DoScan(distance);
                            }
                            else
                            {
                                bot.Energy = 0;
                                State      = BotState.IsDead;
                                await SendChangeInfo();
                                await SendDead();
                            }
                        }
                        else
                        {
                            // ici cas simple du scan à 0, pas de conso d'énergie
                            await DoScan(distance);
                        }
                        break;

                    case BotState.WaitingAction:     // l'action a effectuer
                        BotAction action = (BotAction)buffer[0];
                        switch (action)
                        {
                        case BotAction.None:         // None
                            State = BotState.Ready;
                            Console.WriteLine($"Bot {bot.Name} do nothing");
                            await SendMessage("OK");

                            break;

                        case BotAction.Move:         // move
                            if (result.Count < 2)
                            {
                                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                                IsEnd = true;
                                State = BotState.Disconnect;
                                await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'M'", CancellationToken.None);

                                return;
                            }
                            byte direction = buffer[1];
                            Console.WriteLine($"Bot {bot.Name} moving direction {(MoveDirection)direction}");
                            await DoMove((MoveDirection)direction);

                            State = BotState.Ready;
                            await SendMessage("OK");

                            MainGame.RefreshViewer();

                            break;

                        case BotAction.ShieldLevel:         // shield
                            if (result.Count < 3)
                            {
                                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                                IsEnd = true;
                                State = BotState.Disconnect;
                                await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'S'", CancellationToken.None);

                                return;
                            }
                            UInt16 shieldLevel = (UInt16)(buffer[1] + (buffer[2] << 8));
                            Console.WriteLine($"Bot {bot.Name} activate shield level {shieldLevel}");
                            bot.Energy     += bot.ShieldLevel;
                            bot.ShieldLevel = shieldLevel;
                            MainGame.ViewerPlayerShield(bot.X, bot.Y, (byte)bot.ShieldLevel);
                            if (shieldLevel > bot.Energy)
                            {
                                bot.ShieldLevel = 0;
                                bot.Energy      = 0;
                                await SendChangeInfo();
                                await SendDead();
                            }
                            else
                            {
                                bot.Energy -= shieldLevel;
                            }
                            State = BotState.Ready;
                            await SendMessage("OK");

                            break;

                        case BotAction.CloakLevel:         // cloak
                            if (result.Count < 3)
                            {
                                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                                IsEnd = true;
                                State = BotState.Disconnect;
                                await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'C'", CancellationToken.None);

                                return;
                            }
                            UInt16 cloakLevel = (UInt16)(buffer[1] + (buffer[2] << 8));
                            Console.WriteLine($"Bot {bot.Name} activate cloak level {cloakLevel}");
                            // on récupère l'énergie actuelle dans le cloak
                            bot.Energy += (UInt16)(bot.CloakLevel / MainGame.Settings.EnergyCloakCostMultiplier);
                            // a-t-on assez d'énergie pour le niveau demandé ?
                            if (cloakLevel * MainGame.Settings.EnergyCloakCostMultiplier > bot.Energy)
                            {
                                bot.CloakLevel = 0;
                                bot.Energy     = 0;
                                await SendChangeInfo();
                                await SendDead();
                            }
                            else
                            {
                                bot.Energy    -= (UInt16)(cloakLevel * MainGame.Settings.EnergyCloakCostMultiplier);
                                bot.CloakLevel = cloakLevel;
                                MainGame.ViewerPlayerCloak(bot.X, bot.Y, (byte)bot.CloakLevel);
                            }
                            State = BotState.Ready;
                            await SendMessage("OK");

                            break;

                        case BotAction.Shoot:
                            if (result.Count < 2)
                            {
                                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                                IsEnd = true;
                                State = BotState.Disconnect;
                                await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'F'", CancellationToken.None);

                                return;
                            }
                            byte fireDirection = buffer[1];
                            Console.WriteLine($"Bot {bot.Name} shoot in direction {fireDirection}");
                            if (bot.Energy >= MainGame.Settings.EnergyLostShot)
                            {
                                bot.Energy -= MainGame.Settings.EnergyLostShot;
                                if (turn == 1)
                                {
                                    await IsHit();
                                }
                                else
                                {
                                    DoShoot(fireDirection);
                                }
                            }
                            else
                            {
                                bot.Energy = 0;
                            }
                            if (bot.Energy == 0)
                            {
                                await SendChangeInfo();
                                await SendDead();
                            }
                            State = BotState.Ready;
                            await SendMessage("OK");

                            break;

                        default:
                            Console.WriteLine($"[ERROR] lost with command {action} for state Action");
                            MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                            IsEnd = true;
                            State = BotState.Disconnect;
                            await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[ERROR] lost with command {action} for state Action", CancellationToken.None);

                            return;
                        }
                        break;

                    default:
                        string cmd = System.Text.Encoding.UTF8.GetString(buffer, 0, 1);
                        // on reçoit le nom du BOT
                        if (cmd == "N" && result.Count > 1)
                        {
                            bot.Name = System.Text.Encoding.UTF8.GetString(buffer, 1, result.Count - 1);
                            Console.WriteLine($"Le BOT {bot.GUID} se nomme {bot.Name}");
                            State = BotState.Ready;
                            await SendMessage("OK");

                            MainGame.SendCockpitInfo(bot.GUID, "N" + bot.Name);
                            break;
                        }
                        Console.WriteLine($"[ERROR] lost with state {State}");
                        MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                        IsEnd = true;
                        State = BotState.Disconnect;
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[ERROR] lost with state {State}", CancellationToken.None);

                        return;
                    }

                    /*var text = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
                     * if (text.IndexOf(ClientGuid.ToString()) < 0)
                     *  MainGame.Broadcast(text + " " + ClientGuid.ToString());
                     */

                    /*text = text + " et " + text + " :)";
                     * buffer = System.Text.Encoding.UTF8.GetBytes(text);
                     * await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
                     */
                }
                //result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                try
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                }
                catch (Exception err)
                {
                    Console.WriteLine($"[ERROR] {err.Message}");
                    if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
                    {
                        MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                    }
                    IsEnd = true;
                    State = BotState.Disconnect;
                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Error waiting data", CancellationToken.None);
                    }
                    catch (Exception) { }
                    return;
                }
            }
            if (MainGame.TheMap[bot.X, bot.Y] == CaseState.Ennemy)
            {
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
            }
            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);

            IsEnd = true;
            State = BotState.Disconnect;
        }