diff --git a/README.md b/README.md index d346ee5..c16fdee 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ # Leafsteroids -This repository contains the MongoDB `Leafsteroids` demo. +This repository contains the MongoDB `Leafsteroids` demo. A game developed by the MongoDB team, featuring a 2D arcade-style space shooter. Built with Unity3D and .NET, it includes a game client, an ASP.NET Web API, and a website using Blazor pages. Players aim to destroy bricks (asteroids) and achieve the highest score within 60 seconds by collecting power-ups and destroying targets quickly, while competing against each other within the concept of an event (tournament). The backend uses MongoDB Atlas for data storage, including Atlas Vector Search to match players based on gameplay style, score, and speed. The game is playable on tablets, mobiles, and desktop/laptop, with real-time scoreboards for competitive play. + Follow the instructions in this README to run a clone of your own to get your MongoDB development jump started. +You can also register and create your own event to share with your friends and play live anywhere [here](https://leafsteroids.net/). + ## Architecture +![Leafsteroids Architecture](./arch_diagram.png) + The demo and repository consist of the following parts: - Game Client (Unity3D, .NET, C#) diff --git a/arch_diagram.png b/arch_diagram.png new file mode 100644 index 0000000..3d410aa Binary files /dev/null and b/arch_diagram.png differ diff --git a/rest_service/Controllers/PlayersController.cs b/rest_service/Controllers/PlayersController.cs index 6610c81..b94daec 100644 --- a/rest_service/Controllers/PlayersController.cs +++ b/rest_service/Controllers/PlayersController.cs @@ -1,4 +1,4 @@ -using System.Xml.Linq; +using System.Xml.Linq; using Microsoft.AspNetCore.Mvc; using MongoDB.Bson; using MongoDB.Bson.Serialization; @@ -59,11 +59,11 @@ public async Task> GetPlayers([FromQuery] PlayerRequest pla filter &= Builders.Filter.Eq(x => x.Location, playerUnique.Location); } - var players = await _playersCollection.FindAsync(filter, new FindOptions() { Limit = 10 }); + var players = await _playersCollection.FindAsync(filter, new FindOptions() { Limit = 10 }); var playersResponse = players.ToList().Select(player => new PlayerResponse(player)).ToList(); - + return playersResponse; } @@ -156,7 +156,7 @@ public async Task> CreatePlayer(PlayerRequest playe try { await _playersCollection.InsertOneAsync(session, player); - + await _playersUniqueCollection.InsertOneAsync(session, playerUnique); if (session.IsInTransaction) @@ -205,7 +205,8 @@ public async Task> PlayerAutoComplete([FromQuery] string Name) return arrMatches.GetElement("matches").Value.AsBsonArray .Select(x => x.ToString()) .ToList(); - } catch (Exception e) + } + catch (Exception e) { Logger.LogError("GetPlayerAutoComplete did not find matches"); Logger.LogError(e.Message); diff --git a/rest_service/Dtos/ResponseObjects/PlayerResponse.cs b/rest_service/Dtos/ResponseObjects/PlayerResponse.cs index 1ec4a40..2de3d68 100644 --- a/rest_service/Dtos/ResponseObjects/PlayerResponse.cs +++ b/rest_service/Dtos/ResponseObjects/PlayerResponse.cs @@ -15,8 +15,27 @@ public PlayerResponse(Player player) { Id = player.Id.ToString(); Name = player.Name; - Email = player.Email; + Email = MaskEmail(player.Email ?? string.Empty); Team = player.Team; Location = player.Location; } + + public string MaskEmail(string email) + { + if (string.IsNullOrEmpty(email) || !email.Contains("@")) + return email; + + string[] emailArr = email.Split('@'); + string domainExt = Path.GetExtension(email); + + string maskedEmail = string.Format("{0}****{1}@{2}****{3}{4}", + emailArr[0][0], + emailArr[0].Substring(emailArr[0].Length - 1), + emailArr[1][0], + emailArr[1].Substring(emailArr[1].Length - domainExt.Length - 1, 1), + domainExt + ); + + return maskedEmail; + } } \ No newline at end of file