/// <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; }
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
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(); }
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; } }
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); }
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()
/// <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."); }
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(); } }); }