From 21b7cd96947150535d516aba0db680e98856ab06 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 3 Mar 2025 12:35:08 -0800 Subject: [PATCH 01/18] initial data model work --- src/Controllers/Common/ContentController.cs | 2 +- src/Controllers/Common/MessagingController.cs | 16 +- .../20250303203411_Buddies.Designer.cs | 1307 +++++++++++++++++ src/Migrations/20250303203411_Buddies.cs | 54 + src/Migrations/DBContextModelSnapshot.cs | 50 + src/Model/Buddy.cs | 22 + src/Model/DBContext.cs | 15 + src/Model/Viking.cs | 2 + 8 files changed, 1453 insertions(+), 15 deletions(-) create mode 100644 src/Migrations/20250303203411_Buddies.Designer.cs create mode 100644 src/Migrations/20250303203411_Buddies.cs create mode 100644 src/Model/Buddy.cs diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 4916ab6..9bc67fb 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1147,7 +1147,7 @@ public class ContentController : Controller { [Route("ContentWebService.asmx/GetBuddyList")] public IActionResult GetBuddyList() { // TODO: this is a placeholder - return Ok(new BuddyList { Buddy = new Buddy[0] }); + return Ok(new BuddyList { Buddy = new Schema.Buddy[0] }); } [HttpPost] diff --git a/src/Controllers/Common/MessagingController.cs b/src/Controllers/Common/MessagingController.cs index 1385c70..cbdd63b 100644 --- a/src/Controllers/Common/MessagingController.cs +++ b/src/Controllers/Common/MessagingController.cs @@ -35,21 +35,9 @@ public class MessagingController : Controller { // clients (at least older ones) don't send what typeID the message is, its encoded in data ArrayOfKeyValuePairOfStringString arrayOfKeyValuePairOfStringString = XmlUtil.DeserializeXml(data); - MessageTypeID typeID = MessageTypeID.Unknown; - string typeText = ""; - switch(arrayOfKeyValuePairOfStringString.KeyValuePairOfStringString[0]?.Value) - { - case "Drawing": - typeID = MessageTypeID.GreetingCard; - typeText = "Card"; - break; - case "Photo": - typeID = MessageTypeID.Photo; - typeText = "PhotoBomb"; - break; - } + MessageTypeID typeID = (MessageTypeID)int.Parse(arrayOfKeyValuePairOfStringString.KeyValuePairOfStringString![0].Value ?? "0"); - var msg = messagingService.AddMessageToViking(viking, toViking, MessageType.Data, typeID, MessageLevel.WhiteList, data, "[[Line1]]=[[{{BuddyUserName}}]] has sent you a " + typeText + "!", "[[Line1]]=[[{{BuddyUserName}}]] has sent you a " + typeText + "!"); + var msg = messagingService.AddMessageToViking(viking, toViking, MessageType.Data, typeID, MessageLevel.WhiteList, data, "[[Line1]]=[[{{BuddyUserName}}]] has sent you a {{MessageType}}!", "[[Line1]]=[[{{BuddyUserName}}]] has sent you a {{MessageType}}!"); if (msg != null) return Ok(true); else return Ok(false); } diff --git a/src/Migrations/20250303203411_Buddies.Designer.cs b/src/Migrations/20250303203411_Buddies.Designer.cs new file mode 100644 index 0000000..cc94606 --- /dev/null +++ b/src/Migrations/20250303203411_Buddies.Designer.cs @@ -0,0 +1,1307 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250303203411_Buddies")] + partial class Buddies + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId"); + + b.HasIndex("BuddyVikingId"); + + b.ToTable("Buddy"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250303203411_Buddies.cs b/src/Migrations/20250303203411_Buddies.cs new file mode 100644 index 0000000..0c39613 --- /dev/null +++ b/src/Migrations/20250303203411_Buddies.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Buddies : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Buddy", + columns: table => new + { + VikingId = table.Column(type: "INTEGER", nullable: false), + BuddyVikingId = table.Column(type: "INTEGER", nullable: false), + BuddyStatus1 = table.Column(type: "INTEGER", nullable: false), + BuddyStatus2 = table.Column(type: "INTEGER", nullable: false), + IsBestFriend1 = table.Column(type: "INTEGER", nullable: false), + IsBestFriend2 = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Buddy", x => x.VikingId); + table.ForeignKey( + name: "FK_Buddy_Vikings_BuddyVikingId", + column: x => x.BuddyVikingId, + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Buddy_Vikings_VikingId", + column: x => x.VikingId, + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Buddy_BuddyVikingId", + table: "Buddy", + column: "BuddyVikingId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Buddy"); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 07798dd..a450226 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -70,6 +70,33 @@ namespace sodoff.Migrations b.ToTable("AchievementTaskState"); }); + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId"); + + b.HasIndex("BuddyVikingId"); + + b.ToTable("Buddy"); + }); + modelBuilder.Entity("sodoff.Model.Dragon", b => { b.Property("Id") @@ -849,6 +876,25 @@ namespace sodoff.Migrations b.Navigation("Viking"); }); + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + modelBuilder.Entity("sodoff.Model.Dragon", b => { b.HasOne("sodoff.Model.Viking", "Viking") @@ -1206,6 +1252,10 @@ namespace sodoff.Migrations b.Navigation("AchievementTaskStates"); + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + b.Navigation("Dragons"); b.Navigation("GameData"); diff --git a/src/Model/Buddy.cs b/src/Model/Buddy.cs new file mode 100644 index 0000000..273e3de --- /dev/null +++ b/src/Model/Buddy.cs @@ -0,0 +1,22 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; +using sodoff.Schema; + +namespace sodoff.Model; + +[PrimaryKey(nameof(VikingId))] +public class Buddy +{ + public int VikingId { get; set; } + public int BuddyVikingId { get; set; } + + public BuddyStatus BuddyStatus1 { get; set; } + public BuddyStatus BuddyStatus2 { get; set; } + + public bool IsBestFriend1 { get; set; } + public bool IsBestFriend2 { get; set; } + + public virtual Viking? Viking { get; set; } + public virtual Viking? BuddyViking { get; set; } +} diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index 52f9922..5b154c1 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -167,6 +167,12 @@ public class DBContext : DbContext { builder.Entity().HasMany(v => v.MessagesMade) .WithOne(r => r.Viking); + builder.Entity().HasMany(v => v.BuddyList) + .WithOne(r => r.BuddyViking); + + builder.Entity().HasMany(v => v.BuddiesMade) + .WithOne(r => r.Viking); + // Dragons builder.Entity().HasOne(d => d.Viking) .WithMany(e => e.Dragons) @@ -331,5 +337,14 @@ public class DBContext : DbContext { .WithOne(e => e.ParentMessage) .HasForeignKey(e => e.ParentMessageId) .OnDelete(DeleteBehavior.Cascade); + + // Buddies + builder.Entity().HasOne(r => r.BuddyViking) + .WithMany(e => e.BuddyList) + .HasForeignKey(e => e.BuddyVikingId); + + builder.Entity().HasOne(r => r.Viking) + .WithMany(e => e.BuddiesMade) + .HasForeignKey(e => e.VikingId); } } diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index 28ce7df..a54513e 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -47,6 +47,8 @@ public class Viking { public virtual ICollection UserBans { get; set; } = null!; public virtual ICollection MessageBoard { get; set; } = null!; public virtual ICollection MessagesMade { get; set; } = null!; + public virtual ICollection BuddyList { get; set; } = null!; + public virtual ICollection BuddiesMade { get; set; } = null!; public DateTime? CreationDate { get; set; } public DateTime? BirthDate { get; set; } From a3ba9556d0c50763e20232a67ba97b23b7a85175 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 3 Mar 2025 12:42:49 -0800 Subject: [PATCH 02/18] data model fix --- ...0250303204009_Buddies_DBSetFix.Designer.cs | 1307 +++++++++++++++++ .../20250303204009_Buddies_DBSetFix.cs | 22 + src/Model/DBContext.cs | 1 + 3 files changed, 1330 insertions(+) create mode 100644 src/Migrations/20250303204009_Buddies_DBSetFix.Designer.cs create mode 100644 src/Migrations/20250303204009_Buddies_DBSetFix.cs diff --git a/src/Migrations/20250303204009_Buddies_DBSetFix.Designer.cs b/src/Migrations/20250303204009_Buddies_DBSetFix.Designer.cs new file mode 100644 index 0000000..b7ebf7c --- /dev/null +++ b/src/Migrations/20250303204009_Buddies_DBSetFix.Designer.cs @@ -0,0 +1,1307 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250303204009_Buddies_DBSetFix")] + partial class Buddies_DBSetFix + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId"); + + b.HasIndex("BuddyVikingId"); + + b.ToTable("Buddy"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250303204009_Buddies_DBSetFix.cs b/src/Migrations/20250303204009_Buddies_DBSetFix.cs new file mode 100644 index 0000000..2a83088 --- /dev/null +++ b/src/Migrations/20250303204009_Buddies_DBSetFix.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Buddies_DBSetFix : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index 5b154c1..cc564c6 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -32,6 +32,7 @@ public class DBContext : DbContext { public DbSet UserBadgesCompleted { get; set; } = null!; public DbSet Bans { get; set; } = null!; public DbSet Messages { get; set; } = null!; + public DbSet Buddies { get; set; } = null!; private readonly IOptions config; From 6ede8af20486f0c5bf1954ae80c79299bb09caa4 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 3 Mar 2025 13:29:34 -0800 Subject: [PATCH 03/18] implement ``BuddyService`` add ``CreatedAt`` to ``Buddy`` model add missing schemas --- ...50303212804_Buddies_CreateDate.Designer.cs | 1310 +++++++++++++++++ .../20250303212804_Buddies_CreateDate.cs | 114 ++ src/Migrations/DBContextModelSnapshot.cs | 5 +- src/Model/Buddy.cs | 2 + src/Schema/BuddyActionResult.cs | 22 + src/Schema/BuddyActionResultType.cs | 30 + src/Services/BuddyService.cs | 117 ++ 7 files changed, 1599 insertions(+), 1 deletion(-) create mode 100644 src/Migrations/20250303212804_Buddies_CreateDate.Designer.cs create mode 100644 src/Migrations/20250303212804_Buddies_CreateDate.cs create mode 100644 src/Schema/BuddyActionResult.cs create mode 100644 src/Schema/BuddyActionResultType.cs create mode 100644 src/Services/BuddyService.cs diff --git a/src/Migrations/20250303212804_Buddies_CreateDate.Designer.cs b/src/Migrations/20250303212804_Buddies_CreateDate.Designer.cs new file mode 100644 index 0000000..8e1eb7d --- /dev/null +++ b/src/Migrations/20250303212804_Buddies_CreateDate.Designer.cs @@ -0,0 +1,1310 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250303212804_Buddies_CreateDate")] + partial class Buddies_CreateDate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId"); + + b.HasIndex("BuddyVikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250303212804_Buddies_CreateDate.cs b/src/Migrations/20250303212804_Buddies_CreateDate.cs new file mode 100644 index 0000000..d4efbc9 --- /dev/null +++ b/src/Migrations/20250303212804_Buddies_CreateDate.cs @@ -0,0 +1,114 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Buddies_CreateDate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Buddy_Vikings_BuddyVikingId", + table: "Buddy"); + + migrationBuilder.DropForeignKey( + name: "FK_Buddy_Vikings_VikingId", + table: "Buddy"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Buddy", + table: "Buddy"); + + migrationBuilder.RenameTable( + name: "Buddy", + newName: "Buddies"); + + migrationBuilder.RenameIndex( + name: "IX_Buddy_BuddyVikingId", + table: "Buddies", + newName: "IX_Buddies_BuddyVikingId"); + + migrationBuilder.AddColumn( + name: "CreatedAt", + table: "Buddies", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddPrimaryKey( + name: "PK_Buddies", + table: "Buddies", + column: "VikingId"); + + migrationBuilder.AddForeignKey( + name: "FK_Buddies_Vikings_BuddyVikingId", + table: "Buddies", + column: "BuddyVikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Buddies_Vikings_VikingId", + table: "Buddies", + column: "VikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Buddies_Vikings_BuddyVikingId", + table: "Buddies"); + + migrationBuilder.DropForeignKey( + name: "FK_Buddies_Vikings_VikingId", + table: "Buddies"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Buddies", + table: "Buddies"); + + migrationBuilder.DropColumn( + name: "CreatedAt", + table: "Buddies"); + + migrationBuilder.RenameTable( + name: "Buddies", + newName: "Buddy"); + + migrationBuilder.RenameIndex( + name: "IX_Buddies_BuddyVikingId", + table: "Buddy", + newName: "IX_Buddy_BuddyVikingId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_Buddy", + table: "Buddy", + column: "VikingId"); + + migrationBuilder.AddForeignKey( + name: "FK_Buddy_Vikings_BuddyVikingId", + table: "Buddy", + column: "BuddyVikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Buddy_Vikings_VikingId", + table: "Buddy", + column: "VikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index a450226..74b3ae2 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -84,6 +84,9 @@ namespace sodoff.Migrations b.Property("BuddyVikingId") .HasColumnType("INTEGER"); + b.Property("CreatedAt") + .HasColumnType("TEXT"); + b.Property("IsBestFriend1") .HasColumnType("INTEGER"); @@ -94,7 +97,7 @@ namespace sodoff.Migrations b.HasIndex("BuddyVikingId"); - b.ToTable("Buddy"); + b.ToTable("Buddies"); }); modelBuilder.Entity("sodoff.Model.Dragon", b => diff --git a/src/Model/Buddy.cs b/src/Model/Buddy.cs index 273e3de..37db04a 100644 --- a/src/Model/Buddy.cs +++ b/src/Model/Buddy.cs @@ -17,6 +17,8 @@ public class Buddy public bool IsBestFriend1 { get; set; } public bool IsBestFriend2 { get; set; } + public DateTime CreatedAt { get; set; } + public virtual Viking? Viking { get; set; } public virtual Viking? BuddyViking { get; set; } } diff --git a/src/Schema/BuddyActionResult.cs b/src/Schema/BuddyActionResult.cs new file mode 100644 index 0000000..deb41ca --- /dev/null +++ b/src/Schema/BuddyActionResult.cs @@ -0,0 +1,22 @@ +using sodoff.Schema; +using System.Xml.Serialization; + +namespace sodoff.Schema +{ + [XmlRoot(ElementName = "BuddyActionResult", Namespace = "")] + [Serializable] + public class BuddyActionResult + { + // Token: 0x04000203 RID: 515 + [XmlElement(ElementName = "Result")] + public BuddyActionResultType Result; + + // Token: 0x04000204 RID: 516 + [XmlElement(ElementName = "Status")] + public BuddyStatus Status; + + // Token: 0x04000205 RID: 517 + [XmlElement(ElementName = "BuddyUserID")] + public string BuddyUserID; + } +} \ No newline at end of file diff --git a/src/Schema/BuddyActionResultType.cs b/src/Schema/BuddyActionResultType.cs new file mode 100644 index 0000000..d29ba40 --- /dev/null +++ b/src/Schema/BuddyActionResultType.cs @@ -0,0 +1,30 @@ +using System.Xml.Serialization; + +namespace sodoff.Schema +{ + [Flags] + public enum BuddyActionResultType + { + // Token: 0x04000217 RID: 535 + [XmlEnum("0")] + Unknown = 0, + // Token: 0x04000218 RID: 536 + [XmlEnum("1")] + Success = 1, + // Token: 0x04000219 RID: 537 + [XmlEnum("2")] + BuddyListFull = 2, + // Token: 0x0400021A RID: 538 + [XmlEnum("3")] + FriendBuddyListFull = 3, + // Token: 0x0400021B RID: 539 + [XmlEnum("4")] + AlreadyInList = 4, + // Token: 0x0400021C RID: 540 + [XmlEnum("5")] + InvalidFriendCode = 5, + // Token: 0x0400021D RID: 541 + [XmlEnum("6")] + CannotAddSelf = 6 + } +} \ No newline at end of file diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs new file mode 100644 index 0000000..f750be5 --- /dev/null +++ b/src/Services/BuddyService.cs @@ -0,0 +1,117 @@ +using System; +using System.Data; +using sodoff.Model; +using sodoff.Schema; +using sodoff.Util; + +namespace sodoff.Services; + +public class BuddyService +{ + private readonly DBContext ctx; + private readonly MessagingService messagingService; + public BuddyService(DBContext ctx, MessagingService messagingService) + { + this.ctx = ctx; + this.messagingService = messagingService; + } + + public BuddyActionResult CreateBuddyRelation(Viking viking1, Viking viking2, BuddyStatus buddyStatus1 = BuddyStatus.PendingApprovalFromOther, BuddyStatus buddyStatus2 = BuddyStatus.PendingApprovalFromSelf) + { + // get execution UTC timestamp + DateTime now = DateTime.UtcNow; + + // construct buddy + Model.Buddy buddy = new Model.Buddy + { + Viking = viking1, + VikingId = viking1.Id, + BuddyViking = viking2, + BuddyVikingId = viking2.Id, + BuddyStatus1 = buddyStatus1, + BuddyStatus2 = buddyStatus2, + IsBestFriend1 = false, + IsBestFriend2 = false, + CreatedAt = now + }; + + // do not add if viking1 is on a different game version than viking2 + if (viking1.GameVersion < viking2.GameVersion) return new BuddyActionResult { Result = BuddyActionResultType.InvalidFriendCode }; + + // do not add if relationship already exists + Model.Buddy? existingBuddy = ctx.Buddies.FirstOrDefault(e => e.VikingId == buddy.VikingId && e.BuddyVikingId == buddy.BuddyVikingId); + if (existingBuddy != null) return new BuddyActionResult { Result = BuddyActionResultType.AlreadyInList }; + + // add relationship to database + ctx.Buddies.Add(buddy); + ctx.SaveChanges(); + + // if this is a buddy relationship, use MessagingService to send buddy request message to viking2 + if (buddyStatus1 == BuddyStatus.PendingApprovalFromOther && buddyStatus2 == BuddyStatus.PendingApprovalFromSelf) + messagingService.AddMessageToViking(viking1, viking2, MessageType.Data, MessageTypeID.BuddyList, MessageLevel.WhiteList, "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]", "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]", "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]"); + + // return result + return new BuddyActionResult + { + Result = BuddyActionResultType.Success, + Status = buddy.BuddyStatus1, + BuddyUserID = viking2.Uid.ToString() + }; + } + + public void RemoveBuddy(Viking viking, Guid buddyUid) + { + // find buddy viking + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUid); + + if (buddyViking != null) + { + // find buddy relationship + Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id) + .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id); + + if (buddy != null) + // remove it + ctx.Buddies.Remove(buddy); + else throw new InvalidOperationException("Cannot Remove A Buddy That Doesn't Exist"); + + ctx.SaveChanges(); + } + } + + public BuddyList ConstructBuddyList(Viking viking) + { + // get all relationships viking has made + List buddies = ctx.Buddies.Where(e => e.BuddyVikingId == viking.Id).ToList(); + List schemaBuddies = new(); + foreach (var buddy in buddies) + { + // show differently depending on requester + if (buddy.VikingId == viking.Id) + schemaBuddies.Add(new Schema.Buddy + { + UserID = buddy.BuddyViking.Uid.ToString(), + DisplayName = XmlUtil.DeserializeXml(buddy.BuddyViking.AvatarSerialized).DisplayName, + Status = buddy.BuddyStatus2, + CreateDate = buddy.CreatedAt, + Online = true, // hardcoded until mmo reports precense + OnMobile = false, + BestBuddy = buddy.IsBestFriend2 + }); + else + schemaBuddies.Add(new Schema.Buddy + { + UserID = buddy.Viking.Uid.ToString(), + DisplayName = XmlUtil.DeserializeXml(buddy.Viking.AvatarSerialized).DisplayName, + Status = buddy.BuddyStatus1, + CreateDate = buddy.CreatedAt, + Online = true, // hardcoded until mmo reports precense + OnMobile = false, + BestBuddy = buddy.IsBestFriend1 + }); + } + + // return buddy list + return new BuddyList { Buddy = schemaBuddies.ToArray() }; + } +} From 684e8691d838881b8a961d6a452a606fd16c4e1b Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 3 Mar 2025 13:39:56 -0800 Subject: [PATCH 04/18] implement ``AddBuddy`` and ``ApproveBuddy`` --- src/Controllers/Common/ContentController.cs | 37 +++++++++++++++++++-- src/Program.cs | 1 + src/Services/BuddyService.cs | 23 +++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 9bc67fb..87cbc23 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -24,6 +24,7 @@ public class ContentController : Controller { private DisplayNamesService displayNamesService; private NeighborhoodService neighborhoodService; private WorldIdService worldIdService; + private BuddyService buddyService; private Random random = new Random(); private readonly IOptions config; @@ -40,6 +41,7 @@ public class ContentController : Controller { DisplayNamesService displayNamesService, NeighborhoodService neighborhoodService, WorldIdService worldIdService, + BuddyService buddyService, IOptions config ) { this.ctx = ctx; @@ -54,6 +56,7 @@ public class ContentController : Controller { this.displayNamesService = displayNamesService; this.neighborhoodService = neighborhoodService; this.worldIdService = worldIdService; + this.buddyService = buddyService; this.config = config; } @@ -1142,12 +1145,40 @@ public class ContentController : Controller { return Ok(taskResult); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/AddBuddy")] + [VikingSession] + public IActionResult AddBuddy(Viking viking, [FromForm] Guid buddyUserID) + { + // get buddy + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUserID); + + if (buddyViking != null) + return Ok(buddyService.CreateBuddyRelation(viking, buddyViking)); + else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); + } + + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/ApproveBuddy")] + [VikingSession] + public IActionResult ApproveBuddy(Viking viking, [FromForm] Guid buddyUserID) + { + // get buddy + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUserID); + + if (buddyViking != null) + return Ok(buddyService.UpdateBuddyRelation(viking, buddyViking, BuddyStatus.Approved, BuddyStatus.Approved)); + else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); + } + [HttpPost] [Produces("application/xml")] [Route("ContentWebService.asmx/GetBuddyList")] - public IActionResult GetBuddyList() { - // TODO: this is a placeholder - return Ok(new BuddyList { Buddy = new Schema.Buddy[0] }); + [VikingSession] + public IActionResult GetBuddyList(Viking viking) { + return Ok(buddyService.ConstructBuddyList(viking)); } [HttpPost] diff --git a/src/Program.cs b/src/Program.cs index 1bc1dcd..fb2beee 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -42,6 +42,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); bool assetServer = builder.Configuration.GetSection("AssetServer").GetValue("Enabled"); string assetIP = builder.Configuration.GetSection("AssetServer").GetValue("ListenIP"); diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index f750be5..861cfb7 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -59,6 +59,29 @@ public class BuddyService }; } + public BuddyActionResult UpdateBuddyRelation(Viking viking, Viking buddyViking, BuddyStatus buddyStatus1, BuddyStatus buddyStatus2) + { + // find relation + Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id) + .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id); + + if (buddy != null) + { + // update it + buddy.BuddyStatus1 = buddyStatus1; + buddy.BuddyStatus2 = buddyStatus2; + ctx.SaveChanges(); + + // return result + return new BuddyActionResult + { + Status = buddy.BuddyStatus1, + Result = BuddyActionResultType.Success, + BuddyUserID = buddyViking.Uid.ToString() + }; + } else return new BuddyActionResult { Result = BuddyActionResultType.Unknown }; + } + public void RemoveBuddy(Viking viking, Guid buddyUid) { // find buddy viking From 5bd62186f0d7576495d78516df45f1828048d306 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 3 Mar 2025 17:00:58 -0800 Subject: [PATCH 05/18] implement ``RemoveBuddy`` modify ``SendMessage`` add message of typeid 21 when reply is made reworks some things in ``BuddyService`` --- src/Controllers/Common/ContentController.cs | 16 ++++++- src/Controllers/Common/MessagingController.cs | 38 +++++++++++++++- src/Services/BuddyService.cs | 43 ++++++++----------- src/Services/MessagingService.cs | 13 +++++- 4 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 87cbc23..4a1293f 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1159,6 +1159,20 @@ public class ContentController : Controller { else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/RemoveBuddy")] + [VikingSession] + public IActionResult RemoveBuddy(Viking viking, [FromForm] Guid buddyUserId) + { + // find buddy viking + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUserId); + + if (buddyViking != null) + return Ok(buddyService.RemoveBuddy(viking, buddyViking)); + else return Ok(false); + } + [HttpPost] [Produces("application/xml")] [Route("ContentWebService.asmx/ApproveBuddy")] @@ -1170,7 +1184,7 @@ public class ContentController : Controller { if (buddyViking != null) return Ok(buddyService.UpdateBuddyRelation(viking, buddyViking, BuddyStatus.Approved, BuddyStatus.Approved)); - else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); + else return Ok(false); } [HttpPost] diff --git a/src/Controllers/Common/MessagingController.cs b/src/Controllers/Common/MessagingController.cs index cbdd63b..0e13eb0 100644 --- a/src/Controllers/Common/MessagingController.cs +++ b/src/Controllers/Common/MessagingController.cs @@ -35,9 +35,22 @@ public class MessagingController : Controller { // clients (at least older ones) don't send what typeID the message is, its encoded in data ArrayOfKeyValuePairOfStringString arrayOfKeyValuePairOfStringString = XmlUtil.DeserializeXml(data); - MessageTypeID typeID = (MessageTypeID)int.Parse(arrayOfKeyValuePairOfStringString.KeyValuePairOfStringString![0].Value ?? "0"); + MessageTypeID typeID = MessageTypeID.Unknown; + string typeText = ""; - var msg = messagingService.AddMessageToViking(viking, toViking, MessageType.Data, typeID, MessageLevel.WhiteList, data, "[[Line1]]=[[{{BuddyUserName}}]] has sent you a {{MessageType}}!", "[[Line1]]=[[{{BuddyUserName}}]] has sent you a {{MessageType}}!"); + switch(arrayOfKeyValuePairOfStringString.KeyValuePairOfStringString![0].Value) + { + case "Photo": + typeID = MessageTypeID.Photo; + typeText = "Photo"; + break; + case "Drawing": + typeID = MessageTypeID.GreetingCard; + typeText = "Card"; + break; + } + + var msg = messagingService.AddMessageToViking(viking, toViking, MessageType.Data, typeID, MessageLevel.WhiteList, data, "[[Line1]]=[[{{BuddyUserName}} has sent you a " + typeText + "!]]", "[[Line1]]=[[{{BuddyUserName}} has sent you a " + typeText + "!]]"); if (msg != null) return Ok(true); else return Ok(false); } @@ -71,4 +84,25 @@ public class MessagingController : Controller { messagingService.RemoveMessage(messageID); return Ok(true); } + + [HttpPost] + [Route("Messaging/PostTextMessage")] + public IActionResult PostTextMessage([FromForm] Guid token, [FromForm] Guid userId, [FromForm] string data, [FromForm] int messageLevel, [FromForm] int replyMessageId) + { + // check if session is valid + Session? session = ctx.Sessions.FirstOrDefault(e => e.ApiToken == token); + + // find viking + Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Uid == userId); + + if (session != null && viking != null) + { + // post text message + var message = messagingService.AddMessageToViking(session.Viking, viking, MessageType.Post, MessageTypeID.Messaging, (MessageLevel)messageLevel, data, isReply: replyMessageId > 0, parentMessageId: replyMessageId); + + if (message != null) return Ok(true); + } + + return Ok(false); + } } diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index 861cfb7..b309f17 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -59,11 +59,11 @@ public class BuddyService }; } - public BuddyActionResult UpdateBuddyRelation(Viking viking, Viking buddyViking, BuddyStatus buddyStatus1, BuddyStatus buddyStatus2) + public bool UpdateBuddyRelation(Viking viking, Viking buddyViking, BuddyStatus buddyStatus1, BuddyStatus buddyStatus2) { // find relation - Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id) - .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id); + Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id || e.BuddyVikingId == viking.Id) + .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id || e.VikingId == buddyViking.Id); if (buddy != null) { @@ -73,39 +73,32 @@ public class BuddyService ctx.SaveChanges(); // return result - return new BuddyActionResult - { - Status = buddy.BuddyStatus1, - Result = BuddyActionResultType.Success, - BuddyUserID = buddyViking.Uid.ToString() - }; - } else return new BuddyActionResult { Result = BuddyActionResultType.Unknown }; + return true; + } else return false; } - public void RemoveBuddy(Viking viking, Guid buddyUid) + public bool RemoveBuddy(Viking viking, Viking buddyViking) { - // find buddy viking - Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUid); - - if (buddyViking != null) - { - // find buddy relationship - Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id) - .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id); + // find relation + Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id || e.BuddyVikingId == viking.Id) + .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id || e.VikingId == buddyViking.Id); - if (buddy != null) - // remove it - ctx.Buddies.Remove(buddy); - else throw new InvalidOperationException("Cannot Remove A Buddy That Doesn't Exist"); - + if (buddy != null) + { + // remove it + ctx.Buddies.Remove(buddy); ctx.SaveChanges(); + + return true; } + else return false; } public BuddyList ConstructBuddyList(Viking viking) { // get all relationships viking has made - List buddies = ctx.Buddies.Where(e => e.BuddyVikingId == viking.Id).ToList(); + List buddies = ctx.Buddies.Where(e => e.VikingId == viking.Id || e.BuddyVikingId == viking.Id) + .ToList(); List schemaBuddies = new(); foreach (var buddy in buddies) { diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index 9c60a33..3090580 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -44,7 +44,7 @@ public class MessagingService IsNew = IsNew }; - if (isReply) + if (isReply && parentMessageId > 0) { // get message this is in reply to Model.Message? messageToReplyTo = ctx.Messages.FirstOrDefault(e => e.Id == parentMessageId); @@ -54,6 +54,9 @@ public class MessagingService message.ParentMessage = messageToReplyTo; message.ParentMessageId = messageToReplyTo.Id; message.ConversationID = messageToReplyTo.ConversationID; + + // add a message to the replier's board saying a thread update has occured (if reply isn't to self) + if (message.VikingId != message.ToVikingId) AddMessageToViking(message.Viking, message.ToViking, MessageType.Data, MessageTypeID.ThreadUpdate, MessageLevel.WhiteList, "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]"); } else throw new InvalidOperationException("Tried To Reply To A Message That Doesn't Exist"); } @@ -93,6 +96,8 @@ public class MessagingService message.IsDeleted = IsDeleted; message.LastUpdatedAt = now; + ctx.SaveChanges(); + return message; } else return null; } @@ -242,7 +247,8 @@ public class MessagingService { Viking? msgAuthor = ctx.Vikings.FirstOrDefault(e => e.Id == message.VikingId) ?? new Viking(); - if(!showOldMessages && message.IsNew && DateTime.Compare(message.CreatedAt.AddMinutes(30), now) > 0 || message.IsDeleted) continue; // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response + if(message.IsDeleted) { ctx.Messages.Remove(message); continue; } + if(DateTime.Compare(now, message.CreatedAt.AddMinutes(30)) > 0) { message.IsNew = false; continue; } // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response if(!message.IsNew && !showOldMessages) continue; messageInfos.Add(new MessageInfo { @@ -256,6 +262,9 @@ public class MessagingService }); } + // save any database changes + ctx.SaveChanges(); + // add list as array to response response.MessageInfo = messageInfos.ToArray(); From 6deebb947b53e429475aaaae591dbc2c6c267a70 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 10:52:16 -0800 Subject: [PATCH 06/18] implement ``UpdateBestBuddy`` --- src/Controllers/Common/ContentController.cs | 14 ++++++++++++++ src/Services/BuddyService.cs | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 4a1293f..7d033aa 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1187,6 +1187,20 @@ public class ContentController : Controller { else return Ok(false); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/UpdateBestBuddy")] + [VikingSession] + public IActionResult SetBestBuddy(Viking viking, [FromForm] Guid buddyUserID, [FromForm] bool bestBuddy) + { + // get buddy + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.Uid == buddyUserID); + + if (buddyViking != null) + return Ok(buddyService.UpdateBestBuddy(viking, buddyViking, bestBuddy)); + else return Ok(false); + } + [HttpPost] [Produces("application/xml")] [Route("ContentWebService.asmx/GetBuddyList")] diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index b309f17..0ca60ee 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -77,6 +77,22 @@ public class BuddyService } else return false; } + public bool UpdateBestBuddy(Viking viking, Viking buddyViking, bool bestBuddy) + { + // find relation + Model.Buddy? buddy = ctx.Buddies.Where(e => e.VikingId == viking.Id || e.BuddyVikingId == viking.Id) + .FirstOrDefault(e => e.BuddyVikingId == buddyViking.Id || e.VikingId == buddyViking.Id); + + if (buddy != null) + { + if (buddy.VikingId == viking.Id) + buddy.IsBestFriend1 = bestBuddy; + else buddy.IsBestFriend2 = bestBuddy; + + return true; + } else return false; + } + public bool RemoveBuddy(Viking viking, Viking buddyViking) { // find relation From 3ba60972ad2025e5bbb28bd51f20eed6bafeec7c Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 10:59:13 -0800 Subject: [PATCH 07/18] fix best buddy set --- src/Services/BuddyService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index 0ca60ee..7983230 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -86,8 +86,10 @@ public class BuddyService if (buddy != null) { if (buddy.VikingId == viking.Id) - buddy.IsBestFriend1 = bestBuddy; - else buddy.IsBestFriend2 = bestBuddy; + buddy.IsBestFriend2 = bestBuddy; + else buddy.IsBestFriend1 = bestBuddy; + + ctx.SaveChanges(); return true; } else return false; From c37a719aad835ec626b161d987236c41e3410743 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 11:04:24 -0800 Subject: [PATCH 08/18] add ``Id`` field to ``Buddy`` --- .../20250306190354_Buddies_Id.Designer.cs | 1316 +++++++++++++++++ src/Migrations/20250306190354_Buddies_Id.cs | 57 + src/Migrations/DBContextModelSnapshot.cs | 10 +- src/Model/Buddy.cs | 3 +- 4 files changed, 1383 insertions(+), 3 deletions(-) create mode 100644 src/Migrations/20250306190354_Buddies_Id.Designer.cs create mode 100644 src/Migrations/20250306190354_Buddies_Id.cs diff --git a/src/Migrations/20250306190354_Buddies_Id.Designer.cs b/src/Migrations/20250306190354_Buddies_Id.Designer.cs new file mode 100644 index 0000000..81b21c0 --- /dev/null +++ b/src/Migrations/20250306190354_Buddies_Id.Designer.cs @@ -0,0 +1,1316 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250306190354_Buddies_Id")] + partial class Buddies_Id + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250306190354_Buddies_Id.cs b/src/Migrations/20250306190354_Buddies_Id.cs new file mode 100644 index 0000000..cad3696 --- /dev/null +++ b/src/Migrations/20250306190354_Buddies_Id.cs @@ -0,0 +1,57 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Buddies_Id : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_Buddies", + table: "Buddies"); + + migrationBuilder.AddColumn( + name: "Id", + table: "Buddies", + type: "INTEGER", + nullable: false, + defaultValue: 0) + .Annotation("Sqlite:Autoincrement", true); + + migrationBuilder.AddPrimaryKey( + name: "PK_Buddies", + table: "Buddies", + column: "Id"); + + migrationBuilder.CreateIndex( + name: "IX_Buddies_VikingId", + table: "Buddies", + column: "VikingId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_Buddies", + table: "Buddies"); + + migrationBuilder.DropIndex( + name: "IX_Buddies_VikingId", + table: "Buddies"); + + migrationBuilder.DropColumn( + name: "Id", + table: "Buddies"); + + migrationBuilder.AddPrimaryKey( + name: "PK_Buddies", + table: "Buddies", + column: "VikingId"); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 74b3ae2..3840c48 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -72,7 +72,8 @@ namespace sodoff.Migrations modelBuilder.Entity("sodoff.Model.Buddy", b => { - b.Property("VikingId") + b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); b.Property("BuddyStatus1") @@ -93,10 +94,15 @@ namespace sodoff.Migrations b.Property("IsBestFriend2") .HasColumnType("INTEGER"); - b.HasKey("VikingId"); + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); b.HasIndex("BuddyVikingId"); + b.HasIndex("VikingId"); + b.ToTable("Buddies"); }); diff --git a/src/Model/Buddy.cs b/src/Model/Buddy.cs index 37db04a..3be927d 100644 --- a/src/Model/Buddy.cs +++ b/src/Model/Buddy.cs @@ -5,9 +5,10 @@ using sodoff.Schema; namespace sodoff.Model; -[PrimaryKey(nameof(VikingId))] public class Buddy { + [Key] + public int Id { get; set; } public int VikingId { get; set; } public int BuddyVikingId { get; set; } From b7b99cd3533cd08f7bb04e4f93e540c865a4bf64 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 11:33:08 -0800 Subject: [PATCH 09/18] add ``IsPrivate`` field to ``Message`` --- src/Controllers/Common/MessagingController.cs | 7 +- ...0306193218_Messaging_IsPrivate.Designer.cs | 1319 +++++++++++++++++ .../20250306193218_Messaging_IsPrivate.cs | 29 + src/Migrations/DBContextModelSnapshot.cs | 3 + src/Model/Message.cs | 1 + src/Services/MessagingService.cs | 12 +- 6 files changed, 1364 insertions(+), 7 deletions(-) create mode 100644 src/Migrations/20250306193218_Messaging_IsPrivate.Designer.cs create mode 100644 src/Migrations/20250306193218_Messaging_IsPrivate.cs diff --git a/src/Controllers/Common/MessagingController.cs b/src/Controllers/Common/MessagingController.cs index 0e13eb0..a61c218 100644 --- a/src/Controllers/Common/MessagingController.cs +++ b/src/Controllers/Common/MessagingController.cs @@ -67,12 +67,13 @@ public class MessagingController : Controller { [HttpPost] [Produces("application/xml")] [Route("MessageWebService.asmx/GetCombinedListMessage")] - public ArrayOfCombinedListMessage? GetCombinedListMessage([FromForm] Guid userId) + [VikingSession(UseLock = false)] + public ArrayOfCombinedListMessage? GetCombinedListMessage(Viking viking, [FromForm] Guid userId) { // find viking - Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Uid == userId); + Viking? uidViking = ctx.Vikings.FirstOrDefault(e => e.Uid == userId); - if (viking != null) return messagingService.ConstructCombinedMessageArray(viking); + if (viking != null && uidViking != null) return messagingService.ConstructCombinedMessageArray(viking, uidViking); else return new ArrayOfCombinedListMessage(); } diff --git a/src/Migrations/20250306193218_Messaging_IsPrivate.Designer.cs b/src/Migrations/20250306193218_Messaging_IsPrivate.Designer.cs new file mode 100644 index 0000000..94f5317 --- /dev/null +++ b/src/Migrations/20250306193218_Messaging_IsPrivate.Designer.cs @@ -0,0 +1,1319 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250306193218_Messaging_IsPrivate")] + partial class Messaging_IsPrivate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250306193218_Messaging_IsPrivate.cs b/src/Migrations/20250306193218_Messaging_IsPrivate.cs new file mode 100644 index 0000000..783a11e --- /dev/null +++ b/src/Migrations/20250306193218_Messaging_IsPrivate.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Messaging_IsPrivate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsPrivate", + table: "Messages", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsPrivate", + table: "Messages"); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 3840c48..9c4f511 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -316,6 +316,9 @@ namespace sodoff.Migrations b.Property("IsNew") .HasColumnType("INTEGER"); + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + b.Property("LastUpdatedAt") .HasColumnType("TEXT"); diff --git a/src/Model/Message.cs b/src/Model/Message.cs index 2025db8..11b4dc7 100644 --- a/src/Model/Message.cs +++ b/src/Model/Message.cs @@ -29,6 +29,7 @@ public class Message public bool IsDeleted { get; set; } public bool IsNew { get; set; } + public bool IsPrivate { get; set; } public virtual Viking? Viking { get; set; } public virtual Viking? ToViking { get; set; } diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index 3090580..1c05ba2 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography.X509Certificates; using Microsoft.EntityFrameworkCore; using sodoff.Model; using sodoff.Schema; @@ -15,7 +16,7 @@ public class MessagingService this.ctx = ctx; } - public Model.Message AddMessageToViking(Viking viking, Viking toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, int parentMessageId = 0) + public Model.Message AddMessageToViking(Viking viking, Viking toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0) { // get execution UTC timestamp DateTime now = DateTime.UtcNow; @@ -41,7 +42,8 @@ public class MessagingService CreatedAt = now, LastUpdatedAt = now, IsDeleted = IsDeleted, - IsNew = IsNew + IsNew = IsNew, + IsPrivate = isPrivate }; if (isReply && parentMessageId > 0) @@ -56,7 +58,7 @@ public class MessagingService message.ConversationID = messageToReplyTo.ConversationID; // add a message to the replier's board saying a thread update has occured (if reply isn't to self) - if (message.VikingId != message.ToVikingId) AddMessageToViking(message.Viking, message.ToViking, MessageType.Data, MessageTypeID.ThreadUpdate, MessageLevel.WhiteList, "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]"); + if (message.VikingId != message.ToVikingId) AddMessageToViking(message.Viking, message.ToViking, MessageType.Data, MessageTypeID.ThreadUpdate, MessageLevel.WhiteList, "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", "[[Line1]]=[[{{BuddyUserName}} Replied To Your Message In {{BuddyUserName}}'s Message Board!]]", isPrivate: true); } else throw new InvalidOperationException("Tried To Reply To A Message That Doesn't Exist"); } @@ -102,7 +104,7 @@ public class MessagingService } else return null; } - public ArrayOfCombinedListMessage ConstructCombinedMessageArray(Viking viking) + public ArrayOfCombinedListMessage ConstructCombinedMessageArray(Viking viking, Viking publicViking) { // get all messages in viking board List messages = ctx.Messages.Where(e => e.ToVikingId == viking.Id).ToList(); @@ -118,6 +120,8 @@ public class MessagingService continue; } + if (message.IsPrivate && (viking.Id != publicViking.Id)) continue; + Viking? msgAuthor = ctx.Vikings.FirstOrDefault(e => e.Id == message.VikingId) ?? new Viking(); // construct a CombinedListMessage based on Model.Message From 6c31296d3b7bf7fe379a0c52e79bc61979144021 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 11:45:50 -0800 Subject: [PATCH 10/18] make ``ToVikingId`` nullable for system messages --- ...1_Messaging_ToVikingIdNullable.Designer.cs | 1317 +++++++++++++++++ ...0306194521_Messaging_ToVikingIdNullable.cs | 59 + src/Migrations/DBContextModelSnapshot.cs | 6 +- src/Model/Message.cs | 2 +- 4 files changed, 1379 insertions(+), 5 deletions(-) create mode 100644 src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs create mode 100644 src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs diff --git a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs new file mode 100644 index 0000000..f2609c2 --- /dev/null +++ b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs @@ -0,0 +1,1317 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250306194521_Messaging_ToVikingIdNullable")] + partial class Messaging_ToVikingIdNullable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId"); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs new file mode 100644 index 0000000..435caac --- /dev/null +++ b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Messaging_ToVikingIdNullable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Messages_Vikings_ToVikingId", + table: "Messages"); + + migrationBuilder.AlterColumn( + name: "ToVikingId", + table: "Messages", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AddForeignKey( + name: "FK_Messages_Vikings_ToVikingId", + table: "Messages", + column: "ToVikingId", + principalTable: "Vikings", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Messages_Vikings_ToVikingId", + table: "Messages"); + + migrationBuilder.AlterColumn( + name: "ToVikingId", + table: "Messages", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Messages_Vikings_ToVikingId", + table: "Messages", + column: "ToVikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 9c4f511..6ded7e0 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -343,7 +343,7 @@ namespace sodoff.Migrations b.Property("QueueID") .HasColumnType("INTEGER"); - b.Property("ToVikingId") + b.Property("ToVikingId") .HasColumnType("INTEGER"); b.Property("VikingId") @@ -982,9 +982,7 @@ namespace sodoff.Migrations b.HasOne("sodoff.Model.Viking", "ToViking") .WithMany("MessageBoard") - .HasForeignKey("ToVikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("ToVikingId"); b.HasOne("sodoff.Model.Viking", "Viking") .WithMany("MessagesMade") diff --git a/src/Model/Message.cs b/src/Model/Message.cs index 11b4dc7..e170285 100644 --- a/src/Model/Message.cs +++ b/src/Model/Message.cs @@ -10,7 +10,7 @@ public class Message public int Id { get; set; } public int VikingId { get; set; } - public int ToVikingId { get; set; } + public int? ToVikingId { get; set; } public int QueueID { get; set; } public int? ConversationID { get; set; } From c8c70b220e7537a21c83c7207a7bc120799664f2 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 11:49:59 -0800 Subject: [PATCH 11/18] revert nullable ``ToVikingId`` --- ...1_Messaging_ToVikingIdNullable.Designer.cs | 1317 ----------------- ...0306194521_Messaging_ToVikingIdNullable.cs | 59 - src/Migrations/DBContextModelSnapshot.cs | 68 +- src/Services/MessagingService.cs | 4 +- 4 files changed, 37 insertions(+), 1411 deletions(-) delete mode 100644 src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs delete mode 100644 src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs diff --git a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs deleted file mode 100644 index f2609c2..0000000 --- a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.Designer.cs +++ /dev/null @@ -1,1317 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using sodoff.Model; - -#nullable disable - -namespace sodoff.Migrations -{ - [DbContext(typeof(DBContext))] - [Migration("20250306194521_Messaging_ToVikingIdNullable")] - partial class Messaging_ToVikingIdNullable - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "7.0.20") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true); - - modelBuilder.Entity("GroupViking", b => - { - b.Property("GroupsId") - .HasColumnType("INTEGER"); - - b.Property("VikingsId") - .HasColumnType("INTEGER"); - - b.HasKey("GroupsId", "VikingsId"); - - b.HasIndex("VikingsId"); - - b.ToTable("GroupViking"); - }); - - modelBuilder.Entity("sodoff.Model.AchievementPoints", b => - { - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("Type") - .HasColumnType("INTEGER"); - - b.Property("Value") - .HasColumnType("INTEGER"); - - b.HasKey("VikingId", "Type"); - - b.ToTable("AchievementPoints"); - }); - - modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => - { - b.Property("TaskId") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("Points") - .HasColumnType("INTEGER"); - - b.HasKey("TaskId", "VikingId"); - - b.HasIndex("VikingId"); - - b.ToTable("AchievementTaskState"); - }); - - modelBuilder.Entity("sodoff.Model.Buddy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("BuddyStatus1") - .HasColumnType("INTEGER"); - - b.Property("BuddyStatus2") - .HasColumnType("INTEGER"); - - b.Property("BuddyVikingId") - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("IsBestFriend1") - .HasColumnType("INTEGER"); - - b.Property("IsBestFriend2") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("BuddyVikingId"); - - b.HasIndex("VikingId"); - - b.ToTable("Buddies"); - }); - - modelBuilder.Entity("sodoff.Model.Dragon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("EntityId") - .HasColumnType("TEXT"); - - b.Property("PetXP") - .HasColumnType("INTEGER"); - - b.Property("RaisedPetData") - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("Dragons"); - }); - - modelBuilder.Entity("sodoff.Model.GameData", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("DatePlayed") - .HasColumnType("TEXT"); - - b.Property("Difficulty") - .HasColumnType("INTEGER"); - - b.Property("GameId") - .HasColumnType("INTEGER"); - - b.Property("GameLevel") - .HasColumnType("INTEGER"); - - b.Property("IsMultiplayer") - .HasColumnType("INTEGER"); - - b.Property("Loss") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("Win") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("GameData"); - }); - - modelBuilder.Entity("sodoff.Model.GameDataPair", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("GameDataId") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Value") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("GameDataId"); - - b.ToTable("GameDataPairs"); - }); - - modelBuilder.Entity("sodoff.Model.Group", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ApiKey") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Color") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("GroupID") - .HasColumnType("TEXT"); - - b.Property("Logo") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Type") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.ToTable("Groups"); - }); - - modelBuilder.Entity("sodoff.Model.Image", b => - { - b.Property("ImageType") - .HasColumnType("TEXT"); - - b.Property("ImageSlot") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("ImageData") - .HasColumnType("TEXT"); - - b.Property("TemplateName") - .HasColumnType("TEXT"); - - b.HasKey("ImageType", "ImageSlot", "VikingId"); - - b.HasIndex("VikingId"); - - b.ToTable("Images"); - }); - - modelBuilder.Entity("sodoff.Model.InventoryItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AttributesSerialized") - .HasColumnType("TEXT"); - - b.Property("ItemId") - .HasColumnType("INTEGER"); - - b.Property("Quantity") - .HasColumnType("INTEGER"); - - b.Property("StatsSerialized") - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("InventoryItems"); - }); - - modelBuilder.Entity("sodoff.Model.MMORole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Role") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("MMORoles"); - }); - - modelBuilder.Entity("sodoff.Model.Message", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ConversationID") - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Data") - .HasColumnType("TEXT"); - - b.Property("IsDeleted") - .HasColumnType("INTEGER"); - - b.Property("IsNew") - .HasColumnType("INTEGER"); - - b.Property("IsPrivate") - .HasColumnType("INTEGER"); - - b.Property("LastUpdatedAt") - .HasColumnType("TEXT"); - - b.Property("MemberMessage") - .HasColumnType("TEXT"); - - b.Property("MessageLevel") - .HasColumnType("INTEGER"); - - b.Property("MessageType") - .HasColumnType("INTEGER"); - - b.Property("MessageTypeID") - .HasColumnType("INTEGER"); - - b.Property("NonMemberMessage") - .HasColumnType("TEXT"); - - b.Property("ParentMessageId") - .HasColumnType("INTEGER"); - - b.Property("QueueID") - .HasColumnType("INTEGER"); - - b.Property("ToVikingId") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ParentMessageId"); - - b.HasIndex("ToVikingId"); - - b.HasIndex("VikingId"); - - b.ToTable("Messages"); - }); - - modelBuilder.Entity("sodoff.Model.MissionState", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("MissionId") - .HasColumnType("INTEGER"); - - b.Property("MissionStatus") - .HasColumnType("INTEGER"); - - b.Property("UserAccepted") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("MissionStates"); - }); - - modelBuilder.Entity("sodoff.Model.Neighborhood", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Slot0") - .HasColumnType("TEXT"); - - b.Property("Slot1") - .HasColumnType("TEXT"); - - b.Property("Slot2") - .HasColumnType("TEXT"); - - b.Property("Slot3") - .HasColumnType("TEXT"); - - b.Property("Slot4") - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId") - .IsUnique(); - - b.ToTable("Neighborhoods"); - }); - - modelBuilder.Entity("sodoff.Model.Pair", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Key") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("MasterId") - .HasColumnType("INTEGER"); - - b.Property("Value") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("MasterId"); - - b.ToTable("Pairs"); - }); - - modelBuilder.Entity("sodoff.Model.PairData", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("DragonId") - .HasColumnType("INTEGER"); - - b.Property("PairId") - .HasColumnType("INTEGER"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("DragonId"); - - b.HasIndex("UserId"); - - b.HasIndex("VikingId"); - - b.ToTable("PairData"); - }); - - modelBuilder.Entity("sodoff.Model.Party", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AssetBundle") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ExpirationDate") - .HasColumnType("TEXT"); - - b.Property("Location") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("LocationIconAsset") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("PrivateParty") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("Parties"); - }); - - modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AnswerID") - .HasColumnType("INTEGER"); - - b.Property("QuestionID") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("ProfileAnswers"); - }); - - modelBuilder.Entity("sodoff.Model.Rating", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Date") - .HasColumnType("TEXT"); - - b.Property("RankId") - .HasColumnType("INTEGER"); - - b.Property("Value") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("RankId"); - - b.HasIndex("VikingId"); - - b.ToTable("Ratings"); - }); - - modelBuilder.Entity("sodoff.Model.RatingRank", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CategoryID") - .HasColumnType("INTEGER"); - - b.Property("Rank") - .HasColumnType("INTEGER"); - - b.Property("RatedEntityID") - .HasColumnType("INTEGER"); - - b.Property("RatedUserID") - .HasColumnType("TEXT"); - - b.Property("RatingAverage") - .HasColumnType("REAL"); - - b.Property("UpdateDate") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("RatingRanks"); - }); - - modelBuilder.Entity("sodoff.Model.Room", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("RoomId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("Rooms"); - }); - - modelBuilder.Entity("sodoff.Model.RoomItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("RoomId") - .HasColumnType("INTEGER"); - - b.Property("RoomItemData") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("RoomId"); - - b.ToTable("RoomItems"); - }); - - modelBuilder.Entity("sodoff.Model.SavedData", b => - { - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("SaveId") - .HasColumnType("INTEGER"); - - b.Property("SerializedData") - .HasColumnType("TEXT"); - - b.HasKey("VikingId", "SaveId"); - - b.ToTable("SavedData"); - }); - - modelBuilder.Entity("sodoff.Model.SceneData", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("SceneName") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("XmlData") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("SceneData"); - }); - - modelBuilder.Entity("sodoff.Model.Session", b => - { - b.Property("ApiToken") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("ApiToken"); - - b.HasIndex("UserId"); - - b.HasIndex("VikingId"); - - b.ToTable("Sessions"); - }); - - modelBuilder.Entity("sodoff.Model.TaskStatus", b => - { - b.Property("Id") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("MissionId") - .HasColumnType("INTEGER"); - - b.Property("Completed") - .HasColumnType("INTEGER"); - - b.Property("Payload") - .HasColumnType("TEXT"); - - b.HasKey("Id", "VikingId", "MissionId"); - - b.HasIndex("VikingId"); - - b.ToTable("TaskStatuses"); - }); - - modelBuilder.Entity("sodoff.Model.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Password") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Username") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("BadgeId") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("UserBadgesCompleted"); - }); - - modelBuilder.Entity("sodoff.Model.UserBan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("ExpiresOn") - .HasColumnType("TEXT"); - - b.Property("UserBanType") - .HasColumnType("INTEGER"); - - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("VikingId"); - - b.ToTable("Bans"); - }); - - modelBuilder.Entity("sodoff.Model.UserMissionData", b => - { - b.Property("VikingId") - .HasColumnType("INTEGER"); - - b.Property("WorldId") - .HasColumnType("INTEGER"); - - b.Property("MissionId") - .HasColumnType("INTEGER"); - - b.Property("IsCompleted") - .HasColumnType("INTEGER"); - - b.Property("StepId") - .HasColumnType("INTEGER"); - - b.Property("TaskId") - .HasColumnType("INTEGER"); - - b.HasKey("VikingId", "WorldId", "MissionId"); - - b.ToTable("UserMissionData"); - }); - - modelBuilder.Entity("sodoff.Model.Viking", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("AvatarSerialized") - .HasColumnType("TEXT"); - - b.Property("BirthDate") - .HasColumnType("TEXT"); - - b.Property("CreationDate") - .HasColumnType("TEXT"); - - b.Property("GameVersion") - .HasColumnType("INTEGER"); - - b.Property("Gender") - .HasColumnType("INTEGER"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("SelectedDragonId") - .HasColumnType("INTEGER"); - - b.Property("Uid") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("SelectedDragonId") - .IsUnique(); - - b.HasIndex("Uid"); - - b.HasIndex("UserId"); - - b.ToTable("Vikings"); - }); - - modelBuilder.Entity("GroupViking", b => - { - b.HasOne("sodoff.Model.Group", null) - .WithMany() - .HasForeignKey("GroupsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("sodoff.Model.Viking", null) - .WithMany() - .HasForeignKey("VikingsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("sodoff.Model.AchievementPoints", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("AchievementPoints") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("AchievementTaskStates") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Buddy", b => - { - b.HasOne("sodoff.Model.Viking", "BuddyViking") - .WithMany("BuddyList") - .HasForeignKey("BuddyVikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("BuddiesMade") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("BuddyViking"); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Dragon", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Dragons") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.GameData", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("GameData") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.GameDataPair", b => - { - b.HasOne("sodoff.Model.GameData", "GameData") - .WithMany("GameDataPairs") - .HasForeignKey("GameDataId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GameData"); - }); - - modelBuilder.Entity("sodoff.Model.Image", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Images") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.InventoryItem", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("InventoryItems") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.MMORole", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("MMORoles") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Message", b => - { - b.HasOne("sodoff.Model.Message", "ParentMessage") - .WithMany("Replies") - .HasForeignKey("ParentMessageId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("sodoff.Model.Viking", "ToViking") - .WithMany("MessageBoard") - .HasForeignKey("ToVikingId"); - - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("MessagesMade") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("ParentMessage"); - - b.Navigation("ToViking"); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.MissionState", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("MissionStates") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Neighborhood", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithOne("Neighborhood") - .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Pair", b => - { - b.HasOne("sodoff.Model.PairData", "PairData") - .WithMany("Pairs") - .HasForeignKey("MasterId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("PairData"); - }); - - modelBuilder.Entity("sodoff.Model.PairData", b => - { - b.HasOne("sodoff.Model.Dragon", "Dragon") - .WithMany("PairData") - .HasForeignKey("DragonId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("sodoff.Model.User", "User") - .WithMany("PairData") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("PairData") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade); - - b.Navigation("Dragon"); - - b.Navigation("User"); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Party", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Parties") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("ProfileAnswers") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Rating", b => - { - b.HasOne("sodoff.Model.RatingRank", "Rank") - .WithMany("Ratings") - .HasForeignKey("RankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Ratings") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Rank"); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Room", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Rooms") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.RoomItem", b => - { - b.HasOne("sodoff.Model.Room", "Room") - .WithMany("Items") - .HasForeignKey("RoomId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Room"); - }); - - modelBuilder.Entity("sodoff.Model.SavedData", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("SavedData") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.SceneData", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("SceneData") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Session", b => - { - b.HasOne("sodoff.Model.User", "User") - .WithMany("Sessions") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("Sessions") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade); - - b.Navigation("User"); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.TaskStatus", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("TaskStatuses") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("UserBadgesCompleted") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.UserBan", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("UserBans") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.UserMissionData", b => - { - b.HasOne("sodoff.Model.Viking", "Viking") - .WithMany("UserMissions") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Viking"); - }); - - modelBuilder.Entity("sodoff.Model.Viking", b => - { - b.HasOne("sodoff.Model.Dragon", "SelectedDragon") - .WithOne() - .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); - - b.HasOne("sodoff.Model.User", "User") - .WithMany("Vikings") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("SelectedDragon"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("sodoff.Model.Dragon", b => - { - b.Navigation("PairData"); - }); - - modelBuilder.Entity("sodoff.Model.GameData", b => - { - b.Navigation("GameDataPairs"); - }); - - modelBuilder.Entity("sodoff.Model.Message", b => - { - b.Navigation("Replies"); - }); - - modelBuilder.Entity("sodoff.Model.PairData", b => - { - b.Navigation("Pairs"); - }); - - modelBuilder.Entity("sodoff.Model.RatingRank", b => - { - b.Navigation("Ratings"); - }); - - modelBuilder.Entity("sodoff.Model.Room", b => - { - b.Navigation("Items"); - }); - - modelBuilder.Entity("sodoff.Model.User", b => - { - b.Navigation("PairData"); - - b.Navigation("Sessions"); - - b.Navigation("Vikings"); - }); - - modelBuilder.Entity("sodoff.Model.Viking", b => - { - b.Navigation("AchievementPoints"); - - b.Navigation("AchievementTaskStates"); - - b.Navigation("BuddiesMade"); - - b.Navigation("BuddyList"); - - b.Navigation("Dragons"); - - b.Navigation("GameData"); - - b.Navigation("Images"); - - b.Navigation("InventoryItems"); - - b.Navigation("MMORoles"); - - b.Navigation("MessageBoard"); - - b.Navigation("MessagesMade"); - - b.Navigation("MissionStates"); - - b.Navigation("Neighborhood"); - - b.Navigation("PairData"); - - b.Navigation("Parties"); - - b.Navigation("ProfileAnswers"); - - b.Navigation("Ratings"); - - b.Navigation("Rooms"); - - b.Navigation("SavedData"); - - b.Navigation("SceneData"); - - b.Navigation("Sessions"); - - b.Navigation("TaskStatuses"); - - b.Navigation("UserBadgesCompleted"); - - b.Navigation("UserBans"); - - b.Navigation("UserMissions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs b/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs deleted file mode 100644 index 435caac..0000000 --- a/src/Migrations/20250306194521_Messaging_ToVikingIdNullable.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace sodoff.Migrations -{ - /// - public partial class Messaging_ToVikingIdNullable : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Messages_Vikings_ToVikingId", - table: "Messages"); - - migrationBuilder.AlterColumn( - name: "ToVikingId", - table: "Messages", - type: "INTEGER", - nullable: true, - oldClrType: typeof(int), - oldType: "INTEGER"); - - migrationBuilder.AddForeignKey( - name: "FK_Messages_Vikings_ToVikingId", - table: "Messages", - column: "ToVikingId", - principalTable: "Vikings", - principalColumn: "Id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Messages_Vikings_ToVikingId", - table: "Messages"); - - migrationBuilder.AlterColumn( - name: "ToVikingId", - table: "Messages", - type: "INTEGER", - nullable: false, - defaultValue: 0, - oldClrType: typeof(int), - oldType: "INTEGER", - oldNullable: true); - - migrationBuilder.AddForeignKey( - name: "FK_Messages_Vikings_ToVikingId", - table: "Messages", - column: "ToVikingId", - principalTable: "Vikings", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - } -} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 6ded7e0..0784971 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -33,7 +33,7 @@ namespace sodoff.Migrations b.HasIndex("VikingsId"); - b.ToTable("GroupViking"); + b.ToTable("GroupViking", (string)null); }); modelBuilder.Entity("sodoff.Model.AchievementPoints", b => @@ -49,7 +49,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "Type"); - b.ToTable("AchievementPoints"); + b.ToTable("AchievementPoints", (string)null); }); modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => @@ -67,7 +67,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("AchievementTaskState"); + b.ToTable("AchievementTaskState", (string)null); }); modelBuilder.Entity("sodoff.Model.Buddy", b => @@ -103,7 +103,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Buddies"); + b.ToTable("Buddies", (string)null); }); modelBuilder.Entity("sodoff.Model.Dragon", b => @@ -128,7 +128,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Dragons"); + b.ToTable("Dragons", (string)null); }); modelBuilder.Entity("sodoff.Model.GameData", b => @@ -165,7 +165,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("GameData"); + b.ToTable("GameData", (string)null); }); modelBuilder.Entity("sodoff.Model.GameDataPair", b => @@ -188,7 +188,7 @@ namespace sodoff.Migrations b.HasIndex("GameDataId"); - b.ToTable("GameDataPairs"); + b.ToTable("GameDataPairs", (string)null); }); modelBuilder.Entity("sodoff.Model.Group", b => @@ -221,7 +221,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("Groups"); + b.ToTable("Groups", (string)null); }); modelBuilder.Entity("sodoff.Model.Image", b => @@ -245,7 +245,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Images"); + b.ToTable("Images", (string)null); }); modelBuilder.Entity("sodoff.Model.InventoryItem", b => @@ -273,7 +273,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("InventoryItems"); + b.ToTable("InventoryItems", (string)null); }); modelBuilder.Entity("sodoff.Model.MMORole", b => @@ -292,7 +292,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("MMORoles"); + b.ToTable("MMORoles", (string)null); }); modelBuilder.Entity("sodoff.Model.Message", b => @@ -343,7 +343,7 @@ namespace sodoff.Migrations b.Property("QueueID") .HasColumnType("INTEGER"); - b.Property("ToVikingId") + b.Property("ToVikingId") .HasColumnType("INTEGER"); b.Property("VikingId") @@ -357,7 +357,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Messages"); + b.ToTable("Messages", (string)null); }); modelBuilder.Entity("sodoff.Model.MissionState", b => @@ -382,7 +382,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("MissionStates"); + b.ToTable("MissionStates", (string)null); }); modelBuilder.Entity("sodoff.Model.Neighborhood", b => @@ -414,7 +414,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId") .IsUnique(); - b.ToTable("Neighborhoods"); + b.ToTable("Neighborhoods", (string)null); }); modelBuilder.Entity("sodoff.Model.Pair", b => @@ -438,7 +438,7 @@ namespace sodoff.Migrations b.HasIndex("MasterId"); - b.ToTable("Pairs"); + b.ToTable("Pairs", (string)null); }); modelBuilder.Entity("sodoff.Model.PairData", b => @@ -467,7 +467,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("PairData"); + b.ToTable("PairData", (string)null); }); modelBuilder.Entity("sodoff.Model.Party", b => @@ -501,7 +501,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Parties"); + b.ToTable("Parties", (string)null); }); modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => @@ -523,7 +523,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("ProfileAnswers"); + b.ToTable("ProfileAnswers", (string)null); }); modelBuilder.Entity("sodoff.Model.Rating", b => @@ -550,7 +550,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Ratings"); + b.ToTable("Ratings", (string)null); }); modelBuilder.Entity("sodoff.Model.RatingRank", b => @@ -579,7 +579,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("RatingRanks"); + b.ToTable("RatingRanks", (string)null); }); modelBuilder.Entity("sodoff.Model.Room", b => @@ -602,7 +602,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Rooms"); + b.ToTable("Rooms", (string)null); }); modelBuilder.Entity("sodoff.Model.RoomItem", b => @@ -622,7 +622,7 @@ namespace sodoff.Migrations b.HasIndex("RoomId"); - b.ToTable("RoomItems"); + b.ToTable("RoomItems", (string)null); }); modelBuilder.Entity("sodoff.Model.SavedData", b => @@ -638,7 +638,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "SaveId"); - b.ToTable("SavedData"); + b.ToTable("SavedData", (string)null); }); modelBuilder.Entity("sodoff.Model.SceneData", b => @@ -662,7 +662,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("SceneData"); + b.ToTable("SceneData", (string)null); }); modelBuilder.Entity("sodoff.Model.Session", b => @@ -686,7 +686,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Sessions"); + b.ToTable("Sessions", (string)null); }); modelBuilder.Entity("sodoff.Model.TaskStatus", b => @@ -710,7 +710,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("TaskStatuses"); + b.ToTable("TaskStatuses", (string)null); }); modelBuilder.Entity("sodoff.Model.User", b => @@ -733,7 +733,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("Users"); + b.ToTable("Users", (string)null); }); modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => @@ -752,7 +752,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("UserBadgesCompleted"); + b.ToTable("UserBadgesCompleted", (string)null); }); modelBuilder.Entity("sodoff.Model.UserBan", b => @@ -777,7 +777,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Bans"); + b.ToTable("Bans", (string)null); }); modelBuilder.Entity("sodoff.Model.UserMissionData", b => @@ -802,7 +802,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "WorldId", "MissionId"); - b.ToTable("UserMissionData"); + b.ToTable("UserMissionData", (string)null); }); modelBuilder.Entity("sodoff.Model.Viking", b => @@ -848,7 +848,7 @@ namespace sodoff.Migrations b.HasIndex("UserId"); - b.ToTable("Vikings"); + b.ToTable("Vikings", (string)null); }); modelBuilder.Entity("GroupViking", b => @@ -982,7 +982,9 @@ namespace sodoff.Migrations b.HasOne("sodoff.Model.Viking", "ToViking") .WithMany("MessageBoard") - .HasForeignKey("ToVikingId"); + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); b.HasOne("sodoff.Model.Viking", "Viking") .WithMany("MessagesMade") diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index 1c05ba2..50976a3 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -16,14 +16,14 @@ public class MessagingService this.ctx = ctx; } - public Model.Message AddMessageToViking(Viking viking, Viking toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0) + public Model.Message AddMessageToViking(Viking viking, Viking? toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0) { // get execution UTC timestamp DateTime now = DateTime.UtcNow; // for generating ConversationId and QueueId Random rnd = new Random(); - + // construct message Model.Message message = new Model.Message { From 7e29d5cd4a14ba953dd79a08baadafe01335ffa6 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 12:01:37 -0800 Subject: [PATCH 12/18] add system message support --- src/Services/MessagingService.cs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index 50976a3..fc13216 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -16,19 +16,17 @@ public class MessagingService this.ctx = ctx; } - public Model.Message AddMessageToViking(Viking viking, Viking? toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0) + public Model.Message AddMessageToViking(Viking? viking, Viking toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0) { // get execution UTC timestamp DateTime now = DateTime.UtcNow; // for generating ConversationId and QueueId Random rnd = new Random(); - + // construct message Model.Message message = new Model.Message { - Viking = viking, - VikingId = viking.Id, ToViking = toViking, ToVikingId = toViking.Id, QueueID = rnd.Next(1000, 9999), @@ -46,6 +44,16 @@ public class MessagingService IsPrivate = isPrivate }; + if (viking == null) + { + message.Viking = null; + message.VikingId = -1; // -1 = System Message + } else + { + message.Viking = viking; + message.VikingId = viking.Id; + } + if (isReply && parentMessageId > 0) { // get message this is in reply to @@ -139,7 +147,7 @@ public class MessagingService MessageID = message.Id, ConversationID = message.ConversationID ?? 0, ReplyToMessageID = message.ParentMessageId, - Creator = msgAuthor.Uid.ToString() ?? "Ghost", + Creator = msgAuthor.Uid.ToString() ?? new Guid().ToString(), CreateTime = message.CreatedAt, UpdateDate = message.LastUpdatedAt, MessageType = message.MessageType.Value, @@ -169,7 +177,7 @@ public class MessagingService UserMessageQueueID = message.QueueID, MessageID = message.Id, MessageTypeID = (int?)message.MessageTypeID, - FromUserID = msgAuthor.Uid.ToString() ?? "NotFound", + FromUserID = msgAuthor.Uid.ToString() ?? new Guid().ToString(), MemberMessage = message.MemberMessage ?? "NoData", NonMemberMessage = message.NonMemberMessage ?? "NoData", Data = data @@ -182,7 +190,7 @@ public class MessagingService UserMessageQueueID = message.QueueID, MessageID = message.Id, MessageTypeID = (int?)message.MessageTypeID, - FromUserID = msgAuthor.Uid.ToString() ?? "NotFound", + FromUserID = msgAuthor.Uid.ToString() ?? new Guid().ToString(), MemberMessage = message.MemberMessage ?? "NoData", NonMemberMessage = message.NonMemberMessage ?? "NoData", Data = message.Data @@ -205,7 +213,7 @@ public class MessagingService MessageID = reply.Id, ConversationID = reply.ConversationID ?? 0, ReplyToMessageID = reply.ParentMessageId, - Creator = replyAuthor.Uid.ToString() ?? "Ghost", + Creator = replyAuthor.Uid.ToString() ?? new Guid().ToString(), CreateTime = reply.CreatedAt, UpdateDate = reply.LastUpdatedAt, MessageType = reply.MessageType.Value, @@ -252,13 +260,13 @@ public class MessagingService Viking? msgAuthor = ctx.Vikings.FirstOrDefault(e => e.Id == message.VikingId) ?? new Viking(); if(message.IsDeleted) { ctx.Messages.Remove(message); continue; } - if(DateTime.Compare(now, message.CreatedAt.AddMinutes(30)) > 0) { message.IsNew = false; continue; } // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response + if(DateTime.Compare(now, message.CreatedAt.AddMinutes(30)) > 0 && !showOldMessages) { message.IsNew = false; continue; } // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response if(!message.IsNew && !showOldMessages) continue; messageInfos.Add(new MessageInfo { MessageID = message.Id, UserMessageQueueID = message.QueueID, - FromUserID = msgAuthor.Uid.ToString() ?? "NotFound", + FromUserID = msgAuthor.Uid.ToString() ?? new Guid().ToString(), MessageTypeID = (int?)message.MessageTypeID, Data = message.Data ?? "NoData", MemberMessage = message.MemberMessage ?? "NoMessage", From b090604bc124b5b0126169d0e9cf9e34a0f5c993 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 12:35:25 -0800 Subject: [PATCH 13/18] add message for earning xp (wojs) --- src/Services/AchievementService.cs | 8 +++++++- src/Services/MessagingService.cs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Services/AchievementService.cs b/src/Services/AchievementService.cs index 7e89658..771bc7e 100644 --- a/src/Services/AchievementService.cs +++ b/src/Services/AchievementService.cs @@ -9,11 +9,13 @@ namespace sodoff.Services { public class AchievementService { private AchievementStoreSingleton achievementStore; private InventoryService inventoryService; + private MessagingService messagingService; public readonly DBContext ctx; - public AchievementService(AchievementStoreSingleton achievementStore, InventoryService inventoryService, DBContext ctx) { + public AchievementService(AchievementStoreSingleton achievementStore, InventoryService inventoryService, MessagingService messagingService, DBContext ctx) { this.achievementStore = achievementStore; this.inventoryService = inventoryService; + this.messagingService = messagingService; this.ctx = ctx; } @@ -137,6 +139,10 @@ namespace sodoff.Services { grantedRewards.Add( ApplyAchievementReward(viking, reward) ); + + // add message for earning xp (wojs) + if (reward.PointTypeID == AchievementPointTypes.PlayerXP && viking.GameVersion <= ClientVersion.WoJS) + messagingService.AddMessageToViking(null, viking, MessageType.Data, MessageTypeID.Jumpstar, MessageLevel.WhiteList, $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]", $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]", $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]"); } } diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index fc13216..958916f 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -128,7 +128,7 @@ public class MessagingService continue; } - if (message.IsPrivate && (viking.Id != publicViking.Id)) continue; + if (message.IsPrivate && (viking.Id != publicViking.Id) || message.VikingId == -1) continue; Viking? msgAuthor = ctx.Vikings.FirstOrDefault(e => e.Id == message.VikingId) ?? new Viking(); @@ -259,7 +259,7 @@ public class MessagingService { Viking? msgAuthor = ctx.Vikings.FirstOrDefault(e => e.Id == message.VikingId) ?? new Viking(); - if(message.IsDeleted) { ctx.Messages.Remove(message); continue; } + if(message.IsDeleted && !showDeletedMessages) { ctx.Messages.Remove(message); continue; } if(DateTime.Compare(now, message.CreatedAt.AddMinutes(30)) > 0 && !showOldMessages) { message.IsNew = false; continue; } // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response if(!message.IsNew && !showOldMessages) continue; messageInfos.Add(new MessageInfo From 20452e205851bc98de95ac3a723da7af1be0d6f4 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 15:42:45 -0800 Subject: [PATCH 14/18] make author viking optional for system messages --- ...213_Messaging_VikingIdOptional.Designer.cs | 1317 +++++++++++++++++ ...250306234213_Messaging_VikingIdOptional.cs | 59 + src/Migrations/DBContextModelSnapshot.cs | 68 +- src/Model/DBContext.cs | 3 +- src/Model/Message.cs | 4 +- 5 files changed, 1413 insertions(+), 38 deletions(-) create mode 100644 src/Migrations/20250306234213_Messaging_VikingIdOptional.Designer.cs create mode 100644 src/Migrations/20250306234213_Messaging_VikingIdOptional.cs diff --git a/src/Migrations/20250306234213_Messaging_VikingIdOptional.Designer.cs b/src/Migrations/20250306234213_Messaging_VikingIdOptional.Designer.cs new file mode 100644 index 0000000..ef59613 --- /dev/null +++ b/src/Migrations/20250306234213_Messaging_VikingIdOptional.Designer.cs @@ -0,0 +1,1317 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250306234213_Messaging_VikingIdOptional")] + partial class Messaging_VikingIdOptional + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId"); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250306234213_Messaging_VikingIdOptional.cs b/src/Migrations/20250306234213_Messaging_VikingIdOptional.cs new file mode 100644 index 0000000..d000f50 --- /dev/null +++ b/src/Migrations/20250306234213_Messaging_VikingIdOptional.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Messaging_VikingIdOptional : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Messages_Vikings_VikingId", + table: "Messages"); + + migrationBuilder.AlterColumn( + name: "VikingId", + table: "Messages", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AddForeignKey( + name: "FK_Messages_Vikings_VikingId", + table: "Messages", + column: "VikingId", + principalTable: "Vikings", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Messages_Vikings_VikingId", + table: "Messages"); + + migrationBuilder.AlterColumn( + name: "VikingId", + table: "Messages", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Messages_Vikings_VikingId", + table: "Messages", + column: "VikingId", + principalTable: "Vikings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 0784971..9a86ee3 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -33,7 +33,7 @@ namespace sodoff.Migrations b.HasIndex("VikingsId"); - b.ToTable("GroupViking", (string)null); + b.ToTable("GroupViking"); }); modelBuilder.Entity("sodoff.Model.AchievementPoints", b => @@ -49,7 +49,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "Type"); - b.ToTable("AchievementPoints", (string)null); + b.ToTable("AchievementPoints"); }); modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => @@ -67,7 +67,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("AchievementTaskState", (string)null); + b.ToTable("AchievementTaskState"); }); modelBuilder.Entity("sodoff.Model.Buddy", b => @@ -103,7 +103,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Buddies", (string)null); + b.ToTable("Buddies"); }); modelBuilder.Entity("sodoff.Model.Dragon", b => @@ -128,7 +128,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Dragons", (string)null); + b.ToTable("Dragons"); }); modelBuilder.Entity("sodoff.Model.GameData", b => @@ -165,7 +165,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("GameData", (string)null); + b.ToTable("GameData"); }); modelBuilder.Entity("sodoff.Model.GameDataPair", b => @@ -188,7 +188,7 @@ namespace sodoff.Migrations b.HasIndex("GameDataId"); - b.ToTable("GameDataPairs", (string)null); + b.ToTable("GameDataPairs"); }); modelBuilder.Entity("sodoff.Model.Group", b => @@ -221,7 +221,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("Groups", (string)null); + b.ToTable("Groups"); }); modelBuilder.Entity("sodoff.Model.Image", b => @@ -245,7 +245,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Images", (string)null); + b.ToTable("Images"); }); modelBuilder.Entity("sodoff.Model.InventoryItem", b => @@ -273,7 +273,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("InventoryItems", (string)null); + b.ToTable("InventoryItems"); }); modelBuilder.Entity("sodoff.Model.MMORole", b => @@ -292,7 +292,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("MMORoles", (string)null); + b.ToTable("MMORoles"); }); modelBuilder.Entity("sodoff.Model.Message", b => @@ -346,7 +346,7 @@ namespace sodoff.Migrations b.Property("ToVikingId") .HasColumnType("INTEGER"); - b.Property("VikingId") + b.Property("VikingId") .HasColumnType("INTEGER"); b.HasKey("Id"); @@ -357,7 +357,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Messages", (string)null); + b.ToTable("Messages"); }); modelBuilder.Entity("sodoff.Model.MissionState", b => @@ -382,7 +382,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("MissionStates", (string)null); + b.ToTable("MissionStates"); }); modelBuilder.Entity("sodoff.Model.Neighborhood", b => @@ -414,7 +414,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId") .IsUnique(); - b.ToTable("Neighborhoods", (string)null); + b.ToTable("Neighborhoods"); }); modelBuilder.Entity("sodoff.Model.Pair", b => @@ -438,7 +438,7 @@ namespace sodoff.Migrations b.HasIndex("MasterId"); - b.ToTable("Pairs", (string)null); + b.ToTable("Pairs"); }); modelBuilder.Entity("sodoff.Model.PairData", b => @@ -467,7 +467,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("PairData", (string)null); + b.ToTable("PairData"); }); modelBuilder.Entity("sodoff.Model.Party", b => @@ -501,7 +501,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Parties", (string)null); + b.ToTable("Parties"); }); modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => @@ -523,7 +523,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("ProfileAnswers", (string)null); + b.ToTable("ProfileAnswers"); }); modelBuilder.Entity("sodoff.Model.Rating", b => @@ -550,7 +550,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Ratings", (string)null); + b.ToTable("Ratings"); }); modelBuilder.Entity("sodoff.Model.RatingRank", b => @@ -579,7 +579,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("RatingRanks", (string)null); + b.ToTable("RatingRanks"); }); modelBuilder.Entity("sodoff.Model.Room", b => @@ -602,7 +602,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Rooms", (string)null); + b.ToTable("Rooms"); }); modelBuilder.Entity("sodoff.Model.RoomItem", b => @@ -622,7 +622,7 @@ namespace sodoff.Migrations b.HasIndex("RoomId"); - b.ToTable("RoomItems", (string)null); + b.ToTable("RoomItems"); }); modelBuilder.Entity("sodoff.Model.SavedData", b => @@ -638,7 +638,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "SaveId"); - b.ToTable("SavedData", (string)null); + b.ToTable("SavedData"); }); modelBuilder.Entity("sodoff.Model.SceneData", b => @@ -662,7 +662,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("SceneData", (string)null); + b.ToTable("SceneData"); }); modelBuilder.Entity("sodoff.Model.Session", b => @@ -686,7 +686,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Sessions", (string)null); + b.ToTable("Sessions"); }); modelBuilder.Entity("sodoff.Model.TaskStatus", b => @@ -710,7 +710,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("TaskStatuses", (string)null); + b.ToTable("TaskStatuses"); }); modelBuilder.Entity("sodoff.Model.User", b => @@ -733,7 +733,7 @@ namespace sodoff.Migrations b.HasKey("Id"); - b.ToTable("Users", (string)null); + b.ToTable("Users"); }); modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => @@ -752,7 +752,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("UserBadgesCompleted", (string)null); + b.ToTable("UserBadgesCompleted"); }); modelBuilder.Entity("sodoff.Model.UserBan", b => @@ -777,7 +777,7 @@ namespace sodoff.Migrations b.HasIndex("VikingId"); - b.ToTable("Bans", (string)null); + b.ToTable("Bans"); }); modelBuilder.Entity("sodoff.Model.UserMissionData", b => @@ -802,7 +802,7 @@ namespace sodoff.Migrations b.HasKey("VikingId", "WorldId", "MissionId"); - b.ToTable("UserMissionData", (string)null); + b.ToTable("UserMissionData"); }); modelBuilder.Entity("sodoff.Model.Viking", b => @@ -848,7 +848,7 @@ namespace sodoff.Migrations b.HasIndex("UserId"); - b.ToTable("Vikings", (string)null); + b.ToTable("Vikings"); }); modelBuilder.Entity("GroupViking", b => @@ -988,9 +988,7 @@ namespace sodoff.Migrations b.HasOne("sodoff.Model.Viking", "Viking") .WithMany("MessagesMade") - .HasForeignKey("VikingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("VikingId"); b.Navigation("ParentMessage"); diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index cc564c6..245dcc6 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -328,7 +328,8 @@ public class DBContext : DbContext { // Messages builder.Entity().HasOne(r => r.Viking) .WithMany(e => e.MessagesMade) - .HasForeignKey(e => e.VikingId); + .HasForeignKey(e => e.VikingId) + .IsRequired(false); // system messages usually don't have am author builder.Entity().HasOne(r => r.ToViking) .WithMany(e => e.MessageBoard) diff --git a/src/Model/Message.cs b/src/Model/Message.cs index e170285..8f0c549 100644 --- a/src/Model/Message.cs +++ b/src/Model/Message.cs @@ -9,8 +9,8 @@ public class Message [Key] public int Id { get; set; } - public int VikingId { get; set; } - public int? ToVikingId { get; set; } + public int? VikingId { get; set; } + public int ToVikingId { get; set; } public int QueueID { get; set; } public int? ConversationID { get; set; } From 5d0cb1581d63623514d2e210ffe5b9542d896755 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 6 Mar 2025 17:48:08 -0800 Subject: [PATCH 15/18] further system message fixes --- src/Services/AchievementService.cs | 4 ---- src/Services/MessagingService.cs | 9 ++++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Services/AchievementService.cs b/src/Services/AchievementService.cs index 771bc7e..7c392f8 100644 --- a/src/Services/AchievementService.cs +++ b/src/Services/AchievementService.cs @@ -139,10 +139,6 @@ namespace sodoff.Services { grantedRewards.Add( ApplyAchievementReward(viking, reward) ); - - // add message for earning xp (wojs) - if (reward.PointTypeID == AchievementPointTypes.PlayerXP && viking.GameVersion <= ClientVersion.WoJS) - messagingService.AddMessageToViking(null, viking, MessageType.Data, MessageTypeID.Jumpstar, MessageLevel.WhiteList, $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]", $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]", $"[[Line1]]=[[Congratulations, You've Earned {reward.Amount} JumpStars!]]"); } } diff --git a/src/Services/MessagingService.cs b/src/Services/MessagingService.cs index 958916f..17c1fb5 100644 --- a/src/Services/MessagingService.cs +++ b/src/Services/MessagingService.cs @@ -47,7 +47,7 @@ public class MessagingService if (viking == null) { message.Viking = null; - message.VikingId = -1; // -1 = System Message + message.VikingId = null; } else { message.Viking = viking; @@ -262,7 +262,8 @@ public class MessagingService if(message.IsDeleted && !showDeletedMessages) { ctx.Messages.Remove(message); continue; } if(DateTime.Compare(now, message.CreatedAt.AddMinutes(30)) > 0 && !showOldMessages) { message.IsNew = false; continue; } // sometimes clients won't set IsNew flag when updating messages, so do not add messages more than 30 minutes old to response if(!message.IsNew && !showOldMessages) continue; - messageInfos.Add(new MessageInfo + + MessageInfo messageInfo = new MessageInfo { MessageID = message.Id, UserMessageQueueID = message.QueueID, @@ -271,7 +272,9 @@ public class MessagingService Data = message.Data ?? "NoData", MemberMessage = message.MemberMessage ?? "NoMessage", NonMemberMessage = message.NonMemberMessage ?? "NoMessage" - }); + }; + + messageInfos.Add(messageInfo); } // save any database changes From 44aa98ef3a4e5fb8367f63a66f1848aba9be6ca5 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Fri, 7 Mar 2025 17:20:27 -0800 Subject: [PATCH 16/18] implement buddy codes --- src/Controllers/Common/ContentController.cs | 36 + ...0250308012001_Viking_BuddyCode.Designer.cs | 1320 +++++++++++++++++ .../20250308012001_Viking_BuddyCode.cs | 28 + src/Migrations/DBContextModelSnapshot.cs | 3 + src/Model/Viking.cs | 2 + src/Services/BuddyService.cs | 30 + 6 files changed, 1419 insertions(+) create mode 100644 src/Migrations/20250308012001_Viking_BuddyCode.Designer.cs create mode 100644 src/Migrations/20250308012001_Viking_BuddyCode.cs diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 7d033aa..a4ca9cd 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1159,6 +1159,31 @@ public class ContentController : Controller { else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/AddBuddyByFriendCode")] + [VikingSession] + public IActionResult AddBuddyByFriendCode(Viking viking, [FromForm] string friendCode, [FromForm] string apiKey) + { + // make sure viking doesn't add self as buddy + if (viking.BuddyCode != null && viking.BuddyCode == friendCode) return Ok(new BuddyActionResult{ Result = BuddyActionResultType.CannotAddSelf }); + + // find viking + Viking? buddyViking = ctx.Vikings.FirstOrDefault(e => e.BuddyCode == friendCode); + + if (buddyViking != null) + { + uint gameVersion = ClientVersion.GetVersion(apiKey); + // check if game clients are different + if ( + (buddyViking.GameVersion != gameVersion) && + !(buddyViking.GameVersion >= ClientVersion.Min_SoD && gameVersion >= ClientVersion.Min_SoD) && + !(buddyViking.GameVersion >= ClientVersion.WoJS && gameVersion >= ClientVersion.WoJS && buddyViking.GameVersion < ClientVersion.WoJS_NewAvatar && gameVersion < ClientVersion.WoJS_NewAvatar) + ) return Ok(new BuddyActionResult { Result = BuddyActionResultType.InvalidFriendCode }); + else return Ok(buddyService.CreateBuddyRelation(viking, buddyViking)); + } else return Ok(new BuddyActionResult{ Result = BuddyActionResultType.InvalidFriendCode }); + } + [HttpPost] [Produces("application/xml")] [Route("ContentWebService.asmx/RemoveBuddy")] @@ -1209,6 +1234,17 @@ public class ContentController : Controller { return Ok(buddyService.ConstructBuddyList(viking)); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/GetFriendCode")] + public IActionResult GetFriendCode([FromForm] Guid userId) + { + Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Uid == userId); + + if (viking == null) return NotFound(); + else return Ok(buddyService.GetOrSetBuddyCode(viking)); + } + [HttpPost] [Produces("application/xml")] [Route("/ContentWebService.asmx/RedeemMysteryBoxItems")] diff --git a/src/Migrations/20250308012001_Viking_BuddyCode.Designer.cs b/src/Migrations/20250308012001_Viking_BuddyCode.Designer.cs new file mode 100644 index 0000000..5d4d672 --- /dev/null +++ b/src/Migrations/20250308012001_Viking_BuddyCode.Designer.cs @@ -0,0 +1,1320 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250308012001_Viking_BuddyCode")] + partial class Viking_BuddyCode + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("BuddyCode") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId"); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250308012001_Viking_BuddyCode.cs b/src/Migrations/20250308012001_Viking_BuddyCode.cs new file mode 100644 index 0000000..0939563 --- /dev/null +++ b/src/Migrations/20250308012001_Viking_BuddyCode.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Viking_BuddyCode : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BuddyCode", + table: "Vikings", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BuddyCode", + table: "Vikings"); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 9a86ee3..7aada7e 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -817,6 +817,9 @@ namespace sodoff.Migrations b.Property("BirthDate") .HasColumnType("TEXT"); + b.Property("BuddyCode") + .HasColumnType("TEXT"); + b.Property("CreationDate") .HasColumnType("TEXT"); diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index a54513e..ca6affa 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -19,6 +19,8 @@ public class Viking { public string? AvatarSerialized { get; set; } + public string? BuddyCode { get; set; } + public int? SelectedDragonId { get; set; } public virtual ICollection Sessions { get; set; } = null!; diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index 7983230..57a783d 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -1,5 +1,6 @@ using System; using System.Data; +using System.Security; using sodoff.Model; using sodoff.Schema; using sodoff.Util; @@ -8,8 +9,12 @@ namespace sodoff.Services; public class BuddyService { + private char[] BuddyCodeCharacterList = new char[] + { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0' }; + private readonly DBContext ctx; private readonly MessagingService messagingService; + public BuddyService(DBContext ctx, MessagingService messagingService) { this.ctx = ctx; @@ -95,6 +100,31 @@ public class BuddyService } else return false; } + public string GetOrSetBuddyCode(Viking viking) + { + if (viking.BuddyCode != null) return viking.BuddyCode; + else + { + // generate a buddy code and set it + Random rnd = new Random(); + string code = ""; + do + { + for( int i = 0; i < 5; i++ ) + { + code += BuddyCodeCharacterList[rnd.Next(0, BuddyCodeCharacterList.Length)]; + } + } while (ctx.Vikings.FirstOrDefault(e => e.BuddyCode == code) != null); + + // set code on viking + viking.BuddyCode = code; + ctx.SaveChanges(); + + // return it + return viking.BuddyCode; + } + } + public bool RemoveBuddy(Viking viking, Viking buddyViking) { // find relation From ded2acc5cac376e6c713a9fc840941634a956f31 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Fri, 7 Mar 2025 17:42:44 -0800 Subject: [PATCH 17/18] implement precense endpoint --- src/Controllers/Common/PrecenseController.cs | 25 + src/Controllers/Common/ProfileController.cs | 2 +- .../20250308013623_Viking_Online.Designer.cs | 1323 +++++++++++++++++ .../20250308013623_Viking_Online.cs | 28 + src/Migrations/DBContextModelSnapshot.cs | 3 + src/Model/Viking.cs | 2 + src/Services/BuddyService.cs | 4 +- 7 files changed, 1384 insertions(+), 3 deletions(-) create mode 100644 src/Controllers/Common/PrecenseController.cs create mode 100644 src/Migrations/20250308013623_Viking_Online.Designer.cs create mode 100644 src/Migrations/20250308013623_Viking_Online.cs diff --git a/src/Controllers/Common/PrecenseController.cs b/src/Controllers/Common/PrecenseController.cs new file mode 100644 index 0000000..e0e16fd --- /dev/null +++ b/src/Controllers/Common/PrecenseController.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using sodoff.Attributes; +using sodoff.Model; + +namespace sodoff.Controllers.Common +{ + [ApiController] + public class PrecenseController : Controller + { + private readonly DBContext ctx; + public PrecenseController(DBContext ctx) => this.ctx = ctx; + + [HttpPost] + [Produces("application/json")] + [Route("Precense/SetVikingOnline")] + [VikingSession] + public IActionResult SetVikingOnline(Viking viking, [FromForm] bool online) + { + viking.Online = online; + ctx.SaveChanges(); + return Ok(viking.Online); + } + } +} diff --git a/src/Controllers/Common/ProfileController.cs b/src/Controllers/Common/ProfileController.cs index c6928c2..7802ba7 100644 --- a/src/Controllers/Common/ProfileController.cs +++ b/src/Controllers/Common/ProfileController.cs @@ -177,7 +177,7 @@ public class ProfileController : Controller { GameCurrency = currency.GameCurrency, CashCurrency = currency.CashCurrency, ActivityCount = 0, - BuddyCount = 0, + BuddyCount = viking.BuddiesMade.Count, UserGradeData = new UserGrade { UserGradeID = 0 }, UserProfileTag = new UserProfileTag() { CreateDate = new DateTime(DateTime.Now.Ticks), diff --git a/src/Migrations/20250308013623_Viking_Online.Designer.cs b/src/Migrations/20250308013623_Viking_Online.Designer.cs new file mode 100644 index 0000000..87049c9 --- /dev/null +++ b/src/Migrations/20250308013623_Viking_Online.Designer.cs @@ -0,0 +1,1323 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using sodoff.Model; + +#nullable disable + +namespace sodoff.Migrations +{ + [DbContext(typeof(DBContext))] + [Migration("20250308013623_Viking_Online")] + partial class Viking_Online + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("GroupViking", b => + { + b.Property("GroupsId") + .HasColumnType("INTEGER"); + + b.Property("VikingsId") + .HasColumnType("INTEGER"); + + b.HasKey("GroupsId", "VikingsId"); + + b.HasIndex("VikingsId"); + + b.ToTable("GroupViking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "Type"); + + b.ToTable("AchievementPoints"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Points") + .HasColumnType("INTEGER"); + + b.HasKey("TaskId", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("AchievementTaskState"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus1") + .HasColumnType("INTEGER"); + + b.Property("BuddyStatus2") + .HasColumnType("INTEGER"); + + b.Property("BuddyVikingId") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsBestFriend1") + .HasColumnType("INTEGER"); + + b.Property("IsBestFriend2") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BuddyVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Buddies"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("PetXP") + .HasColumnType("INTEGER"); + + b.Property("RaisedPetData") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Dragons"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DatePlayed") + .HasColumnType("TEXT"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("INTEGER"); + + b.Property("GameLevel") + .HasColumnType("INTEGER"); + + b.Property("IsMultiplayer") + .HasColumnType("INTEGER"); + + b.Property("Loss") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("Win") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GameDataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GameDataId"); + + b.ToTable("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GroupID") + .HasColumnType("TEXT"); + + b.Property("Logo") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.Property("ImageType") + .HasColumnType("TEXT"); + + b.Property("ImageSlot") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("ImageData") + .HasColumnType("TEXT"); + + b.Property("TemplateName") + .HasColumnType("TEXT"); + + b.HasKey("ImageType", "ImageSlot", "VikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributesSerialized") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("StatsSerialized") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MMORoles"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConversationID") + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Data") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsNew") + .HasColumnType("INTEGER"); + + b.Property("IsPrivate") + .HasColumnType("INTEGER"); + + b.Property("LastUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("MemberMessage") + .HasColumnType("TEXT"); + + b.Property("MessageLevel") + .HasColumnType("INTEGER"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("MessageTypeID") + .HasColumnType("INTEGER"); + + b.Property("NonMemberMessage") + .HasColumnType("TEXT"); + + b.Property("ParentMessageId") + .HasColumnType("INTEGER"); + + b.Property("QueueID") + .HasColumnType("INTEGER"); + + b.Property("ToVikingId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ParentMessageId"); + + b.HasIndex("ToVikingId"); + + b.HasIndex("VikingId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("MissionStatus") + .HasColumnType("INTEGER"); + + b.Property("UserAccepted") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("MissionStates"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Slot0") + .HasColumnType("TEXT"); + + b.Property("Slot1") + .HasColumnType("TEXT"); + + b.Property("Slot2") + .HasColumnType("TEXT"); + + b.Property("Slot3") + .HasColumnType("TEXT"); + + b.Property("Slot4") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId") + .IsUnique(); + + b.ToTable("Neighborhoods"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MasterId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MasterId"); + + b.ToTable("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DragonId") + .HasColumnType("INTEGER"); + + b.Property("PairId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DragonId"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AssetBundle") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExpirationDate") + .HasColumnType("TEXT"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LocationIconAsset") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PrivateParty") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Parties"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnswerID") + .HasColumnType("INTEGER"); + + b.Property("QuestionID") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("ProfileAnswers"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("RankId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RankId"); + + b.HasIndex("VikingId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryID") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("RatedEntityID") + .HasColumnType("INTEGER"); + + b.Property("RatedUserID") + .HasColumnType("TEXT"); + + b.Property("RatingAverage") + .HasColumnType("REAL"); + + b.Property("UpdateDate") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RatingRanks"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RoomId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RoomId") + .HasColumnType("INTEGER"); + + b.Property("RoomItemData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("RoomItems"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("SaveId") + .HasColumnType("INTEGER"); + + b.Property("SerializedData") + .HasColumnType("TEXT"); + + b.HasKey("VikingId", "SaveId"); + + b.ToTable("SavedData"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SceneName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("XmlData") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("SceneData"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.Property("ApiToken") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("ApiToken"); + + b.HasIndex("UserId"); + + b.HasIndex("VikingId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("INTEGER"); + + b.Property("Payload") + .HasColumnType("TEXT"); + + b.HasKey("Id", "VikingId", "MissionId"); + + b.HasIndex("VikingId"); + + b.ToTable("TaskStatuses"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BadgeId") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("UserBadgesCompleted"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("UserBanType") + .HasColumnType("INTEGER"); + + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("VikingId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.Property("VikingId") + .HasColumnType("INTEGER"); + + b.Property("WorldId") + .HasColumnType("INTEGER"); + + b.Property("MissionId") + .HasColumnType("INTEGER"); + + b.Property("IsCompleted") + .HasColumnType("INTEGER"); + + b.Property("StepId") + .HasColumnType("INTEGER"); + + b.Property("TaskId") + .HasColumnType("INTEGER"); + + b.HasKey("VikingId", "WorldId", "MissionId"); + + b.ToTable("UserMissionData"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AvatarSerialized") + .HasColumnType("TEXT"); + + b.Property("BirthDate") + .HasColumnType("TEXT"); + + b.Property("BuddyCode") + .HasColumnType("TEXT"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("GameVersion") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Online") + .HasColumnType("INTEGER"); + + b.Property("SelectedDragonId") + .HasColumnType("INTEGER"); + + b.Property("Uid") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SelectedDragonId") + .IsUnique(); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Vikings"); + }); + + modelBuilder.Entity("GroupViking", b => + { + b.HasOne("sodoff.Model.Group", null) + .WithMany() + .HasForeignKey("GroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", null) + .WithMany() + .HasForeignKey("VikingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("sodoff.Model.AchievementPoints", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementPoints") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.AchievementTaskState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("AchievementTaskStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Buddy", b => + { + b.HasOne("sodoff.Model.Viking", "BuddyViking") + .WithMany("BuddyList") + .HasForeignKey("BuddyVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("BuddiesMade") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BuddyViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Dragons") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("GameData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.GameDataPair", b => + { + b.HasOne("sodoff.Model.GameData", "GameData") + .WithMany("GameDataPairs") + .HasForeignKey("GameDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameData"); + }); + + modelBuilder.Entity("sodoff.Model.Image", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Images") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.InventoryItem", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("InventoryItems") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MMORole", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MMORoles") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.HasOne("sodoff.Model.Message", "ParentMessage") + .WithMany("Replies") + .HasForeignKey("ParentMessageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "ToViking") + .WithMany("MessageBoard") + .HasForeignKey("ToVikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MessagesMade") + .HasForeignKey("VikingId"); + + b.Navigation("ParentMessage"); + + b.Navigation("ToViking"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.MissionState", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("MissionStates") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Neighborhood", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithOne("Neighborhood") + .HasForeignKey("sodoff.Model.Neighborhood", "VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Pair", b => + { + b.HasOne("sodoff.Model.PairData", "PairData") + .WithMany("Pairs") + .HasForeignKey("MasterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.HasOne("sodoff.Model.Dragon", "Dragon") + .WithMany("PairData") + .HasForeignKey("DragonId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("PairData") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("PairData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Dragon"); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Party", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Parties") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.ProfileAnswer", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("ProfileAnswers") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Rating", b => + { + b.HasOne("sodoff.Model.RatingRank", "Rank") + .WithMany("Ratings") + .HasForeignKey("RankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Ratings") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Rank"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Rooms") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.RoomItem", b => + { + b.HasOne("sodoff.Model.Room", "Room") + .WithMany("Items") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("sodoff.Model.SavedData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SavedData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.SceneData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("SceneData") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Session", b => + { + b.HasOne("sodoff.Model.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("Sessions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.TaskStatus", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("TaskStatuses") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBadgeCompleteData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBadgesCompleted") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserBan", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserBans") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.UserMissionData", b => + { + b.HasOne("sodoff.Model.Viking", "Viking") + .WithMany("UserMissions") + .HasForeignKey("VikingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Viking"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.HasOne("sodoff.Model.Dragon", "SelectedDragon") + .WithOne() + .HasForeignKey("sodoff.Model.Viking", "SelectedDragonId"); + + b.HasOne("sodoff.Model.User", "User") + .WithMany("Vikings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SelectedDragon"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("sodoff.Model.Dragon", b => + { + b.Navigation("PairData"); + }); + + modelBuilder.Entity("sodoff.Model.GameData", b => + { + b.Navigation("GameDataPairs"); + }); + + modelBuilder.Entity("sodoff.Model.Message", b => + { + b.Navigation("Replies"); + }); + + modelBuilder.Entity("sodoff.Model.PairData", b => + { + b.Navigation("Pairs"); + }); + + modelBuilder.Entity("sodoff.Model.RatingRank", b => + { + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("sodoff.Model.Room", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("sodoff.Model.User", b => + { + b.Navigation("PairData"); + + b.Navigation("Sessions"); + + b.Navigation("Vikings"); + }); + + modelBuilder.Entity("sodoff.Model.Viking", b => + { + b.Navigation("AchievementPoints"); + + b.Navigation("AchievementTaskStates"); + + b.Navigation("BuddiesMade"); + + b.Navigation("BuddyList"); + + b.Navigation("Dragons"); + + b.Navigation("GameData"); + + b.Navigation("Images"); + + b.Navigation("InventoryItems"); + + b.Navigation("MMORoles"); + + b.Navigation("MessageBoard"); + + b.Navigation("MessagesMade"); + + b.Navigation("MissionStates"); + + b.Navigation("Neighborhood"); + + b.Navigation("PairData"); + + b.Navigation("Parties"); + + b.Navigation("ProfileAnswers"); + + b.Navigation("Ratings"); + + b.Navigation("Rooms"); + + b.Navigation("SavedData"); + + b.Navigation("SceneData"); + + b.Navigation("Sessions"); + + b.Navigation("TaskStatuses"); + + b.Navigation("UserBadgesCompleted"); + + b.Navigation("UserBans"); + + b.Navigation("UserMissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Migrations/20250308013623_Viking_Online.cs b/src/Migrations/20250308013623_Viking_Online.cs new file mode 100644 index 0000000..d34779c --- /dev/null +++ b/src/Migrations/20250308013623_Viking_Online.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace sodoff.Migrations +{ + /// + public partial class Viking_Online : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Online", + table: "Vikings", + type: "INTEGER", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Online", + table: "Vikings"); + } + } +} diff --git a/src/Migrations/DBContextModelSnapshot.cs b/src/Migrations/DBContextModelSnapshot.cs index 7aada7e..ce20490 100644 --- a/src/Migrations/DBContextModelSnapshot.cs +++ b/src/Migrations/DBContextModelSnapshot.cs @@ -833,6 +833,9 @@ namespace sodoff.Migrations .IsRequired() .HasColumnType("TEXT"); + b.Property("Online") + .HasColumnType("INTEGER"); + b.Property("SelectedDragonId") .HasColumnType("INTEGER"); diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index ca6affa..50418d1 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -23,6 +23,8 @@ public class Viking { public int? SelectedDragonId { get; set; } + public bool? Online { get; set; } + public virtual ICollection Sessions { get; set; } = null!; public virtual User User { get; set; } = null!; public virtual ICollection Dragons { get; set; } = null!; diff --git a/src/Services/BuddyService.cs b/src/Services/BuddyService.cs index 57a783d..6e68e0e 100644 --- a/src/Services/BuddyService.cs +++ b/src/Services/BuddyService.cs @@ -158,7 +158,7 @@ public class BuddyService DisplayName = XmlUtil.DeserializeXml(buddy.BuddyViking.AvatarSerialized).DisplayName, Status = buddy.BuddyStatus2, CreateDate = buddy.CreatedAt, - Online = true, // hardcoded until mmo reports precense + Online = buddy.BuddyViking.Online ?? false, OnMobile = false, BestBuddy = buddy.IsBestFriend2 }); @@ -169,7 +169,7 @@ public class BuddyService DisplayName = XmlUtil.DeserializeXml(buddy.Viking.AvatarSerialized).DisplayName, Status = buddy.BuddyStatus1, CreateDate = buddy.CreatedAt, - Online = true, // hardcoded until mmo reports precense + Online = buddy.Viking.Online ?? false, OnMobile = false, BestBuddy = buddy.IsBestFriend1 }); From e0c1d2cab2f31a49c86d21ebbdc13e72543bd102 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Fri, 7 Mar 2025 18:13:17 -0800 Subject: [PATCH 18/18] precense fixes --- src/Controllers/Common/PrecenseController.cs | 15 ++++++++++----- src/Controllers/Common/ProfileController.cs | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Controllers/Common/PrecenseController.cs b/src/Controllers/Common/PrecenseController.cs index e0e16fd..d522dea 100644 --- a/src/Controllers/Common/PrecenseController.cs +++ b/src/Controllers/Common/PrecenseController.cs @@ -14,12 +14,17 @@ namespace sodoff.Controllers.Common [HttpPost] [Produces("application/json")] [Route("Precense/SetVikingOnline")] - [VikingSession] - public IActionResult SetVikingOnline(Viking viking, [FromForm] bool online) + public IActionResult SetVikingOnline([FromForm] Guid token, [FromForm] bool online) { - viking.Online = online; - ctx.SaveChanges(); - return Ok(viking.Online); + // get viking from session + Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == token)?.Viking; + + if (viking != null) + { + viking.Online = online; + ctx.SaveChanges(); + return Ok(viking.Online); + } else return Ok(false); } } } diff --git a/src/Controllers/Common/ProfileController.cs b/src/Controllers/Common/ProfileController.cs index 7802ba7..44f8652 100644 --- a/src/Controllers/Common/ProfileController.cs +++ b/src/Controllers/Common/ProfileController.cs @@ -177,7 +177,7 @@ public class ProfileController : Controller { GameCurrency = currency.GameCurrency, CashCurrency = currency.CashCurrency, ActivityCount = 0, - BuddyCount = viking.BuddiesMade.Count, + BuddyCount = viking.BuddyList.Count + viking.BuddiesMade.Count, // relations are hard UserGradeData = new UserGrade { UserGradeID = 0 }, UserProfileTag = new UserProfileTag() { CreateDate = new DateTime(DateTime.Now.Ticks),