diff --git a/OshimaModules/Items/GiftBox/礼包.cs b/OshimaModules/Items/GiftBox/礼包.cs index ad34254..911d71e 100644 --- a/OshimaModules/Items/GiftBox/礼包.cs +++ b/OshimaModules/Items/GiftBox/礼包.cs @@ -196,6 +196,27 @@ namespace Oshima.FunGame.OshimaModules.Items } } + public class 探索助力礼包 : Item, 礼包.GiftBox + { + public override long Id => (long)GiftBoxID.探索助力礼包; + public override string Name => "探索助力礼包"; + public override string Description => Skills.Active?.Description ?? ""; + public override QualityType QualityType => QualityType.Red; + public Dictionary Gifts { get; set; } = []; + + public 探索助力礼包(User? user = null, int remainUseTimes = 1) : base(ItemType.GiftBox) + { + User = user; + 礼包.Init(this, new() + { + { General.GameplayEquilibriumConstant.InGameCurrency, 20000 }, + { General.GameplayEquilibriumConstant.InGameMaterial, 50 }, + { new 升华之印().Name, 20 }, + { new 技能卷轴().Name, 20 }, + }, remainUseTimes); + } + } + public class 礼包技能 : Skill { public override long Id => (long)ItemActiveID.礼包; diff --git a/OshimaModules/Items/ItemID.cs b/OshimaModules/Items/ItemID.cs index 57351c3..b0ab311 100644 --- a/OshimaModules/Items/ItemID.cs +++ b/OshimaModules/Items/ItemID.cs @@ -55,6 +55,7 @@ 蛇年大吉 = 20002, 新春快乐 = 20003, 毕业礼包 = 20004, - 魔法卡礼包 = 20005 + 魔法卡礼包 = 20005, + 探索助力礼包 = 20006 } } diff --git a/OshimaModules/Modules/ItemModule.cs b/OshimaModules/Modules/ItemModule.cs index bbdee5b..9feff30 100644 --- a/OshimaModules/Modules/ItemModule.cs +++ b/OshimaModules/Modules/ItemModule.cs @@ -74,6 +74,7 @@ namespace Oshima.FunGame.OshimaModules (long)GiftBoxID.新春快乐 => new 新春快乐(), (long)GiftBoxID.毕业礼包 => new 毕业礼包(), (long)GiftBoxID.魔法卡礼包 => new 魔法卡礼包(), + (long)GiftBoxID.探索助力礼包 => new 探索助力礼包(), _ => null, }; }; diff --git a/OshimaModules/Regions/OshimaRegion.cs b/OshimaModules/Regions/OshimaRegion.cs index b4a7912..dfdd6a4 100644 --- a/OshimaModules/Regions/OshimaRegion.cs +++ b/OshimaModules/Regions/OshimaRegion.cs @@ -22,9 +22,14 @@ namespace Oshima.FunGame.OshimaModules.Regions return other is OshimaRegion && other.GetIdName() == GetIdName(); } - public virtual string VisitStore(EntityModuleConfig stores, User user, string storeName) + public virtual Store? VisitStore(EntityModuleConfig stores, User user, string storeName) { - return ""; + return null; + } + + public virtual void SaveGlobalStore(Store store, string storeName) + { + } public override string ToString() diff --git a/OshimaModules/Regions/Players.cs b/OshimaModules/Regions/Players.cs index 4f370b1..8ba7313 100644 --- a/OshimaModules/Regions/Players.cs +++ b/OshimaModules/Regions/Players.cs @@ -1,7 +1,5 @@ using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; -using Oshima.FunGame.OshimaModules.Items; namespace Oshima.FunGame.OshimaModules.Regions { @@ -24,37 +22,82 @@ namespace Oshima.FunGame.OshimaModules.Regions ChangeRandomWeather(); } - public override string VisitStore(EntityModuleConfig stores, User user, string storeName) + public override Store? VisitStore(EntityModuleConfig stores, User user, string storeName) { + EntityModuleConfig storeTemplate = new("stores", "dokyo"); + storeTemplate.LoadConfig(); + Store? template = storeTemplate.Get(storeName); + + if (template is null) + { + return null; + } + + if (template.NextRefreshDate < DateTime.Now) + { + template.NextRefreshDate = DateTime.Today.AddHours(4); + template.UpdateRefreshTime(template.NextRefreshDate); + storeTemplate.Add(storeName, template); + storeTemplate.SaveConfig(); + } + + if (template.GlobalStock) + { + return template; + } + Store? store = stores.Get(storeName); if (store is null) { - EntityModuleConfig storeTemplate = new("stores", "dokyo"); - storeTemplate.LoadConfig(); - Store? template = storeTemplate.Get(storeName); - if (template != null) + template.NextRefreshGoods.Clear(); + stores.Add(storeName, template); + stores.SaveConfig(); + stores.LoadConfig(); + store = stores.Get(storeName); + } + else + { + if (template.GetNewerGoodsOnVisiting) { - if (template.NextRefreshDate < DateTime.Now) - { - template.NextRefreshDate = DateTime.Today.AddHours(4); - template.UpdateRefreshTime(template.NextRefreshDate); - storeTemplate.Add(storeName, template); - storeTemplate.SaveConfig(); - } + Dictionary goodsNameAndStock = store.Goods.Values.ToDictionary(g => g.Name, g => g.Stock); + Dictionary> usersBuyCount = store.Goods.Values.ToDictionary(g => g.Name, g => g.UsersBuyCount); + template.NextRefreshGoods.Clear(); stores.Add(storeName, template); stores.SaveConfig(); stores.LoadConfig(); store = stores.Get(storeName); + if (store != null) + { + foreach (Goods goods in store.Goods.Values) + { + if (goodsNameAndStock.TryGetValue(goods.Name, out int stock) && stock < goods.Stock) + { + goods.Stock = stock; + } + if (usersBuyCount.TryGetValue(goods.Name, out Dictionary? userBuyCount) && userBuyCount != null) + { + foreach (long uid in userBuyCount.Keys) + { + goods.UsersBuyCount[uid] = userBuyCount[uid]; + } + } + } + stores.Add(storeName, store); + stores.SaveConfig(); + } } } - if (store != null) - { - return store.ToString(); - } + return store; + } - return ""; + public override void SaveGlobalStore(Store store, string storeName) + { + EntityModuleConfig storeTemplate = new("stores", "dokyo"); + storeTemplate.LoadConfig(); + storeTemplate.Add(storeName, store); + storeTemplate.SaveConfig(); } } } diff --git a/OshimaServers/AnonymousServer.cs b/OshimaServers/AnonymousServer.cs index 55d1708..d1c29a9 100644 --- a/OshimaServers/AnonymousServer.cs +++ b/OshimaServers/AnonymousServer.cs @@ -218,30 +218,57 @@ namespace Oshima.FunGame.OshimaServers Task.Run(() => { // 刷新商店 - string directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/stores"; + string directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/storeNames"; if (Directory.Exists(directoryPath)) { string[] filePaths = Directory.GetFiles(directoryPath); foreach (string filePath in filePaths) { string fileName = Path.GetFileNameWithoutExtension(filePath); + EntityModuleConfig stores = new("storeNames", fileName); + stores.LoadConfig(); + string[] storeNames = [.. stores.Keys]; if (long.TryParse(fileName, out long userId) && FunGameConstant.UserIdAndUsername.TryGetValue(userId, out User? user) && user != null) { - EntityModuleConfig store = new("stores", fileName); - store.LoadConfig(); - store.Remove("daily"); - string[] stores = [.. store.Keys]; - foreach (string key in stores) + // 更新玩家商店数据,移除所有当天刷新的商店 + FunGameConstant.UserLastVisitStore.Remove(userId); + stores.Remove("daily"); + foreach (string key in storeNames) { - Store? s = store.Get(key); - if (s != null && s.AutoRefresh && s.NextRefreshDate.Date == DateTime.Today) + Store? store = stores.Get(key); + if (store != null && (store.GlobalStock || (store.AutoRefresh && store.NextRefreshDate.Date <= DateTime.Today))) { - store.Remove(key); + stores.Remove(key); } } - FunGameService.CheckDailyStore(store, user); - store.SaveConfig(); + FunGameService.CheckDailyStore(stores, user); } + else + { + // 非玩家商店数据,需要更新模板的商品 + foreach (string key in storeNames) + { + Store? store = stores.Get(key); + if (store != null) + { + if (store.ExpireTime != null && store.ExpireTime.Value.Date <= DateTime.Today) + { + stores.Remove(key); + continue; + } + if (store.AutoRefresh && store.NextRefreshDate.Date <= DateTime.Today) + { + store.Goods.Clear(); + foreach (long goodsId in store.NextRefreshGoods.Keys) + { + store.Goods[goodsId] = store.NextRefreshGoods[goodsId]; + } + store.NextRefreshDate = DateTime.Today.AddHours(4).AddDays(store.RefreshInterval); + } + } + } + } + stores.SaveConfig(); } Controller.WriteLine("刷新商店"); } diff --git a/OshimaServers/Service/FunGameConstant.cs b/OshimaServers/Service/FunGameConstant.cs index ea9c255..84084a7 100644 --- a/OshimaServers/Service/FunGameConstant.cs +++ b/OshimaServers/Service/FunGameConstant.cs @@ -427,6 +427,17 @@ namespace Oshima.FunGame.OshimaServers.Service { QualityType.Gold, (130000, 240000) } }; + public static Dictionary DecomposedMaterials { get; } = new() + { + { QualityType.Gold, 128 }, + { QualityType.Red, 6 }, + { QualityType.Orange, 32 }, + { QualityType.Purple, 16 }, + { QualityType.Blue, 8 }, + { QualityType.Green, 3 }, + { QualityType.White, 1 } + }; + public static string[] GreekAlphabet { get; } = ["α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "σ", "τ", "υ", "φ", "χ", "ψ", "ω"]; public static string[] CommonSurnames { get; } = [ diff --git a/OshimaServers/Service/FunGameOrderList.cs b/OshimaServers/Service/FunGameOrderList.cs index fa689dc..6102313 100644 --- a/OshimaServers/Service/FunGameOrderList.cs +++ b/OshimaServers/Service/FunGameOrderList.cs @@ -54,6 +54,7 @@ {"合成魔法卡 <{物品序号...}>", "3张魔法卡合成(空格隔开)"}, {"分解物品 <{物品序号...}>", "分解指定物品"}, {"分解 <物品名称> <数量>", "分解指定数量物品"}, + {"强制分解 <物品名称> <数量>", "分解指定数量物品"}, {"品质分解 <品质索引>", "按品质分解(0-6:普通/优秀/稀有/史诗/传说/神话/不朽)"}, }; @@ -130,6 +131,7 @@ {"商店1", "查看后勤部商品"}, {"商店2", "查看武器商会商品"}, {"商店3", "查看杂货铺商品"}, + {"商店4", "查看慈善基金会商品"}, {"商店查看 <商品序号>", "查看指定商品详情,访问任意商店后2分钟内可用"}, {"商店购买 <商品序号>", "购买指定商品,访问任意商店后2分钟内可用"}, {"商店出售 <物品序号>", "向商店出售具有回收价的指定物品"}, diff --git a/OshimaServers/Service/FunGameService.cs b/OshimaServers/Service/FunGameService.cs index 1e5d28c..4cc59ea 100644 --- a/OshimaServers/Service/FunGameService.cs +++ b/OshimaServers/Service/FunGameService.cs @@ -2118,6 +2118,12 @@ namespace Oshima.FunGame.OshimaServers.Service return msg = $"此商品【{goods.Name}】库存不足,无法购买!\r\n你想要购买 {count} 件,但库存只有 {goods.Stock} 件。"; } + goods.UsersBuyCount.TryGetValue(user.Id, out int buyCount); + if (goods.Quota > 0 && (buyCount + count > goods.Quota)) + { + return msg = $"此商品【{goods.Name}】限量购买 {goods.Quota} 件!\r\n你已经购买了 {buyCount} 件,想要购买 {count} 件,超过了购买限制。"; + } + foreach (string needy in goods.Prices.Keys) { if (needy == General.GameplayEquilibriumConstant.InGameCurrency) @@ -2176,7 +2182,12 @@ namespace Oshima.FunGame.OshimaServers.Service if (goods.Stock < 0) goods.Stock = 0; } - msg += $"恭喜你成功购买 {count} 件【{goods.Name}】!\r\n" + + if (!goods.UsersBuyCount.TryAdd(user.Id, count)) + { + goods.UsersBuyCount[user.Id] += count; + } + + msg += $"恭喜你成功购买 {count} 件【{goods.Name}】!\r\n" + (goods.Quota > 0 ? $"此商品限购 {goods.Quota} 件,你还可以再购买 {goods.Quota - count - buyCount} 件。\r\n" : "") + $"总计消费:{(goods.Prices.Count > 0 ? string.Join("、", goods.Prices.Select(kv => $"{kv.Value * count:0.##} {kv.Key}")) : "免单")}\r\n" + $"包含物品:{string.Join("、", goods.Items.Select(i => $"[{ItemSet.GetQualityTypeName(i.QualityType)}|{ItemSet.GetItemTypeName(i.ItemType)}] {i.Name} * {count}"))}\r\n" + $"{store.Name}期待你的下次光临。"; @@ -3397,7 +3408,7 @@ namespace Oshima.FunGame.OshimaServers.Service Item newItem = item; if (copyNew) newItem = item.Copy(copyLevel); newItem.User = user; - if (hasLock && newItem.QualityType >= QualityType.Orange) newItem.IsLock = true; + if (hasLock && (newItem.QualityType >= QualityType.Orange || FunGameConstant.CharacterLevelBreakItems.Any(c => c.Id == item.Id)) || FunGameConstant.SkillLevelUpItems.Any(c => c.Id == item.Id)) newItem.IsLock = true; if (hasSellAndTradeTime) SetSellAndTradeTime(newItem); if (hasPrice) { @@ -3947,6 +3958,27 @@ namespace Oshima.FunGame.OshimaServers.Service return builder.ToString().Trim(); } + public static Store? GetRegionStore(EntityModuleConfig stores, User user, string storeRegion, string storeName) + { + Store? store = null; + + Dictionary regionStores = FunGameConstant.PlayerRegions.ToDictionary(r => r.Name, r => r); + if (regionStores.TryGetValue(storeRegion, out OshimaRegion? value) && value != null) + { + store = value.VisitStore(stores, user, storeName); + } + + return store; + } + + public static void SaveRegionStore(Store store, string storeRegion, string storeName) + { + if (FunGameConstant.PlayerRegions.FirstOrDefault(r => r.Name == storeRegion) is OshimaRegion value) + { + value.SaveGlobalStore(store, storeName); + } + } + public static string CheckRegionStore(EntityModuleConfig stores, User user, string storeRegion, string storeName, out bool exist) { string msg = ""; @@ -3955,8 +3987,9 @@ namespace Oshima.FunGame.OshimaServers.Service Dictionary regionStores = FunGameConstant.PlayerRegions.ToDictionary(r => r.Name, r => r); if (regionStores.TryGetValue(storeRegion, out OshimaRegion? value) && value != null) { - msg = value.VisitStore(stores, user, storeName); - exist = msg != ""; + Store? store = value.VisitStore(stores, user, storeName); + exist = store != null; + msg = store?.ToString() ?? ""; } if (!exist) diff --git a/OshimaWebAPI/Controllers/FunGameController.cs b/OshimaWebAPI/Controllers/FunGameController.cs index 9cdb295..021e1b9 100644 --- a/OshimaWebAPI/Controllers/FunGameController.cs +++ b/OshimaWebAPI/Controllers/FunGameController.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.SQLScript.Entity; @@ -2238,7 +2239,7 @@ namespace Oshima.FunGame.WebAPI.Controllers else { FunGameService.ReleaseUserSemaphoreSlim(userid); - return "此物品的可使用数量小于你想要使用的数量!"; + return $"此物品的可使用数量({items.Count()})小于你想要使用的数量({useCount})!"; } } else @@ -3006,16 +3007,7 @@ namespace Oshima.FunGame.WebAPI.Controllers if (user.Inventory.Items.Remove(item)) { - double gained = item.QualityType switch - { - QualityType.Gold => 128, - QualityType.Red => 64, - QualityType.Orange => 32, - QualityType.Purple => 16, - QualityType.Blue => 8, - QualityType.Green => 3, - _ => 1 - }; + double gained = FunGameConstant.DecomposedMaterials[item.QualityType]; totalGained += gained; successCount++; } @@ -3043,7 +3035,7 @@ namespace Oshima.FunGame.WebAPI.Controllers } [HttpPost("decomposeitem2")] - public string DecomposeItem2([FromQuery] long? uid = null, [FromQuery] string? name = null, [FromQuery] int? count = null) + public string DecomposeItem2([FromQuery] long? uid = null, [FromQuery] string? name = null, [FromQuery] int? count = null, [FromQuery] bool allowLock = false) { try { @@ -3067,11 +3059,11 @@ namespace Oshima.FunGame.WebAPI.Controllers { itemTrading = SQLService.GetUserItemGuids(sql, userid); } - IEnumerable items = user.Inventory.Items.Where(i => i.Name == name && i.Character is null && !i.IsLock && !itemTrading.Contains(i.Guid)); + IEnumerable items = user.Inventory.Items.Where(i => i.Name == name && i.Character is null && (!allowLock || !i.IsLock) && !itemTrading.Contains(i.Guid)); if (!items.Any()) { FunGameService.ReleaseUserSemaphoreSlim(userid); - return $"库存中不存在名称为【{name}】,且未上锁、未在进行交易的物品!"; + return $"库存中不存在名称为【{name}】,且{(!allowLock ? "未上锁、" : "")}未在进行交易的物品!"; } if (items.Count() >= useCount) @@ -3085,16 +3077,7 @@ namespace Oshima.FunGame.WebAPI.Controllers { if (user.Inventory.Items.Remove(item)) { - double gained = item.QualityType switch - { - QualityType.Gold => 128, - QualityType.Red => 64, - QualityType.Orange => 32, - QualityType.Purple => 16, - QualityType.Blue => 8, - QualityType.Green => 3, - _ => 1 - }; + double gained = FunGameConstant.DecomposedMaterials[item.QualityType]; totalGained += gained; successCount++; } @@ -3109,7 +3092,7 @@ namespace Oshima.FunGame.WebAPI.Controllers else { FunGameService.ReleaseUserSemaphoreSlim(userid); - return $"此物品的可分解数量({items.Count()} 件)小于你想要分解的数量!"; + return $"此物品的可分解数量({items.Count()} 件)小于你想要分解的数量({useCount})!"; } } else @@ -3161,16 +3144,7 @@ namespace Oshima.FunGame.WebAPI.Controllers List msgs = []; int successCount = 0; - double gained = items.First().QualityType switch - { - QualityType.Gold => 128, - QualityType.Red => 64, - QualityType.Orange => 32, - QualityType.Purple => 16, - QualityType.Blue => 8, - QualityType.Green => 3, - _ => 1 - }; + double gained = FunGameConstant.DecomposedMaterials[items.First().QualityType]; foreach (Item item in items) { @@ -3529,7 +3503,7 @@ namespace Oshima.FunGame.WebAPI.Controllers { if (skill.SkillType == SkillType.Skill || skill.SkillType == SkillType.SuperSkill) { - if (skill.Level + 1 == General.GameplayEquilibriumConstant.MaxSkillLevel) + if (skill.Level == General.GameplayEquilibriumConstant.MaxSkillLevel) { return $"此技能【{skill.Name}】已经升至满级!"; } @@ -3725,7 +3699,7 @@ namespace Oshima.FunGame.WebAPI.Controllers NormalAttack na = character.NormalAttack; - if (na.Level + 1 == General.GameplayEquilibriumConstant.MaxNormalAttackLevel) + if (na.Level == General.GameplayEquilibriumConstant.MaxNormalAttackLevel) { return $"角色 [ {character} ] 的【{na.Name}】已经升至满级!"; } @@ -5377,7 +5351,7 @@ namespace Oshima.FunGame.WebAPI.Controllers Store? daily = stores.Get("daily"); if (daily != null) { - if (daily.Goods.Values.FirstOrDefault(g => g.Id == goodid) is Goods good) + if (daily.Goods.Values.FirstOrDefault(g => g.Id == goodid && (!g.ExpireTime.HasValue || g.ExpireTime.Value > DateTime.Now)) is Goods good) { msg = FunGameService.StoreBuyItem(daily, good, pc, user, buycount); } @@ -5425,7 +5399,7 @@ namespace Oshima.FunGame.WebAPI.Controllers Store? daily = stores.Get("daily"); if (daily != null) { - if (daily.Goods.Values.FirstOrDefault(g => g.Id == goodid) is Goods good) + if (daily.Goods.Values.FirstOrDefault(g => g.Id == goodid && (!g.ExpireTime.HasValue || g.ExpireTime.Value > DateTime.Now)) is Goods good) { int count = 0; string itemMsg = ""; @@ -5439,7 +5413,7 @@ namespace Oshima.FunGame.WebAPI.Controllers } msg = good.ToString().Split("包含物品:")[0].Trim(); msg += $"\r\n包含物品:\r\n" + itemMsg + - $"\r\n剩余库存:{(good.Stock == - 1 ? "不限量提供" : good.Stock)}"; + $"\r\n剩余库存:{(good.Stock == -1 ? "不限量提供" : good.Stock)}"; } else { @@ -6050,12 +6024,13 @@ namespace Oshima.FunGame.WebAPI.Controllers Item item = user.Inventory.Items.ToList()[itemIndex - 1]; if (msg != "") msg += "\r\n"; + string isUnLock = unlock ? "解锁" : "锁定"; using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); try { if (sql != null && SQLService.IsItemInOffers(sql, item.Guid)) { - msg += $"这个物品 {itemIndex}. {item.Name} 无法上锁/解锁。因为它正在进行交易,请检查交易报价!"; + msg += $"这个物品 {itemIndex}. {item.Name} 无法{isUnLock}。因为它正在进行交易,请检查交易报价!"; continue; } } @@ -6088,7 +6063,7 @@ namespace Oshima.FunGame.WebAPI.Controllers else { item.IsLock = true; - msg += $"物品上锁成功:{itemIndex}. {item.Name}"; + msg += $"物品锁定成功:{itemIndex}. {item.Name}"; } } else @@ -6120,6 +6095,100 @@ namespace Oshima.FunGame.WebAPI.Controllers } } + [HttpPost("lockitems")] + public string LockItems([FromQuery] long uid = -1, [FromQuery] string name = "", [FromQuery] int count = 0, [FromQuery] bool unlock = false) + { + try + { + if (count <= 0) + { + return "数量必须大于0!"; + } + + PluginConfig pc = FunGameService.GetUserConfig(uid, out _); + + if (pc.Count > 0) + { + User user = FunGameService.GetUser(pc); + + string msg = ""; + using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); + List itemTrading = []; + if (sql != null) + { + itemTrading = SQLService.GetUserItemGuids(sql, uid); + } + + Dictionary items = user.Inventory.Items.Select((i, index) => new { Item = i, Index = index + 1 }). + Where(x => x.Item.Name == name && x.Item.Character is null && x.Item.IsLock == unlock && !itemTrading.Contains(x.Item.Guid)). + ToDictionary(x => x.Item, x => x.Index); + string isUnLock = unlock ? "解锁" : "锁定"; + + if (items.Count == 0) + { + msg = $"库存中不存在名称为【{name}】,且未在进行交易的物品,或者这些物品都已经被{isUnLock}了!"; + } + else if (items.Count >= count) + { + items = items.TakeLast(count).ToDictionary(); + List msgs = []; + int successCount = 0; + + foreach (Item item in items.Keys) + { + if (unlock) + { + PluginConfig renameExamine = new("examines", "rename"); + renameExamine.LoadConfig(); + List strings = renameExamine.Get>(user.Id.ToString()) ?? []; + if (strings.Count > 0) + { + string guid = strings[1]; + Item? gmk = user.Inventory.Items.FirstOrDefault(i => i.Guid.ToString() == guid); + if (gmk != null) + { + msg = $"物品 {items[item]}. {item.Name} 已被自定义改名系统锁定,无法自行解锁。"; + continue; + } + } + + item.IsLock = false; + msg += $"物品解锁成功:{items[item]}. {item.Name}"; + successCount++; + } + else + { + item.IsLock = true; + msg += $"物品锁定成功:{items[item]}. {item.Name}"; + successCount++; + } + } + + FunGameService.SetUserConfigAndReleaseSemaphoreSlim(uid, pc, user); + return $"{isUnLock}完毕!{isUnLock} {count} 件,库存允许{isUnLock} {items.Count} 件,成功 {successCount} 件!"; + } + else + { + msg = $"此物品的可{isUnLock}数量({items.Count})小于你想要{isUnLock}的数量({count})!"; + } + + FunGameService.ReleaseUserSemaphoreSlim(uid); + return msg; + } + else + { + FunGameService.ReleaseUserSemaphoreSlim(uid); + return noSaved; + } + } + catch (Exception e) + { + FunGameService.ReleaseUserSemaphoreSlim(uid.ToString() ?? ""); + Logger.LogError(e, "Error: {e}", e); + return busy; + } + } + [HttpPost("makeoffer")] public string MakeOffer([FromQuery] long? uid = null, [FromQuery] long? offeree = null) { @@ -6992,7 +7061,7 @@ namespace Oshima.FunGame.WebAPI.Controllers EntityModuleConfig stores = new("stores", userid.ToString()); stores.LoadConfig(); - string msg = FunGameService.CheckRegionStore(stores, user, storeRegion, storeName, out bool exist); + string msg = FunGameService.CheckRegionStore(stores, user, storeRegion, storeName, out _); FunGameService.SetUserConfigAndReleaseSemaphoreSlim(userid, pc, user); return msg; @@ -7003,7 +7072,7 @@ namespace Oshima.FunGame.WebAPI.Controllers return noSaved; } } - + [HttpPost("systemstorebuy")] public string SystemStoreBuy([FromQuery] long? uid = null, [FromQuery] string storeRegion = "", [FromQuery] string storeName = "", [FromQuery] long id = 0, [FromQuery] int count = 0) { @@ -7018,14 +7087,21 @@ namespace Oshima.FunGame.WebAPI.Controllers EntityModuleConfig stores = new("stores", userid.ToString()); stores.LoadConfig(); string msg = ""; - Store? store = stores.Get(storeName); + Store? store = FunGameService.GetRegionStore(stores, user, storeRegion, storeName); if (store != null) { - if (store.Goods.Values.FirstOrDefault(g => g.Id == id) is Goods good) + if (store.Goods.Values.FirstOrDefault(g => g.Id == id && (!g.ExpireTime.HasValue || g.ExpireTime.Value > DateTime.Now)) is Goods good) { msg = FunGameService.StoreBuyItem(store, good, pc, user, count); - stores.Add(storeName, store); - stores.SaveConfig(); + if (store.GlobalStock) + { + FunGameService.SaveRegionStore(store, storeRegion, storeName); + } + else + { + stores.Add(storeName, store); + stores.SaveConfig(); + } } else { @@ -7068,7 +7144,7 @@ namespace Oshima.FunGame.WebAPI.Controllers Store? store = stores.Get(storeName); if (store != null) { - if (store.Goods.Values.FirstOrDefault(g => g.Id == goodid) is Goods good) + if (store.Goods.Values.FirstOrDefault(g => g.Id == goodid && (!g.ExpireTime.HasValue || g.ExpireTime.Value > DateTime.Now)) is Goods good) { int count = 0; string itemMsg = ""; diff --git a/OshimaWebAPI/Services/RainBOTService.cs b/OshimaWebAPI/Services/RainBOTService.cs index a98768d..28732fa 100644 --- a/OshimaWebAPI/Services/RainBOTService.cs +++ b/OshimaWebAPI/Services/RainBOTService.cs @@ -1511,6 +1511,27 @@ namespace Oshima.FunGame.WebAPI.Services return result; } + if (e.Detail.StartsWith("强制分解", StringComparison.CurrentCultureIgnoreCase)) + { + string detail = e.Detail.Replace("强制分解", "").Trim(); + string pattern = @"\s*(?[^\d]+)\s*(?\d+)\s*"; + Match match = Regex.Match(detail, pattern); + if (match.Success) + { + string itemName = match.Groups["itemName"].Value.Trim(); + if (int.TryParse(match.Groups["count"].Value, out int count)) + { + string msg = Controller.DecomposeItem2(uid, itemName, count, true); + if (msg != "") + { + await SendAsync(e, "分解", msg); + } + } + } + + return result; + } + if (e.Detail.StartsWith("分解", StringComparison.CurrentCultureIgnoreCase)) { string detail = e.Detail.Replace("分解", "").Trim(); @@ -2383,6 +2404,48 @@ namespace Oshima.FunGame.WebAPI.Services return result; } + if (e.Detail.StartsWith("批量锁定", StringComparison.CurrentCultureIgnoreCase)) + { + string detail = e.Detail.Replace("批量锁定", "").Trim(); + string pattern = @"\s*(?[^\d]+)\s*(?\d+)\s*"; + Match match = Regex.Match(detail, pattern); + if (match.Success) + { + string itemName = match.Groups["itemName"].Value.Trim(); + if (int.TryParse(match.Groups["count"].Value, out int count)) + { + string msg = Controller.LockItems(uid, itemName, count, false); + if (msg != "") + { + await SendAsync(e, "批量锁定", msg); + } + } + } + + return result; + } + + if (e.Detail.StartsWith("批量解锁", StringComparison.CurrentCultureIgnoreCase)) + { + string detail = e.Detail.Replace("批量解锁", "").Trim(); + string pattern = @"\s*(?[^\d]+)\s*(?\d+)\s*"; + Match match = Regex.Match(detail, pattern); + if (match.Success) + { + string itemName = match.Groups["itemName"].Value.Trim(); + if (int.TryParse(match.Groups["count"].Value, out int count)) + { + string msg = Controller.LockItems(uid, itemName, count, true); + if (msg != "") + { + await SendAsync(e, "批量解锁", msg); + } + } + } + + return result; + } + if (e.Detail.StartsWith("上锁") || e.Detail.StartsWith("锁定")) { string detail = e.Detail.Replace("上锁", "").Replace("锁定", "").Trim(); @@ -2779,6 +2842,9 @@ namespace Oshima.FunGame.WebAPI.Services case 3: msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_yuki"); break; + case 4: + msg = Controller.ShowSystemStore(uid, "铎京城", "dokyo_welfare"); + break; default: break; }