Added mongodb as database
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Prospect.Server.Api.Config
|
||||||
|
{
|
||||||
|
public class DatabaseSettings
|
||||||
|
{
|
||||||
|
public string ConnectionString { get; set; }
|
||||||
|
public string DatabaseName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Prospect.Server.Api.Config
|
||||||
|
{
|
||||||
|
public class PlayFabSettings
|
||||||
|
{
|
||||||
|
public string PublisherId { get; set; }
|
||||||
|
public string TitleId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Prospect.Server.Api.Config;
|
||||||
using Prospect.Server.Api.Models.Client;
|
using Prospect.Server.Api.Models.Client;
|
||||||
using Prospect.Server.Api.Models.Client.Data;
|
using Prospect.Server.Api.Models.Client.Data;
|
||||||
|
using Prospect.Server.Api.Services.Database;
|
||||||
|
using Prospect.Server.Api.Services.Database.Models;
|
||||||
using Prospect.Server.Steam;
|
using Prospect.Server.Steam;
|
||||||
|
|
||||||
namespace Prospect.Server.Api.Controllers
|
namespace Prospect.Server.Api.Controllers
|
||||||
@@ -11,22 +16,30 @@ namespace Prospect.Server.Api.Controllers
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
public class ClientController : Controller
|
public class ClientController : Controller
|
||||||
{
|
{
|
||||||
|
private readonly PlayFabSettings _settings;
|
||||||
|
private readonly DbUserService _userService;
|
||||||
|
private readonly DbEntityService _entityService;
|
||||||
|
|
||||||
|
public ClientController(IOptions<PlayFabSettings> settings, DbUserService userService, DbEntityService entityService)
|
||||||
|
{
|
||||||
|
_settings = settings.Value;
|
||||||
|
_userService = userService;
|
||||||
|
_entityService = entityService;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("LoginWithSteam")]
|
[HttpPost("LoginWithSteam")]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
public IActionResult LoginWithSteam(ClientLoginWithSteamRequest request)
|
public async Task<IActionResult> LoginWithSteam(ClientLoginWithSteamRequest request)
|
||||||
{
|
{
|
||||||
var playerIdOne = "AAAABBBBCCCCDDDD"; // PlayFabId
|
|
||||||
var playerIdTwo = "0000111122223333"; // EntityId
|
|
||||||
var playerName = "AeonLucid";
|
|
||||||
|
|
||||||
var titleId = "A22AB";
|
|
||||||
var publisherId = "850902E5B40508ED";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(request.SteamTicket))
|
if (!string.IsNullOrEmpty(request.SteamTicket))
|
||||||
{
|
{
|
||||||
var ticket = AppTicket.Parse(request.SteamTicket);
|
var ticket = AppTicket.Parse(request.SteamTicket);
|
||||||
if (ticket.IsValid && ticket.HasValidSignature)
|
if (ticket.IsValid && ticket.HasValidSignature)
|
||||||
{
|
{
|
||||||
|
var userSteamId = ticket.SteamId.ToString();
|
||||||
|
var user = await _userService.FindOrCreateAsync(PlayFabUserAuthType.Steam, userSteamId);
|
||||||
|
var entity = await _entityService.FindOrCreateAsync(user.Id);
|
||||||
|
|
||||||
return Ok(new ClientResponse<FServerLoginResult>
|
return Ok(new ClientResponse<FServerLoginResult>
|
||||||
{
|
{
|
||||||
Code = 200,
|
Code = 200,
|
||||||
@@ -37,7 +50,7 @@ namespace Prospect.Server.Api.Controllers
|
|||||||
{
|
{
|
||||||
Entity = new FEntityKey
|
Entity = new FEntityKey
|
||||||
{
|
{
|
||||||
Id = playerIdTwo,
|
Id = entity.Id,
|
||||||
Type = "title_player_account",
|
Type = "title_player_account",
|
||||||
TypeString = "title_player_account"
|
TypeString = "title_player_account"
|
||||||
},
|
},
|
||||||
@@ -49,10 +62,10 @@ namespace Prospect.Server.Api.Controllers
|
|||||||
CharacterInventories = new List<object>(),
|
CharacterInventories = new List<object>(),
|
||||||
PlayerProfile = new FPlayerProfileModel
|
PlayerProfile = new FPlayerProfileModel
|
||||||
{
|
{
|
||||||
DisplayName = playerName,
|
DisplayName = user.DisplayName,
|
||||||
PlayerId = playerIdOne,
|
PlayerId = user.Id,
|
||||||
PublisherId = publisherId,
|
PublisherId = _settings.PublisherId,
|
||||||
TitleId = titleId
|
TitleId = _settings.TitleId
|
||||||
},
|
},
|
||||||
UserDataVersion = 0,
|
UserDataVersion = 0,
|
||||||
UserInventory = new List<object>(),
|
UserInventory = new List<object>(),
|
||||||
@@ -60,7 +73,7 @@ namespace Prospect.Server.Api.Controllers
|
|||||||
},
|
},
|
||||||
LastLoginTime = DateTime.UtcNow,
|
LastLoginTime = DateTime.UtcNow,
|
||||||
NewlyCreated = false,
|
NewlyCreated = false,
|
||||||
PlayFabId = playerIdOne,
|
PlayFabId = user.Id,
|
||||||
SessionTicket = "SOME",
|
SessionTicket = "SOME",
|
||||||
SettingsForUser = new FUserSettings
|
SettingsForUser = new FUserSettings
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MongoDB.Driver" Version="2.13.2" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using Prospect.Server.Api.Config;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database
|
||||||
|
{
|
||||||
|
public abstract class BaseDbService<T>
|
||||||
|
{
|
||||||
|
protected BaseDbService(IOptions<DatabaseSettings> options, string collection)
|
||||||
|
{
|
||||||
|
var settings = options.Value;
|
||||||
|
var client = new MongoClient(settings.ConnectionString);
|
||||||
|
var database = client.GetDatabase(settings.DatabaseName);
|
||||||
|
|
||||||
|
Collection = database.GetCollection<T>(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IMongoCollection<T> Collection { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using Prospect.Server.Api.Config;
|
||||||
|
using Prospect.Server.Api.Services.Database.Models;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database
|
||||||
|
{
|
||||||
|
public class DbEntityService : BaseDbService<PlayFabEntity>
|
||||||
|
{
|
||||||
|
public DbEntityService(IOptions<DatabaseSettings> settings) : base(settings, nameof(DbEntityService))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlayFabEntity> FindAsync(string userId)
|
||||||
|
{
|
||||||
|
return await Collection.Find(user => user.UserId == userId).FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<PlayFabEntity> CreateAsync(string userId)
|
||||||
|
{
|
||||||
|
var user = new PlayFabEntity
|
||||||
|
{
|
||||||
|
UserId = userId
|
||||||
|
};
|
||||||
|
|
||||||
|
await Collection.InsertOneAsync(user);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlayFabEntity> FindOrCreateAsync(string userId)
|
||||||
|
{
|
||||||
|
return await FindAsync(userId) ??
|
||||||
|
await CreateAsync(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using Prospect.Server.Api.Config;
|
||||||
|
using Prospect.Server.Api.Services.Database.Models;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database
|
||||||
|
{
|
||||||
|
public class DbUserService : BaseDbService<PlayFabUser>
|
||||||
|
{
|
||||||
|
public DbUserService(IOptions<DatabaseSettings> settings) : base(settings, nameof(PlayFabUser))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlayFabUser> FindAsync(PlayFabUserAuthType type, string key)
|
||||||
|
{
|
||||||
|
return await Collection.Find(user => user.Auth.Any(auth =>
|
||||||
|
auth.Type == type &&
|
||||||
|
auth.Key == key)).FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<PlayFabUser> CreateAsync(PlayFabUserAuthType type, string key)
|
||||||
|
{
|
||||||
|
var user = new PlayFabUser
|
||||||
|
{
|
||||||
|
DisplayName = "Unknown",
|
||||||
|
Auth = new List<PlayFabUserAuth>
|
||||||
|
{
|
||||||
|
new PlayFabUserAuth
|
||||||
|
{
|
||||||
|
Type = type,
|
||||||
|
Key = key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await Collection.InsertOneAsync(user);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlayFabUser> FindOrCreateAsync(PlayFabUserAuthType type, string key)
|
||||||
|
{
|
||||||
|
return await FindAsync(type, key) ??
|
||||||
|
await CreateAsync(type, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using MongoDB.Bson.Serialization;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database.Generator
|
||||||
|
{
|
||||||
|
public class PlayFabIdGenerator : IIdGenerator
|
||||||
|
{
|
||||||
|
private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
|
||||||
|
|
||||||
|
public object GenerateId(object container, object document)
|
||||||
|
{
|
||||||
|
Span<byte> data = stackalloc byte[8];
|
||||||
|
Random.GetBytes(data);
|
||||||
|
return Convert.ToHexString(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty(object id)
|
||||||
|
{
|
||||||
|
return id is not string idStr || string.IsNullOrEmpty(idStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using Prospect.Server.Api.Services.Database.Generator;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// title_player_account
|
||||||
|
/// </summary>
|
||||||
|
public class PlayFabEntity
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(PlayFabIdGenerator))]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
[BsonRequired]
|
||||||
|
[BsonElement("UserId")]
|
||||||
|
public string UserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using Prospect.Server.Api.Services.Database.Generator;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// master_player_account
|
||||||
|
/// </summary>
|
||||||
|
public class PlayFabUser
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(PlayFabIdGenerator))]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
[BsonRequired]
|
||||||
|
[BsonElement("DisplayName")]
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
|
[BsonRequired]
|
||||||
|
[BsonElement("Auth")]
|
||||||
|
public List<PlayFabUserAuth> Auth { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Database.Models
|
||||||
|
{
|
||||||
|
public class PlayFabUserAuth
|
||||||
|
{
|
||||||
|
[BsonElement("Type")]
|
||||||
|
public PlayFabUserAuthType Type { get; set; }
|
||||||
|
|
||||||
|
[BsonElement("Key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Prospect.Server.Api.Services.Database.Models
|
||||||
|
{
|
||||||
|
public enum PlayFabUserAuthType
|
||||||
|
{
|
||||||
|
Epic,
|
||||||
|
Steam
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,32 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Prospect.Server.Api.Config;
|
||||||
using Prospect.Server.Api.Middleware;
|
using Prospect.Server.Api.Middleware;
|
||||||
|
using Prospect.Server.Api.Services.Database;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Prospect.Server.Api
|
namespace Prospect.Server.Api
|
||||||
{
|
{
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IConfiguration Configuration { get; }
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
services.Configure<DatabaseSettings>(Configuration.GetSection(nameof(DatabaseSettings)));
|
||||||
|
services.Configure<PlayFabSettings>(Configuration.GetSection(nameof(PlayFabSettings)));
|
||||||
|
|
||||||
|
services.AddSingleton<DbUserService>();
|
||||||
|
services.AddSingleton<DbEntityService>();
|
||||||
|
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"DatabaseSettings": {
|
||||||
|
"ConnectionString": "mongodb://localhost:27017",
|
||||||
|
"DatabaseName": "ProspectDb"
|
||||||
|
},
|
||||||
|
"PlayFabSettings": {
|
||||||
|
"PublisherId": "850902E5B40508ED",
|
||||||
|
"TitleId": "A22AB"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,5 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Classes_0020and_0020structs/@EntryIndexedValue"><NamingElement Priority="1"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="__interface" /><type Name="class" /><type Name="struct" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Classes_0020and_0020structs/@EntryIndexedValue"><NamingElement Priority="1"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="__interface" /><type Name="class" /><type Name="struct" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020methods/@EntryIndexedValue"><NamingElement Priority="10"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="member function" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020methods/@EntryIndexedValue"><NamingElement Priority="10"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="member function" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Namespaces/@EntryIndexedValue"><NamingElement Priority="17"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="namespace" /><type Name="namespace alias" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String></wpf:ResourceDictionary>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Namespaces/@EntryIndexedValue"><NamingElement Priority="17"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="namespace" /><type Name="namespace alias" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PF/@EntryIndexedValue">PF</s:String></wpf:ResourceDictionary>
|
||||||
Reference in New Issue
Block a user