YoshiCraft64 cecaa50610
support for old ("steps") missions (#20)
* add support for old missions API (aka "steps missions")
* config option to disable loading non SoD Data (used only for missions and achievements for now)
* make AuthenticateUser endpoint compatible with games that use e-mail as login
* add api keys for lands
* add GetGameCurrency endpoint
* allow create empty stores and add store "8" (empty)

---------

Co-authored-by: Robert Paciorek <robert@opcode.eu.org>
2025-02-13 22:58:19 +01:00

87 lines
3.7 KiB
C#

using sodoff.Schema;
using sodoff.Util;
namespace sodoff.Services;
public class StoreService {
Dictionary<int, ItemsInStoreData> stores = new();
public StoreService(ItemService itemService, ModdingService moddingService) {
StoreData[] storeArray = XmlUtil.DeserializeXml<StoreData[]>(XmlUtil.ReadResourceXmlString("store"));
foreach (var s in storeArray) {
ItemsInStoreData newStore = new() {
ID = s.Id % 1000, // % 1000 for support store variants (for example 30123 and 123 is the same store but for different games / versions)
StoreName = s.StoreName,
Description = s.Description,
SalesAtStore = s.SalesAtStore,
PopularItems = s.PopularItems
};
List<ItemData> itemsList = new();
IEnumerable<ItemsInStoreDataSale>? memberSales = s.SalesAtStore?.Where(x => x.ForMembers == true);
IEnumerable<ItemsInStoreDataSale>? normalSales = s.SalesAtStore?.Where(x => x.ForMembers == false || x.ForMembers == null);
if (s.ItemId != null) {
for (int i = 0; i < s.ItemId.Length; ++i) {
ItemData item = itemService.GetItem(s.ItemId[i]);
if (item is null) continue; // skip removed items
itemsList.Add(item);
UpdateItemSaleModifier(item, memberSales, normalSales);
}
}
foreach (int itemID in moddingService.GetStoreItem(s.Id)) {
ItemData item = itemService.GetItem(itemID);
itemsList.Add(item);
UpdateItemSaleModifier(item, memberSales, normalSales);
}
newStore.Items = itemsList.ToArray();
stores.Add(s.Id, newStore);
}
}
public ItemsInStoreData GetStore(int id) {
return stores[id];
}
public ItemsInStoreData GetStore(int id, uint gameVersion) {
if (gameVersion < ClientVersion.WoJS_NewAvatar) {
if (stores.ContainsKey(id+30000))
return stores[id+30000];
}
return stores[id];
}
private bool IsSaleOutdated(ItemsInStoreDataSale sale) {
if (sale.EndDate == null)
return false;
return sale.EndDate < DateTime.Now;
}
private void UpdateItemSaleModifier(ItemData item, IEnumerable<ItemsInStoreDataSale>? memberSales, IEnumerable<ItemsInStoreDataSale>? normalSales) {
if (memberSales != null) {
foreach (var memberSale in memberSales) {
if (IsSaleOutdated(memberSale)) continue;
if (item.Category != null && memberSale.CategoryIDs != null && item.Category.Any(x => memberSale.CategoryIDs.Contains(x.CategoryId))) {
item.MemberDiscountModifier = memberSale.Modifier;
break;
}
if (memberSale.ItemIDs != null && memberSale.ItemIDs.Contains(item.ItemID)) {
item.MemberDiscountModifier = memberSale.Modifier;
break;
}
}
}
if (normalSales != null) {
foreach (var normalSale in normalSales) {
if (IsSaleOutdated(normalSale)) continue;
if (item.Category != null && normalSale.CategoryIDs != null && item.Category.Any(x => normalSale.CategoryIDs.Contains(x.CategoryId))) {
item.NormalDiscoutModifier = normalSale.Modifier;
break;
}
if (normalSale.ItemIDs != null && normalSale.ItemIDs.Contains(item.ItemID)) {
item.NormalDiscoutModifier = normalSale.Modifier;
break;
}
}
}
}
}