Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/.docker/usersessioncache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3.7'

services:
usersessioncache:
hostname: 'ows2'
container_name: usersessioncache
image: valkey/valkey:latest
restart: always
command: valkey-server --appendonly yes --requirepass "${UserSessionCacheValkeyPassword}"
ports:
- "6379:6379"
volumes:
- usersessioncache:/data
environment:
TZ=America/New_York
volumes:
usersessioncache:
5 changes: 4 additions & 1 deletion src/.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ RabbitMQUserName="dev"
RabbitMQPassword="test"

# Matchmaking Cache Redis
# MatchmakingCacheRedisPassword='YourRedi$Pa$$word'
# MatchmakingCacheRedisPassword='YourRedi$Pa$$word'

# User Session Cache Redis
# UserSessionCacheValkeyPassword='YourValkeyPa$$word'
3 changes: 2 additions & 1 deletion src/OWSData/OWSData.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
Expand All @@ -13,6 +13,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.5" />
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OWSShared\OWSShared.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
p,
commandType: CommandType.Text);
}
catch (Exception ex)

Check warning on line 47 in src/OWSData/Repositories/Implementations/Postgres/UsersRepository.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'ex' is declared but never used
{
return [];
}
Expand All @@ -67,7 +67,7 @@
p.Add("@CharacterName", characterName);
p.Add("@ClassName", className);

outputObject = await connection.QuerySingleAsync<CreateCharacter>("select * from AddCharacter(@CustomerGUID,@UserSessionGUID,@CharacterName,@ClassName)",
outputObject = await Connection.QuerySingleAsync<CreateCharacter>(GenericQueries.CreateCharacterSQL,
p,
commandType: CommandType.Text);
}
Expand Down Expand Up @@ -153,7 +153,7 @@
p.Add("@UserSessionGUID", userSessionGUID);
p.Add("@PlayerGroupTypeID", playerGroupTypeID);

outputObject = await connection.QueryAsync<GetPlayerGroupsCharacterIsIn>("select * from GetPlayerGroupsCharacterIsIn(@CustomerGUID,@CharName,@UserSessionGUID,@PlayerGroupTypeID)",
outputObject = await connection.QueryAsync<GetPlayerGroupsCharacterIsIn>(GenericQueries.GetPlayerGroupsCharacterIsIn,
p,
commandType: CommandType.Text);
}
Expand All @@ -179,7 +179,7 @@
p.Add("@CustomerGUID", customerGuid);
p.Add("@UserGUID", userGuid);

outputObject = await connection.QuerySingleOrDefaultAsync<User>("select * from GetUser(@CustomerGUID,@UserGUID)",
outputObject = await connection.QuerySingleOrDefaultAsync<User>(GenericQueries.GetUser,
p,
commandType: CommandType.Text);

Expand Down Expand Up @@ -227,7 +227,7 @@
p.Add("@CustomerGUID", customerGuid);
p.Add("@UserSessionGUID", userSessionGuid);

outputObject = await connection.QuerySingleOrDefaultAsync<GetUserSession>("select * from GetUserSession(@CustomerGUID,@UserSessionGUID)",
outputObject = await connection.QuerySingleOrDefaultAsync<GetUserSession>(GenericQueries.GetUserSession,
p,
commandType: CommandType.Text);

Expand Down Expand Up @@ -305,7 +305,7 @@
p.Add("@Password", password);
p.Add("@DontCheckPassword", dontCheckPassword);

outputObject = await connection.QuerySingleOrDefaultAsync<PlayerLoginAndCreateSession>($"select * from PlayerLoginAndCreateSession(@CustomerGUID,@Email,@Password,@DontCheckPassword)",
outputObject = await connection.QuerySingleOrDefaultAsync<PlayerLoginAndCreateSession>(GenericQueries.PlayerLoginAndCreateSession,
p,
commandType: CommandType.Text);
}
Expand Down Expand Up @@ -355,7 +355,7 @@
p.Add("@UserSessionGUID", userSessionGUID);
p.Add("@SelectedCharacterName", selectedCharacterName);

await connection.ExecuteAsync("call UserSessionSetSelectedCharacter(@CustomerGUID, @UserSessionGUID, @SelectedCharacterName)",
await connection.ExecuteAsync(GenericQueries.UserSessionSetSelectedCharacter,
p,
commandType: CommandType.Text);
}
Expand Down Expand Up @@ -390,7 +390,7 @@
p.Add("@LastName", lastName);
p.Add("@Role", "Player");

await connection.ExecuteAsync("select * from AddUser(@CustomerGUID, @FirstName, @LastName, @Email, @Password, @Role)",
await connection.ExecuteAsync(GenericQueries.AddUser,
p,
commandType: CommandType.Text);
}
Expand Down Expand Up @@ -427,14 +427,22 @@
{
using (var connection = (NpgsqlConnection)Connection)
{
await connection.OpenAsync();

using (IDbTransaction transaction = connection.BeginTransaction())
{
var p = new DynamicParameters();
p.Add("@CustomerGUID", customerGUID);
p.Add("@UserSessionGUID", userSessionGUID);
p.Add("@CharacterName", characterName);

await connection.ExecuteAsync("call RemoveCharacter(@CustomerGUID,@UserSessionGUID,@CharacterName)",
await connection.ExecuteAsync(GenericQueries.RemoveCharacter,
p,
transaction,
commandType: CommandType.Text);

transaction.Commit();
}
}

return new SuccessAndErrorMessage()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Text.Json;
using System.Threading.Tasks;
using OWSData.Models.StoredProcs;
using OWSData.Repositories.Interfaces;
using StackExchange.Redis;

namespace OWSData.Repositories.Implementations.ValKey
{
public class UserSessionRepository : IUserSessionRepository
{
private const string ValKeyConnectionString = "localhost:6379,password=YourValkeyPa$$word";
private static readonly Lazy<ConnectionMultiplexer> Connection =
new(() => ConnectionMultiplexer.Connect(ValKeyConnectionString));

private static IDatabase Database => Connection.Value.GetDatabase();
private static string keyPrefix = "user:session:";

private string constructUserSessionKeyFromUserGuid(Guid UserGuid)
{
return $"{keyPrefix}{UserGuid.ToString()}";
}

public async Task<GetUserSession> GetUserSession(Guid UserGuid)
{
string key = constructUserSessionKeyFromUserGuid(UserGuid);
ValidateKey(key);

RedisValue userSessionJson = await Database.StringGetAsync(key);
if (userSessionJson.IsNullOrEmpty)
{
return new GetUserSession();
}

try
{
var userSession = JsonSerializer.Deserialize<GetUserSession>(userSessionJson!);
return userSession ?? new GetUserSession();
}
catch (JsonException)
{
return new GetUserSession();
}
}

public async Task SetUserSession(Guid UserGuid, GetUserSession userSession)
{
string key = constructUserSessionKeyFromUserGuid(UserGuid);
ValidateKey(key);

if (userSession == null)
{
throw new ArgumentNullException(nameof(userSession));
}

string userSessionJson = JsonSerializer.Serialize(userSession);
await Database.StringSetAsync(key, userSessionJson);
}

private static void ValidateKey(string key)
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("A non-empty session key is required.", nameof(key));
}
}
}
}
12 changes: 12 additions & 0 deletions src/OWSData/Repositories/Interfaces/IUserSessionRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Threading.Tasks;
using OWSData.Models.StoredProcs;

namespace OWSData.Repositories.Interfaces
{
public interface IUserSessionRepository
{
Task<GetUserSession> GetUserSession(Guid UserGuid);
Task SetUserSession(Guid UserGuid, GetUserSession userSession);
}
}
Loading
Loading