Compare commits

..

No commits in common. 'master' and 'Api' have entirely different histories.
master ... Api

@ -7,57 +7,17 @@ trigger:
- push - push
steps: steps:
- name: build
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- cd code/server
- dotnet workload restore
- dotnet restore Server.sln
- dotnet build Server.sln -c Release --no-restore
- dotnet publish Server.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release
- name: tests
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- cd code/server
- dotnet restore Server.sln
- dotnet test Server.sln --no-restore
depends_on: [build]
- name: code-analysis
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dronesonarplugin-dotnet6
commands:
- cd code/server
- dotnet workload restore
- dotnet restore Server.sln
- dotnet sonarscanner begin /k:PongSrv /d:sonar.host.url=$${PLUGIN_SONAR_HOST} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions="Tests/**,DataBase/Program.cs,DataBase/Migrations/**,DataBase/DataManager/**,DataBase/Context/PongDbContextWithStub.cs" /d:sonar.login=$${PLUGIN_SONAR_TOKEN}
- dotnet build Server.sln -c Release --no-restore
- dotnet test Server.sln --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
- dotnet publish Server.sln -c Release --no-restore -o CI_PROJECT_DIR/build/release
- dotnet sonarscanner end /d:sonar.login=$${PLUGIN_SONAR_TOKEN}
secrets: [ SECRET_SONAR_LOGIN ]
settings:
# accessible en ligne de commande par ${PLUGIN_SONAR_HOST}
sonar_host: https://codefirst.iut.uca.fr/sonar/
# accessible en ligne de commande par ${PLUGIN_SONAR_TOKEN}
sonar_token:
from_secret: SECRET_SONAR_LOGIN
depends_on: [tests]
- name: build-docker-image - name: build-docker-image
image: plugins/docker image: plugins/docker
settings: settings:
dockerfile: code/server/Dockerfile dockerfile: code/Dockerfile
context: code/server context: code/
registry: hub.codefirst.iut.uca.fr registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/leap-hit-team/leap-hit-server repo: hub.codefirst.iut.uca.fr/leap-hit-team/leap-hit-server
username: username:
from_secret: SECRET_REGISTRY_USERNAME from_secret: SECRET_REGISTRY_USERNAME
password: password:
from_secret: SECRET_REGISTRY_PASSWORD from_secret: SECRET_REGISTRY_PASSWORD
depends_on: [tests]
# container deployment # container deployment
- name: deploy-server - name: deploy-server
@ -68,24 +28,4 @@ steps:
COMMAND: create COMMAND: create
OVERWRITE: true OVERWRITE: true
ADMINS: brunoda_costa_cunha,noanrandon,ramikhedair,lorisperret,hugolivet ADMINS: brunoda_costa_cunha,noanrandon,ramikhedair,lorisperret,hugolivet
depends_on: [ build-docker-image ]
# database container deployment
- name: deploy-container-mysql
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: mariadb:10
CONTAINERNAME: mysql
COMMAND: create
# OVERWRITE: false
PRIVATE: true
CODEFIRST_CLIENTDRONE_ENV_MARIADB_ROOT_PASSWORD:
from_secret: db_root_password
CODEFIRST_CLIENTDRONE_ENV_MARIADB_DATABASE:
from_secret: db_database
CODEFIRST_CLIENTDRONE_ENV_MARIADB_USER:
from_secret: db_user
CODEFIRST_CLIENTDRONE_ENV_MARIADB_PASSWORD:
from_secret: db_password
ADMINS: noanrandon,hugolivet,ramikhedair,lorisperret,brunoda_costa_cunha
depends_on: [ build-docker-image ] depends_on: [ build-docker-image ]

4
.gitignore vendored

@ -10,8 +10,6 @@
*.userosscache *.userosscache
*.sln.docstates *.sln.docstates
Server.exe
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs
@ -397,4 +395,4 @@ FodyWeavers.xsd
*.msp *.msp
# JetBrains Rider # JetBrains Rider
*.sln.iml *.sln.iml

@ -1 +1 @@
# LeapHitServer # LeapHitServer

@ -108,7 +108,7 @@ namespace ApiLeapHit.Controllers
[HttpGet("Player/{id}")] [HttpGet("Player/{id}")]
public async Task<ActionResult<List<DTOChat>>> GetChatsByIdPlayer(string id) public async Task<ActionResult<List<DTOChat>>> GetChatsByIdPlayer(int id)
{ {
try try
{ {
@ -135,7 +135,7 @@ namespace ApiLeapHit.Controllers
} }
[HttpGet("Players/{idPlayer1}/{idPlayer2}")] [HttpGet("Players/{idPlayer1}/{idPlayer2}")]
public async Task<ActionResult<List<DTOChat>>> GetChatsByIdPlayers(string idPlayer1, string idPlayer2) public async Task<ActionResult<List<DTOChat>>> GetChatsByIdPlayers(int idPlayer1, int idPlayer2)
{ {
try try
{ {

@ -95,14 +95,13 @@ namespace ApiLeapHit.Controllers
//} //}
[HttpGet("Player/{id}")] [HttpGet("Player/{id}")]
public async Task<ActionResult<IEnumerable<DTOGame>>> GetGameByIdPlayer(string id) public async Task<ActionResult<IEnumerable<DTOGame>>> GetGameByIdPlayer(int id)
{ {
try try
{ {
var games = await _dataManager.GetGameById(id); var games = await _dataManager.GetGameById(id);
if (games == null || games.Count == 0) if (games == null || games.Count == 0)
{ {
var message = $"Aucune game trouvée pour le joueur avec l'id {id}."; var message = $"Aucune game trouvée pour le joueur avec l'id {id}.";
_logger.LogInformation(message); _logger.LogInformation(message);

@ -1,56 +0,0 @@
using DataBase.DataManager;
using DataBase.Entity;
using DTO.Factory;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net;
namespace ApiLeapHit.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PlayersConnexionController : Controller
{
private readonly DbDataManager _dataManager;
private readonly ILogger<PlayersConnexionController> _logger;
public PlayersConnexionController(DbDataManager dataManager, ILogger<PlayersConnexionController> logger)
{
_dataManager = dataManager;
_logger = logger;
}
[HttpGet("{idIdentification}")]
public async Task<ActionResult<ApiResponse<string>>> CreatePlayer(string idIdentification)
{
try
{
if (!idIdentification.Equals("K02q7naLzjmodzAFfoSO4mPydr7W5hydPMrHtA6D"))
{
return StatusCode((int)HttpStatusCode.NotFound, new ApiResponse("Le numéro n'est pas correct."));
}
var player = new Player();
string id;
do
{
// Générer un id unique avec des chiffres et des lettres
id = Guid.NewGuid().ToString("N").Substring(0, 6);
}
while (await _dataManager.GetPlayer(id) != null);
player.playerId = id;
player.name = id;
player.timePlayed = 0;
player.nbBallTouchTotal = 0;
await _dataManager.AddPlayer(player);
//var response = new ApiResponse<string>($"Le joueur a été créé avec succès. Id du joueur : {id}.", id);
return Ok(id);
}
catch (Exception ex)
{
_logger.LogError(ex, "Une erreur est survenue lors de la création du joueur.");
return StatusCode((int)HttpStatusCode.InternalServerError, new ApiResponse("Une erreur est survenue lors de la création du joueur."));
}
}
}
}

@ -22,6 +22,32 @@ namespace ApiLeapHit.Controllers
_logger = logger; _logger = logger;
} }
[HttpPost]
public async Task<ActionResult<ApiResponse<string>>> CreatePlayer()
{
try
{
var player = new Player();
string id;
do
{
// Générer un id unique avec des chiffres et des lettres
id = Guid.NewGuid().ToString("N");
}
while (await _dataManager.GetPlayer(id) != null);
player.playerId = id;
await _dataManager.AddPlayer(player);
var response = new ApiResponse<string>($"Le joueur a été créé avec succès. Id du joueur : {id}.", id);
return Ok(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "Une erreur est survenue lors de la création du joueur.");
return StatusCode((int)HttpStatusCode.InternalServerError, new ApiResponse("Une erreur est survenue lors de la création du joueur."));
}
}
[HttpGet("{id}")] [HttpGet("{id}")]
public async Task<ActionResult<ApiResponse<DTOPlayer>>> GetPlayer(string id) public async Task<ActionResult<ApiResponse<DTOPlayer>>> GetPlayer(string id)
{ {

@ -14,8 +14,8 @@ namespace ApiLeapHit.Mapper
nbMaxEchanges = game.nbMaxEchanges, nbMaxEchanges = game.nbMaxEchanges,
playerWinner = game.winner, playerWinner = game.winner,
playerLoser = game.loser, playerLoser = game.loser,
scoreLoser = game.scoreLoser, scoreLoser = game.loser,
scoreWinner = game.scoreWinner scoreWinner = game.winner
}; };
return dtoGame; return dtoGame;
} }

@ -1,6 +1,4 @@
using DataBase.Context;
using DataBase.DataManager; using DataBase.DataManager;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -10,14 +8,7 @@ builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<DbDataManager>(); builder.Services.AddScoped<DbDataManager>();
var context = new PongDbContext(); //ou une autre classe dérivant de TheDbContext
await context.Database.EnsureCreatedAsync();
//builder.Services.AddSingleton<IDataManager, StubData>(); //builder.Services.AddSingleton<IDataManager, StubData>();
// Add logging // Add logging
@ -26,11 +17,11 @@ builder.Logging.AddConsole();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
//{ {
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
//} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();

@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -1,46 +0,0 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to LeapHit Multiplayer - Client");
StartClient();
}
static void StartClient()
{
//IPEndPoint serverEndPoint = new IPEndPoint(Dns.GetHostAddresses("hulivet.fr").FirstOrDefault(), 3131);
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("192.168.205.58"), 3131);
UdpClient client = new UdpClient();
// Send connection message to server
string connectionMessage = "Connect";
byte[] connectionData = Encoding.ASCII.GetBytes(connectionMessage);
client.Send(connectionData, connectionData.Length, serverEndPoint);
// Receive connection message from server
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receivedData = client.Receive(ref remoteEndPoint);
string receivedPort = Encoding.ASCII.GetString(receivedData);
Console.WriteLine("Received port: " + receivedPort);
// Send data to server
string message = "";
while (message != "exit")
{
serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), int.Parse(receivedPort));
Console.Write("Enter message to send (or 'exit' to quit): ");
message = Console.ReadLine();
byte[] data = Encoding.ASCII.GetBytes(message);
client.Send(data, data.Length, serverEndPoint);
}
// Close client
client.Close();
}
}

@ -1,7 +1,5 @@
using DataBase.Entity; using DataBase.Entity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using System.Reflection;
namespace DataBase.Context namespace DataBase.Context
{ {
@ -15,32 +13,13 @@ namespace DataBase.Context
public PongDbContext() { } public PongDbContext() { }
public PongDbContext(DbContextOptions<PongDbContext> options) : base(options) { } public PongDbContext(DbContextOptions<PongDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
modelBuilder.Entity<Player>().ToTable("Players"); //base.OnConfiguring(optionsBuilder);
modelBuilder.Entity<Game>().ToTable("Games");
modelBuilder.Entity<Message>().ToTable("Messages");
modelBuilder.Entity<Chat>().ToTable("Chats");
}
protected override async void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
if (!optionsBuilder.IsConfigured) if (!optionsBuilder.IsConfigured)
{ {
//optionsBuilder.UseNpgsql(@"host=localhost;database=postgres;user id=postgres;password=1234;"); optionsBuilder.UseSqlite($"Data Source=C:\\Users\\noanr\\source\\repos\\leap-hit-server\\code\\server\\DataBase\\PongDB.db");
//string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..\\..\\..\\..\\DataBase\\PongDB.db");
//optionsBuilder.UseSqlite($"Data Source={path}");
var dbDatabase = Environment.GetEnvironmentVariable("MARIADB_DATABASE", EnvironmentVariableTarget.Process);
var dbUser = Environment.GetEnvironmentVariable("MARIADB_USER", EnvironmentVariableTarget.Process);
var dbPassword = Environment.GetEnvironmentVariable("MARIADB_PASSWORD", EnvironmentVariableTarget.Process);
var dbServer = Environment.GetEnvironmentVariable("DB_SERVER", EnvironmentVariableTarget.Process);
Debug.WriteLine(dbPassword);
optionsBuilder.UseMySql($"server=leap-hit-team-mysql;port=3306;user=leaphit;password=leaphit;database=leaphit", new MySqlServerVersion(new Version(10, 11, 1)));
} }
} }
} }

@ -9,15 +9,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -10,9 +10,9 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace DataBase.Migrations namespace DataBase.Migrations
{ {
[DbContext(typeof(PongDbContext))] [DbContext(typeof(PongDbContextWithStub))]
[Migration("20230316103854_mymigrations")] [Migration("20230228121953_Migrations")]
partial class mymigrations partial class Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -26,13 +26,11 @@ namespace DataBase.Migrations
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("player1") b.Property<int>("player1")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<string>("player2") b.Property<int>("player2")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.HasKey("chatId"); b.HasKey("chatId");
@ -40,7 +38,15 @@ namespace DataBase.Migrations
b.HasIndex("player2"); b.HasIndex("player2");
b.ToTable("Chats", (string)null); b.ToTable("Chats");
b.HasData(
new
{
chatId = 1,
player1 = 1,
player2 = 2
});
}); });
modelBuilder.Entity("DataBase.Entity.Game", b => modelBuilder.Entity("DataBase.Entity.Game", b =>
@ -52,9 +58,8 @@ namespace DataBase.Migrations
b.Property<int>("durationGame") b.Property<int>("durationGame")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("loser") b.Property<int>("loser")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<int>("nbMaxEchanges") b.Property<int>("nbMaxEchanges")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -65,9 +70,8 @@ namespace DataBase.Migrations
b.Property<int>("scoreWinner") b.Property<int>("scoreWinner")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("winner") b.Property<int>("winner")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.HasKey("gameId"); b.HasKey("gameId");
@ -75,7 +79,19 @@ namespace DataBase.Migrations
b.HasIndex("winner"); b.HasIndex("winner");
b.ToTable("Games", (string)null); b.ToTable("Games");
b.HasData(
new
{
gameId = 1,
durationGame = 65,
loser = 2,
nbMaxEchanges = 5,
scoreLoser = 2,
scoreWinner = 6,
winner = 1
});
}); });
modelBuilder.Entity("DataBase.Entity.Message", b => modelBuilder.Entity("DataBase.Entity.Message", b =>
@ -91,9 +107,8 @@ namespace DataBase.Migrations
.IsRequired() .IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("player") b.Property<int>("player")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<DateTime>("timestamp") b.Property<DateTime>("timestamp")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -104,13 +119,32 @@ namespace DataBase.Migrations
b.HasIndex("player"); b.HasIndex("player");
b.ToTable("Messages", (string)null); b.ToTable("Messages");
b.HasData(
new
{
messageId = 1,
chat = 1,
message = "Salut mon gars !",
player = 1,
timestamp = new DateTime(2023, 2, 16, 17, 5, 12, 0, DateTimeKind.Unspecified)
},
new
{
messageId = 2,
chat = 1,
message = "Comment tu vas ?",
player = 2,
timestamp = new DateTime(2023, 2, 16, 17, 12, 35, 0, DateTimeKind.Unspecified)
});
}); });
modelBuilder.Entity("DataBase.Entity.Player", b => modelBuilder.Entity("DataBase.Entity.Player", b =>
{ {
b.Property<string>("playerId") b.Property<int>("playerId")
.HasColumnType("TEXT"); .ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("name") b.Property<string>("name")
.IsRequired() .IsRequired()
@ -124,7 +158,23 @@ namespace DataBase.Migrations
b.HasKey("playerId"); b.HasKey("playerId");
b.ToTable("Players", (string)null); b.ToTable("Players");
b.HasData(
new
{
playerId = 1,
name = "Rami",
nbBallTouchTotal = 20,
timePlayed = 120
},
new
{
playerId = 2,
name = "Hugo",
nbBallTouchTotal = 90,
timePlayed = 250
});
}); });
modelBuilder.Entity("DataBase.Entity.Chat", b => modelBuilder.Entity("DataBase.Entity.Chat", b =>

@ -3,10 +3,12 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace DataBase.Migrations namespace DataBase.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class mymigrations : Migration public partial class Migrations : Migration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
@ -15,7 +17,8 @@ namespace DataBase.Migrations
name: "Players", name: "Players",
columns: table => new columns: table => new
{ {
playerId = table.Column<string>(type: "TEXT", nullable: false), playerId = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
name = table.Column<string>(type: "TEXT", nullable: false), name = table.Column<string>(type: "TEXT", nullable: false),
nbBallTouchTotal = table.Column<int>(type: "INTEGER", nullable: false), nbBallTouchTotal = table.Column<int>(type: "INTEGER", nullable: false),
timePlayed = table.Column<int>(type: "INTEGER", nullable: false) timePlayed = table.Column<int>(type: "INTEGER", nullable: false)
@ -31,8 +34,8 @@ namespace DataBase.Migrations
{ {
chatId = table.Column<int>(type: "INTEGER", nullable: false) chatId = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true), .Annotation("Sqlite:Autoincrement", true),
player1 = table.Column<string>(type: "TEXT", nullable: false), player1 = table.Column<int>(type: "INTEGER", nullable: false),
player2 = table.Column<string>(type: "TEXT", nullable: false) player2 = table.Column<int>(type: "INTEGER", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -59,8 +62,8 @@ namespace DataBase.Migrations
.Annotation("Sqlite:Autoincrement", true), .Annotation("Sqlite:Autoincrement", true),
durationGame = table.Column<int>(type: "INTEGER", nullable: false), durationGame = table.Column<int>(type: "INTEGER", nullable: false),
nbMaxEchanges = table.Column<int>(type: "INTEGER", nullable: false), nbMaxEchanges = table.Column<int>(type: "INTEGER", nullable: false),
winner = table.Column<string>(type: "TEXT", nullable: false), winner = table.Column<int>(type: "INTEGER", nullable: false),
loser = table.Column<string>(type: "TEXT", nullable: false), loser = table.Column<int>(type: "INTEGER", nullable: false),
scoreWinner = table.Column<int>(type: "INTEGER", nullable: false), scoreWinner = table.Column<int>(type: "INTEGER", nullable: false),
scoreLoser = table.Column<int>(type: "INTEGER", nullable: false) scoreLoser = table.Column<int>(type: "INTEGER", nullable: false)
}, },
@ -89,7 +92,7 @@ namespace DataBase.Migrations
.Annotation("Sqlite:Autoincrement", true), .Annotation("Sqlite:Autoincrement", true),
message = table.Column<string>(type: "TEXT", nullable: false), message = table.Column<string>(type: "TEXT", nullable: false),
timestamp = table.Column<DateTime>(type: "TEXT", nullable: false), timestamp = table.Column<DateTime>(type: "TEXT", nullable: false),
player = table.Column<string>(type: "TEXT", nullable: false), player = table.Column<int>(type: "INTEGER", nullable: false),
chat = table.Column<int>(type: "INTEGER", nullable: false) chat = table.Column<int>(type: "INTEGER", nullable: false)
}, },
constraints: table => constraints: table =>
@ -109,6 +112,34 @@ namespace DataBase.Migrations
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.InsertData(
table: "Players",
columns: new[] { "playerId", "name", "nbBallTouchTotal", "timePlayed" },
values: new object[,]
{
{ 1, "Rami", 20, 120 },
{ 2, "Hugo", 90, 250 }
});
migrationBuilder.InsertData(
table: "Chats",
columns: new[] { "chatId", "player1", "player2" },
values: new object[] { 1, 1, 2 });
migrationBuilder.InsertData(
table: "Games",
columns: new[] { "gameId", "durationGame", "loser", "nbMaxEchanges", "scoreLoser", "scoreWinner", "winner" },
values: new object[] { 1, 65, 2, 5, 2, 6, 1 });
migrationBuilder.InsertData(
table: "Messages",
columns: new[] { "messageId", "chat", "message", "player", "timestamp" },
values: new object[,]
{
{ 1, 1, "Salut mon gars !", 1, new DateTime(2023, 2, 16, 17, 5, 12, 0, DateTimeKind.Unspecified) },
{ 2, 1, "Comment tu vas ?", 2, new DateTime(2023, 2, 16, 17, 12, 35, 0, DateTimeKind.Unspecified) }
});
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Chats_player1", name: "IX_Chats_player1",
table: "Chats", table: "Chats",

@ -9,8 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace DataBase.Migrations namespace DataBase.Migrations
{ {
[DbContext(typeof(PongDbContext))] [DbContext(typeof(PongDbContextWithStub))]
partial class PongDbContextModelSnapshot : ModelSnapshot partial class PongDbContextWithStubModelSnapshot : ModelSnapshot
{ {
protected override void BuildModel(ModelBuilder modelBuilder) protected override void BuildModel(ModelBuilder modelBuilder)
{ {
@ -23,13 +23,11 @@ namespace DataBase.Migrations
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("player1") b.Property<int>("player1")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<string>("player2") b.Property<int>("player2")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.HasKey("chatId"); b.HasKey("chatId");
@ -37,7 +35,15 @@ namespace DataBase.Migrations
b.HasIndex("player2"); b.HasIndex("player2");
b.ToTable("Chats", (string)null); b.ToTable("Chats");
b.HasData(
new
{
chatId = 1,
player1 = 1,
player2 = 2
});
}); });
modelBuilder.Entity("DataBase.Entity.Game", b => modelBuilder.Entity("DataBase.Entity.Game", b =>
@ -49,9 +55,8 @@ namespace DataBase.Migrations
b.Property<int>("durationGame") b.Property<int>("durationGame")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("loser") b.Property<int>("loser")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<int>("nbMaxEchanges") b.Property<int>("nbMaxEchanges")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -62,9 +67,8 @@ namespace DataBase.Migrations
b.Property<int>("scoreWinner") b.Property<int>("scoreWinner")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("winner") b.Property<int>("winner")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.HasKey("gameId"); b.HasKey("gameId");
@ -72,7 +76,19 @@ namespace DataBase.Migrations
b.HasIndex("winner"); b.HasIndex("winner");
b.ToTable("Games", (string)null); b.ToTable("Games");
b.HasData(
new
{
gameId = 1,
durationGame = 65,
loser = 2,
nbMaxEchanges = 5,
scoreLoser = 2,
scoreWinner = 6,
winner = 1
});
}); });
modelBuilder.Entity("DataBase.Entity.Message", b => modelBuilder.Entity("DataBase.Entity.Message", b =>
@ -88,9 +104,8 @@ namespace DataBase.Migrations
.IsRequired() .IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("player") b.Property<int>("player")
.IsRequired() .HasColumnType("INTEGER");
.HasColumnType("TEXT");
b.Property<DateTime>("timestamp") b.Property<DateTime>("timestamp")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -101,13 +116,32 @@ namespace DataBase.Migrations
b.HasIndex("player"); b.HasIndex("player");
b.ToTable("Messages", (string)null); b.ToTable("Messages");
b.HasData(
new
{
messageId = 1,
chat = 1,
message = "Salut mon gars !",
player = 1,
timestamp = new DateTime(2023, 2, 16, 17, 5, 12, 0, DateTimeKind.Unspecified)
},
new
{
messageId = 2,
chat = 1,
message = "Comment tu vas ?",
player = 2,
timestamp = new DateTime(2023, 2, 16, 17, 12, 35, 0, DateTimeKind.Unspecified)
});
}); });
modelBuilder.Entity("DataBase.Entity.Player", b => modelBuilder.Entity("DataBase.Entity.Player", b =>
{ {
b.Property<string>("playerId") b.Property<int>("playerId")
.HasColumnType("TEXT"); .ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("name") b.Property<string>("name")
.IsRequired() .IsRequired()
@ -121,7 +155,23 @@ namespace DataBase.Migrations
b.HasKey("playerId"); b.HasKey("playerId");
b.ToTable("Players", (string)null); b.ToTable("Players");
b.HasData(
new
{
playerId = 1,
name = "Rami",
nbBallTouchTotal = 20,
timePlayed = 120
},
new
{
playerId = 2,
name = "Hugo",
nbBallTouchTotal = 90,
timePlayed = 250
});
}); });
modelBuilder.Entity("DataBase.Entity.Chat", b => modelBuilder.Entity("DataBase.Entity.Chat", b =>

Binary file not shown.

@ -1,3 +1,5 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app WORKDIR /app
EXPOSE 80 EXPOSE 80

@ -11,16 +11,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DTO", "DTO\DTO.csproj", "{B
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataBase", "DataBase\DataBase.csproj", "{FCCE7DEC-1F7B-4C66-8C61-3FCB668F9008}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataBase", "DataBase\DataBase.csproj", "{FCCE7DEC-1F7B-4C66-8C61-3FCB668F9008}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestControleurs", "TestControleurs\TestControleurs.csproj", "{A9DFF203-7F27-44BA-A460-F65C01D0EDFD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestControleurs", "TestControleurs\TestControleurs.csproj", "{A9DFF203-7F27-44BA-A460-F65C01D0EDFD}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{12A97D16-34BB-4D4F-9F76-D74061A9BA77}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{12A97D16-34BB-4D4F-9F76-D74061A9BA77}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientConsole", "ClientConsole\ClientConsole.csproj", "{33F7C629-F92B-459C-BCC5-6A4601D6D9EA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{CA1465F2-A006-4AF6-8231-59DB00963BD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsDatabase", "TestsDatabase\TestsDatabase.csproj", "{EDAC56C7-0AC9-465A-A361-63347F435327}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -47,25 +41,12 @@ Global
{A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU {A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU {A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Release|Any CPU.Build.0 = Release|Any CPU {A9DFF203-7F27-44BA-A460-F65C01D0EDFD}.Release|Any CPU.Build.0 = Release|Any CPU
{33F7C629-F92B-459C-BCC5-6A4601D6D9EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33F7C629-F92B-459C-BCC5-6A4601D6D9EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33F7C629-F92B-459C-BCC5-6A4601D6D9EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33F7C629-F92B-459C-BCC5-6A4601D6D9EA}.Release|Any CPU.Build.0 = Release|Any CPU
{CA1465F2-A006-4AF6-8231-59DB00963BD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA1465F2-A006-4AF6-8231-59DB00963BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA1465F2-A006-4AF6-8231-59DB00963BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA1465F2-A006-4AF6-8231-59DB00963BD0}.Release|Any CPU.Build.0 = Release|Any CPU
{EDAC56C7-0AC9-465A-A361-63347F435327}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDAC56C7-0AC9-465A-A361-63347F435327}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDAC56C7-0AC9-465A-A361-63347F435327}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDAC56C7-0AC9-465A-A361-63347F435327}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{A9DFF203-7F27-44BA-A460-F65C01D0EDFD} = {12A97D16-34BB-4D4F-9F76-D74061A9BA77} {A9DFF203-7F27-44BA-A460-F65C01D0EDFD} = {12A97D16-34BB-4D4F-9F76-D74061A9BA77}
{EDAC56C7-0AC9-465A-A361-63347F435327} = {12A97D16-34BB-4D4F-9F76-D74061A9BA77}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4BE2DC93-D511-4DA9-9C47-F286E71354BA} SolutionGuid = {4BE2DC93-D511-4DA9-9C47-F286E71354BA}

@ -1,149 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using DataBase.Entity;
using Shared.DTO;
using System.Text.Json;
using Server;
using System.ComponentModel;
public class PongServer
{
//sert juste à stocker les connexions pour l'instant
static Dictionary<IPEndPoint, UdpClient> clients = new Dictionary<IPEndPoint, UdpClient>();
Dictionary<string, Room> rooms = new Dictionary<string, Room>();
int nextPort;
int listenPort;
public PongServer(int port = 3131)
{
nextPort = port + 1;
listenPort = port;
}
public void StartServer()
{
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Any, listenPort);
UdpClient serverSocket = new UdpClient(serverEndPoint);
Console.WriteLine("Server started, waiting for clients to connect...");
while (true)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receivedData = serverSocket.Receive(ref remoteEndPoint);
string fileJson = Encoding.UTF8.GetString(receivedData);
ObjectTransfert<Player> data = JsonSerializer.Deserialize<ObjectTransfert<Player>>(fileJson);
if (data.Informations.Action == Shared.DTO.Action.Host)
{
Host(data, remoteEndPoint, serverSocket, false);
}
if (data.Informations.Action == Shared.DTO.Action.Join)
{
var choisenRoom = rooms.FirstOrDefault(room => room.Key == data.Informations.IdRoom);
if(choisenRoom.Value != default)
{
Join(data, remoteEndPoint, serverSocket, choisenRoom.Value);
}
}
if (data.Informations.Action == Shared.DTO.Action.Connect) // Join = rejoindre un room , et Host ça va juste créer un room
{
var choisenRoom = rooms.FirstOrDefault(room => room.Value.Availaible);
Console.WriteLine("Connection " + choisenRoom.Key);
if (choisenRoom.Value != default )
{
Join(data, remoteEndPoint, serverSocket, choisenRoom.Value);
}
else
{
Host(data, remoteEndPoint, serverSocket, true);
}
}
Console.WriteLine("");
}
}
private void Host(ObjectTransfert<Player> data, IPEndPoint remoteEndPoint, UdpClient serverSocket, bool availaible)
{
var choisenRoom = rooms.FirstOrDefault(room => room.Value.Free);
var chosenPort = nextPort;
if (choisenRoom.Value != default)
{
chosenPort= choisenRoom.Value.Port;
rooms.Remove(choisenRoom.Key);
choisenRoom = default;
}
Room room = new Room(data.Data.playerId, availaible);
// Assign a unique port to the client
IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, chosenPort);
UdpClient clientSocket = new UdpClient(clientEndPoint);
room.playerHost = new KeyValuePair<Player,UdpClient>(data.Data,clientSocket);
room.NbPlayer++;
Console.WriteLine("New connection Host From " + remoteEndPoint.ToString());
room.Port = chosenPort;
if(chosenPort==nextPort)
{
nextPort++;
}
Tuple<int, bool> dataToSend = new Tuple<int, bool>(room.Port, true);
Console.WriteLine(JsonSerializer.Serialize(dataToSend));
// Send port message to client
byte[] connectionData = Encoding.ASCII.GetBytes(JsonSerializer.Serialize(dataToSend));
serverSocket.Send(connectionData, connectionData.Length, remoteEndPoint);
rooms[data.Data.playerId] = room;
Console.WriteLine("FIN HOST...............");
}
private void Join(ObjectTransfert<Player> data, IPEndPoint remoteEndPoint, UdpClient serverSocket, Room room)
{
room.playerJoin = new KeyValuePair<Player, UdpClient>(data.Data, room.playerHost.Value);
Console.WriteLine("New connection Client from " + remoteEndPoint.ToString());
Tuple<int, bool> dataToSend = new Tuple<int, bool>(room.Port, false);
Console.WriteLine(JsonSerializer.Serialize(dataToSend));
// Send port message to client
byte[] connectionData = Encoding.ASCII.GetBytes(JsonSerializer.Serialize(dataToSend));
serverSocket.Send(connectionData, connectionData.Length, remoteEndPoint);
room.PropertyChanged += room.OnReadyChanged;
room.NbPlayer++;
Console.WriteLine("FIN JOIN...............");
}
}

@ -1,21 +1,29 @@
using System; using System;
using System.Collections.Generic; using System.Net;
using System.Net; using System.Net.Sockets;
using System.Net.Sockets;
using System.Text;
using System.Threading; class Program
using DataBase.Entity; {
using Shared.DTO; static void Main(string[] args)
using System.Text.Json; {
using Server; Console.WriteLine("Welcome to LeapHit Multiplayer - Server");
StartServer();
class Program }
{
static void Main(string[] args) static void StartServer()
{ {
PongServer server = new PongServer(); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 3131);
Console.WriteLine("Welcome to LeapHit Multiplayer - Server"); UdpClient server = new UdpClient(endPoint);
server.StartServer(); Console.WriteLine("Server started, waiting for clients to connect...");
} Console.WriteLine(endPoint.Address.ToString());
} while (true)
{
IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = server.Receive(ref clientEndPoint);
string dataReceived = System.Text.Encoding.ASCII.GetString(data);
Console.WriteLine("Data received from client: " + dataReceived + " from " + clientEndPoint.ToString());
}
}
}

@ -1,194 +0,0 @@
using DataBase.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Shared.DTO;
using System.ComponentModel;
using System.Text.Json;
using static System.Formats.Asn1.AsnWriter;
namespace Server
{
public class Room : INotifyPropertyChanged
{
public Room(string id, bool availaible)
{
Id = id;
Availaible = availaible;
}
Tuple<int, int> ScoreImp = new(0, 0);
ObjectTransfert<Tuple<GameEntities, Tuple<int, int>>> data ;
public bool Availaible { get; set; }
public bool Free { get; set; }=false;
public event PropertyChangedEventHandler? PropertyChanged;
public string Id { get; set; }
public KeyValuePair <Player, UdpClient> playerHost;
public KeyValuePair <Player, UdpClient> playerJoin;
public int Port { get; set; }
public bool gameRunning=true ;
public int NbPlayer
{
get
{
return nbPlayer;
}
set
{
nbPlayer = value;
if (value >= 2)
{
NotifyPropertyChanged("nbPlayer");
}
}
}
private int nbPlayer;
protected void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void ReceiveMessages(UdpClient clientSocket1, UdpClient clientSocket2, IPEndPoint endpoint2, Semaphore semaphore,bool isHost)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
Thread secondsCount = new Thread(() => CountSeconds() );
bool isDisconected=false;
secondsCount.Start();
while ((ScoreImp.Item1<6 && ScoreImp.Item2 < 6) && gameRunning)
{
try
{
byte[] receivedData = clientSocket1.Receive(ref remoteEndPoint);
if (isHost) {
string fileJson = Encoding.UTF8.GetString(receivedData);
try
{
data = JsonSerializer.Deserialize<ObjectTransfert<Tuple<GameEntities, Tuple<int, int>>>>(fileJson);
ScoreImp = data.Data.Item2 != null ? data.Data.Item2 : ScoreImp;
}
catch (Exception ex) { }
}
semaphore.WaitOne();
clientSocket2.Send(receivedData, receivedData.Length, endpoint2);
semaphore.Release();
} catch (SocketException){
try
{
semaphore.Release();
}catch { }
isDisconected = true;
break;
}
}
//Tuple<GameEntities, Tuple<int, int>> game = new Tuple<GameEntities, Tuple<int, int>>(new GameEntities(new Tuple<float,float>(0,0),0), ScoreImp);
/* ObjectTransfert<Tuple<GameEntities, Tuple<int, int>>> data2 = new ObjectTransfert<Tuple<GameEntities, Tuple<int, int>>>() {
Informations = new Informations(Shared.DTO.Action.End, 0, typeof(Tuple<GameEntities, Tuple<int, int>>).ToString()),
Data = game
};*/
if (!isDisconected)
{
data.Informations.Action = Shared.DTO.Action.End;
string sendFinish = JsonSerializer.Serialize(data);
byte[] sendFinishByt = Encoding.ASCII.GetBytes(sendFinish);
try
{
clientSocket2.Send(sendFinishByt, sendFinishByt.Length, endpoint2);
}
catch (Exception ex) { }
}
if (isHost)
{
try
{
semaphore.Release();
}
catch { }
playerJoin.Value.Close();
}
else
{
playerHost.Value.Close();
}
Free = true;
Console.WriteLine("Game Finished Am i host " + isHost);
}
private void CountSeconds()
{
int seconds = 0;
while (seconds<=122)
{
seconds++;
Thread.Sleep(1000);
}
gameRunning = false;
}
async public void OnReadyChanged(object sender, PropertyChangedEventArgs e)
{
await Task.Run(() =>
{
Room room = sender as Room;
int maxPlayer = room.nbPlayer;
if (maxPlayer == 2)
{
room.Availaible = false;
IPEndPoint remoteEndPointHost = new IPEndPoint(IPAddress.Any, room.Port);
IPEndPoint remoteEndPointJoin = new IPEndPoint(IPAddress.Any, room.Port);
byte[] receivedDataHost = playerHost.Value.Receive(ref remoteEndPointHost);
byte[] receivedDataJoin = playerJoin.Value.Receive(ref remoteEndPointJoin);
playerJoin.Value.Send(receivedDataHost, receivedDataHost.Length, remoteEndPointHost);
playerHost.Value.Send(receivedDataJoin, receivedDataJoin.Length, remoteEndPointJoin);
Semaphore semaphore = new Semaphore(2, 2);
Thread receiveThread1 = new Thread(() => ReceiveMessages(playerHost.Value, playerJoin.Value, remoteEndPointJoin, semaphore,true));
Thread receiveThread2 = new Thread(() =>
{
ReceiveMessages(playerJoin.Value, playerHost.Value, remoteEndPointHost, semaphore,false);
});
receiveThread1.Start();
receiveThread2.Start();
receiveThread1.Join();
receiveThread2.Join();
}
});
}
}
}

@ -1,15 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> </Project>
<ProjectReference Include="..\DataBase\DataBase.csproj" />
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

@ -1,4 +0,0 @@
#! /bin/bash
mcs -out:Server.exe Program.cs
screen -d -m -S leapServer mono Server.exe

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO
{
public enum Action
{
Join,
Host,
Connect,
End,
SendPlayer,
RecivePlayer,
SendEntities,
SendScore
}
}

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO
{
public class GameEntities
{
public Tuple<float, float> Ball { get; set; }
public float Paddle { get; set; }
public GameEntities(Tuple<float, float> ball, float paddle)
{
Ball = ball;
Paddle = paddle;
}
}
}

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO
{
public class Informations
{
public Action Action { get; set; }
public long Frame { get; set; }
public string TypeData { get; set; }
public string? IdRoom { get; set; }
public Informations(Action action, long frame, string typeData, string? idRoom = null)
{
Action = action;
Frame = frame;
TypeData = typeData;
IdRoom = idRoom;
}
}
}

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared.DTO
{
public class ObjectTransfert<T>
{
public Informations Informations { get; set; }
public T Data { get; set; }
}
}

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -20,146 +20,146 @@ namespace TestControleurs
[TestClass] [TestClass]
public class UnitTestChats public class UnitTestChats
{ {
//private DbDataManager _dataManager = new DbDataManager(); private DbDataManager _dataManager = new DbDataManager();
//private readonly ILogger<ChatsController> _logger = new NullLogger<ChatsController>(); private readonly ILogger<ChatsController> _logger = new NullLogger<ChatsController>();
//[TestMethod] [TestMethod]
//public async Task AddChat_ReturnsOkResult_WhenChatIsAdded() public async Task AddChat_ReturnsOkResult_WhenChatIsAdded()
//{ {
// // Arrange // Arrange
// var player1 = new Player { playerId = 1, name = "Player1" }; var player1 = new Player { playerId = 1, name = "Player1" };
// var player2 = new Player { playerId = 2, name = "Player2" }; var player2 = new Player { playerId = 2, name = "Player2" };
// var dtoChat = new DTOChat { PlayerId1 = player1.playerId, PlayerId2 = player2.playerId }; var dtoChat = new DTOChat { PlayerId1 = player1.playerId, PlayerId2 = player2.playerId };
// var controller = new ChatsController(_dataManager, _logger); var controller = new ChatsController(_dataManager, _logger);
// // Act // Act
// var result = await controller.AddChat(dtoChat); var result = await controller.AddChat(dtoChat);
// var objectResult = result as ObjectResult; var objectResult = result as ObjectResult;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task AddChat_ReturnsBadRequestResult() public async Task AddChat_ReturnsBadRequestResult()
//{ {
// // Arrange // Arrange
// var nb = await _dataManager.GetNbChats(); var nb = await _dataManager.GetNbChats();
// var dtoChat = new DTOChat { PlayerId1 = 1, PlayerId2 = "test" }; var dtoChat = new DTOChat { PlayerId1 = 1, PlayerId2 = nb+10 };
// var controller = new ChatsController(_dataManager, _logger); var controller = new ChatsController(_dataManager, _logger);
// // Act // Act
// var result = await controller.AddChat(dtoChat); var result = await controller.AddChat(dtoChat);
// var objectResult = result as ObjectResult; var objectResult = result as ObjectResult;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode);
//} }
[TestMethod]
public async Task GetChats_ReturnsOkResult()
{
// Arrange
var controller = new ChatsController(_dataManager, _logger);
// Act
var result = await controller.GetChats();
var objectResult = (ObjectResult)result.Result;
var dtoChats = objectResult.Value as IEnumerable<DTOChat>;
// Assert
Assert.IsNotNull(objectResult);
Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
}
//[TestMethod] //[TestMethod]
//public async Task GetChats_ReturnsOkResult() //public async Task GetChats_ReturnsNotFoundResult()
//{ //{
// // Arrange // // Arrange
// var controller = new ChatsController(_dataManager, _logger); // var mockDataManager = new Mock<DbDataManager>();
// mockDataManager.Setup(dm => dm.GetChats()).ReturnsAsync(new List<Chat>());
// var controller = new ChatsController(mockDataManager.Object, _logger);
// // Act // // Act
// var result = await controller.GetChats(); // var result = await controller.GetChats();
// var objectResult = (ObjectResult)result.Result; // var objectResult = (ObjectResult)result.Result;
// var dtoChats = objectResult.Value as IEnumerable<DTOChat>;
// // Assert
// Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
//}
////[TestMethod]
////public async Task GetChats_ReturnsNotFoundResult()
////{
//// // Arrange
//// var mockDataManager = new Mock<DbDataManager>();
//// mockDataManager.Setup(dm => dm.GetChats()).ReturnsAsync(new List<Chat>());
//// var controller = new ChatsController(mockDataManager.Object, _logger);
//// // Act
//// var result = await controller.GetChats();
//// var objectResult = (ObjectResult)result.Result;
//// // Assert
//// Assert.IsNotNull(objectResult);
//// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
////}
//[TestMethod]
//public async Task GetChatById_ReturnsOkResult()
//{
// // Arrange
// var chat = new Chat { chatId = 1, player1 = 1, player2 = 2 };
// var controller = new ChatsController(_dataManager, _logger);
// // Act
// var result = await controller.GetChatById(chat.chatId);
// var objectResult = result.Result as ObjectResult;
// var dtoChat = objectResult.Value as DTOChat;
// // Assert
// Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
// Assert.IsNotNull(dtoChat);
// Assert.AreEqual(chat.chatId, dtoChat.chatId);
//}
//[TestMethod]
//public async Task GetChatById_ReturnsNotFoundResult()
//{
// // Arrange
// var chatId = 1000;
// var controller = new ChatsController(_dataManager, _logger);
// // Act
// var result = await controller.GetChatById(chatId);
// var objectResult = result.Result as ObjectResult;
// // Assert // // Assert
// Assert.IsNotNull(objectResult); // Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); // Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
//} //}
//[TestMethod] [TestMethod]
//public async Task RemoveChat_ReturnsOkResult() public async Task GetChatById_ReturnsOkResult()
//{ {
// // Arrange // Arrange
// var nb = await _dataManager.GetNbChats(); var chat = new Chat { chatId = 1, player1 = 1, player2 = 2 };
// var chat = new Chat { chatId = nb+1, player1 = 1, player2 = 2 }; var controller = new ChatsController(_dataManager, _logger);
// await _dataManager.AddChat(chat);
// var controller = new ChatsController(_dataManager, _logger); // Act
var result = await controller.GetChatById(chat.chatId);
// // Act var objectResult = result.Result as ObjectResult;
// var result = await controller.RemoveChat(chat.chatId); var dtoChat = objectResult.Value as DTOChat;
// var objectResult = result as ObjectResult;
// Assert
// // Assert Assert.IsNotNull(objectResult);
// Assert.IsNotNull(objectResult); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.IsNotNull(dtoChat);
//} Assert.AreEqual(chat.chatId, dtoChat.chatId);
}
//[TestMethod]
//public async Task RemoveChat_ReturnsNotFoundResult() [TestMethod]
//{ public async Task GetChatById_ReturnsNotFoundResult()
// // Arrange {
// var chatId = 1000; // Arrange
// var controller = new ChatsController(_dataManager, _logger); var chatId = 1000;
var controller = new ChatsController(_dataManager, _logger);
// // Act
// var result = await controller.RemoveChat(chatId); // Act
// var objectResult = result as ObjectResult; var result = await controller.GetChatById(chatId);
var objectResult = result.Result as ObjectResult;
// // Assert
// Assert.IsNotNull(objectResult); // Assert
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.IsNotNull(objectResult);
//} Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
}
[TestMethod]
public async Task RemoveChat_ReturnsOkResult()
{
// Arrange
var nb = await _dataManager.GetNbChats();
var chat = new Chat { chatId = nb+1, player1 = 1, player2 = 2 };
await _dataManager.AddChat(chat);
var controller = new ChatsController(_dataManager, _logger);
// Act
var result = await controller.RemoveChat(chat.chatId);
var objectResult = result as ObjectResult;
// Assert
Assert.IsNotNull(objectResult);
Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
}
[TestMethod]
public async Task RemoveChat_ReturnsNotFoundResult()
{
// Arrange
var chatId = 1000;
var controller = new ChatsController(_dataManager, _logger);
// Act
var result = await controller.RemoveChat(chatId);
var objectResult = result as ObjectResult;
// Assert
Assert.IsNotNull(objectResult);
Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
}
} }
} }

@ -19,111 +19,111 @@ namespace TestControleurs
[TestClass] [TestClass]
public class UnitTestGames public class UnitTestGames
{ {
//private DbDataManager _dataManager = new DbDataManager(); private DbDataManager _dataManager = new DbDataManager();
//private readonly ILogger<GamesController> _logger = new NullLogger<GamesController>(); private readonly ILogger<GamesController> _logger = new NullLogger<GamesController>();
//[TestMethod] [TestMethod]
//public async Task GetGame_ReturnsOkResult() public async Task GetGame_ReturnsOkResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbGames(); var nb = _dataManager.GetNbGames();
// var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = 1, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 }; var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = 1, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 };
// await _dataManager.AddGame(testGame); await _dataManager.AddGame(testGame);
// // Act // Act
// var result = await controller.GetGame(nb.Result + 1); var result = await controller.GetGame(nb.Result + 1);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task GetGame_ReturnsNotFoundResult() public async Task GetGame_ReturnsNotFoundResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbGames(); var nb = _dataManager.GetNbGames();
// // Act // Act
// var result = await controller.GetGame(nb.Result + 1); var result = await controller.GetGame(nb.Result + 1);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task RemoveGame_ReturnsNotFoundResult() public async Task RemoveGame_ReturnsNotFoundResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbGames(); var nb = _dataManager.GetNbGames();
// // Act // Act
// var result = await controller.RemoveGame(nb.Result + 1); var result = await controller.RemoveGame(nb.Result + 1);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task RemoveGame_ReturnsOKResult() public async Task RemoveGame_ReturnsOKResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbGames(); var nb = _dataManager.GetNbGames();
// var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = 1, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 }; var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = 1, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 };
// await _dataManager.AddGame(testGame); await _dataManager.AddGame(testGame);
// // Act // Act
// var result = await controller.RemoveGame(nb.Result + 1); var result = await controller.RemoveGame(nb.Result + 1);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task GetGameByIdPlayer_ReturnsOKResult() public async Task GetGameByIdPlayer_ReturnsOKResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbGames(); var nb = _dataManager.GetNbGames();
// var nbP = _dataManager.GetNbPlayers(); var nbP = _dataManager.GetNbPlayers();
// var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = nbP.Result, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 }; var testGame = new Game { gameId = nb.Result + 1, durationGame = 3, loser = nbP.Result, winner = 2, nbMaxEchanges = 33, scoreLoser = 5, scoreWinner = 6 };
// await _dataManager.AddGame(testGame); await _dataManager.AddGame(testGame);
// // Act // Act
// var result = await controller.GetGameByIdPlayer(nbP.Result); var result = await controller.GetGameByIdPlayer(nbP.Result);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
//} }
//[TestMethod] [TestMethod]
//public async Task GetGameByIdPlayer_ReturnsNotFoundResult() public async Task GetGameByIdPlayer_ReturnsNotFoundResult()
//{ {
// // Arrange // Arrange
// var controller = new GamesController(_dataManager, _logger); var controller = new GamesController(_dataManager, _logger);
// var nb = _dataManager.GetNbPlayers(); var nb = _dataManager.GetNbPlayers();
// // Act // Act
// var result = await controller.GetGameByIdPlayer(nb.Result + 1); var result = await controller.GetGameByIdPlayer(nb.Result + 1);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
//} }
//[HttpPost] //[HttpPost]
//public async Task<ActionResult> AddGame([FromBody] DTOGame dtoGame) //public async Task<ActionResult> AddGame([FromBody] DTOGame dtoGame)

@ -16,114 +16,114 @@ using System.Threading.Tasks;
namespace TestControleurs namespace TestControleurs
{ {
//[TestClass] [TestClass]
//public class UnitTestMessages public class UnitTestMessages
//{ {
// private DbDataManager _dataManager = new DbDataManager(); private DbDataManager _dataManager = new DbDataManager();
// private readonly ILogger<MessagesController> _logger = new NullLogger<MessagesController>(); private readonly ILogger<MessagesController> _logger = new NullLogger<MessagesController>();
// [TestMethod] [TestMethod]
// public async Task ReceiveMessage_ReturnsOkResult() public async Task ReceiveMessage_ReturnsOkResult()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// var testMessage = new Message { messageId = nb.Result+1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), player = 1 , chat =1}; var testMessage = new Message { messageId = nb.Result+1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), player = 1 , chat =1};
// await _dataManager.SendMessage(testMessage); await _dataManager.SendMessage(testMessage);
// // Act // Act
// var result = await controller.ReceiveMessage(1); var result = await controller.ReceiveMessage(1);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.OK, objectResult.StatusCode);
// } }
// [TestMethod] [TestMethod]
// public async Task ReceiveMessage_ReturnsNotFound() public async Task ReceiveMessage_ReturnsNotFound()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// // Act // Act
// var result = await controller.ReceiveMessage(nb.Result+1); var result = await controller.ReceiveMessage(nb.Result+1);
// var objectResult = (ObjectResult)result.Result; var objectResult = (ObjectResult)result.Result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
// } }
// [TestMethod] [TestMethod]
// public async Task RemoveMessage_ReturnsBadRequest() public async Task RemoveMessage_ReturnsBadRequest()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// // Act // Act
// var result = await controller.RemoveMessage(nb.Result + 1); var result = await controller.RemoveMessage(nb.Result + 1);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode);
// } }
// [TestMethod] [TestMethod]
// public async Task RemoveMessage_ReturnsOk() public async Task RemoveMessage_ReturnsOk()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// var testMessage = new Message { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), player = 1, chat = 1 }; var testMessage = new Message { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), player = 1, chat = 1 };
// // Act // Act
// var result = await controller.RemoveMessage(nb.Result + 1); var result = await controller.RemoveMessage(nb.Result + 1);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.BadRequest, objectResult.StatusCode);
// } }
// [TestMethod] [TestMethod]
// public async Task SendMessage_ReturnsCreated() public async Task SendMessage_ReturnsCreated()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// var testMessage = new DTOMessage { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), PlayerId = 1, ChatId = 1 }; var testMessage = new DTOMessage { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), PlayerId = 1, ChatId = 1 };
// // Act // Act
// var result = await controller.SendMessage(testMessage); var result = await controller.SendMessage(testMessage);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.Created, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.Created, objectResult.StatusCode);
// await controller.RemoveMessage(nb.Result + 1); await controller.RemoveMessage(nb.Result + 1);
// } }
// [TestMethod] [TestMethod]
// public async Task SendMessage_ReturnsNotFound() public async Task SendMessage_ReturnsNotFound()
// { {
// // Arrange // Arrange
// var controller = new MessagesController(_dataManager, _logger); var controller = new MessagesController(_dataManager, _logger);
// var nb = _dataManager.GetNbMessages(); var nb = _dataManager.GetNbMessages();
// var nbP = _dataManager.GetNbPlayers(); var nbP = _dataManager.GetNbPlayers();
// var testMessage = new DTOMessage { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), PlayerId = nb.Result+1, ChatId = 1 }; var testMessage = new DTOMessage { messageId = nb.Result + 1, message = "Test message", timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc), PlayerId = nb.Result+1, ChatId = 1 };
// // Act // Act
// var result = await controller.SendMessage(testMessage); var result = await controller.SendMessage(testMessage);
// var objectResult = (ObjectResult)result; var objectResult = (ObjectResult)result;
// // Assert // Assert
// Assert.IsNotNull(objectResult); Assert.IsNotNull(objectResult);
// Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode); Assert.AreEqual((int)HttpStatusCode.NotFound, objectResult.StatusCode);
// await controller.RemoveMessage(nb.Result + 1); await controller.RemoveMessage(nb.Result + 1);
// } }
//} }
} }

@ -1,150 +0,0 @@
using DataBase.Context;
using DataBase.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestsDatabase
{
public class TestsChat
{
[Fact]
public void Add_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_Database_Chats")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
context.Players.Add(player);
context.Players.Add(player2);
context.Chats.Add(chat);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
Assert.Equal(1, context.Chats.Count());
Assert.Equal(1, context.Chats.First().chatId);
}
}
[Fact]
public void Modify_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Modify_Test_Database_Chats")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
context.Players.Add(player);
context.Players.Add(player2);
context.Chats.Add(chat);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int chatid = 1;
Assert.Equal(1, context.Chats.Where(n => n.chatId.Equals(chatid)).Count());
var elementalist = context.Chats.Where(n => n.chatId.Equals(chatid)).First();
elementalist.player1 = "Loris1";
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int chatid = 1;
Assert.Equal(1, context.Chats.Where(n => n.chatId.Equals(chatid)).Count());
var elementalist = context.Chats.Where(n => n.chatId.Equals(chatid)).First();
Assert.Equal("Loris1", elementalist.player1);
}
}
[Fact]
public void Delete_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Delete_Test_Database_Chats")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
context.Players.Add(player);
context.Players.Add(player2);
context.Chats.Add(chat);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int chatid = 1;
Assert.Equal(1, context.Chats.Where(n => n.chatId.Equals(chatid)).Count());
context.Chats.Remove(context.Chats.Where(n => n.chatId.Equals(chatid)).First());
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int chatid = 1;
Assert.NotEqual(1, context.Chats.Where(n => n.chatId.Equals(chatid)).Count());
}
}
[Fact]
public void GetAllChat_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "GetAllSkin_Test_Database_Chats")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
Chat chat2 = new Chat { chatId = 2, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
context.Players.Add(player);
context.Players.Add(player2);
context.Chats.Add(chat);
context.Chats.Add(chat2);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
var chats = context.Chats.ToList();
Assert.Equal(2, chats.Count);
var classic = chats.FirstOrDefault(c => c.chatId == 1);
Assert.NotNull(classic);
Assert.Equal("Loris12345", classic.player1);
Assert.Equal("Rami12345", classic.player2);
var elementalist = chats.FirstOrDefault(c => c.chatId == 2);
Assert.NotNull(elementalist);
Assert.Equal("Loris12345", elementalist.player1);
Assert.Equal("Rami12345", elementalist.player2);
}
}
}
}

@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DataBase\DataBase.csproj" />
</ItemGroup>
</Project>

@ -1,150 +0,0 @@
using DataBase.Context;
using DataBase.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace TestsDatabase
{
public class TestsGame
{
[Fact]
public void Add_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_Database_Games")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player playerRami = new Player { playerId = "Rami12345", name = "The Lady Rami", nbBallTouchTotal = 9, timePlayed = 3 };
Game game = new Game { gameId = 1, durationGame = 2, nbMaxEchanges = 8, loser = "Loris12345", winner = "Rami12345", scoreLoser = 2, scoreWinner = 6, PlayerLoser = player, PlayerWinner = playerRami };
context.Players.Add(player);
context.Players.Add(playerRami);
context.Games.Add(game);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
Assert.Equal(1, context.Games.Count());
Assert.Equal(1, context.Games.First().gameId);
}
}
[Fact]
public void Modify_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Modify_Test_Database_Games")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player playerRami = new Player { playerId = "Rami12345", name = "The Lady Rami", nbBallTouchTotal = 9, timePlayed = 3 };
Game game = new Game { gameId = 1, durationGame = 2, nbMaxEchanges = 8, loser = "Loris12345", winner = "Rami12345", scoreLoser = 2, scoreWinner = 6, PlayerLoser = player, PlayerWinner = playerRami };
context.Players.Add(player);
context.Players.Add(playerRami);
context.Games.Add(game);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int idPong = 1;
Assert.Equal(1, context.Games.Where(n => n.gameId.Equals(idPong)).Count());
var elementalist = context.Games.Where(n => n.gameId.Equals(idPong)).First();
elementalist.nbMaxEchanges = 6;
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int idPong = 1;
Assert.Equal(1, context.Games.Where(n => n.gameId.Equals(idPong)).Count());
var elementalist = context.Games.Where(n => n.gameId.Equals(idPong)).First();
Assert.Equal(6, elementalist.nbMaxEchanges);
}
}
[Fact]
public void Delete_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Delete_Test_Database_Games")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player playerRami = new Player { playerId = "Rami12345", name = "The Lady Rami", nbBallTouchTotal = 9, timePlayed = 3 };
Game game = new Game { gameId = 1, durationGame = 2, nbMaxEchanges = 8, loser = "Loris12345", winner = "Rami12345", scoreLoser = 2, scoreWinner = 6, PlayerLoser = player, PlayerWinner = playerRami };
context.Players.Add(player);
context.Players.Add(playerRami);
context.Games.Add(game);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int idPong = 1;
Assert.Equal(1, context.Games.Where(n => n.gameId.Equals(idPong)).Count());
context.Games.Remove(context.Games.Where(n => n.gameId.Equals(idPong)).First());
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int idPong = 1;
Assert.NotEqual(1, context.Games.Where(n => n.gameId.Equals(idPong)).Count());
}
}
[Fact]
public void GetAllGame_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "GetAllSkin_Test_Database_Games")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player playerRami = new Player { playerId = "Rami12345", name = "The Lady Rami", nbBallTouchTotal = 9, timePlayed = 3 };
Game game = new Game { gameId = 1, durationGame = 2, nbMaxEchanges = 8, loser = "Loris12345", winner = "Rami12345", scoreLoser = 2, scoreWinner = 6, PlayerLoser = player, PlayerWinner = playerRami };
Game game2 = new Game { gameId = 2, durationGame = 2, nbMaxEchanges = 8, loser = "Loris12345", winner = "Rami12345", scoreLoser = 2, scoreWinner = 6, PlayerLoser = player, PlayerWinner = playerRami };
context.Players.Add(player);
context.Players.Add(playerRami);
context.Games.Add(game);
context.Games.Add(game2);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
var games = context.Games.ToList();
Assert.Equal(2, games.Count);
var classic = games.FirstOrDefault(c => c.gameId == 1);
Assert.NotNull(classic);
Assert.Equal(2, classic.durationGame);
Assert.Equal(2, classic.scoreLoser);
var elementalist = games.FirstOrDefault(c => c.gameId == 2);
Assert.NotNull(elementalist);
Assert.Equal(2, elementalist.durationGame);
Assert.Equal(2, elementalist.scoreLoser);
}
}
}
}

@ -1,143 +0,0 @@
using DataBase.Context;
using DataBase.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestsDatabase
{
public class TestsMessage
{
[Fact]
public void Add_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_Database_Messages")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
Message message = new Message { messageId = 1, ChatId = chat, message = "message", chat = 1, player = "Loris12345", PlayerId = player, timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc) };
context.Messages.Add(message);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
Assert.Equal(1, context.Messages.Count());
Assert.Equal(1, context.Messages.First().messageId);
}
}
[Fact]
public void Modify_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Modify_Test_Database_Messages")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
Message message = new Message { messageId = 1, ChatId = chat, message = "message", chat = 1, player = "Loris12345", PlayerId = player, timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc) };
context.Messages.Add(message);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int messageId = 1;
Assert.Equal(1, context.Messages.Where(n => n.messageId.Equals(messageId)).Count());
var elementalist = context.Messages.Where(n => n.messageId.Equals(messageId)).First();
elementalist.message = "Loris1";
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int messageId = 1;
Assert.Equal(1, context.Messages.Where(n => n.messageId.Equals(messageId)).Count());
var elementalist = context.Messages.Where(n => n.messageId.Equals(messageId)).First();
Assert.Equal("Loris1", elementalist.message);
}
}
[Fact]
public void Delete_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Delete_Test_Database_Messages")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
Message message = new Message { messageId = 1, ChatId = chat, message = "message", chat = 1, player = "Loris12345", PlayerId = player, timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc) };
context.Messages.Add(message);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int messageId = 1;
Assert.Equal(1, context.Messages.Where(n => n.messageId.Equals(messageId)).Count());
context.Messages.Remove(context.Messages.Where(n => n.messageId.Equals(messageId)).First());
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
int messageId = 1;
Assert.Equal(0, context.Messages.Where(n => n.messageId.Equals(messageId)).Count());
}
}
[Fact]
public void GetAllMessage_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "GetAllSkin_Test_Database_Messages")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Rami12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Chat chat = new Chat { chatId = 1, player1 = "Loris12345", player2 = "Rami12345", PlayerId1 = player, PlayerId2 = player2 };
Message message = new Message { messageId = 1, ChatId = chat, message = "message", chat = 1, player = "Loris12345", PlayerId = player, timestamp = new DateTime(2023, 3, 10, 14, 30, 0, DateTimeKind.Utc) };
context.Messages.Add(message);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
var messages = context.Messages.ToList();
Assert.Equal(1, messages.Count);
var classic = messages.FirstOrDefault(c => c.messageId == 1);
Assert.NotNull(classic);
Assert.Equal("Loris12345", classic.player);
Assert.Equal("message", classic.message);
}
}
}
}

@ -1,134 +0,0 @@
using DataBase.Context;
using DataBase.Entity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestsDatabase
{
public class TestsPlayer
{
[Fact]
public void Add_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Add_Test_Database_Players")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
context.Players.Add(player);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
Assert.Equal(1, context.Players.Count());
Assert.Equal("The Lady", context.Players.First().name);
}
}
[Fact]
public void Modify_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Modify_Test_Database_Players")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
context.Players.Add(player);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
string nameToFind = "the lady";
Assert.Equal(1, context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).Count());
var elementalist = context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).First();
elementalist.nbBallTouchTotal = 8;
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
string nameToFind = "the lady";
Assert.Equal(1, context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).Count());
var elementalist = context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).First();
Assert.Equal(8, elementalist.nbBallTouchTotal);
}
}
[Fact]
public void Delete_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "Delete_Test_Database_Players")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
context.Players.Add(player);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
string nameToFind = "the lady";
Assert.Equal(1, context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).Count());
context.Players.Remove(context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).First());
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
string nameToFind = "the lady";
Assert.NotEqual(1, context.Players.Where(n => n.name.ToLower().Contains(nameToFind)).Count());
}
}
[Fact]
public void GetAllPlayer_Test()
{
var options = new DbContextOptionsBuilder<PongDbContext>()
.UseInMemoryDatabase(databaseName: "GetAllSkin_Test_Database_Players")
.Options;
using (var context = new PongDbContext(options))
{
Player player = new Player { playerId = "Loris12345", name = "The Lady", nbBallTouchTotal = 8, timePlayed = 2 };
Player player2 = new Player { playerId = "Noan12345", name = "The Lady Noan", nbBallTouchTotal = 9, timePlayed = 5 };
context.Players.Add(player);
context.Players.Add(player2);
context.SaveChanges();
}
using (var context = new PongDbContext(options))
{
var players = context.Players.ToList();
Assert.Equal(2, players.Count);
var classic = players.FirstOrDefault(c => c.name == "The Lady Noan");
Assert.NotNull(classic);
Assert.Equal(9, classic.nbBallTouchTotal);
Assert.Equal(5, classic.timePlayed);
var elementalist = players.FirstOrDefault(c => c.name == "The Lady");
Assert.NotNull(elementalist);
Assert.Equal(8, elementalist.nbBallTouchTotal);
Assert.Equal(2, elementalist.timePlayed);
}
}
}
}

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<svg width="354" height="372" viewBox="0 0 354 372" xmlns="http://www.w3.org/2000/svg"> <svg width="354" height="338" viewBox="0 0 354 338" xmlns="http://www.w3.org/2000/svg">
<rect id="frame" x="0" y="0" width="354" height="372" fill="#fff" stroke="none" stroke-width="0"/> <rect id="frame" x="0" y="0" width="354" height="338" fill="#fff" stroke="none" stroke-width="0"/>
<!-- Association CHAT --> <!-- Association CHAT -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<path d="M181 169 C138.33 123.67 138.33 84.33 181 51" fill="none" stroke="#878787" stroke-width="2"/> <path d="M181 169 C138.33 123.67 138.33 84.33 181 51" fill="none" stroke="#878787" stroke-width="2"/>
<text x="155" y="110" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text> <text x="155" y="110" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text>
<path d="M181 169 C223.67 123.67 223.67 84.33 181 51" fill="none" stroke="#878787" stroke-width="2"/> <path d="M181 169 C223.67 123.67 223.67 84.33 181 51" fill="none" stroke="#878787" stroke-width="2"/>
@ -21,8 +21,8 @@
</g> </g>
<!-- Association WIN --> <!-- Association WIN -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<line x1="67" y1="304" x2="67" y2="169" stroke="#878787" stroke-width="2"/> <line x1="67" y1="287" x2="67" y2="169" stroke="#878787" stroke-width="2"/>
<text x="72" y="237" fill="#b2182b" font-family="Verdana" font-size="12">1,1</text> <text x="72" y="237" fill="#b2182b" font-family="Verdana" font-size="12">1,1</text>
<line x1="181" y1="169" x2="67" y2="169" stroke="#878787" stroke-width="2"/> <line x1="181" y1="169" x2="67" y2="169" stroke="#878787" stroke-width="2"/>
<text x="97" y="186" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text> <text x="97" y="186" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text>
@ -36,7 +36,7 @@
</g> </g>
<!-- Association POSSESS --> <!-- Association POSSESS -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<line x1="181" y1="169" x2="306" y2="169" stroke="#878787" stroke-width="2"/> <line x1="181" y1="169" x2="306" y2="169" stroke="#878787" stroke-width="2"/>
<text x="243" y="186" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text> <text x="243" y="186" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text>
<line x1="306" y1="51" x2="306" y2="169" stroke="#878787" stroke-width="2"/> <line x1="306" y1="51" x2="306" y2="169" stroke="#878787" stroke-width="2"/>
@ -51,22 +51,22 @@
</g> </g>
<!-- Association LOSE --> <!-- Association LOSE -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<line x1="67" y1="304" x2="181" y2="304" stroke="#878787" stroke-width="2"/> <line x1="67" y1="287" x2="181" y2="287" stroke="#878787" stroke-width="2"/>
<text x="130" y="321" fill="#b2182b" font-family="Verdana" font-size="12">1,1</text> <text x="130" y="304" fill="#b2182b" font-family="Verdana" font-size="12">1,1</text>
<line x1="181" y1="169" x2="181" y2="304" stroke="#878787" stroke-width="2"/> <line x1="181" y1="169" x2="181" y2="287" stroke="#878787" stroke-width="2"/>
<text x="186" y="237" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text> <text x="186" y="237" fill="#b2182b" font-family="Verdana" font-size="12">0,N</text>
<g> <g>
<path d="M191 279 a14 14 90 0 1 14 14 V304 h-48 V293 a14 14 90 0 1 14 -14" fill="#bababa" stroke="#bababa" stroke-width="0"/> <path d="M191 262 a14 14 90 0 1 14 14 V287 h-48 V276 a14 14 90 0 1 14 -14" fill="#bababa" stroke="#bababa" stroke-width="0"/>
<path d="M205 304 v11 a14 14 90 0 1 -14 14 H171 a14 14 90 0 1 -14 -14 V304 H48" fill="#e0e0e0" stroke="#e0e0e0" stroke-width="0"/> <path d="M205 287 v11 a14 14 90 0 1 -14 14 H171 a14 14 90 0 1 -14 -14 V287 H48" fill="#e0e0e0" stroke="#e0e0e0" stroke-width="0"/>
<rect x="157" y="279" width="48" height="50" fill="none" rx="14" stroke="#878787" stroke-width="2"/> <rect x="157" y="262" width="48" height="50" fill="none" rx="14" stroke="#878787" stroke-width="2"/>
<line x1="157" y1="304" x2="205" y2="304" stroke="#878787" stroke-width="1"/> <line x1="157" y1="287" x2="205" y2="287" stroke="#878787" stroke-width="1"/>
<text x="165" y="296.75" fill="#000" font-family="Verdana" font-size="12">LOSE</text> <text x="165" y="279.75" fill="#000" font-family="Verdana" font-size="12">LOSE</text>
</g> </g>
</g> </g>
<!-- Entity MESSAGE --> <!-- Entity MESSAGE -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<g> <g>
<rect x="267" y="9" width="78" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/> <rect x="267" y="9" width="78" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="267" y="34" width="78" height="59" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/> <rect x="267" y="34" width="78" height="59" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
@ -81,7 +81,7 @@
</g> </g>
<!-- Entity PLAYER --> <!-- Entity PLAYER -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<g> <g>
<rect x="124" y="118" width="114" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/> <rect x="124" y="118" width="114" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="124" y="143" width="114" height="77" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/> <rect x="124" y="143" width="114" height="77" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
@ -97,11 +97,11 @@
</g> </g>
<!-- Entity GAME --> <!-- Entity GAME -->
<g class="page_0_yKSJcw2n diagram_page" visibility="visible"> <g class="page_0_x0FZqot8 diagram_page" visibility="visible">
<g> <g>
<rect x="9" y="245" width="116" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/> <rect x="9" y="245" width="116" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="9" y="270" width="116" height="93" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/> <rect x="9" y="270" width="116" height="59" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="9" y="245" width="116" height="118" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/> <rect x="9" y="245" width="116" height="84" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="9" y1="270" x2="125" y2="270" stroke="#d6604d" stroke-width="1"/> <line x1="9" y1="270" x2="125" y2="270" stroke="#d6604d" stroke-width="1"/>
</g> </g>
<text x="49" y="262.75" fill="#000" font-family="Verdana" font-size="12">GAME</text> <text x="49" y="262.75" fill="#000" font-family="Verdana" font-size="12">GAME</text>
@ -109,30 +109,28 @@
<line x1="14" y1="290" x2="61" y2="290" stroke="#000" stroke-width="1"/> <line x1="14" y1="290" x2="61" y2="290" stroke="#000" stroke-width="1"/>
<text x="14" y="304.8" fill="#000" font-family="Verdana" font-size="12">durationGame</text> <text x="14" y="304.8" fill="#000" font-family="Verdana" font-size="12">durationGame</text>
<text x="14" y="321.8" fill="#000" font-family="Verdana" font-size="12">nbMaxExchanges</text> <text x="14" y="321.8" fill="#000" font-family="Verdana" font-size="12">nbMaxExchanges</text>
<text x="14" y="338.8" fill="#000" font-family="Verdana" font-size="12">scoreWinner</text>
<text x="14" y="355.8" fill="#000" font-family="Verdana" font-size="12">scoreLoser</text>
</g> </g>
<!-- Notes --> <!-- Notes -->
<script type="text/ecmascript"> <script type="text/ecmascript">
<![CDATA[ <![CDATA[
function show(evt, text) { function show(evt, text) {
var pos = (evt.target.getAttribute("y") < 327) ? "bottom" : "top"; var pos = (evt.target.getAttribute("y") < 293) ? "bottom" : "top";
var note = document.getElementById(pos + "_note_yKSJcw2n"); var note = document.getElementById(pos + "_note_x0FZqot8");
note.textContent = text; note.textContent = text;
note.setAttributeNS(null, "visibility", "visible"); note.setAttributeNS(null, "visibility", "visible");
document.getElementById(pos + "_overlay_yKSJcw2n").setAttributeNS(null, "visibility", "visible"); document.getElementById(pos + "_overlay_x0FZqot8").setAttributeNS(null, "visibility", "visible");
} }
function hide(evt) { function hide(evt) {
document.getElementById("top_note_yKSJcw2n").setAttributeNS(null, "visibility", "hidden"); document.getElementById("top_note_x0FZqot8").setAttributeNS(null, "visibility", "hidden");
document.getElementById("top_overlay_yKSJcw2n").setAttributeNS(null, "visibility", "hidden"); document.getElementById("top_overlay_x0FZqot8").setAttributeNS(null, "visibility", "hidden");
document.getElementById("bottom_note_yKSJcw2n").setAttributeNS(null, "visibility", "hidden"); document.getElementById("bottom_note_x0FZqot8").setAttributeNS(null, "visibility", "hidden");
document.getElementById("bottom_overlay_yKSJcw2n").setAttributeNS(null, "visibility", "hidden"); document.getElementById("bottom_overlay_x0FZqot8").setAttributeNS(null, "visibility", "hidden");
} }
]]> ]]>
</script> </script>
<rect id="top_overlay_yKSJcw2n" x="0" y="0" width="100%" height="40" fill="#4d4d4d" stroke-width="0" opacity="0.9" visibility="hidden"/> <rect id="top_overlay_x0FZqot8" x="0" y="0" width="100%" height="40" fill="#4d4d4d" stroke-width="0" opacity="0.9" visibility="hidden"/>
<text id="top_note_yKSJcw2n" text-anchor="middle" x="177" y="24" fill="#fff" font-family="Verdana" font-size="14" visibility="hidden"></text> <text id="top_note_x0FZqot8" text-anchor="middle" x="177" y="24" fill="#fff" font-family="Verdana" font-size="14" visibility="hidden"></text>
<rect id="bottom_overlay_yKSJcw2n" x="0" y="332" width="100%" height="40" fill="#4d4d4d" stroke-width="0" opacity="0.9" visibility="hidden"/> <rect id="bottom_overlay_x0FZqot8" x="0" y="298" width="100%" height="40" fill="#4d4d4d" stroke-width="0" opacity="0.9" visibility="hidden"/>
<text id="bottom_note_yKSJcw2n" text-anchor="middle" x="177" y="356" fill="#fff" font-family="Verdana" font-size="14" visibility="hidden"></text> <text id="bottom_note_x0FZqot8" text-anchor="middle" x="177" y="322" fill="#fff" font-family="Verdana" font-size="14" visibility="hidden"></text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="376" height="279" viewBox="0 0 376 279" xmlns="http://www.w3.org/2000/svg">
<rect id="frame" x="0" y="0" width="376" height="279" fill="#fff" stroke="none" stroke-width="0"/>
<!-- Entity PLAYER -->
<g class="page_0_6Lmn8J6X diagram_page" visibility="visible">
<g>
<rect x="41" y="17" width="114" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="41" y="42" width="114" height="77" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="41" y="17" width="114" height="102" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="41" y1="42" x2="155" y2="42" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="75" y="34.75" fill="#000" font-family="Verdana" font-size="12">PLAYER</text>
<text x="46" y="59.8" fill="#000" font-family="Verdana" font-size="12">playerId</text>
<line x1="46" y1="62" x2="97" y2="62" stroke="#000" stroke-width="1"/>
<text x="46" y="76.8" fill="#000" font-family="Verdana" font-size="12">name</text>
<text x="46" y="93.8" fill="#000" font-family="Verdana" font-size="12">nbBallTouchTotal</text>
<text x="46" y="110.8" fill="#000" font-family="Verdana" font-size="12">timePlayed</text>
</g>
<!-- Entity GAME -->
<g class="page_0_6Lmn8J6X diagram_page" visibility="visible">
<g>
<rect x="219" y="9" width="116" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="219" y="34" width="116" height="93" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="219" y="9" width="116" height="118" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="219" y1="34" x2="335" y2="34" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="259" y="26.75" fill="#000" font-family="Verdana" font-size="12">GAME</text>
<text x="224" y="51.8" fill="#000" font-family="Verdana" font-size="12">gameId</text>
<line x1="224" y1="54" x2="271" y2="54" stroke="#000" stroke-width="1"/>
<text x="224" y="68.8" fill="#000" font-family="Verdana" font-size="12">#playerWinner</text>
<text x="224" y="85.8" fill="#000" font-family="Verdana" font-size="12">#playerLoser</text>
<text x="224" y="102.8" fill="#000" font-family="Verdana" font-size="12">durationGame</text>
<text x="224" y="119.8" fill="#000" font-family="Verdana" font-size="12">nbMaxExchanges</text>
</g>
<!-- Entity CHAT -->
<g class="page_0_6Lmn8J6X diagram_page" visibility="visible">
<g>
<rect x="62" y="169" width="72" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="62" y="194" width="72" height="59" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="62" y="169" width="72" height="84" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="62" y1="194" x2="134" y2="194" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="81" y="186.75" fill="#000" font-family="Verdana" font-size="12">CHAT</text>
<text x="67" y="211.8" fill="#000" font-family="Verdana" font-size="12">chatId</text>
<line x1="67" y1="214" x2="106" y2="214" stroke="#000" stroke-width="1"/>
<text x="67" y="228.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
<text x="67" y="245.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
</g>
<!-- Entity MESSAGE -->
<g class="page_0_6Lmn8J6X diagram_page" visibility="visible">
<g>
<rect x="238" y="152" width="78" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="238" y="177" width="78" height="93" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="238" y="152" width="78" height="118" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="238" y1="177" x2="316" y2="177" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="247" y="169.75" fill="#000" font-family="Verdana" font-size="12">MESSAGE</text>
<text x="243" y="194.8" fill="#000" font-family="Verdana" font-size="12">messageId</text>
<line x1="243" y1="197" x2="310" y2="197" stroke="#000" stroke-width="1"/>
<text x="243" y="211.8" fill="#000" font-family="Verdana" font-size="12">message</text>
<text x="243" y="228.8" fill="#000" font-family="Verdana" font-size="12">timestamp</text>
<text x="243" y="245.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
<text x="243" y="262.8" fill="#000" font-family="Verdana" font-size="12">#idChat</text>
</g>
<!-- Link from &quot;playerId&quot; (GAME) to &quot;playerId&quot; (PLAYER) -->
<path d="M219 64.5 C187 60 197.67 55.5 155 55.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="155 55.5 167 49.5 163 55.5 167 61.5" fill="#878787" stroke-width="0"/>
<circle cx="219" cy="64.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (GAME) to &quot;playerId&quot; (PLAYER) -->
<path d="M219 81.5 C187 68.5 197.67 55.5 155 55.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="155 55.5 167 49.5 163 55.5 167 61.5" fill="#878787" stroke-width="0"/>
<circle cx="219" cy="81.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (CHAT) to &quot;playerId&quot; (PLAYER) -->
<path d="M62 224.5 C8 140 -13 55.5 41 55.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="41 55.5 29 61.5 33 55.5 29 49.5" fill="#878787" stroke-width="0"/>
<circle cx="62" cy="224.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (CHAT) to &quot;playerId&quot; (PLAYER) -->
<path d="M134 241.5 C188 148.5 209 55.5 155 55.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="155 55.5 167 49.5 163 55.5 167 61.5" fill="#878787" stroke-width="0"/>
<circle cx="134" cy="241.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (MESSAGE) to &quot;playerId&quot; (PLAYER) -->
<path d="M238 241.5 C196.5 148.5 210.33 55.5 155 55.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="155 55.5 167 49.5 163 55.5 167 61.5" fill="#878787" stroke-width="0"/>
<circle cx="238" cy="241.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;chatId&quot; (MESSAGE) to &quot;chatId&quot; (CHAT) -->
<path d="M238 258.5 C186 233 203.33 207.5 134 207.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="134 207.5 146 201.5 142 207.5 146 213.5" fill="#878787" stroke-width="0"/>
<circle cx="238" cy="258.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="512" height="288" viewBox="0 0 512 288" xmlns="http://www.w3.org/2000/svg">
<rect id="frame" x="0" y="0" width="512" height="288" fill="#fff" stroke="none" stroke-width="0"/>
<!-- Entity MESSAGE -->
<g class="page_0_vszgn7mY diagram_page" visibility="visible">
<g>
<rect x="239" y="9" width="78" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="239" y="34" width="78" height="93" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="239" y="9" width="78" height="118" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="239" y1="34" x2="317" y2="34" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="248" y="26.75" fill="#000" font-family="Verdana" font-size="12">MESSAGE</text>
<text x="244" y="51.8" fill="#000" font-family="Verdana" font-size="12">messageId</text>
<line x1="244" y1="54" x2="311" y2="54" stroke="#000" stroke-width="1"/>
<text x="244" y="68.8" fill="#000" font-family="Verdana" font-size="12">message</text>
<text x="244" y="85.8" fill="#000" font-family="Verdana" font-size="12">timestamp</text>
<text x="244" y="102.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
<text x="244" y="119.8" fill="#000" font-family="Verdana" font-size="12">#idChat</text>
</g>
<!-- Entity GAME -->
<g class="page_0_vszgn7mY diagram_page" visibility="visible">
<g>
<rect x="41" y="127" width="116" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="41" y="152" width="116" height="127" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="41" y="127" width="116" height="152" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="41" y1="152" x2="157" y2="152" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="81" y="144.75" fill="#000" font-family="Verdana" font-size="12">GAME</text>
<text x="46" y="169.8" fill="#000" font-family="Verdana" font-size="12">gameId</text>
<line x1="46" y1="172" x2="93" y2="172" stroke="#000" stroke-width="1"/>
<text x="46" y="186.8" fill="#000" font-family="Verdana" font-size="12">#playerWinner</text>
<text x="46" y="203.8" fill="#000" font-family="Verdana" font-size="12">#playerLoser</text>
<text x="46" y="220.8" fill="#000" font-family="Verdana" font-size="12">durationGame</text>
<text x="46" y="237.8" fill="#000" font-family="Verdana" font-size="12">nbMaxExchanges</text>
<text x="46" y="254.8" fill="#000" font-family="Verdana" font-size="12">scoreWinner</text>
<text x="46" y="271.8" fill="#000" font-family="Verdana" font-size="12">scoreLoser</text>
</g>
<!-- Entity PLAYER -->
<g class="page_0_vszgn7mY diagram_page" visibility="visible">
<g>
<rect x="221" y="152" width="114" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="221" y="177" width="114" height="77" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="221" y="152" width="114" height="102" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="221" y1="177" x2="335" y2="177" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="255" y="169.75" fill="#000" font-family="Verdana" font-size="12">PLAYER</text>
<text x="226" y="194.8" fill="#000" font-family="Verdana" font-size="12">playerId</text>
<line x1="226" y1="197" x2="277" y2="197" stroke="#000" stroke-width="1"/>
<text x="226" y="211.8" fill="#000" font-family="Verdana" font-size="12">name</text>
<text x="226" y="228.8" fill="#000" font-family="Verdana" font-size="12">nbBallTouchTotal</text>
<text x="226" y="245.8" fill="#000" font-family="Verdana" font-size="12">timePlayed</text>
</g>
<!-- Entity CHAT -->
<g class="page_0_vszgn7mY diagram_page" visibility="visible">
<g>
<rect x="399" y="161" width="72" height="25" fill="#f4a582" stroke="#f4a582" stroke-width="0" opacity="1"/>
<rect x="399" y="186" width="72" height="59" fill="#fddbc7" stroke="#fddbc7" stroke-width="0" opacity="1"/>
<rect x="399" y="161" width="72" height="84" fill="none" stroke="#d6604d" stroke-width="2" opacity="1"/>
<line x1="399" y1="186" x2="471" y2="186" stroke="#d6604d" stroke-width="1"/>
</g>
<text x="418" y="178.75" fill="#000" font-family="Verdana" font-size="12">CHAT</text>
<text x="404" y="203.8" fill="#000" font-family="Verdana" font-size="12">chatId</text>
<line x1="404" y1="206" x2="443" y2="206" stroke="#000" stroke-width="1"/>
<text x="404" y="220.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
<text x="404" y="237.8" fill="#000" font-family="Verdana" font-size="12">#playerId</text>
</g>
<!-- Link from &quot;playerId&quot; (MESSAGE) to &quot;playerId&quot; (PLAYER) -->
<path d="M239 98.5 C185 144.5 167 190.5 221 190.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="221 190.5 209 196.5 213 190.5 209 184.5" fill="#878787" stroke-width="0"/>
<circle cx="239" cy="98.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;chatId&quot; (MESSAGE) to &quot;chatId&quot; (CHAT) -->
<path d="M317 115.5 C358 157.5 344.33 199.5 399 199.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="399 199.5 387 205.5 391 199.5 387 193.5" fill="#878787" stroke-width="0"/>
<circle cx="317" cy="115.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (GAME) to &quot;playerId&quot; (PLAYER) -->
<path d="M157 182.5 C189 186.5 178.33 190.5 221 190.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="221 190.5 209 196.5 213 190.5 209 184.5" fill="#878787" stroke-width="0"/>
<circle cx="157" cy="182.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (GAME) to &quot;playerId&quot; (PLAYER) -->
<path d="M157 199.5 C189 195 178.33 190.5 221 190.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="221 190.5 209 196.5 213 190.5 209 184.5" fill="#878787" stroke-width="0"/>
<circle cx="157" cy="199.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (CHAT) to &quot;playerId&quot; (PLAYER) -->
<path d="M399 216.5 C367 203.5 377.67 190.5 335 190.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="335 190.5 347 184.5 343 190.5 347 196.5" fill="#878787" stroke-width="0"/>
<circle cx="399" cy="216.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
<!-- Link from &quot;playerId&quot; (CHAT) to &quot;playerId&quot; (PLAYER) -->
<path d="M399 233.5 C367 212 377.67 190.5 335 190.5" fill="none" stroke="#878787" stroke-width="2"/>
<polygon points="335 190.5 347 184.5 343 190.5 347 196.5" fill="#878787" stroke-width="0"/>
<circle cx="399" cy="233.5" r="2" stroke="#878787" stroke-width="2" fill="#878787"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

Loading…
Cancel
Save