mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 07:29:00 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
namespace RadicadeServer.RecNet.Enums.Inventions
|
||||
{
|
||||
public enum InventionRole
|
||||
{
|
||||
Unassigned,
|
||||
LimitedOneUseOnly = 10,
|
||||
UseOnly = 20,
|
||||
EditAndSave = 40,
|
||||
Publish = 60,
|
||||
Charge = 80,
|
||||
Unlimited = 100
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace RadicadeServer.RecNet.Enums.Inventions
|
||||
{
|
||||
public enum InventionStatus
|
||||
{
|
||||
Success,
|
||||
InvalidParameters,
|
||||
PlayerCannotUpload,
|
||||
DuplicateName,
|
||||
NameTooShort,
|
||||
NameTooLong,
|
||||
NotCreator,
|
||||
DoesNotExist,
|
||||
ImageDoesNotExist,
|
||||
InventionLimitReached,
|
||||
DescriptionTooLong,
|
||||
InnapropriateName,
|
||||
InnapropriateDescription,
|
||||
CannotBeModified,
|
||||
PlayerCannotPublish,
|
||||
AlreadyPublished,
|
||||
AlreadyUnpublished,
|
||||
InventionUnderModerationReview,
|
||||
PlayerCannotDownload,
|
||||
PlayerAlreadyOwns,
|
||||
DescriptionTooShort,
|
||||
DoesNotHavePermission,
|
||||
PermissionLevelCannotBeChanged,
|
||||
AlreadyCheered,
|
||||
AlreadyRemovedCheer,
|
||||
ModeratorRestrictedPublishing,
|
||||
PlayerCannotSell,
|
||||
InvalidPrice,
|
||||
PriceCannotBeChanged,
|
||||
InvalidPermissionForPaidInvention,
|
||||
PurchaseFailed,
|
||||
CannotDownloadPaidInvention,
|
||||
CannotSellUnownedLineage,
|
||||
DoesNotAllowTrial,
|
||||
StillOnTrialCooldown,
|
||||
PlayerCannotTrial,
|
||||
PaidInventionPublishingDisabled,
|
||||
PaidInventionPurchasingDisabled,
|
||||
OperationIsDisabled,
|
||||
PlayerRestrictedFromP2PSelling,
|
||||
PlayerNotRecRoomPlusMember
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class FullInvention
|
||||
{
|
||||
public InventionStatus Status { get; set; } = InventionStatus.DoesNotExist;
|
||||
public Invention? Invention { get; set; } = null;
|
||||
public InventionVersion? InventionVersion { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class Invention
|
||||
{
|
||||
public long InventionId { get; set; }
|
||||
public long CreationRoomId { get; set; }
|
||||
public string ReplicationId { get; set; } = null!;
|
||||
public long CreatorPlayerId { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public string Description { get; set; } = null!;
|
||||
public string ImageName { get; set; } = null!;
|
||||
public int CurrentVersionNumber { get; set; }
|
||||
public bool IsPublished { get; set; }
|
||||
public bool AllowTrial { get; set; }
|
||||
public DateTime ModifiedAt { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public int NumPlayersHaveUsedInRoom { get; set; }
|
||||
public int NumDownloads { get; set; }
|
||||
public int CheerCount { get; set; }
|
||||
public InventionRole CreatorPermission { get; set; }
|
||||
public InventionRole GeneralPermission { get; set; }
|
||||
public bool IsAGInvention { get; set; }
|
||||
public bool IsCertifiedInvention { get; set; }
|
||||
public int? Price { get; set; }
|
||||
public bool HideFromPlayer { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SixLabors.ImageSharp;
|
||||
|
||||
namespace RadicadeServer.CDN
|
||||
{
|
||||
[Route("cdn/invention/")]
|
||||
public class InventionCDN : Controller
|
||||
{
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Index() => Ok(new { status = "ok" });
|
||||
|
||||
[HttpGet("{datablob}")]
|
||||
public IActionResult GetDataBlob(string datablob)
|
||||
{
|
||||
if (!CdnStorageNames.IsServable(datablob)) return BadRequest();
|
||||
|
||||
var name = CdnStorageNames.Resolve(datablob);
|
||||
if (name == null) return NotFound();
|
||||
|
||||
CdnCaching.Apply(this, CdnCaching.ForBlob(name));
|
||||
|
||||
return PhysicalFile(Path.Join(DBConfig.CDNStorage, name), "application/octet-stream", enableRangeProcessing: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class InventionDB
|
||||
{
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long InventionId { get; set; }
|
||||
public string ReplicationId { get; set; } = "";
|
||||
public long CreatorPlayerId { get; set; } = 1;
|
||||
|
||||
public string Name { get; set; } = "";
|
||||
public string Description { get; set; } = "";
|
||||
public string ImageName { get; set; } = DBConfig.DefaultRoomImage;
|
||||
|
||||
public int CurrentVersionNumber { get; set; } = 0;
|
||||
|
||||
public DateTime ModifiedAt { get; set; } = DateTime.Now;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
||||
|
||||
public int NumPlayersHaveUsedInRoom { get; set; } = 0;
|
||||
public int NumDownloads { get; set; } = 0;
|
||||
public int CheerCount { get; set; } = 0;
|
||||
|
||||
public InventionRole CreatorPermission { get; set; } = InventionRole.Unlimited;
|
||||
public InventionRole GeneralPermission { get; set; } = InventionRole.Unassigned;
|
||||
|
||||
public bool IsAGInvention { get; set; } = false;
|
||||
public bool IsCertifiedInvention { get; set; } = false;
|
||||
public bool IsPublished { get; set; } = false;
|
||||
|
||||
public bool AllowTrial { get; set; } = false;
|
||||
public bool HideFromPlayer { get; set; } = false;
|
||||
|
||||
public int? Price { get; set; } = 0;
|
||||
|
||||
public string BlobName { get; set; } = "";
|
||||
public int InstantiationCost { get; set; } = 0;
|
||||
|
||||
public int LightsCost { get; set; } = 0;
|
||||
public int AICost { get; set; } = 0;
|
||||
public int ChipsCost { get; set; } = 0;
|
||||
public int CloudVariablesCost { get; set; } = 0;
|
||||
|
||||
public long RoomOrigin { get; set; } = -1;
|
||||
public string Tags { get; set; } = string.Empty;
|
||||
|
||||
public Invention ToInvention()
|
||||
{
|
||||
return new Invention
|
||||
{
|
||||
InventionId = InventionId,
|
||||
CreationRoomId = RoomOrigin >= 0 ? RoomOrigin : 0,
|
||||
ReplicationId = ReplicationId,
|
||||
CreatorPlayerId = CreatorPlayerId,
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
ImageName = ImageName,
|
||||
CurrentVersionNumber = CurrentVersionNumber,
|
||||
ModifiedAt = ModifiedAt,
|
||||
CreatedAt = CreatedAt,
|
||||
NumPlayersHaveUsedInRoom = NumPlayersHaveUsedInRoom,
|
||||
NumDownloads = NumDownloads,
|
||||
CheerCount = CheerCount,
|
||||
CreatorPermission = CreatorPermission,
|
||||
GeneralPermission = GeneralPermission,
|
||||
IsAGInvention = IsAGInvention,
|
||||
IsCertifiedInvention = IsCertifiedInvention,
|
||||
IsPublished = IsPublished,
|
||||
AllowTrial = AllowTrial,
|
||||
HideFromPlayer = HideFromPlayer,
|
||||
Price = Price is > 0 ? Price : null
|
||||
};
|
||||
}
|
||||
public InventionVersion ToVersion()
|
||||
{
|
||||
return new InventionVersion
|
||||
{
|
||||
InventionId = InventionId,
|
||||
ReplicationId = ReplicationId,
|
||||
|
||||
BlobName = BlobName,
|
||||
|
||||
InstantiationCost = InstantiationCost,
|
||||
LightsCost = LightsCost,
|
||||
ChipsCost = ChipsCost,
|
||||
CloudVariablesCost = CloudVariablesCost,
|
||||
|
||||
VersionNumber = CurrentVersionNumber,
|
||||
};
|
||||
}
|
||||
public async Task<FullInvention> ToFullInvention(RecDBContext ctx)
|
||||
{
|
||||
var full = new FullInvention();
|
||||
full.Status = InventionStatus.Success;
|
||||
full.Invention = ToInvention();
|
||||
full.InventionVersion = await ctx.GetInventionVersion(CurrentVersionNumber, InventionId);
|
||||
return full;
|
||||
}
|
||||
public async Task<FullInvention> ToFullInvention(RecDBContext ctx, int version)
|
||||
{
|
||||
var full = new FullInvention();
|
||||
full.Status = InventionStatus.Success;
|
||||
full.Invention = ToInvention();
|
||||
full.InventionVersion = await ctx.GetInventionVersion(version, InventionId);
|
||||
return full;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InventionGetter
|
||||
{
|
||||
public static async Task<InventionVersion?> GetLatestInventionVersion(this RecDBContext ctx, long inventionId)
|
||||
{
|
||||
var ver = await ctx.InventionVersions.LastOrDefaultAsync(x => x.InventionId == inventionId);
|
||||
return ver;
|
||||
}
|
||||
public static async Task<InventionVersion?> GetInventionVersion(this RecDBContext ctx, int version, long inventionId)
|
||||
{
|
||||
var ver = await ctx.InventionVersions.FirstOrDefaultAsync(x => x.InventionId == inventionId && x.VersionNumber == version);
|
||||
return ver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class InventionPersonalDetails
|
||||
{
|
||||
[JsonIgnore, Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long DetailId { get; set; }
|
||||
[JsonIgnore]
|
||||
public long PlayerId { get; set; }
|
||||
[JsonIgnore]
|
||||
public long InventionId { get; set; }
|
||||
|
||||
public bool IsCheering { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class InventionVersion
|
||||
{
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), JsonIgnore]
|
||||
public long VersionId { get; set; }
|
||||
|
||||
public long InventionId { get; set; }
|
||||
public string ReplicationId { get; set; } = "";
|
||||
|
||||
public int VersionNumber { get; set; } = 0;
|
||||
|
||||
public int InstantiationCost { get; set; } = 0;
|
||||
public int CloudVariablesCost { get; set; } = 0;
|
||||
public int ChipsCost { get; set; } = 0;
|
||||
public int LightsCost { get; set; } = 0;
|
||||
|
||||
public string BlobName { get; set; } = "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
using CSharpDiscordWebhook.Objects;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
using RadicadeServer.RecNet;
|
||||
using RadicadeServer.RecNet.Inventions;
|
||||
using RadicadeServer.RecNet.Responses;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
using RadicadeServer.Utils;
|
||||
|
||||
namespace RadicadeServer.API.Inventions.V1
|
||||
{
|
||||
[Route("api/inventions/v1")]
|
||||
public class InventionsV1(RecDBContext db) : Controller
|
||||
{
|
||||
[HttpGet("room")]
|
||||
public List<object> GetInventionsInRoom()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
[HttpGet("fromcreators")]
|
||||
public async Task<IActionResult> GetInventionsFromCreators(
|
||||
[FromQuery] long[]? id,
|
||||
[FromQuery] int skip = 0,
|
||||
[FromQuery] int take = 100)
|
||||
{
|
||||
if (id == null || id.Length == 0)
|
||||
return BadRequest(new { error = "At least one creator id is required." });
|
||||
|
||||
var creatorIds = id.Where(creatorId => creatorId > 0).Distinct().ToArray();
|
||||
var offset = Math.Max(0, skip);
|
||||
var limit = Math.Clamp(take, 1, 100);
|
||||
var inventions = await db.Inventions
|
||||
.Where(invention => creatorIds.Contains(invention.CreatorPlayerId))
|
||||
.OrderByDescending(invention => invention.CreatedAt)
|
||||
.ThenByDescending(invention => invention.InventionId)
|
||||
.Skip(offset)
|
||||
.Take(limit)
|
||||
.ToListAsync();
|
||||
|
||||
return Ok(inventions.Select(invention => invention.ToInvention()).ToList());
|
||||
}
|
||||
|
||||
[HttpGet("unpublish"), Authorize]
|
||||
public async Task<FullInvention?> UnpublishInvention([FromQuery] long inventionId)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.CreatorPlayerId == userId && x.InventionId == inventionId);
|
||||
if (invention == null) return null;
|
||||
|
||||
invention.IsPublished = false;
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return await invention.ToFullInvention(db);
|
||||
}
|
||||
|
||||
[HttpGet("personaldetails/{inventionId}")]
|
||||
public async Task<InventionPersonalDetails?> GetPersonalDetailsForInvention(long inventionId)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var details = await db.InventionPersonalDetails.FirstOrDefaultAsync(x => x.InventionId == inventionId && x.PlayerId == userId);
|
||||
if (details == null) return new InventionPersonalDetails { IsCheering = false };
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
[HttpGet("tagfilters")]
|
||||
public RoomFilters? GetTagFilters()
|
||||
{
|
||||
return new RoomFilters
|
||||
{
|
||||
PinnedFilters = ["dormskin", "weapon", "certified", "plushie", "scifi", "fantasy", "costume", "art", "character", "environment", "gadget"],
|
||||
PopularFilters = ["dormskin", "weapon", "certified", "plushie", "scifi", "fantasy", "costume", "art", "character", "environment", "gadget"],
|
||||
TrendingFilters = []
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet("dormskinsfromids")]
|
||||
public async Task<List<long>> GetDormSkinsFromIds([FromQuery] string[]? ids)
|
||||
{
|
||||
var parsed = (ids ?? Array.Empty<string>())
|
||||
.SelectMany(raw => (raw ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
||||
.Select(part => long.TryParse(part, out var value) ? value : -1)
|
||||
.Where(value => value > 0)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (parsed.Count == 0) return [];
|
||||
|
||||
var known = await db.Inventions.AsNoTracking()
|
||||
.Where(x => parsed.Contains(x.InventionId) && !x.HideFromPlayer)
|
||||
.Select(x => x.InventionId)
|
||||
.ToListAsync();
|
||||
var knownSet = known.ToHashSet();
|
||||
|
||||
return parsed.Where(knownSet.Contains).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("featureddormskins")]
|
||||
public async Task<List<Invention>> GetFeaturedDormSkins()
|
||||
{
|
||||
var featured = await db.Inventions.AsNoTracking()
|
||||
.Where(x => !x.HideFromPlayer && x.IsPublished)
|
||||
.OrderByDescending(x => x.ModifiedAt)
|
||||
.Take(24)
|
||||
.ToListAsync();
|
||||
|
||||
return featured.Select(x => x.ToInvention()).ToList();
|
||||
}
|
||||
|
||||
[HttpGet("version"), Authorize]
|
||||
public async Task<InventionVersion?> GetInventionVersion([FromQuery] long inventionId, [FromQuery] int version)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == inventionId);
|
||||
if (invention == null) return null;
|
||||
|
||||
return await db.GetInventionVersion(version, inventionId);
|
||||
}
|
||||
|
||||
[HttpGet("update"), Authorize]
|
||||
public async Task<FullInvention?> UpdateInvention([FromQuery] long inventionId, [FromQuery] string? name, [FromQuery] string? imgName, [FromQuery] string? description, [FromQuery] string? permission)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.CreatorPlayerId == userId && x.InventionId == inventionId);
|
||||
if (invention == null) return null;
|
||||
|
||||
if (name != null)
|
||||
invention.Name = name;
|
||||
if (description != null)
|
||||
invention.Description = description;
|
||||
if (imgName != null)
|
||||
invention.ImageName = imgName;
|
||||
|
||||
if (permission != null)
|
||||
{
|
||||
if (Enum.TryParse<InventionRole>(permission, out var parsedRole))
|
||||
invention.GeneralPermission = parsedRole;
|
||||
}
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return await invention.ToFullInvention(db);
|
||||
}
|
||||
|
||||
[HttpGet("toptoday")]
|
||||
public async Task<List<Invention>> GetTopInventions()
|
||||
{
|
||||
var topInventions = await db.Inventions.Where(x => !x.HideFromPlayer && x.IsPublished)
|
||||
.OrderByDescending(x => x.ModifiedAt).ToListAsync();
|
||||
|
||||
var converted = new List<Invention>();
|
||||
foreach (var i in topInventions)
|
||||
{
|
||||
var invention = i.ToInvention();
|
||||
converted.Add(invention);
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
[HttpGet("featured")]
|
||||
public async Task<List<Invention>> GetFeaturedInventions()
|
||||
{
|
||||
var featured = await db.Inventions
|
||||
.Where(x => !x.HideFromPlayer && x.IsPublished)
|
||||
.OrderByDescending(x => x.ModifiedAt)
|
||||
.Take(24)
|
||||
.ToListAsync();
|
||||
|
||||
return featured.Select(x => x.ToInvention()).ToList();
|
||||
}
|
||||
|
||||
[HttpPost("settags"), Authorize]
|
||||
public async Task<InventionTagResponse?> UpdateInventionTags([FromBody] ModifyInventionTagsRequest req)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.CreatorPlayerId == userId && x.InventionId == req.InventionId);
|
||||
if (invention == null) return new InventionTagResponse { Result = RecNet.Enums.InventionTagResult.InventionDoesNotExist };
|
||||
if (req.CustomTags.Count >= 10) new InventionTagResponse { Result = RecNet.Enums.InventionTagResult.TooManyTags };
|
||||
|
||||
var tags = new List<ItemTag>();
|
||||
foreach (string tag in req.AutoTags)
|
||||
{
|
||||
tags.Add(new ItemTag { Tag = tag, Type = RecNet.Enums.TagType.Auto });
|
||||
}
|
||||
foreach (string tag in req.CustomTags)
|
||||
{
|
||||
tags.Add(new ItemTag { Tag = tag, Type = RecNet.Enums.TagType.General });
|
||||
}
|
||||
invention.Tags = StringTools.CreateTagString(tags);
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return new InventionTagResponse { Tags = StringTools.TagsToStrings(tags), Result = RecNet.Enums.InventionTagResult.Success };
|
||||
}
|
||||
|
||||
[HttpGet("details"), Authorize]
|
||||
public async Task<TagResponse?> GetInventionDetails([FromQuery] long inventionId)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == inventionId);
|
||||
|
||||
if (invention == null)
|
||||
return null;
|
||||
if (invention.Tags == null)
|
||||
return new TagResponse { Tags = [] };
|
||||
|
||||
return new TagResponse { Tags = StringTools.ReadTags(invention.Tags) };
|
||||
}
|
||||
|
||||
[HttpGet("batch"), Authorize]
|
||||
public async Task<List<Invention>?> GetBatchInventions([FromBody] List<long> ids)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var inventions = new List<Invention>();
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == id);
|
||||
if (invention == null) continue;
|
||||
inventions.Add(invention.ToInvention());
|
||||
}
|
||||
|
||||
return inventions;
|
||||
}
|
||||
|
||||
[HttpGet("fulllineageowner"), Authorize]
|
||||
public async Task<bool> OwnsInventionLineage([FromQuery] List<long> id)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var unlocks = await db.Unlocks.AsNoTracking().FirstOrDefaultAsync(x => x.AccountId == userId);
|
||||
var bought = new HashSet<long>();
|
||||
if (unlocks != null && !string.IsNullOrWhiteSpace(unlocks.Inventions) && unlocks.Inventions != "null")
|
||||
{
|
||||
try { bought = (unlocks.Inventions.FromJson<List<long>>() ?? new List<long>()).ToHashSet(); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
bool owns = false;
|
||||
foreach (var i in id)
|
||||
{
|
||||
if (bought.Contains(i))
|
||||
{
|
||||
owns = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == i);
|
||||
|
||||
|
||||
|
||||
if (invention != null)
|
||||
owns = (invention.CreatorPlayerId == userId || invention.GeneralPermission == InventionRole.Publish);
|
||||
|
||||
if (owns) break;
|
||||
}
|
||||
|
||||
return owns;
|
||||
}
|
||||
|
||||
[HttpGet(""), Authorize]
|
||||
public async Task<InventionDB?> GetInventionById([FromQuery] long id)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == id);
|
||||
if (invention == null) return null;
|
||||
|
||||
return invention;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
using RadicadeServer.RecNet.Inventions;
|
||||
|
||||
namespace RadicadeServer.API.Inventions.V2
|
||||
{
|
||||
[Route("api/inventions/v2")]
|
||||
public class InventionsV2(RecDBContext db) : Controller
|
||||
{
|
||||
[HttpGet("search")]
|
||||
public async Task<List<Invention>> SearchInventions([FromQuery] int? take, [FromQuery] string? value)
|
||||
{
|
||||
if (take == null) take = 50;
|
||||
|
||||
List<InventionDB>? foundInventions = null;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
foundInventions = await db.Inventions.Where(x => !x.HideFromPlayer && x.IsPublished &&
|
||||
(x.Name.Contains(value) || x.Description.Contains(value) || x.Tags.Contains(value))
|
||||
).OrderByDescending(x => x.ModifiedAt).Take((int)take).ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
foundInventions = await db.Inventions.Where(x => !x.HideFromPlayer && x.IsPublished)
|
||||
.OrderByDescending(x => x.ModifiedAt).Take((int)take).ToListAsync();
|
||||
}
|
||||
|
||||
var converted = new List<Invention>();
|
||||
foreach (var i in foundInventions)
|
||||
{
|
||||
var invention = i.ToInvention();
|
||||
converted.Add(invention);
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
[HttpGet("batch"), Authorize]
|
||||
public async Task<List<Invention>?> GetBatchInventions_V2([FromQuery] List<long> id)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var inventions = new List<Invention>();
|
||||
|
||||
foreach (var i in id)
|
||||
{
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == i);
|
||||
if (invention == null) continue;
|
||||
inventions.Add(invention.ToInvention());
|
||||
}
|
||||
|
||||
return inventions;
|
||||
}
|
||||
|
||||
[HttpGet("mine"), Authorize]
|
||||
public async Task<List<Invention>> GetOwnedInventions()
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var unlocks = await db.Unlocks.FirstOrDefaultAsync(x => x.AccountId == userId);
|
||||
if (unlocks == null) return [];
|
||||
|
||||
var ownedInventions = unlocks.Inventions.FromJson<List<long>>() ?? new List<long>();
|
||||
|
||||
var allInventions = new List<Invention>();
|
||||
foreach (var invention in ownedInventions)
|
||||
{
|
||||
var foundInvention = await db.Inventions.FirstOrDefaultAsync(x => x.InventionId == invention);
|
||||
if (foundInvention != null)
|
||||
allInventions.Add(foundInvention.ToInvention());
|
||||
}
|
||||
|
||||
return allInventions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
using RadicadeServer.RecNet.Inventions;
|
||||
|
||||
namespace RadicadeServer.API.Inventions.V3
|
||||
{
|
||||
[Route("api/inventions/v3")]
|
||||
public class InventionsV3(RecDBContext db) : Controller
|
||||
{
|
||||
[HttpGet("publish"), Authorize]
|
||||
public async Task<FullInvention?> PublishInvention([FromQuery] long inventionId, [FromQuery] InventionRole permissionLevel, [FromQuery] int? price)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.CreatorPlayerId == userId && x.InventionId == inventionId);
|
||||
if (invention == null) return null;
|
||||
|
||||
invention.IsPublished = true;
|
||||
invention.HideFromPlayer = false;
|
||||
|
||||
if (price.HasValue)
|
||||
invention.Price = price.Value;
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return await invention.ToFullInvention(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
using RadicadeServer.RecNet.Inventions;
|
||||
|
||||
namespace RadicadeServer.API.Inventions.V4
|
||||
{
|
||||
[Route("api/inventions/v4")]
|
||||
public class InventionsV4(RecDBContext db) : Controller
|
||||
{
|
||||
[HttpPost("addversion"), Authorize]
|
||||
public async Task<FullInvention?> AddInventionVersion([FromBody] NewInventionVersionDTO req)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
var invention = await db.Inventions.FirstOrDefaultAsync(x => x.CreatorPlayerId == userId && x.InventionId == req.inventionId);
|
||||
if (invention == null) return null;
|
||||
|
||||
var version = new InventionVersion
|
||||
{
|
||||
BlobName = req.inventionDataFilename,
|
||||
ChipsCost = req.chipsCost,
|
||||
CloudVariablesCost = req.cloudVariablesCost,
|
||||
InstantiationCost = req.instantiationCost,
|
||||
InventionId = req.inventionId,
|
||||
ReplicationId = invention.ReplicationId,
|
||||
LightsCost = invention.LightsCost,
|
||||
VersionNumber = invention.CurrentVersionNumber + 1
|
||||
};
|
||||
|
||||
await db.InventionVersions.AddAsync(version);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
invention.CurrentVersionNumber = version.VersionNumber;
|
||||
|
||||
invention.BlobName = req.inventionDataFilename;
|
||||
|
||||
invention.RoomOrigin = req.creationRoomId;
|
||||
|
||||
invention.ModifiedAt = DateTime.Now;
|
||||
|
||||
invention.InstantiationCost = req.instantiationCost;
|
||||
invention.LightsCost = req.lightsCost;
|
||||
invention.ChipsCost = req.chipsCost;
|
||||
invention.CloudVariablesCost = req.cloudVariablesCost;
|
||||
invention.AICost = req.aiCost;
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return await invention.ToFullInvention(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Enums.Inventions;
|
||||
using RadicadeServer.RecNet.Inventions;
|
||||
using RadicadeServer.Utils;
|
||||
|
||||
namespace RadicadeServer.API.Inventions.V6
|
||||
{
|
||||
[Route("api/inventions/v6")]
|
||||
public class InventionsV6(RecDBContext db) : Controller
|
||||
{
|
||||
[HttpPost("save"), Authorize]
|
||||
public async Task<FullInvention?> SaveInventionV6([FromBody] NewInventionRequestDTO_V6 dto)
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
||||
if (!dto.name.IsPure()) return new FullInvention { Status = InventionStatus.InnapropriateName };
|
||||
if (!dto.description.IsPure()) return new FullInvention { Status = InventionStatus.InnapropriateDescription };
|
||||
|
||||
var playerUnlocks = await db.Unlocks.FirstOrDefaultAsync(x => x.AccountId == userId);
|
||||
if (playerUnlocks == null) return null;
|
||||
|
||||
var invention = new InventionDB
|
||||
{
|
||||
Name = dto.name,
|
||||
CreatorPlayerId = (long)userId!,
|
||||
InstantiationCost = dto.instantiationCost,
|
||||
LightsCost = dto.lightsCost,
|
||||
RoomOrigin = dto.creationRoomId,
|
||||
ImageName = dto.imageName,
|
||||
BlobName = dto.inventionDataFilename,
|
||||
Description = dto.description,
|
||||
ReplicationId = Guid.NewGuid().ToString(),
|
||||
GeneralPermission = InventionRole.Publish
|
||||
};
|
||||
|
||||
await db.AddAsync(invention);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var version = new InventionVersion
|
||||
{
|
||||
BlobName = dto.inventionDataFilename,
|
||||
ChipsCost = dto.chipsCost,
|
||||
CloudVariablesCost = dto.cloudVariablesCost,
|
||||
InstantiationCost = dto.instantiationCost,
|
||||
InventionId = invention.InventionId,
|
||||
ReplicationId = invention.ReplicationId,
|
||||
LightsCost = invention.LightsCost,
|
||||
VersionNumber = invention.CurrentVersionNumber
|
||||
};
|
||||
|
||||
await db.InventionVersions.AddAsync(version);
|
||||
|
||||
var inventionIds = playerUnlocks.Inventions.FromJson<List<long>>();
|
||||
if (inventionIds == null) inventionIds = new List<long>();
|
||||
if (!inventionIds.Contains(invention.InventionId))
|
||||
{
|
||||
inventionIds.Add(invention.InventionId);
|
||||
playerUnlocks.Inventions = inventionIds.ToJson();
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return await invention.ToFullInvention(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class ModifyInventionTagsRequest
|
||||
{
|
||||
public long InventionId { get; set; }
|
||||
public List<string> AutoTags { get; set; } = new();
|
||||
public List<string> CustomTags { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using RadicadeServer.RecNet.Enums.Rooms;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class NewInventionRequestDTO
|
||||
{
|
||||
public string name { get; set; } = "";
|
||||
public string description { get; set; } = "";
|
||||
public string imageName { get; set; } = "";
|
||||
public string inventionDataFilename { get; set; } = "";
|
||||
|
||||
public List<long> referencedInventions { get; set; } = new();
|
||||
|
||||
public RoleType creatorAccountRole { get; set; }
|
||||
|
||||
public int instantiationCost { get; set; }
|
||||
public int lightsCost { get; set; }
|
||||
public int aiCost { get; set; }
|
||||
|
||||
public long creationRoomId { get; set; }
|
||||
}
|
||||
public class NewInventionRequestDTO_V6
|
||||
{
|
||||
public string name { get; set; } = "";
|
||||
public string description { get; set; } = "";
|
||||
public string imageName { get; set; } = "";
|
||||
public string inventionDataFilename { get; set; } = "";
|
||||
|
||||
public List<long> referencedInventions { get; set; } = new();
|
||||
|
||||
public RoleType creatorAccountRole { get; set; } = RoleType.Creator;
|
||||
|
||||
public int instantiationCost { get; set; } = 0;
|
||||
public int cloudVariablesCost { get; set; } = 0;
|
||||
public int chipsCost { get; set; } = 0;
|
||||
public int lightsCost { get; set; } = 0;
|
||||
public int aiCost { get; set; } = 0;
|
||||
|
||||
public long creationRoomId { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace RadicadeServer.RecNet.Inventions
|
||||
{
|
||||
public class NewInventionVersionDTO
|
||||
{
|
||||
public int aiCost { get; set; } = 0;
|
||||
public int chipsCost { get; set; } = 0;
|
||||
public int cloudVariablesCost { get; set; } = 0;
|
||||
public int lightsCost { get; set; } = 0;
|
||||
public int instantiationCost { get; set; } = 0;
|
||||
|
||||
public string inventionDataFilename { get; set; } = "";
|
||||
|
||||
public List<long> referencedInventions { get; set; } = new();
|
||||
|
||||
public long inventionId { get; set; } = 0;
|
||||
public long creationRoomId { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user