mirror of
https://github.com/oshima-studios/OshimaGameModule.git
synced 2025-12-05 16:16:35 +00:00
允许运行时修改商品价格和减少库存量;添加限购和全局库存商店;可以自适应刷新商品的属性;添加了过期检查
This commit is contained in:
parent
08f4664604
commit
596611edd8
@ -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<string, int> 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.礼包;
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
蛇年大吉 = 20002,
|
||||
新春快乐 = 20003,
|
||||
毕业礼包 = 20004,
|
||||
魔法卡礼包 = 20005
|
||||
魔法卡礼包 = 20005,
|
||||
探索助力礼包 = 20006
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ namespace Oshima.FunGame.OshimaModules
|
||||
(long)GiftBoxID.新春快乐 => new 新春快乐(),
|
||||
(long)GiftBoxID.毕业礼包 => new 毕业礼包(),
|
||||
(long)GiftBoxID.魔法卡礼包 => new 魔法卡礼包(),
|
||||
(long)GiftBoxID.探索助力礼包 => new 探索助力礼包(),
|
||||
_ => null,
|
||||
};
|
||||
};
|
||||
|
||||
@ -22,9 +22,14 @@ namespace Oshima.FunGame.OshimaModules.Regions
|
||||
return other is OshimaRegion && other.GetIdName() == GetIdName();
|
||||
}
|
||||
|
||||
public virtual string VisitStore(EntityModuleConfig<Store> stores, User user, string storeName)
|
||||
public virtual Store? VisitStore(EntityModuleConfig<Store> stores, User user, string storeName)
|
||||
{
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void SaveGlobalStore(Store store, string storeName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
||||
@ -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<Store> stores, User user, string storeName)
|
||||
public override Store? VisitStore(EntityModuleConfig<Store> stores, User user, string storeName)
|
||||
{
|
||||
EntityModuleConfig<Store> 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<Store> 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<string, int> goodsNameAndStock = store.Goods.Values.ToDictionary(g => g.Name, g => g.Stock);
|
||||
Dictionary<string, Dictionary<long, int>> 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<long, int>? 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<Store> storeTemplate = new("stores", "dokyo");
|
||||
storeTemplate.LoadConfig();
|
||||
storeTemplate.Add(storeName, store);
|
||||
storeTemplate.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<Store> 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> 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("刷新商店");
|
||||
}
|
||||
|
||||
@ -427,6 +427,17 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
{ QualityType.Gold, (130000, 240000) }
|
||||
};
|
||||
|
||||
public static Dictionary<QualityType, double> 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; } = [
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
{"合成魔法卡 <{物品序号...}>", "3张魔法卡合成(空格隔开)"},
|
||||
{"分解物品 <{物品序号...}>", "分解指定物品"},
|
||||
{"分解 <物品名称> <数量>", "分解指定数量物品"},
|
||||
{"强制分解 <物品名称> <数量>", "分解指定数量物品"},
|
||||
{"品质分解 <品质索引>", "按品质分解(0-6:普通/优秀/稀有/史诗/传说/神话/不朽)"},
|
||||
};
|
||||
|
||||
@ -130,6 +131,7 @@
|
||||
{"商店1", "查看后勤部商品"},
|
||||
{"商店2", "查看武器商会商品"},
|
||||
{"商店3", "查看杂货铺商品"},
|
||||
{"商店4", "查看慈善基金会商品"},
|
||||
{"商店查看 <商品序号>", "查看指定商品详情,访问任意商店后2分钟内可用"},
|
||||
{"商店购买 <商品序号>", "购买指定商品,访问任意商店后2分钟内可用"},
|
||||
{"商店出售 <物品序号>", "向商店出售具有回收价的指定物品"},
|
||||
|
||||
@ -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<Store> stores, User user, string storeRegion, string storeName)
|
||||
{
|
||||
Store? store = null;
|
||||
|
||||
Dictionary<string, OshimaRegion> 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<Store> stores, User user, string storeRegion, string storeName, out bool exist)
|
||||
{
|
||||
string msg = "";
|
||||
@ -3955,8 +3987,9 @@ namespace Oshima.FunGame.OshimaServers.Service
|
||||
Dictionary<string, OshimaRegion> 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)
|
||||
|
||||
@ -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<Item> items = user.Inventory.Items.Where(i => i.Name == name && i.Character is null && !i.IsLock && !itemTrading.Contains(i.Guid));
|
||||
IEnumerable<Item> 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<string> 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<Guid> itemTrading = [];
|
||||
if (sql != null)
|
||||
{
|
||||
itemTrading = SQLService.GetUserItemGuids(sql, uid);
|
||||
}
|
||||
|
||||
Dictionary<Item, int> 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<string> msgs = [];
|
||||
int successCount = 0;
|
||||
|
||||
foreach (Item item in items.Keys)
|
||||
{
|
||||
if (unlock)
|
||||
{
|
||||
PluginConfig renameExamine = new("examines", "rename");
|
||||
renameExamine.LoadConfig();
|
||||
List<string> strings = renameExamine.Get<List<string>>(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<Store> 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;
|
||||
@ -7018,14 +7087,21 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
||||
EntityModuleConfig<Store> 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 = "";
|
||||
|
||||
@ -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*(?<itemName>[^\d]+)\s*(?<count>\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*(?<itemName>[^\d]+)\s*(?<count>\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*(?<itemName>[^\d]+)\s*(?<count>\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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user