fisr commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "7.0.8",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
global using System;
|
||||
global using System.Linq;
|
||||
global using System.Collections;
|
||||
global using System.Collections.Generic;
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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>
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://192.168.1.64:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"Database": {
|
||||
"ConnectionString": "mongodb://yandex:yandexgame@192.168.1.64:27017",
|
||||
"DatabaseName": "yandex"
|
||||
},
|
||||
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
Reference in New Issue
Block a user