Radicade Public Code

This commit is contained in:
JogmansonReal
2026-10-16 23:33:13 -07:00
commit 55175acdf6
832 changed files with 363261 additions and 0 deletions
+13
View File
@@ -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
}
}
+11
View File
@@ -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;
}
}
+29
View File
@@ -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; }
}
}
+27
View File
@@ -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);
}
}
}
+128
View File
@@ -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; }
}
}
+24
View File
@@ -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; } = "";
}
}
+291
View File
@@ -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;
}
}
}
+81
View File
@@ -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;
}
}
}
+33
View File
@@ -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);
}
}
}
+56
View File
@@ -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);
}
}
}
+69
View File
@@ -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; }
}
}