572 lines
20 KiB
C#
572 lines
20 KiB
C#
using Dm.util;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Application.Domain;
|
|
|
|
public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGameFightService, ITransient
|
|
{
|
|
#region 用户战斗索引
|
|
|
|
public async Task<List<string>> GetUserFight(string userId)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKey, "UserFight");
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
return await redis.GetHashAsync<List<string>>(key, userId);
|
|
}
|
|
|
|
List<string> data = new List<string>();
|
|
await redis.AddHashAsync(key, userId, data);
|
|
return data;
|
|
}
|
|
|
|
private async Task<bool> AddUserFight(string userId, string fightId)
|
|
{
|
|
var data = await GetUserFight(userId);
|
|
data.Add(fightId);
|
|
string key = string.Format(FightCache.FightCacheKey, "UserFight");
|
|
bool result = await redis.AddHashAsync(key, userId, data);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> RemoveUserFight(string userId, string fightId)
|
|
{
|
|
var data = await GetUserFight(userId);
|
|
data.Remove(fightId);
|
|
string key = string.Format(FightCache.FightCacheKey, "UserFight");
|
|
bool result = await redis.AddHashAsync(key, userId, data);
|
|
return result;
|
|
}
|
|
|
|
private async Task RemoveUserFight(string userId)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKey, "UserFight");
|
|
bool result = await redis.AddHashAsync(key, userId, new List<string>());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 战斗信息
|
|
|
|
public async Task<game_fight_data> GetFightInfo(string fightId)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKeys, "FightData:Info", fightId);
|
|
if (await redis.ExistsAsync(key))
|
|
{
|
|
return await redis.GetAsync<game_fight_data>(key);
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_fight_data>();
|
|
game_fight_data data = await db.Queryable<game_fight_data>().Where(it => it.fightId == fightId).SingleAsync();
|
|
await redis.SetAsync(key, data, 3600);
|
|
return data;
|
|
}
|
|
|
|
|
|
public async Task AddFightHarm(string fightId, string userId, long harm)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKeys, "FightData:Harm", fightId);
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
long sum = await redis.GetHashAsync<long>(key, userId);
|
|
sum += harm;
|
|
await redis.AddHashAsync(key, userId, sum);
|
|
}
|
|
else
|
|
{
|
|
await redis.AddHashAsync(key, userId, harm);
|
|
}
|
|
}
|
|
|
|
public async Task RemoveFightHarm(string fightId, string userId)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKeys, "FightData:Harm", fightId);
|
|
await redis.DelHashAsync(key, userId);
|
|
}
|
|
|
|
|
|
private async Task ClearFightInfoCache(string fightId, string keyId, bool remMonsterBool = false)
|
|
{
|
|
List<string> keys = new List<string>();
|
|
keys.Add(string.Format(FightCache.FightCacheKeys, "FightData:Info", fightId));
|
|
if (remMonsterBool)
|
|
{
|
|
keys.Add(string.Format(FightCache.FightCacheKeys, "FightData:Blood", keyId));
|
|
}
|
|
|
|
await redis.DelAsync(keys.ToArray());
|
|
}
|
|
|
|
public async Task<bool> AddFight(string fightId, string areaCode, string keyId, string mainId, string code,
|
|
string scene, string mapId,
|
|
string userId, long exp = 0, long copper = 0, long petExp = 0, string award = "", string pars = "")
|
|
{
|
|
long addTime = TimeExtend.GetTimeStampSeconds;
|
|
long endTime = addTime + 24 * 60 * 60;
|
|
|
|
List<game_fight_data> fights = new List<game_fight_data>();
|
|
|
|
game_fight_data data = new game_fight_data()
|
|
{
|
|
fightId = fightId,
|
|
areaCode = areaCode,
|
|
keyId = keyId,
|
|
mainId = mainId,
|
|
code = code,
|
|
scene = scene,
|
|
mapId = mapId,
|
|
userId = userId,
|
|
state = 0,
|
|
winUser = "",
|
|
exp = exp,
|
|
copper = copper,
|
|
petExp = petExp,
|
|
award = award,
|
|
pars = pars,
|
|
addTime = addTime,
|
|
okTime = 0,
|
|
endTime = endTime
|
|
};
|
|
fights.Add(data);
|
|
if (code == nameof(GameEnum.FightCode.PVP))
|
|
{
|
|
fights.Add(new game_fight_data()
|
|
{
|
|
fightId = StringAssist.NewGuid,
|
|
areaCode = areaCode,
|
|
keyId = keyId,
|
|
mainId = userId,
|
|
code = code,
|
|
scene = scene,
|
|
mapId = mapId,
|
|
userId = mainId,
|
|
state = 0,
|
|
winUser = "",
|
|
exp = exp,
|
|
copper = copper,
|
|
petExp = petExp,
|
|
award = award,
|
|
pars = pars,
|
|
addTime = addTime,
|
|
okTime = 0,
|
|
endTime = endTime
|
|
});
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_fight_data>();
|
|
bool result = await db.Insertable(fights).ExecuteCommandAsync() > 0;
|
|
if (result)
|
|
{
|
|
foreach (var item in fights)
|
|
{
|
|
await AddUserFight(item.userId, item.fightId);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> SetFightWin(game_fight_data fightData, string winUser,bool setDefMap=true)
|
|
{
|
|
bool result = false;
|
|
long okTime = TimeExtend.GetTimeStampSeconds;
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_fight_data>();
|
|
if (fightData.code == nameof(GameEnum.FightCode.PVE))
|
|
{
|
|
if (fightData.userId == winUser)
|
|
{
|
|
var data = await db.Queryable<game_fight_data>()
|
|
.Where(it =>
|
|
it.keyId == fightData.keyId && it.state == 0 && it.code == nameof(GameEnum.FightCode.PVE))
|
|
.ToListAsync();
|
|
|
|
foreach (var item in data)
|
|
{
|
|
db.Updateable<game_fight_data>().SetColumns(it => it.state == 1)
|
|
.SetColumns(it => it.winUser == winUser)
|
|
.SetColumns(it => it.winCode == nameof(UserEnum.AttrCode.Person))
|
|
.SetColumnsIF(item.userId == winUser, it => it.okTime == okTime)
|
|
.Where(it => it.fightId == item.fightId).AddQueue();
|
|
}
|
|
|
|
result = await db.SaveQueuesAsync() > 0;
|
|
if (result)
|
|
{
|
|
foreach (var item in data)
|
|
{
|
|
await ClearFightInfoCache(item.fightId, item.keyId, true);
|
|
}
|
|
|
|
fightData.state = 1;
|
|
fightData.winCode = nameof(UserEnum.AttrCode.Person);
|
|
fightData.winUser = winUser;
|
|
fightData.okTime = okTime;
|
|
//此处调用战斗结束相关
|
|
var _eventPublisher = App.GetService<IEventPublisher>();
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.PutFightAward,
|
|
fightData));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//清理相关pvp数据
|
|
result = await HandleFightUserDataByPvp(fightData.fightId, fightData.keyId,
|
|
nameof(UserEnum.AttrCode.Monster), winUser, fightData.userId, okTime);
|
|
if (result)
|
|
{
|
|
await RemoveUserFight(fightData.userId);
|
|
if (setDefMap)
|
|
{
|
|
await UserStateTool.SetUserMapDefault(fightData.userId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (fightData.code == nameof(GameEnum.FightCode.PVP))
|
|
{
|
|
string lowUser = fightData.userId == winUser ? fightData.mainId : fightData.userId;
|
|
result = await HandleFightUserDataByPvp(fightData.fightId, fightData.keyId,
|
|
nameof(UserEnum.AttrCode.Person), winUser, lowUser, okTime);
|
|
if (result)
|
|
{
|
|
await RemoveUserFight(lowUser);
|
|
if (setDefMap)
|
|
{
|
|
await UserStateTool.SetUserMapDefault(lowUser);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<bool> HandleFightUserDataByPvp(string fightId, string keyId, string winCode, string winUser,
|
|
string lowUser, long okTime)
|
|
{
|
|
bool result = true;
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_fight_data>();
|
|
var data = await db.Queryable<game_fight_data>()
|
|
.Where(it => it.state == 0 &&
|
|
((it.keyId.Contains(lowUser) && it.code == nameof(GameEnum.FightCode.PVP)) ||
|
|
(it.userId == lowUser && it.code == nameof(GameEnum.FightCode.PVE))))
|
|
.ToListAsync();
|
|
|
|
foreach (var item in data)
|
|
{
|
|
db.Updateable<game_fight_data>().SetColumns(it => it.state == 1)
|
|
.SetColumns(it => it.winCode == winCode)
|
|
.SetColumns(it => it.winUser == winUser)
|
|
.SetColumnsIF(item.userId == winUser && winCode == nameof(UserEnum.AttrCode.Person),
|
|
it => it.okTime == okTime)
|
|
.Where(it => it.fightId == item.fightId).AddQueue();
|
|
}
|
|
|
|
result = await db.SaveQueuesAsync() > 0;
|
|
if (result)
|
|
{
|
|
foreach (var item in data)
|
|
{
|
|
await ClearFightInfoCache(item.fightId, item.keyId, false);
|
|
}
|
|
|
|
if (winCode == nameof(UserEnum.AttrCode.Person))
|
|
{
|
|
var winFight = data.Find(it => it.userId == winUser);
|
|
if (winFight != null)
|
|
{
|
|
winFight.state = 1;
|
|
winFight.code = winCode;
|
|
winFight.winUser = winUser;
|
|
winFight.okTime = okTime;
|
|
|
|
var _eventPublisher = App.GetService<IEventPublisher>();
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.PutFightAward,
|
|
winFight));
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 战斗相关
|
|
|
|
public async Task<int> GetUserFightHarm(string userId)
|
|
{
|
|
int result = 0;
|
|
string key = string.Format(FightCache.FightCacheKey, "UserHarm");
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
result = await redis.GetHashAsync<int>(key, userId);
|
|
}
|
|
|
|
if (result > 0)
|
|
{
|
|
await redis.AddHashAsync(key, userId, 0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task SetUserFightHarm(string userId, int harm)
|
|
{
|
|
string key = string.Format(FightCache.FightCacheKey, "UserHarm");
|
|
await redis.AddHashAsync(key, userId, harm);
|
|
}
|
|
|
|
#region 战斗地图掉落
|
|
|
|
public async Task HandleFight(game_fight_data fightData)
|
|
{
|
|
string winUser = fightData.winUser;
|
|
|
|
#region 发放基础奖励
|
|
|
|
if (fightData.exp > 0)
|
|
{
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
await attrService.UpdateUserExp(winUser, (long)fightData.exp, 1);
|
|
}
|
|
|
|
if (fightData.copper > 0)
|
|
{
|
|
var accService = App.GetService<IUnitUserAccService>();
|
|
await accService.UpdateUserCopper(winUser, 1, (long)fightData.copper, "击杀怪物");
|
|
}
|
|
|
|
if (fightData.petExp > 0) //宠物经验
|
|
{
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(fightData.award)) //发放物品奖励
|
|
{
|
|
await PutFightAwardGoods(fightData);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
private async Task PutFightAwardGoods(game_fight_data fightData)
|
|
{
|
|
var fightAward = JsonConvert.DeserializeObject<FightAwardModel>(fightData.award);
|
|
if (fightAward.code == "Default")
|
|
{
|
|
var userService = App.GetService<IUnitUserService>();
|
|
var userConfig = await userService.GetUserConfigInfo(fightData.winUser);
|
|
List<TowerGet> AddMapGoods = new List<TowerGet>();
|
|
var opGoods = JsonConvert.DeserializeObject<List<TowerGet>>(fightAward.award.ToString());
|
|
string addGoodsUser = fightData.areaCode == nameof(GameEnum.AreaCode.Public) ? "0" : fightData.winUser;
|
|
if (userConfig.autoBag == 1)
|
|
{
|
|
var weightService = App.GetService<IUnitUserWeight>();
|
|
bool auto = true;
|
|
foreach (var item in opGoods)
|
|
{
|
|
if (auto == false)
|
|
{
|
|
AddMapGoods.Add(item);
|
|
}
|
|
else
|
|
{
|
|
if (await weightService.CheckUserWeight(fightData.winUser, item))
|
|
{
|
|
await GameBus.UpdateBag(fightData.winUser, 1, item.code, item.parameter, item.count,
|
|
"战斗获得");
|
|
}
|
|
else
|
|
{
|
|
auto = false;
|
|
AddMapGoods.add(item);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AddMapGoods = opGoods;
|
|
}
|
|
|
|
if (AddMapGoods.Count > 0)
|
|
{
|
|
await AddMapFightGoods(addGoodsUser, fightData.mapId, AddMapGoods);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<List<game_map_goods>> GetMapFightGoods(string mapId)
|
|
{
|
|
List<game_map_goods> result = new List<game_map_goods>();
|
|
string key = string.Format(FightCache.FightCacheKeys, "MapGoods", mapId);
|
|
if (await redis.ExistsAsync(key))
|
|
{
|
|
result = await redis.GetAsync<List<game_map_goods>>(key);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<game_map_goods> GetFightGoodsInfo(string mapId, string mgId)
|
|
{
|
|
var data = await GetMapFightGoods(mapId);
|
|
var result = data.Find(it => it.mgId == mgId);
|
|
return result;
|
|
}
|
|
|
|
private async Task AddMapFightGoods(string userId, string mapId, List<TowerGet> goods)
|
|
{
|
|
var data = await GetMapFightGoods(mapId);
|
|
List<game_map_goods> addData = new List<game_map_goods>();
|
|
foreach (var item in goods)
|
|
{
|
|
game_map_goods temp = new game_map_goods()
|
|
{
|
|
mgId = StringAssist.NewGuid,
|
|
userId = userId,
|
|
mapId = mapId,
|
|
name = item.name,
|
|
code = item.code,
|
|
par = item.parameter,
|
|
count = item.count
|
|
};
|
|
addData.Add(temp);
|
|
}
|
|
|
|
data.AddRange(addData);
|
|
string key = string.Format(FightCache.FightCacheKeys, "MapGoods", mapId);
|
|
await redis.SetAsync(key, data, 600);
|
|
}
|
|
|
|
public async Task RemoveFightGoods(string mapId, string mgId)
|
|
{
|
|
var data = await GetMapFightGoods(mapId);
|
|
data = data.FindAll(it => it.mgId != mgId);
|
|
string key = string.Format(FightCache.FightCacheKeys, "MapGoods", mapId);
|
|
await redis.SetAsync(key, data, 600);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 自动使用药品
|
|
|
|
public async Task AutoUseDrug(UserAttrModel user, game_fight_data fight)
|
|
{
|
|
var userService = App.GetService<IUnitUserService>();
|
|
var userConfig = await userService.GetUserConfigInfo(user.id);
|
|
await UseBloodDrug(user, fight, userConfig.autoDrug == 1, user.upBlood - user.blood);
|
|
if (userConfig.autoDrug == 1)
|
|
{
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
var myDrug = await attrService.GetUserDrug(user.id);
|
|
var loadDrug = myDrug.drug.Find(it => it.code == nameof(GoodsEnum.DrugCls.LoadBuff) && it.count > 0);
|
|
if (loadDrug != null)
|
|
{
|
|
var goodsService = App.GetService<IGameGoodsService>();
|
|
var _drugConfig = await goodsService.GetGoodsContent(loadDrug.goodsId);
|
|
string check = await goodsService.CheckUseDrug(user.id, loadDrug.goodsId, _drugConfig, fight.fightId);
|
|
if (string.IsNullOrEmpty(check))
|
|
{
|
|
if (await attrService.UpdateUserDrug(user.id, loadDrug.id, 0, 1))
|
|
{
|
|
await goodsService.UseDrug(user.id, loadDrug.goodsId, _drugConfig, fight.fightId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task UseBloodDrug(UserAttrModel user, game_fight_data fight, bool isAuto, int addBlood)
|
|
{
|
|
//先判断储存状态
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
var goodsService = App.GetService<IGameGoodsService>();
|
|
var bloodStock = await attrService.GetUserStock(user.id, "Blood");
|
|
var myDrug = await attrService.GetUserDrug(user.id);
|
|
if (bloodStock.Count > 0)
|
|
{
|
|
foreach (var item in bloodStock)
|
|
{
|
|
string[] config = item.par.split("|");
|
|
if (config[0] == fight.code || config[0] == "ALL")
|
|
{
|
|
decimal okLimit = Convert.ToDecimal(config[1]);
|
|
if ((Convert.ToDecimal(addBlood) / Convert.ToDecimal(user.upBlood) ) > okLimit)
|
|
{
|
|
if (item.type == "Number")
|
|
{
|
|
int opCount = item.sign > addBlood ? addBlood : Convert.ToInt32(item.sign);
|
|
item.sign = item.sign - opCount;
|
|
if (await attrService.UpdateUserStock(item))
|
|
{
|
|
addBlood -= opCount;
|
|
await attrService.UpdateUserBlood(user.id, 1, opCount);
|
|
if (addBlood < 1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (item.type == "Time")
|
|
{
|
|
await attrService.UpdateUserBlood(user.id, 1, addBlood);
|
|
addBlood = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isAuto && addBlood > 0)
|
|
{
|
|
//优先开放储存
|
|
var stockDrug = myDrug.drug.Find(it => it.code == nameof(GoodsEnum.DrugCls.BloodStock) && it.count > 0);
|
|
if (stockDrug != null)
|
|
{
|
|
var _drugConfig = await goodsService.GetGoodsContent(stockDrug.goodsId);
|
|
string check = await goodsService.CheckUseDrug(user.id, stockDrug.goodsId, _drugConfig, fight.fightId);
|
|
if (string.IsNullOrEmpty(check))
|
|
{
|
|
if (await attrService.UpdateUserDrug(user.id, stockDrug.id, 0, 1))
|
|
{
|
|
if (await goodsService.UseDrug(user.id, stockDrug.goodsId, _drugConfig, fight.fightId))
|
|
{
|
|
await UseBloodDrug(user, fight, isAuto, addBlood);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//使用普通药品
|
|
if (addBlood > 0)
|
|
{
|
|
var unitDrug = myDrug.drug.Find(it => it.code == nameof(GoodsEnum.DrugCls.Blood) && it.count > 0);
|
|
if (unitDrug != null)
|
|
{
|
|
var _drugConfig = await goodsService.GetGoodsContent(unitDrug.goodsId);
|
|
string check =
|
|
await goodsService.CheckUseDrug(user.id, unitDrug.goodsId, _drugConfig, fight.fightId);
|
|
if (string.IsNullOrEmpty(check))
|
|
{
|
|
if (await attrService.UpdateUserDrug(user.id, unitDrug.id, 0, 1))
|
|
{
|
|
await goodsService.UseDrug(user.id, unitDrug.goodsId, _drugConfig, fight.fightId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
public async Task HandelFightEnd(string userId, List<dynamic> data)
|
|
{
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
#endregion
|
|
} |