forked from SoDOff-Project/sodoff
support for mods - items add/overwrite interface
This commit is contained in:
parent
18f7e89509
commit
7888445eee
@ -19,6 +19,7 @@ builder.Services.AddControllers(options => {
|
||||
});
|
||||
builder.Services.AddDbContext<DBContext>();
|
||||
|
||||
builder.Services.AddSingleton<ModdingService>();
|
||||
builder.Services.AddSingleton<MissionStoreSingleton>();
|
||||
builder.Services.AddSingleton<AchievementStoreSingleton>();
|
||||
builder.Services.AddSingleton<ItemService>();
|
||||
@ -44,6 +45,10 @@ using var scope = app.Services.CreateScope();
|
||||
|
||||
scope.ServiceProvider.GetRequiredService<DBContext>().Database.EnsureCreated();
|
||||
|
||||
// create Modding Service singleton ... do this before start http server to avoid serve invalid assets list
|
||||
|
||||
new ModdingService();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
||||
if (assetServer)
|
||||
|
17
src/Schema/ModAction.cs
Normal file
17
src/Schema/ModAction.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
public enum ModAction {
|
||||
[XmlEnum("defualt")]
|
||||
Default = 0,
|
||||
|
||||
[XmlEnum("add")]
|
||||
Add = 1,
|
||||
|
||||
[XmlEnum("replace")]
|
||||
Replace = 2,
|
||||
|
||||
[XmlEnum("remove")]
|
||||
Remove = 3,
|
||||
}
|
17
src/Schema/ModItem.cs
Normal file
17
src/Schema/ModItem.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
public class ModItem {
|
||||
[XmlAttribute("action")]
|
||||
public ModAction action { get; set; } = ModAction.Default;
|
||||
|
||||
[XmlElement(ElementName = "id")]
|
||||
public int? ItemID;
|
||||
|
||||
[XmlElement(ElementName = "storeID")]
|
||||
public int[] stores;
|
||||
|
||||
[XmlElement(ElementName = "data")]
|
||||
public ItemData data;
|
||||
}
|
9
src/Schema/ModManifest.cs
Normal file
9
src/Schema/ModManifest.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
[XmlRoot(ElementName = "sodoffmod", Namespace = "")]
|
||||
public class ModManifest {
|
||||
[XmlArrayItem(ElementName = "item")]
|
||||
public ModItem [] items { get; set; }
|
||||
}
|
@ -120,6 +120,7 @@ namespace sodoff.Services {
|
||||
foreach (InventoryItem item in items) {
|
||||
if (item.Quantity == 0) continue; // Don't include an item that the viking doesn't have
|
||||
ItemData itemData = itemService.GetItem(item.ItemId);
|
||||
if (itemData is null) continue; // Don't include items removed from item database
|
||||
UserItemData uid = new UserItemData {
|
||||
UserInventoryID = item.Id,
|
||||
ItemID = itemData.ItemID,
|
||||
|
@ -11,17 +11,23 @@ namespace sodoff.Services {
|
||||
int[] itemsRewardForDT;
|
||||
Random random = new Random();
|
||||
|
||||
public ItemService() {
|
||||
public ItemService(ModdingService moddingService) {
|
||||
ServerItemArray itemArray = XmlUtil.DeserializeXml<ServerItemArray>(XmlUtil.ReadResourceXmlString("items"));
|
||||
foreach (var item in itemArray.ItemDataArray) {
|
||||
items.Add(item.ItemID, item);
|
||||
}
|
||||
|
||||
itemsRewardForDT = XmlUtil.DeserializeXml<int[]>(XmlUtil.ReadResourceXmlString("dtrewards"));
|
||||
|
||||
moddingService.UpdateItems(ref items);
|
||||
}
|
||||
|
||||
public ItemData GetItem(int id) {
|
||||
try {
|
||||
return items[id];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemData GetDTReward(Gender gender) {
|
||||
|
94
src/Services/ModdingService.cs
Normal file
94
src/Services/ModdingService.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using sodoff.Schema;
|
||||
using sodoff.Util;
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Services;
|
||||
|
||||
public class ModdingService {
|
||||
|
||||
private Dictionary<int, ModItem> itemsToUpdate = new();
|
||||
private Dictionary<int, List<int>> itemsInStore = new();
|
||||
|
||||
public ModdingService() {
|
||||
if (!Directory.Exists("mods/"))
|
||||
return;
|
||||
foreach (var dir in Directory.GetDirectories("mods/")) {
|
||||
string manifestFile = dir + "/manifest.xml";
|
||||
if (File.Exists(manifestFile)) {
|
||||
Console.WriteLine($"Load mod manifest from {manifestFile}");
|
||||
ModManifest modManifest = XmlUtil.DeserializeXml<ModManifest>(System.IO.File.ReadAllText(manifestFile));
|
||||
|
||||
if (modManifest.items != null) {
|
||||
foreach (ModItem item in modManifest.items) {
|
||||
// get item id from mod-level info
|
||||
int? itemID = item.ItemID;
|
||||
|
||||
// process item data itemID value
|
||||
if (itemID is null)
|
||||
itemID = item.data?.ItemID;
|
||||
else if (item.data != null)
|
||||
item.data.ItemID = (int)itemID;
|
||||
|
||||
// check for unset itemID
|
||||
if (itemID is null) {
|
||||
Console.WriteLine("Missing item id.");
|
||||
System.Environment.Exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
itemsToUpdate.Add((int)itemID, item);
|
||||
if (item.stores != null && (item.action == ModAction.Add || item.action == ModAction.Default)) {
|
||||
foreach (int storeID in item.stores) {
|
||||
try {
|
||||
itemsInStore[storeID].Add((int)itemID);
|
||||
} catch (System.Collections.Generic.KeyNotFoundException) {
|
||||
itemsInStore.Add(storeID, new List<int> {(int)itemID});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (System.ArgumentException) {
|
||||
Console.WriteLine($"Conflict for ItemID = {itemID} with previous modification.");
|
||||
System.Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Console.WriteLine($"Skip mod directory {dir} (missing manifest file)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateItems(ref Dictionary<int, ItemData> items) {
|
||||
foreach (var item in itemsToUpdate) {
|
||||
if (item.Value.action == ModAction.Remove) {
|
||||
try {
|
||||
items.Remove(item.Key);
|
||||
} catch {
|
||||
Console.WriteLine($"Can't remove item with ID = {item.Key} - not found");
|
||||
}
|
||||
} else if (item.Value.action == ModAction.Replace) {
|
||||
try {
|
||||
items[item.Key] = item.Value.data;
|
||||
} catch {
|
||||
Console.WriteLine($"Can't replace item with ID = {item.Key} - not found");
|
||||
}
|
||||
} else /*if (item.Value.action == ModAction.Add || item.Value.action == ModAction.Default)*/ {
|
||||
try {
|
||||
items.Add(item.Key, item.Value.data);
|
||||
} catch {
|
||||
Console.WriteLine($"Item with ID = {item.Key} is already defined in base item set.");
|
||||
System.Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsToUpdate.Clear();
|
||||
}
|
||||
public List<int> GetStoreItem(int storeID) {
|
||||
if (itemsInStore.ContainsKey(storeID)) {
|
||||
return itemsInStore[storeID];
|
||||
} else {
|
||||
return new List<int>();
|
||||
}
|
||||
}
|
||||
}
|
@ -6,23 +6,31 @@ namespace sodoff.Services;
|
||||
public class StoreService {
|
||||
Dictionary<int, ItemsInStoreData> stores = new();
|
||||
|
||||
public StoreService(ItemService itemService) {
|
||||
public StoreService(ItemService itemService, ModdingService moddingService) {
|
||||
StoreData[] storeArray = XmlUtil.DeserializeXml<StoreData[]>(XmlUtil.ReadResourceXmlString("store"));
|
||||
foreach (var s in storeArray) {
|
||||
var newStore = new ItemsInStoreData {
|
||||
ItemsInStoreData newStore = new() {
|
||||
ID = s.Id,
|
||||
StoreName = s.StoreName,
|
||||
Description = s.Description,
|
||||
Items = new ItemData[s.ItemId.Length],
|
||||
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);
|
||||
for (int i = 0; i < s.ItemId.Length; ++i) {
|
||||
newStore.Items[i] = itemService.GetItem(s.ItemId[i]);
|
||||
UpdateItemSaleModifier(newStore.Items[i], memberSales, normalSales);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user