Пример #1
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;
                                //MainGame.SendCockpitInfo(bot.GUID, "N" + bot.Name);
                                MainGame.RefreshViewer();
                                await SendMessage("OK");

                                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;
        }
Пример #2
0
        public async Task DoMove(MoveDirection direction)
        {
            if (bot.Energy > MainGame.Settings.EnergyLostByMove)
            {
                bot.Energy -= MainGame.Settings.EnergyLostByMove;
            }
            else
            {
                bot.Energy = 0;
            }
            int x = 0;
            int y = 0;

            switch (direction)
            {// TODO: check if it is ok for east/west. Ok for north/south
            // pour l'instant, on se déplace haut/bas/gauche/droite, pas de diagonale
            case MoveDirection.North: y = 1; break;

            case MoveDirection.South: y = -1; break;

            case MoveDirection.East: x = -1; break;

            case MoveDirection.West: x = 1; break;

                /*case MoveDirection.NorthWest: y = 1; x = 1; break;
                 * case MoveDirection.NorthEast: y = 1; x = -1; break;
                 * case MoveDirection.SouthWest: y = -1; x = 1; break;
                 * case MoveDirection.SouthEast: y = -1; x = -1; break;
                 */
            }
            switch (MainGame.TheMap[bot.X + x, bot.Y + y])
            {
            case CaseState.Empty:
                MainGame.ViewerMovePlayer(bot.X, bot.Y, (byte)(bot.X + x), (byte)(bot.Y + y));
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                bot.X = (byte)(bot.X + x);
                bot.Y = (byte)(bot.Y + y);
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Ennemy;
                SendPositionToCockpit();
                break;

            case CaseState.Energy:
                MainGame.ViewerClearCase((byte)(bot.X + x), (byte)(bot.Y + y));
                MainGame.ViewerMovePlayer(bot.X, bot.Y, (byte)(bot.X + x), (byte)(bot.Y + y));
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Empty;
                bot.X = (byte)(bot.X + x);
                bot.Y = (byte)(bot.Y + y);
                MainGame.TheMap[bot.X, bot.Y] = CaseState.Ennemy;
                UInt16 temp = (UInt16)(MainGame.RND.Next(1 + MainGame.Settings.EnergyPodMax - MainGame.Settings.EnergyPodFrom) + MainGame.Settings.EnergyPodFrom);
                bot.Energy += temp;
                Console.WriteLine($"Bot {bot.Name} win energy: {temp}");
                bot.Score += MainGame.Settings.PointByEnergyFound;
                SendPositionToCockpit();
                break;

            case CaseState.Ennemy:     // on tamponne un bot adverse
                if (bot.ShieldLevel >= MainGame.Settings.EnergyLostContactEnemy)
                {
                    bot.ShieldLevel -= MainGame.Settings.EnergyLostContactEnemy;
                    MainGame.ViewerPlayerShield(bot.X, bot.Y, bot.ShieldLevel);
                }
                else
                {
                    UInt16 tmp = bot.ShieldLevel;
                    bot.ShieldLevel = 0;
                    tmp             = (UInt16)(2 * (MainGame.Settings.EnergyLostContactEnemy - tmp));
                    if (bot.Energy >= tmp)
                    {
                        bot.Energy -= tmp;
                    }
                    else
                    {
                        bot.Energy = 0;
                    }
                }
                // perte du champ occultant
                if (bot.CloakLevel > 0)
                {
                    bot.CloakLevel = 0;
                    MainGame.ViewerPlayerCloak(bot.X, bot.Y, bot.CloakLevel);
                }
                bot.Score += MainGame.Settings.PointByEnnemyTouch;
                Console.WriteLine($"Bot {bot.Name} tamponne un bot ennemi !");
                TouchEnemy((UInt16)(bot.X + x), (UInt16)(bot.Y + y));
                break;

            case CaseState.Wall:
                if (bot.ShieldLevel > 0)
                {
                    bot.ShieldLevel--;
                    MainGame.ViewerPlayerShield(bot.X, bot.Y, bot.ShieldLevel);
                }
                else
                {
                    if (bot.Energy > MainGame.Settings.EnergyLostContactWall)
                    {
                        bot.Energy -= MainGame.Settings.EnergyLostContactWall;
                    }
                    else
                    {
                        bot.Energy = 0;
                    }
                }
                // perte du champ occultant
                if (bot.CloakLevel > 0)
                {
                    bot.CloakLevel = 0;
                    MainGame.ViewerPlayerCloak(bot.X, bot.Y, bot.CloakLevel);
                }
                break;
            }
            await SendChangeInfo();

            //MainGame.RefreshViewer();
            if (bot.Energy == 0)
            {
                await SendDead();
            }
        } // DoMove
Пример #3
0
        static void Main(string[] args)
        {
            var currentDir = Directory.GetCurrentDirectory();
            var theFile    = Path.Combine(currentDir, "settings.json");

            // création du fichier settings.json avec les valeurs par défaut
            if (!File.Exists(theFile))
            {
                MainGame.Settings = new Settings();
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(MainGame.Settings, Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(theFile, json);
            }
            var prm = Newtonsoft.Json.JsonConvert.DeserializeObject <Settings>(File.ReadAllText(theFile));

            MainGame.Settings = prm;
            if (MainGame.Settings.MapName != "")
            {
                MainGame.LoadMap(MainGame.Settings.MapName);
            }
            else
            {
                MainGame.InitNewMap();
            }



            var host = new WebHostBuilder()
                       .UseKestrel()
                       .UseStartup <Startup>()
                       .ConfigureKestrel((context, options) => { options.ListenAnyIP(MainGame.Settings.ServerPort); })
                       .Build();

            host.Start();                     //Start server non-blocking

            ShowHelp();
            bool exit = false;

            while (!exit)
            {
                Console.Write(">");
                var key = Console.ReadKey(true);
                switch (key.KeyChar.ToString().ToLower())
                {
                case "h":
                    ShowHelp();
                    break;

                case "e":
                    Console.WriteLine("Exit program");
                    if (MainGame.AllBot.Count > 0)
                    {
                        Console.WriteLine("Not possible, at least 1 BOT is in arena.");
                    }
                    else
                    {
                        if (MainGame.AllViewer.Count > 0)
                        {
                            Console.WriteLine("Not possible, at least 1 VIEWER is working.");
                        }
                        else
                        {
                            exit = true;
                        }
                    }
                    break;

                case "g":
                    Console.WriteLine("GO!");
                    MainGame.RunSimulator();
                    break;

                case "s":
                    Console.WriteLine("Stop");
                    MainGame.StopSimulator();
                    break;

                case "x":     // debug stuff to view shield
                    foreach (OneBot x in MainGame.AllBot)
                    {
                        x.bot.ShieldLevel++;
                        if (x.bot.ShieldLevel > 10)
                        {
                            x.bot.ShieldLevel = 0;
                        }
                        MainGame.ViewerPlayerShield(x.bot.X, x.bot.Y, x.bot.ShieldLevel);
                    }
                    break;

                case "w":     // debug stuff to view cloak
                    foreach (OneBot x in MainGame.AllBot)
                    {
                        x.bot.CloakLevel++;
                        if (x.bot.CloakLevel > 10)
                        {
                            x.bot.CloakLevel = 0;
                        }
                        MainGame.ViewerPlayerCloak(x.bot.X, x.bot.Y, x.bot.CloakLevel);
                    }
                    break;
                }
            }
            host.StopAsync();
        }
Пример #4
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;
            }
        }
Пример #5
0
        public async Task WaitReceive()
        {
            // 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);
            }
            catch (Exception err)
            {
                MustRemove = true;
                Console.WriteLine($"[VIEWER ERROR] {err.Message}");
                try
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Error waiting data", CancellationToken.None);
                }
                catch (Exception) { }
                return;
            }
            while (!result.CloseStatus.HasValue)
            {
                if (result.Count < 1)
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Missing data in answer", CancellationToken.None);

                    return;
                }

                string command = System.Text.Encoding.UTF8.GetString(buffer, 0, 1);
                Console.WriteLine($"[DISPLAY] Received command '{command}'");
                if (command == "Q")
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, $"[DISPLAY CLOSING] receive {command}", CancellationToken.None);

                    return;
                }
                if (command == "S")
                {
                    MainGame.RunSimulator();
                    return;
                }
                if (command != "M")
                {
                    MustRemove = true;
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[DISPLAY ERROR] Not the right answer, waiting M#, receive {command}", CancellationToken.None);

                    return;
                }

                /*if (result.Count < 1)
                 * {
                 *  MustRemove = true;
                 *  await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Missing data in answer 'D'", CancellationToken.None);
                 *  return;
                 * }*/
                //SendMapInfo();
                //SendBotInfo();

                try
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                }
                catch (Exception err)
                {
                    MustRemove = true;
                    System.Diagnostics.Debug.WriteLine($"[DISPLAY ERROR] {err.Message}");
                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "[DISPLAY] Error waiting data", CancellationToken.None);
                    }
                    catch (Exception) { }
                    return;
                }
            }
            MustRemove = true;
            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
Пример #6
0
        public async Task WaitReceive()
        {
            var buffer = new byte[1024 * 4];
            WebSocketReceiveResult result = null;

            try
            {
                result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
            }
            catch (Exception err)
            {
                Console.WriteLine($"[COCKPIT ERROR] {err.Message}");
                State      = BotState.Disconnect;
                MustRemove = true;
                try
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Error waiting data", CancellationToken.None);
                }
                catch (Exception) { }
                return;
            }

            while (!result.CloseStatus.HasValue)
            {
                // 1 - réception du GUID

                if (State == BotState.WaitingGUID)
                {
                    if (result.Count != 38 && result.Count != 36 && result.Count != 32) // pas de GUID ?
                    {
                        MustRemove = true;
                        State      = BotState.Disconnect;
                        if (result.Count > 0)
                        {
                            var temp = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
                            Console.WriteLine($"[COCKPIT 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 ClientGuid))
                    {
                        Console.WriteLine($"[COCKPIT] {ClientGuid}");
                        State = BotState.Ready;
                        await SendMessage("OK");

                        MainGame.SendMapInfoToCockpit(ClientGuid);
                    }
                    else
                    {
                        MustRemove = true;
                        State      = BotState.Disconnect;
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, $"[{text}] is not a GUID", CancellationToken.None);

                        return;
                    }
                } // réception GUID
                else
                {
                }

                try
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                }
                catch (Exception err)
                {
                    Console.WriteLine($"[COCKPIT ERROR] {err.Message}");
                    MustRemove = true;
                    State      = BotState.Disconnect;
                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.ProtocolError, "Error waiting data", CancellationToken.None);
                    }
                    catch (Exception) { }
                    return;
                }
            } // while

            MustRemove = true;
            State      = BotState.Disconnect;
            try
            {
                await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
            } catch (Exception) { }
        } // WaitReceive()
Пример #7
0
        /// <summary>
        /// Exécute la simulation dans son ensemble !
        /// </summary>
        public static async void DoTurns()
        {
            if (turnRunning)
            {
                return;
            }
            turnRunning = true;
            Console.WriteLine("Running simulator...");
            int turnCount = 0;

            while (turnRunning)
            {
                //System.Diagnostics.Debug.WriteLine("One turns...");
                OneBot[] bots  = null;
                int      count = 0;
                lock (lockListBot)
                {
                    count = AllBot.Count;
                    if (count > 0)
                    {
                        bots = new OneBot[count];
                        AllBot.CopyTo(bots);
                    }
                }
                if (count == 0)
                {
                    if (Settings.EndlessMode)

                    {
                        // Disabled: Will spam the console until a bot joins.
                        // Console.WriteLine("Last bot left. Endless mode is active, continuing");
                    }
                    else
                    {
                        Console.WriteLine("No more BOT, ending simulator.");
                        turnRunning = false;
                    }
                }
                else
                {
                    for (int i = 0; i < bots.Length; i++)
                    {
                        Console.WriteLine($"Turn #{turnCount} Bot {bots[i].bot.Name}");
                        await    bots[i].StartNewTurn();
                        DateTime start = DateTime.UtcNow;
                        while ((bots[i].State != BotState.Ready) && (DateTime.UtcNow - start).TotalSeconds < Settings.MaxDelaySecondByTurn)
                        {
                            Thread.Sleep(2);
                        }
                        if (bots[i].State != BotState.Ready)
                        {
                            // trop long, ajout pénalité !
                            // TODO: rien pour le moment
                        }
                        Thread.Sleep(Settings.DelayBetweenEachBotTurn);
                    }
                    // on génère de l'énergie si nécessaire
                    MainGame.RefuelMap();
                    turnCount++;
                    if (turnCount % MainGame.Settings.EnergyPodLessEvery == 0)
                    {
                        if (Settings.EnergyPodMax > Settings.EnergyPodMin)
                        {
                            Settings.EnergyPodMax--;
                        }
                    }
                }
            }
            Console.WriteLine("End of running.");
        }
Пример #8
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseDefaultFiles();

            var webSocketOptions = new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(30),
                ReceiveBufferSize = 4 * 1024
            };

            app.UseWebSockets(webSocketOptions);

            // ICI on fonctionne en THREAD !
            app.Use(async(context, next) =>
            {
                bool wsok = false;
                Console.WriteLine("New WebSocket connection");
                // ouverture d'une websocket, un nouveau bot se connecte
                if (context.Request.Path == "/bot")
                {
                    Console.WriteLine("WebSocket /bot");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        //Console.WriteLine("AcceptWebSocketAsync");
                        // on l'ajoute à notre simulation !
                        WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                        //await Echo(context, webSocket);
                        Console.WriteLine("A new BOT in arena!");
                        // Démarrage d'un nouveau bot. Si on revient c'est qu'il est mort !
                        await MainGame.AddBot(webSocket);
                        Console.WriteLine($"#BOTS: {MainGame.AllBot.Count}");
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    }
                }
                if (context.Request.Path == "/display")
                {
                    Console.WriteLine("[SOCKET] WebSocket /display");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        // on l'ajoute à notre simulation !
                        WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                        Console.WriteLine("[DISPLAY] New DISPLAY!");
                        await MainGame.AddViewer(webSocket);
                        Console.WriteLine($"[DISPLAY] number= {MainGame.AllViewer.Count}");
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    }
                }
                if (context.Request.Path == "/cockpit")
                {
                    Console.WriteLine("WebSocket /cockpit");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        // on l'ajoute à notre simulation !
                        WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                        Console.WriteLine("New COCKPIT!");
                        await MainGame.AddCockpit(webSocket);
                        Console.WriteLine($"#COCKPIT: {MainGame.AllCockpit.Count}");
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    }
                }

                if (context.Request.Path == "/startsim")
                {
                    Console.WriteLine("WebSocket /startsim");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        MainGame.RunSimulator();
                        Console.WriteLine($"[SIM]: Start simulation");
                        context.Response.StatusCode = 200;
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    }
                }

                if (context.Request.Path == "/stopsim")
                {
                    Console.WriteLine("WebSocket /stopsim");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        MainGame.StopSimulator();
                        Console.WriteLine($"[SIM]: Stop simulation");
                        context.Response.StatusCode = 200;
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    }
                }
                if (context.Request.Path == "/statsim")
                {
                    Console.WriteLine("WebSocket /statsim");
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        wsok = true;
                        MainGame.StopSimulator();
                        Console.WriteLine($"[SIM]: Ask server status ");
                        context.Response.StatusCode = 200;
                        var buffer          = new byte[4];
                        buffer[0]           = MainGame.isRunning();
                        buffer[1]           = (byte)MainGame.AllBot.Count;
                        buffer[2]           = (byte)MainGame.TheMap.Length;
                        buffer[3]           = (byte)MainGame.TheMap.Length;
                        WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                        await webSocket.SendAsync(new ArraySegment <byte>(buffer, 0, buffer.Length), WebSocketMessageType.Binary, true, CancellationToken.None);
                        await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
                        Console.WriteLine($"[SIM]: Status sent ! ");
                    }
                }

                if (!wsok)
                {
                    context.Response.StatusCode = 400;
                    Console.WriteLine("WebSocket ERROR : Not a WebSocket establishment request.");
                    await next();
                }
            });
        }