365 lines
13 KiB
C#
365 lines
13 KiB
C#
using DeluxeBackend.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Numerics;
|
|
using DeluxeBackend.Models;
|
|
using System.Security.Claims;
|
|
using static DeluxeBackend.Enums;
|
|
|
|
namespace DeluxeBackend.Controllers.Api
|
|
{
|
|
[Route("api/relationships")]
|
|
[ApiController]
|
|
public class RelationshipsController : ControllerBase//this is from KittyRec https://git.tabbycluster.net/KittyRec/KittyRec-Api/src/branch/main/Controllers/relationshipsController.cs
|
|
{
|
|
private readonly ILiteDbService db;
|
|
private readonly IJwtService jwt;
|
|
private readonly INotificationService ws;
|
|
private readonly IMessageService messageService;
|
|
|
|
public RelationshipsController(ILiteDbService _db, IJwtService _jwt, INotificationService _ws, IMessageService _messageService)
|
|
{
|
|
db = _db;
|
|
jwt = _jwt;
|
|
ws = _ws;
|
|
messageService = _messageService;
|
|
}
|
|
|
|
private long? GetCurrentPlayerId()
|
|
{
|
|
string? raw = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? User.FindFirst("sub")?.Value;
|
|
if (long.TryParse(raw, out long id)) return id;
|
|
return null;
|
|
}
|
|
|
|
private Relationship? GetRelationship(long playerId, long targetId) =>
|
|
db.Relationships
|
|
.Include(x => x.Player)
|
|
.Include(x => x.TargetPlayer)
|
|
.FindOne(x => x.Player.Id == playerId && x.TargetPlayer.Id == targetId);
|
|
|
|
private Relationship GetOrCreate(long playerId, long targetId)
|
|
{
|
|
var rel = GetRelationship(playerId, targetId);
|
|
if (rel != null) return rel;
|
|
rel = new Relationship
|
|
{
|
|
Player = db.Accounts.FindById(playerId),
|
|
TargetPlayer = db.Accounts.FindById(targetId)
|
|
};
|
|
db.Relationships.Insert(rel);
|
|
return rel;
|
|
}
|
|
|
|
private async Task PushRelToPlayer(long toPlayerId, long aboutPlayerId)
|
|
{
|
|
var rel = GetRelationship(toPlayerId, aboutPlayerId);
|
|
await ws.SendToPlayer(toPlayerId, PushNotification.RelationshipChanged, new Dictionary<string, object>
|
|
{
|
|
["PlayerID"] = aboutPlayerId,
|
|
["RelationshipType"] = (int)(rel?.RelationshipType ?? RelationshipType.None),
|
|
["Muted"] = (int)(rel?.Muted ?? MuteState.None),
|
|
["Ignored"] = (int)(rel?.Ignored ?? IgnoreState.None),
|
|
["Favorited"] = rel?.Favorited ?? 0
|
|
});
|
|
}
|
|
|
|
private void DeleteFriendInvites(long fromPlayerId, long toPlayerId)
|
|
{
|
|
var messageToDelete = db.Messages.FindOne(m =>
|
|
m.FromPlayer.Id == fromPlayerId &&
|
|
m.Player.Id == toPlayerId &&
|
|
m.Type == MessageType.FriendInvite);
|
|
|
|
if (messageToDelete != null)
|
|
{
|
|
db.Messages.Delete(messageToDelete.Id);
|
|
|
|
ws.SendToPlayer(toPlayerId, PushNotification.MessageDeleted, new Dictionary<string, object>
|
|
{
|
|
["Id"] = messageToDelete.Id
|
|
});
|
|
}
|
|
}
|
|
|
|
[HttpGet("v2/get")]
|
|
[Authorize]
|
|
public async Task<IActionResult> get()
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
var rels = db.Relationships
|
|
.Query()
|
|
.Include(x => x.Player)
|
|
.Include(x => x.TargetPlayer)
|
|
.Where(x => x.Player.Id == pid.Value)
|
|
.ToList()
|
|
.Select(r => r.ToDictionary())
|
|
.ToList();
|
|
|
|
return Ok(rels);
|
|
}
|
|
|
|
[HttpGet("v2/sendfriendrequest")]
|
|
[Authorize]
|
|
public async Task<IActionResult> SendFriendRequest([FromQuery] long id = 0)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (id == 0 || id == pid || db.Accounts.FindById(id) == null)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, id);
|
|
var theirRel = GetOrCreate(id, pid.Value);
|
|
|
|
if (myRel.RelationshipType == RelationshipType.Friend)
|
|
return Ok();
|
|
|
|
// they already sent us one — auto-accept both sides
|
|
if (theirRel.RelationshipType == RelationshipType.Sent || myRel.RelationshipType == RelationshipType.Received)
|
|
{
|
|
myRel.RelationshipType = RelationshipType.Friend;
|
|
theirRel.RelationshipType = RelationshipType.Friend;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
DeleteFriendInvites(pid.Value, id);
|
|
|
|
Account me = db.Accounts.FindById(pid.Value);
|
|
Account them = db.Accounts.FindById(id);
|
|
await messageService.SendMessage(me, them, MessageType.FriendRequestAccepted, pid.Value.ToString());
|
|
|
|
await PushRelToPlayer(id, pid.Value);
|
|
await PushRelToPlayer(pid.Value, id);
|
|
return Ok();
|
|
}
|
|
|
|
// new outgoing request
|
|
myRel.RelationshipType = RelationshipType.Sent;
|
|
theirRel.RelationshipType = RelationshipType.Received;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
DeleteFriendInvites(id, pid.Value);
|
|
|
|
Account sender = db.Accounts.FindById(pid.Value);
|
|
Account recipient = db.Accounts.FindById(id);
|
|
await messageService.SendMessage(sender, recipient, MessageType.FriendInvite, pid.Value.ToString());
|
|
|
|
await PushRelToPlayer(id, pid.Value);
|
|
await PushRelToPlayer(pid.Value, id);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpGet("v2/addfriend")]
|
|
[Authorize]
|
|
public async Task<IActionResult> AddFriend([FromQuery] long id = 0) =>
|
|
await SendFriendRequest(id);
|
|
|
|
[HttpGet("v2/acceptfriendrequest")]
|
|
[Authorize]
|
|
public async Task<IActionResult> AcceptFriendRequest([FromQuery] long id = 0)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (id == 0 || id == pid)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, id);
|
|
var theirRel = GetOrCreate(id, pid.Value);
|
|
|
|
if (theirRel.RelationshipType != RelationshipType.Sent && myRel.RelationshipType != RelationshipType.Received)
|
|
return Ok();
|
|
|
|
myRel.RelationshipType = RelationshipType.Friend;
|
|
theirRel.RelationshipType = RelationshipType.Friend;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
DeleteFriendInvites(pid.Value, id);
|
|
|
|
Account me = db.Accounts.FindById(pid.Value);
|
|
Account them = db.Accounts.FindById(id);
|
|
await messageService.SendMessage(me, them, MessageType.FriendRequestAccepted, pid.Value.ToString());
|
|
|
|
await PushRelToPlayer(id, pid.Value);
|
|
await PushRelToPlayer(pid.Value, id);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpGet("v2/removefriend")]
|
|
[Authorize]
|
|
public async Task<IActionResult> RemoveFriend([FromQuery] long id = 0)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (id != 0 && id != pid)
|
|
{
|
|
var myRel = GetRelationship(pid.Value, id);
|
|
var theirRel = GetRelationship(id, pid.Value);
|
|
|
|
if (myRel != null) { myRel.RelationshipType = RelationshipType.None; db.Relationships.Update(myRel); }
|
|
if (theirRel != null) { theirRel.RelationshipType = RelationshipType.None; db.Relationships.Update(theirRel); }
|
|
|
|
DeleteFriendInvites(pid.Value, id);
|
|
DeleteFriendInvites(id, pid.Value);
|
|
|
|
await PushRelToPlayer(id, pid.Value);
|
|
await PushRelToPlayer(pid.Value, id);
|
|
|
|
Dictionary<string, object> gg = new()
|
|
{
|
|
["PlayerID"] = pid,
|
|
["RelationshipType"] = (int)(myRel?.RelationshipType ?? RelationshipType.None),
|
|
["Muted"] = (int)(myRel?.Muted ?? MuteState.None),
|
|
["Ignored"] = (int)(myRel?.Ignored ?? IgnoreState.None),
|
|
["Favorited"] = myRel?.Favorited ?? 0
|
|
};
|
|
|
|
return Ok(gg);
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
|
|
[HttpGet("v1/favorite")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Favorite([FromQuery] long id = 0)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (id != 0 && id != pid)
|
|
{
|
|
var rel = GetOrCreate(pid.Value, id);
|
|
rel.Favorited = 1;
|
|
db.Relationships.Update(rel);
|
|
return Ok(rel.ToDictionary());
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
|
|
[HttpGet("v1/unfavorite")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Unfavorite([FromQuery] long id = 0)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (id != 0 && id != pid)
|
|
{
|
|
var rel = GetOrCreate(pid.Value, id);
|
|
rel.Favorited = 0;
|
|
db.Relationships.Update(rel);
|
|
return Ok(rel.ToDictionary());
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("v1/mute")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Mute([FromForm(Name = "PlayerId"), Required] long playerId)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (playerId == 0 || playerId == pid)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, playerId);
|
|
var theirRel = GetOrCreate(playerId, pid.Value);
|
|
|
|
myRel.Muted = MuteState.Local;
|
|
theirRel.Muted = MuteState.Remote;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
await PushRelToPlayer(pid.Value, playerId);
|
|
await PushRelToPlayer(playerId, pid.Value);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpPost("v1/unmute")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Unmute([FromForm(Name = "PlayerId"), Required] long playerId)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (playerId == 0 || playerId == pid)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, playerId);
|
|
var theirRel = GetOrCreate(playerId, pid.Value);
|
|
|
|
myRel.Muted = MuteState.None;
|
|
if (theirRel.Muted == MuteState.Remote) theirRel.Muted = MuteState.None;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
await PushRelToPlayer(pid.Value, playerId);
|
|
await PushRelToPlayer(playerId, pid.Value);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpPost("v1/ignore")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Ignore([FromForm(Name = "PlayerId"), Required] long playerId)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (playerId == 0 || playerId == pid)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, playerId);
|
|
var theirRel = GetOrCreate(playerId, pid.Value);
|
|
|
|
myRel.Ignored = IgnoreState.Local;
|
|
theirRel.Ignored = IgnoreState.Remote;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
await PushRelToPlayer(pid.Value, playerId);
|
|
await PushRelToPlayer(playerId, pid.Value);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpPost("v1/unignore")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Unignore([FromForm(Name = "PlayerId"), Required] long playerId)
|
|
{
|
|
long? pid = GetCurrentPlayerId();
|
|
if (pid == null) return Unauthorized();
|
|
|
|
if (playerId == 0 || playerId == pid)
|
|
return Ok();
|
|
|
|
var myRel = GetOrCreate(pid.Value, playerId);
|
|
var theirRel = GetOrCreate(playerId, pid.Value);
|
|
|
|
myRel.Ignored = IgnoreState.None;
|
|
if (theirRel.Ignored == IgnoreState.Remote) theirRel.Ignored = IgnoreState.None;
|
|
db.Relationships.Update(myRel);
|
|
db.Relationships.Update(theirRel);
|
|
|
|
await PushRelToPlayer(pid.Value, playerId);
|
|
await PushRelToPlayer(playerId, pid.Value);
|
|
return Ok(myRel.ToDictionary());
|
|
}
|
|
|
|
[HttpPost("v1/bulkignoreplatformusers")]
|
|
public IActionResult BulkIgnorePlatformUsers() =>
|
|
Ok();
|
|
|
|
}
|
|
}
|