support for items and inventories

This commit is contained in:
Spirtix 2023-06-22 13:59:14 +02:00
parent 2fa769fda8
commit 94da3ff337
12 changed files with 648048 additions and 38 deletions

View File

@ -21,6 +21,8 @@ methods = [
'GetUserProfile',
'GetQuestions',
'GetCommonInventory',
'SetCommonInventory',
'GetItem',
'GetAuthoritativeTime',
'SetAvatar',
'GetPetAchievementsByUserID',

View File

@ -12,9 +12,11 @@ public class ContentController : Controller {
private readonly DBContext ctx;
private KeyValueService keyValueService;
public ContentController(DBContext ctx, KeyValueService keyValueService) {
private ItemService itemService;
public ContentController(DBContext ctx, KeyValueService keyValueService, ItemService itemService) {
this.ctx = ctx;
this.keyValueService = keyValueService;
this.itemService = itemService;
}
[HttpPost]
@ -118,7 +120,6 @@ public class ContentController : Controller {
[HttpPost]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/GetCommonInventory")]
[Route("ContentWebService.asmx/GetCommonInventory")]
public IActionResult GetCommonInventory([FromForm] string apiToken) {
// TODO, this is a placeholder
@ -129,44 +130,72 @@ public class ContentController : Controller {
}
return Ok(new CommonInventoryData {
UserID = Guid.Parse(user is not null ? user.Id : viking.Id),
Item = new UserItemData[] {
new UserItemData {
UserInventoryID = 1099730701,
ItemID = 8977,
Quantity = 1,
Uses = -1,
ModifiedDate = DateTime.Now,
Item = new ItemData {
AssetName = "DragonStableINTDO",
Cost = 100000,
CashCost = -1,
CreativePoints = 0,
Description = "Any dragon would be glad to make one of the two available nests home!",
IconName = "RS_DATA/DragonsStablesDO.unity3d/IcoDWDragonStableDefault",
InventoryMax = 1,
ItemID = 8977,
ItemName = "Dragon Stable",
Locked = false,
Stackable = false,
AllowStacking = false,
SaleFactor = 10,
Uses = -1,
Attribute = new ItemAttribute[] {
new ItemAttribute { Key = "2D", Value = "1" },
new ItemAttribute { Key = "NestCount", Value = "2" },
new ItemAttribute { Key = "StableType", Value = "All" }
},
Category = new ItemDataCategory[] {
new ItemDataCategory { CategoryId = 455, CategoryName = "Dragons Dragon Stable", IconName = "8977"}
}
}
}
}
UserID = Guid.Parse(user is not null ? user.Id : viking.Id)
});
}
[HttpPost]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/GetCommonInventory")]
public IActionResult GetCommonInventoryV2([FromForm] string apiToken) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null || viking.Inventory is null) return Ok();
List<InventoryItem> items = viking.Inventory.InventoryItems.ToList();
List<UserItemData> userItemData = new();
foreach (InventoryItem item in items) {
ItemData itemData = itemService.GetItem(item.ItemId);
UserItemData uid = new UserItemData {
UserInventoryID = viking.Inventory.Id,
ItemID = itemData.ItemID,
Quantity = item.Quantity,
Uses = itemData.Uses,
ModifiedDate = DateTime.Now,
Item = itemData
};
userItemData.Add(uid);
}
CommonInventoryData invData = new CommonInventoryData {
UserID = Guid.Parse(viking.UserId),
Item = userItemData.ToArray()
};
return Ok(invData);
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/SetCommonInventory")]
public IActionResult SetCommonInventory([FromForm] string apiToken, [FromForm] string commonInventoryRequestXml) {
CommonInventoryRequest[] request = XmlUtil.DeserializeXml<CommonInventoryRequest[]>(commonInventoryRequestXml);
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null || viking.Inventory is null) return Ok();
// Set inventory items
List<CommonInventoryResponseItem> responseItems = new();
foreach (var req in request) {
InventoryItem? item = viking.Inventory.InventoryItems.FirstOrDefault(e => e.ItemId == req.ItemID);
if (item is null) item = new InventoryItem { ItemId = (int)req.ItemID, Quantity = 0 };
int origQuantity = item.Quantity;
item.Quantity = request[0].Quantity;
responseItems.Add(new CommonInventoryResponseItem {
CommonInventoryID = viking.InventoryId,
ItemID = item.ItemId,
Quantity = origQuantity
});
viking.Inventory.InventoryItems.Add(item);
}
CommonInventoryResponse response = new CommonInventoryResponse {
Success = true,
CommonInventoryIDs = responseItems.ToArray()
};
ctx.SaveChanges();
return Ok(response);
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/GetAuthoritativeTime")]
@ -174,6 +203,13 @@ public class ContentController : Controller {
return Ok(new DateTime(DateTime.Now.Ticks));
}
[HttpPost]
[Produces("application/xml")]
[Route("ItemStoreWebService.asmx/GetItem")] // NOTE: Should be in a separate controler, but it's inventory related, so I'll leave it here for now
public IActionResult GetItem([FromForm] int itemId) {
return Ok(itemService.GetItem(itemId));
}
[HttpPost]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/SetAvatar")]

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using sodoff.Attributes;
using sodoff.Model;
using sodoff.Schema;
using sodoff.Services;
using sodoff.Util;
namespace sodoff.Controllers.Common;
@ -10,9 +11,11 @@ namespace sodoff.Controllers.Common;
public class RegistrationController : Controller {
private readonly DBContext ctx;
private ItemService itemService;
public RegistrationController(DBContext ctx) {
public RegistrationController(DBContext ctx, ItemService itemService) {
this.ctx = ctx;
this.itemService = itemService;
}
[HttpPost]
@ -79,10 +82,13 @@ public class RegistrationController : Controller {
return Ok(new RegistrationResult { Status = MembershipUserStatus.DuplicateUserName });
}
Inventory inv = new Inventory { InventoryItems = new List<InventoryItem>() };
inv.InventoryItems.Add(new InventoryItem { ItemId = 8977, Quantity = 1 }); // DragonStableINTDO - Dragons Dragon Stable
Viking v = new Viking {
Id = Guid.NewGuid().ToString(),
Name = data.ChildName,
User = user,
Inventory = inv
};
ctx.Vikings.Add(v);
ctx.SaveChanges();

View File

@ -10,6 +10,9 @@ public class DBContext : DbContext {
public DbSet<Pair> Pairs { get; set; } = null!;
public DbSet<PairData> PairData { get; set; } = null!;
public DbSet<TaskStatus> TaskStatuses { get; set; } = null!;
public DbSet<Inventory> Inventories { get; set; } = null!;
public DbSet<InventoryItem> InventoryItems { get; set; } = null!;
public string DbPath { get; }
public DBContext() {
@ -38,6 +41,10 @@ public class DBContext : DbContext {
.WithMany(e => e.Vikings)
.HasForeignKey(e => e.UserId);
builder.Entity<Viking>().HasOne(v => v.Inventory)
.WithOne(e => e.Viking)
.HasForeignKey<Viking>(e => e.InventoryId);
builder.Entity<User>().HasMany(u => u.Vikings)
.WithOne(e => e.User);
@ -63,6 +70,9 @@ public class DBContext : DbContext {
builder.Entity<Viking>().HasMany(u => u.Images)
.WithOne(e => e.Viking);
builder.Entity<Viking>().HasOne(v => v.Inventory)
.WithOne(e => e.Viking);
builder.Entity<PairData>()
.HasKey(e => e.Id);
@ -80,5 +90,22 @@ public class DBContext : DbContext {
builder.Entity<TaskStatus>()
.HasOne(t => t.Viking)
.WithMany();
builder.Entity<Inventory>().HasKey(e => e.Id);
builder.Entity<Inventory>()
.HasOne(i => i.Viking)
.WithOne(e => e.Inventory)
.HasForeignKey<Inventory>(e => e.VikingId);
builder.Entity<Inventory>()
.HasMany(i => i.InventoryItems)
.WithOne(e => e.Inventory);
builder.Entity<InventoryItem>()
.HasOne(e => e.Inventory)
.WithMany(e => e.InventoryItems)
.HasForeignKey(e => e.InventoryId);
}
}

13
src/Model/Inventory.cs Normal file
View File

@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace sodoff.Model;
public class Inventory {
[Key]
public int Id { get; set; }
public string VikingId { get; set; }
public virtual Viking? Viking { get; set; }
public virtual ICollection<InventoryItem> InventoryItems { get; set; } = null!;
}

View File

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
namespace sodoff.Model {
public class InventoryItem {
[Key]
public int Id { get; set; }
public int ItemId { get; set; }
public int InventoryId { get; set; }
public virtual Inventory Inventory { get; set; }
public int Quantity;
}
}

View File

@ -20,4 +20,8 @@ public class Viking {
public virtual ICollection<Dragon> Dragons { get; set; } = null!;
public virtual ICollection<Image> Images { get; set; } = null!;
public virtual Dragon? SelectedDragon { get; set; }
public int InventoryId { get; set; }
public virtual Inventory Inventory { get; set; } = null!;
}

View File

@ -13,6 +13,7 @@ builder.Services.AddControllers(options => {
});
builder.Services.AddDbContext<DBContext>();
builder.Services.AddScoped<KeyValueService>();
builder.Services.AddSingleton<ItemService>();
var app = builder.Build();

647863
src/Resources/items.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
using System.Xml.Serialization;
namespace sodoff.Schema {
// NOTE: This schema is NOT used by the client
// This is a schema specific to the sodoff server
[XmlRoot(ElementName = "Items", Namespace = "")]
public class ServerItemArray {
[XmlElement(ElementName = "I", IsNullable = true)]
public ItemData[] ItemDataArray;
}
}

View File

@ -0,0 +1,23 @@
using sodoff.Schema;
using sodoff.Util;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
namespace sodoff.Services {
public class ItemService {
Dictionary<int, ItemData> items = new();
public ItemService() {
ServerItemArray itemArray = XmlUtil.DeserializeXml<ServerItemArray>(XmlUtil.ReadResourceXmlString("items"));
foreach (var item in itemArray.ItemDataArray) {
items.Add(item.ItemID, item);
}
}
public ItemData GetItem(int id) {
return items[id];
}
}
}

View File

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<None Remove="Resources\items.xml" />
<None Remove="Resources\store.xml" />
<None Remove="Resources\allranks.xml" />
<None Remove="Resources\tutorialmission.xml" />
@ -22,6 +23,9 @@
</None>
<None Update="Resources\store.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\items.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\tutorialmission.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@ -33,6 +37,9 @@
</EmbeddedResource>
<EmbeddedResource Include="Resources\allranks.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\items.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\tutorialmission.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>