fisr commit

This commit is contained in:
2023-07-08 21:28:08 +05:00
parent d9b74220d3
commit 7e1abc6db0
14 changed files with 502 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.8",
"commands": [
"dotnet-ef"
]
}
}
}
+77
View File
@@ -0,0 +1,77 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Text;
using YandexGameServer.Models;
using YandexGameServer.Services;
namespace YandexGameServer.Controllers
{
[ApiController]
[Route("[controller]")]
public class AuthController : ControllerBase
{
private readonly DatabaseService _databaseService;
private readonly CodeGenerationService _codeGenerationService;
private readonly ILogger<AuthController> _logger;
public AuthController(DatabaseService databaseService, ILogger<AuthController> logger, CodeGenerationService codeGenerationService)
{
_codeGenerationService = codeGenerationService;
_logger = logger;
_databaseService = databaseService;
}
[HttpGet("{code:int}")]
public async Task<IActionResult> Authorization(int code)
{
var cities = await _databaseService.GetCitiesCodesAsync();
CityUniqueCode? cityCode = cities.Find(x => x.key == code);
if (cityCode == null) return NotFound("Такого кода нет в базе");
else
{
var client = new Client() { city = cityCode.cityEnum, games = new List<Games>() };
await _databaseService.CreateAsync(client);
return Ok(client);
}
}
[HttpGet("admin/{code:int}")]
public async Task<IActionResult> AdminAuthorization(int code)
{
var cities = await _databaseService.GetCitiesCodesAsync();
CityUniqueCode? cityCode = cities.Find(x => x.adminKey == code);
if (cityCode == null) return NotFound();
else return Ok(cityCode);
}
[HttpGet("secretcode/{cityId:int}")]
public async Task<IActionResult> GetAuthorizationCodeAsync(int cityId)
{
Cities cityCode = (Cities)cityId;
var cities = await _databaseService.GetCitiesCodesAsync();
if (cities.Any(x => x.cityEnum == cityCode))
{
var cityData = cities.Find(x => x.cityEnum == cityCode);
return Ok(cityData.key);
}
else return NotFound("Нет соответствующего секретного кода");
}
[HttpGet("all")]
public async Task<IActionResult> GetAllCodes()
{
StringBuilder stringBuilder = new StringBuilder();
var codes = await _databaseService.GetCitiesCodesAsync();
foreach(var code in _codeGenerationService.citiesTranslation.Keys)
{
var data = codes.Find(x => x.cityEnum.Equals(code));
stringBuilder.AppendLine($"{_codeGenerationService.citiesTranslation[code]} - {data.key}");
}
return Ok(stringBuilder.ToString());
}
}
}
+86
View File
@@ -0,0 +1,86 @@
using Microsoft.AspNetCore.Mvc;
using YandexGameServer.Services;
using YandexGameServer.Models;
using System.Text;
namespace YandexGameServer.Controllers
{
public enum Games
{
Surprise,
Excursion,
MasterClass,
Entertainment,
Sport,
Kids,
GoodDeeds,
Mask,
Duck,
Butterfly
}
[ApiController]
[Route("[controller]")]
public class GameController : ControllerBase
{
private readonly DatabaseService _databaseService;
public GameController(DatabaseService databaseService)
{
_databaseService = databaseService;
}
[HttpGet("find")]
public async Task<IActionResult> OnClientFindTag([FromQuery] string id, [FromQuery] Games game)
{
var clients = await _databaseService.GetClientsAsync();
var client = clients.Find(x => x.id == id);
client.games.Add(game);
await _databaseService.UpdateAsync(client);
if (client.games.Count == 10)
{
client.gameFinishedDate = DateTime.UtcNow;
await _databaseService.UpdateAsync(client);
clients = await _databaseService.GetClientsAsync();
var bestClients = clients
.Where(x => x.gameFinishedDate != null && x.city == client.city)
.OrderBy(x => x.gameFinishedDate)
.ToList();
return Ok(bestClients.IndexOf(clients.Find(x => x.id == id)) + 1);
}
else return BadRequest();
}
[HttpGet("best/{key:int}")]
public async Task<IActionResult> GetBestClientsInCity(int key)
{
StringBuilder sb = new StringBuilder();
var cities = await _databaseService.GetCitiesCodesAsync();
var city = cities.Find(x => x.key == key);
if (city == null) return NotFound();
var clients = await _databaseService.GetClientsAsync();
var bestClients = clients
.Where(x => x.gameFinishedDate != null && x.city == city.cityEnum)
.OrderBy(x => x.gameFinishedDate)
.ToList();
if(bestClients.Count == 0)
return BadRequest($"В городе {city.city} ещё нет игроков, завершивших квест");
sb.AppendLine($"количество игроков, завершивших квест в городе {city.city}:\n");
foreach(var client in bestClients)
{
sb.AppendLine($"{bestClients.IndexOf(client) + 1} - закончил(а) квест {client.gameFinishedDate.Value.ToShortDateString()} в {client.gameFinishedDate.Value.ToShortTimeString()}");
}
return Ok(sb.ToString());
}
}
}
+4
View File
@@ -0,0 +1,4 @@
global using System;
global using System.Linq;
global using System.Collections;
global using System.Collections.Generic;
+17
View File
@@ -0,0 +1,17 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson;
using YandexGameServer.Services;
namespace YandexGameServer.Models
{
[Serializable]
public class CityUniqueCode
{
[BsonId, BsonRepresentation(BsonType.ObjectId)]
public string id { get; set; }
public Cities cityEnum { get; set; }
public string city { get; set; }
public int key { get; set; }
public int adminKey { get; set; }
}
}
+18
View File
@@ -0,0 +1,18 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using YandexGameServer.Controllers;
using YandexGameServer.Services;
namespace YandexGameServer.Models
{
[Serializable]
public class Client
{
[BsonId, BsonRepresentation(BsonType.ObjectId)]
public string id { get; set; }
public Cities city { get; set; }
public List<Games> games { get; set; } = new List<Games>();
public DateTime? gameFinishedDate { get; set; }
public bool isAdmin { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson;
namespace YandexGameServer.Models
{
[Serializable]
public class Tag
{
[BsonId, BsonRepresentation(BsonType.ObjectId)]
public string id { get; set; }
public string descrition { get; set; }
public string? city { get; set; }
}
}
+13
View File
@@ -0,0 +1,13 @@
using YandexGameServer.Services;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("http://0.0.0.0:5000");
builder.Services.AddControllers();
builder.Services.AddSingleton<DatabaseService>();
builder.Services.AddSingleton<CodeGenerationService>();
var app = builder.Build();
app.MapControllers();
app.Services.GetService(typeof(CodeGenerationService));
app.Run();
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<DeleteExistingFiles>false</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>C:\Users\VladimirGRAFF\Desktop\yandex-game-server</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
<_TargetId>Folder</_TargetId>
<SiteUrlToLaunchAfterPublish />
<TargetFramework>net7.0</TargetFramework>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<ProjectGuid>765c9a4d-466f-473a-b38e-5b893db09ac8</ProjectGuid>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>
+13
View File
@@ -0,0 +1,13 @@
{
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://192.168.1.64:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
}
}
}
+142
View File
@@ -0,0 +1,142 @@
using YandexGameServer.Models;
namespace YandexGameServer.Services
{
public enum Cities
{
MoscowRedRose,
MoscowCity,
MoscowSkolkovo,
SaintPetersburg,
Yekaterinburg,
Novosibirsk,
Kazan,
Innopolis,
RostovOnDon,
NizhnyNovgorod,
Simferopol,
Vladivostok,
Krasnodar,
Samara,
Chelyabinsk,
Perm,
Tula,
Sochi,
Ufa,
Krasnoyarsk,
Tumen,
Voronezh,
Minsk,
Serbia
}
public class CodeGenerationService : IDisposable
{
private readonly DatabaseService _databaseService;
private readonly ILogger<CodeGenerationService> _logger;
private CancellationTokenSource _cts;
private DateTime _triggerDate;
public readonly Dictionary<Cities, string> citiesTranslation = new Dictionary<Cities, string>()
{
{ Cities.MoscowRedRose, "Москва, Красная Роза" },
{ Cities.MoscowCity, "Москва, Москва-Сити" },
{ Cities.MoscowSkolkovo, "Москва, Сколково" },
{ Cities.SaintPetersburg, "Санкт-Петербург" },
{ Cities.Yekaterinburg, "Екатеринбург" },
{ Cities.Novosibirsk, "Новосибирск" },
{ Cities.Kazan, "Казань" },
{ Cities.Innopolis, "Иннополис" },
{ Cities.RostovOnDon, "Ростов-На-Дону" },
{ Cities.NizhnyNovgorod, "Нижний Новгород" },
{ Cities.Simferopol, "Симферополь" },
{ Cities.Vladivostok, "Владивосток" },
{ Cities.Krasnodar, "Краснодар" },
{ Cities.Samara, "Самара" },
{ Cities.Chelyabinsk, "Челябинск" },
{ Cities.Perm, "Пермь" },
{ Cities.Tula, "Тула" },
{ Cities.Sochi, "Сочи" },
{ Cities.Ufa, "Уфа" },
{ Cities.Krasnoyarsk, "Красноярск" },
{ Cities.Tumen, "Тюмень" },
{ Cities.Voronezh, "Воронеж" },
{ Cities.Minsk, "Минск" },
{ Cities.Serbia, "Сербия" }
};
public CodeGenerationService(DatabaseService databaseService, ILogger<CodeGenerationService> logger)
{
_cts = new CancellationTokenSource();
_databaseService = databaseService;
_logger = logger;
_triggerDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 0, 0, 0) + TimeSpan.FromDays(1);
_logger.LogInformation($"дата и время следующей смены: {_triggerDate.ToShortDateString()}, {_triggerDate.ToShortTimeString()}");
Task.Run(async () =>
{
var list = await _databaseService.GetCitiesCodesAsync();
if (list.Count == 0)
{
await InitKeys();
await UpdateCityCodes();
}
while (!_cts.Token.IsCancellationRequested)
{
if (DateTime.UtcNow > _triggerDate)
{
_logger.LogWarning($"смена кода ({DateTime.UtcNow.ToShortTimeString()})");
await UpdateCityCodes();
_triggerDate += TimeSpan.FromDays(1);
}
await Task.Delay(1000);
}
});
}
public async Task InitKeys()
{
Cities cities = new Cities();
for(int i = 0; i < citiesTranslation.Count; i++)
{
cities = (Cities)i;
await _databaseService.CreateAsync(new CityUniqueCode() { cityEnum = cities, city = citiesTranslation[cities], adminKey = new Random().Next(0, 1000000) });
}
}
private async Task UpdateCityCodes()
{
Random rand = new Random();
List<int> codesInUse = new List<int>();
var citiesCodes = await _databaseService.GetCitiesCodesAsync();
for (int i = 0; i < citiesCodes.Count; i++)
{
var randomCode = rand.Next(100000, 1000000);
while (codesInUse.Contains(randomCode))
{
randomCode = rand.Next(100000, 1000000);
await Task.Yield();
}
citiesCodes[i].key = randomCode;
codesInUse.Add(randomCode);
await _databaseService.UpdateAsync(citiesCodes[i]);
}
}
public void Dispose()
{
_cts.Cancel();
_cts.Dispose();
_cts = null;
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using MongoDB.Driver;
using YandexGameServer.Models;
using Tag = YandexGameServer.Models.Tag;
namespace YandexGameServer.Services
{
public class DatabaseService
{
private readonly string _connectionString;
private readonly string _databaseName;
private readonly IMongoCollection<Client> _clientsCollection;
private readonly IMongoCollection<Tag> _tagsCollection;
private readonly IMongoCollection<CityUniqueCode> _citiesCollection;
public DatabaseService(IConfiguration configuration)
{
var databaseSection = configuration.GetSection("Database");
_connectionString = databaseSection["ConnectionString"];
_databaseName = databaseSection["DatabaseName"];
var mongoClient = new MongoClient(_connectionString);
var database = mongoClient.GetDatabase(_databaseName);
_clientsCollection = database.GetCollection<Client>("clients");
_tagsCollection = database.GetCollection<Tag>("tags");
_citiesCollection = database.GetCollection<CityUniqueCode>("cities-codes");
}
public async Task CreateAsync<T>(T data)
{
if (data is Client) await _clientsCollection.InsertOneAsync(data as Client);
else if (data is Tag) await _tagsCollection.InsertOneAsync(data as Tag);
else if (data is CityUniqueCode) await _citiesCollection.InsertOneAsync(data as CityUniqueCode);
else throw new NullReferenceException();
}
public async Task<List<Client>?> GetClientsAsync() => await _clientsCollection.Find(_ => true).ToListAsync();
public async Task<List<Tag>?> GetTagsAsync() => await _tagsCollection.Find(_ => true).ToListAsync();
public async Task<List<CityUniqueCode>?> GetCitiesCodesAsync() => await _citiesCollection.Find(_ => true).ToListAsync();
public async Task UpdateAsync<T>(T data)
{
if (data is Client)
{
Client client = data as Client;
_clientsCollection.ReplaceOne(x => x.id == client.id, client);
}
else if (data is Tag)
{
Tag tag = data as Tag;
_tagsCollection.ReplaceOne(x => x.id == tag.id, tag);
}
else if (data is CityUniqueCode)
{
CityUniqueCode cityCode = data as CityUniqueCode;
_citiesCollection.ReplaceOne(x => x.id == cityCode.id, cityCode);
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"Database": {
"ConnectionString": "mongodb://yandex:yandexgame@192.168.1.64:27017",
"DatabaseName": "yandex"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}