Merge pull request #14 from LBPUnion/hearted-levels

Hearted levels
This commit is contained in:
jvyden 2021-10-18 23:18:07 -04:00 committed by GitHub
commit 5487d06fec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 595 additions and 63 deletions

View file

@ -11,5 +11,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=lolcatftw/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=lolcatftw/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Swingy/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Swingy/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=thumbsup/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=thumbsup/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=unfavourite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unpublish/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Unpublish/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=yourthumb/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/UserDictionary/Words/=yourthumb/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -0,0 +1,119 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ProjectLighthouse.Serialization;
using ProjectLighthouse.Types;
namespace ProjectLighthouse.Controllers {
[ApiController]
[Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")]
public class LevelListController : ControllerBase {
private readonly Database database;
public LevelListController(Database database) {
this.database = database;
}
#region Level Queue (lolcatftw)
[HttpGet("slots/lolcatftw/{username}")]
public IActionResult GetLevelQueue(string username) {
IEnumerable<QueuedLevel> queuedLevels = new Database().QueuedLevels
.Include(q => q.User)
.Include(q => q.Slot)
.Include(q => q.Slot.Location)
.Where(q => q.User.Username == username)
.AsEnumerable();
string response = queuedLevels.Aggregate(string.Empty, (current, q) => current + q.Slot.Serialize());
return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "total", 1));
}
[HttpPost("lolcatftw/remove/user/{id:int}")]
public async Task<IActionResult> RemoveQueuedLevel(int id) {
User? user = await this.database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
QueuedLevel queuedLevel = await this.database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(queuedLevel != null) this.database.QueuedLevels.Remove(queuedLevel);
await this.database.SaveChangesAsync();
return this.Ok();
}
[HttpPost("lolcatftw/add/user/{id:int}")]
public async Task<IActionResult> AddQueuedLevel(int id) {
User? user = await this.database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
QueuedLevel queuedLevel = await this.database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(queuedLevel != null) return this.Ok();
this.database.QueuedLevels.Add(new QueuedLevel {
SlotId = id,
UserId = user.UserId,
});
await this.database.SaveChangesAsync();
return this.Ok();
}
#endregion
#region Hearted Levels
[HttpGet("favouriteSlots/{username}")]
public async Task<IActionResult> GetFavouriteSlots(string username) {
IEnumerable<HeartedLevel> heartedLevels = new Database().HeartedLevels
.Include(q => q.User)
.Include(q => q.Slot)
.Include(q => q.Slot.Location)
.Where(q => q.User.Username == username)
.AsEnumerable();
string response = heartedLevels.Aggregate(string.Empty, (current, q) => current + q.Slot.Serialize());
return this.Ok(LbpSerializer.TaggedStringElement("favouriteSlots", response, "total", 1));
}
[HttpPost("favourite/slot/user/{id:int}")]
public async Task<IActionResult> AddFavourite(int id) {
User? user = await this.database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
HeartedLevel heartedLevel = await this.database.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(heartedLevel != null) return this.Ok();
this.database.HeartedLevels.Add(new HeartedLevel {
SlotId = id,
UserId = user.UserId,
});
await this.database.SaveChangesAsync();
return this.Ok();
}
[HttpPost("unfavourite/slot/user/{id:int}")]
public async Task<IActionResult> RemoveFavourite(int id) {
User? user = await this.database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
HeartedLevel heartedLevel = await this.database.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(heartedLevel != null) this.database.HeartedLevels.Remove(heartedLevel);
await this.database.SaveChangesAsync();
return this.Ok();
}
#endregion
}
}

View file

@ -1,63 +0,0 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ProjectLighthouse.Serialization;
using ProjectLighthouse.Types;
namespace ProjectLighthouse.Controllers {
[ApiController]
[Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")]
public class LevelQueueController : ControllerBase {
[HttpGet("slots/lolcatftw/{username}")]
public IActionResult GetLevelQueue(string username) {
IEnumerable<QueuedLevel> queuedLevels = new Database().QueuedLevels
.Include(q => q.User)
.Include(q => q.Slot)
.Where(q => q.User.Username == username)
.AsEnumerable();
string response = queuedLevels.Aggregate(string.Empty, (current, q) => current + q.Slot.Serialize());
return this.Ok(LbpSerializer.TaggedStringElement("slots", response, "total", 1));
}
[HttpPost("lolcatftw/remove/user/{id:int}")]
public async Task<IActionResult> RemoveQueuedLevel(int id) {
await using Database database = new();
User? user = await database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
QueuedLevel queuedLevel = await database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(queuedLevel != null) database.QueuedLevels.Remove(queuedLevel);
await database.SaveChangesAsync();
return this.Ok();
}
[HttpPost("lolcatftw/add/user/{id:int}")]
public async Task<IActionResult> AddQueuedLevel(int id) {
await using Database database = new();
User? user = await database.UserFromRequest(this.Request);
if(user == null) return this.StatusCode(403, "");
QueuedLevel queuedLevel = await database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id);
if(queuedLevel != null) return this.Ok();
database.QueuedLevels.Add(new QueuedLevel {
SlotId = id,
UserId = user.UserId
});
await database.SaveChangesAsync();
return this.Ok();
}
}
}

View file

@ -10,6 +10,7 @@ namespace ProjectLighthouse {
public DbSet<Location> Locations { get; set; } public DbSet<Location> Locations { get; set; }
public DbSet<Slot> Slots { get; set; } public DbSet<Slot> Slots { get; set; }
public DbSet<QueuedLevel> QueuedLevels { get; set; } public DbSet<QueuedLevel> QueuedLevels { get; set; }
public DbSet<HeartedLevel> HeartedLevels { get; set; }
public DbSet<Comment> Comments { get; set; } public DbSet<Comment> Comments { get; set; }
public DbSet<Token> Tokens { get; set; } public DbSet<Token> Tokens { get; set; }

View file

@ -0,0 +1,364 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ProjectLighthouse;
namespace ProjectLighthouse.Migrations
{
[DbContext(typeof(Database))]
[Migration("20211019031221_HeartedLevels")]
partial class HeartedLevels
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.11");
modelBuilder.Entity("ProjectLighthouse.Types.Comment", b =>
{
b.Property<int>("CommentId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Message")
.HasColumnType("longtext");
b.Property<int>("PosterUserId")
.HasColumnType("int");
b.Property<int>("TargetUserId")
.HasColumnType("int");
b.Property<int>("ThumbsDown")
.HasColumnType("int");
b.Property<int>("ThumbsUp")
.HasColumnType("int");
b.Property<long>("Timestamp")
.HasColumnType("bigint");
b.HasKey("CommentId");
b.HasIndex("PosterUserId");
b.HasIndex("TargetUserId");
b.ToTable("Comments");
});
modelBuilder.Entity("ProjectLighthouse.Types.HeartedLevel", b =>
{
b.Property<int>("HeartedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("HeartedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("HeartedLevels");
});
modelBuilder.Entity("ProjectLighthouse.Types.Location", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("X")
.HasColumnType("int");
b.Property<int>("Y")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Locations");
});
modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b =>
{
b.Property<int>("QueuedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("QueuedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("QueuedLevels");
});
modelBuilder.Entity("ProjectLighthouse.Types.Slot", b =>
{
b.Property<int>("SlotId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("AuthorLabels")
.HasColumnType("longtext");
b.Property<string>("BackgroundHash")
.HasColumnType("longtext");
b.Property<int>("CreatorId")
.HasColumnType("int");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<string>("IconHash")
.HasColumnType("longtext");
b.Property<bool>("InitiallyLocked")
.HasColumnType("tinyint(1)");
b.Property<bool>("Lbp1Only")
.HasColumnType("tinyint(1)");
b.Property<int>("LocationId")
.HasColumnType("int");
b.Property<int>("MaximumPlayers")
.HasColumnType("int");
b.Property<int>("MinimumPlayers")
.HasColumnType("int");
b.Property<bool>("MoveRequired")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.HasColumnType("longtext");
b.Property<string>("Resource")
.HasColumnType("longtext");
b.Property<string>("RootLevel")
.HasColumnType("longtext");
b.Property<int>("Shareable")
.HasColumnType("int");
b.Property<bool>("SubLevel")
.HasColumnType("tinyint(1)");
b.HasKey("SlotId");
b.HasIndex("CreatorId");
b.HasIndex("LocationId");
b.ToTable("Slots");
});
modelBuilder.Entity("ProjectLighthouse.Types.Token", b =>
{
b.Property<int>("TokenId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<string>("UserToken")
.HasColumnType("longtext");
b.HasKey("TokenId");
b.ToTable("Tokens");
});
modelBuilder.Entity("ProjectLighthouse.Types.User", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Biography")
.HasColumnType("longtext");
b.Property<string>("BooHash")
.HasColumnType("longtext");
b.Property<int>("CommentCount")
.HasColumnType("int");
b.Property<bool>("CommentsEnabled")
.HasColumnType("tinyint(1)");
b.Property<int>("FavouriteSlotCount")
.HasColumnType("int");
b.Property<int>("FavouriteUserCount")
.HasColumnType("int");
b.Property<int>("Game")
.HasColumnType("int");
b.Property<int>("HeartCount")
.HasColumnType("int");
b.Property<string>("IconHash")
.HasColumnType("longtext");
b.Property<int>("Lists")
.HasColumnType("int");
b.Property<int>("LocationId")
.HasColumnType("int");
b.Property<int>("LolCatFtwCount")
.HasColumnType("int");
b.Property<int>("PhotosByMeCount")
.HasColumnType("int");
b.Property<int>("PhotosWithMeCount")
.HasColumnType("int");
b.Property<string>("Pins")
.HasColumnType("longtext");
b.Property<string>("PlanetHash")
.HasColumnType("longtext");
b.Property<int>("ReviewCount")
.HasColumnType("int");
b.Property<int>("StaffChallengeBronzeCount")
.HasColumnType("int");
b.Property<int>("StaffChallengeGoldCount")
.HasColumnType("int");
b.Property<int>("StaffChallengeSilverCount")
.HasColumnType("int");
b.Property<int>("UsedSlots")
.HasColumnType("int");
b.Property<string>("Username")
.HasColumnType("longtext");
b.Property<string>("YayHash")
.HasColumnType("longtext");
b.HasKey("UserId");
b.HasIndex("LocationId");
b.ToTable("Users");
});
modelBuilder.Entity("ProjectLighthouse.Types.Comment", b =>
{
b.HasOne("ProjectLighthouse.Types.User", "Poster")
.WithMany()
.HasForeignKey("PosterUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ProjectLighthouse.Types.User", "Target")
.WithMany()
.HasForeignKey("TargetUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Poster");
b.Navigation("Target");
});
modelBuilder.Entity("ProjectLighthouse.Types.HeartedLevel", b =>
{
b.HasOne("ProjectLighthouse.Types.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b =>
{
b.HasOne("ProjectLighthouse.Types.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("ProjectLighthouse.Types.Slot", b =>
{
b.HasOne("ProjectLighthouse.Types.User", "Creator")
.WithMany()
.HasForeignKey("CreatorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ProjectLighthouse.Types.Location", "Location")
.WithMany()
.HasForeignKey("LocationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Creator");
b.Navigation("Location");
});
modelBuilder.Entity("ProjectLighthouse.Types.User", b =>
{
b.HasOne("ProjectLighthouse.Types.Location", "Location")
.WithMany()
.HasForeignKey("LocationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Location");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace ProjectLighthouse.Migrations
{
public partial class HeartedLevels : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "HeartedLevels",
columns: table => new
{
HeartedLevelId = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(type: "int", nullable: false),
SlotId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_HeartedLevels", x => x.HeartedLevelId);
table.ForeignKey(
name: "FK_HeartedLevels_Slots_SlotId",
column: x => x.SlotId,
principalTable: "Slots",
principalColumn: "SlotId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_HeartedLevels_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_HeartedLevels_SlotId",
table: "HeartedLevels",
column: "SlotId");
migrationBuilder.CreateIndex(
name: "IX_HeartedLevels_UserId",
table: "HeartedLevels",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "HeartedLevels");
}
}
}

View file

@ -49,6 +49,27 @@ namespace ProjectLighthouse.Migrations
b.ToTable("Comments"); b.ToTable("Comments");
}); });
modelBuilder.Entity("ProjectLighthouse.Types.HeartedLevel", b =>
{
b.Property<int>("HeartedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("HeartedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("HeartedLevels");
});
modelBuilder.Entity("ProjectLighthouse.Types.Location", b => modelBuilder.Entity("ProjectLighthouse.Types.Location", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -268,6 +289,25 @@ namespace ProjectLighthouse.Migrations
b.Navigation("Target"); b.Navigation("Target");
}); });
modelBuilder.Entity("ProjectLighthouse.Types.HeartedLevel", b =>
{
b.HasOne("ProjectLighthouse.Types.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b => modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b =>
{ {
b.HasOne("ProjectLighthouse.Types.Slot", "Slot") b.HasOne("ProjectLighthouse.Types.Slot", "Slot")

View file

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ProjectLighthouse.Types {
public class HeartedLevel {
[Key] public int HeartedLevelId { get; set; }
public int UserId { get; set; }
[ForeignKey(nameof(UserId))] public User User { get; set; }
public int SlotId { get; set; }
[ForeignKey(nameof(SlotId))] public Slot Slot { get; set; }
}
}