1212121
This commit is contained in:
@@ -10,6 +10,7 @@ namespace Application.Domain
|
||||
{
|
||||
public enum BusEventsName
|
||||
{
|
||||
HandleOnHook,//处理挂机
|
||||
PutFightAward,//战斗奖励事件
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,12 @@
|
||||
var fightService = App.GetService<IGameFightService>();
|
||||
await fightService.HandleFight(data);
|
||||
}
|
||||
|
||||
[EventSubscribe(BusEventsEnum.BusEventsName.HandleOnHook, NumRetries = 0,RetryTimeout = 999999999)]
|
||||
public async Task HandleOnHook(EventHandlerExecutingContext context)
|
||||
{
|
||||
var hookService = App.GetService<IOnHookService>();
|
||||
await hookService.HandleHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
public static class GameEnum
|
||||
{
|
||||
public enum JobType
|
||||
{
|
||||
single,//1次
|
||||
alway,//永久
|
||||
}
|
||||
public enum JobCode
|
||||
{
|
||||
OnHook,//定时任务
|
||||
}
|
||||
public enum PropCode//游戏资源编码
|
||||
{
|
||||
Monster,//怪物
|
||||
|
||||
@@ -10,4 +10,10 @@ public class MapEnum
|
||||
add_blood,
|
||||
add_copper,
|
||||
}
|
||||
|
||||
public enum MapCode
|
||||
{
|
||||
DEF_MAP,
|
||||
Dup_Map
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
public interface IGameAutoJobService
|
||||
{
|
||||
Task<List<game_job>> GetJobData();
|
||||
Task<game_job> GetJobInfo(string jobId);
|
||||
Task StartJob();
|
||||
Task StopJob(string jobId);
|
||||
Task HandleJob(game_job data);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
public interface IOnHookService
|
||||
{
|
||||
Task<game_onhook> GetUserOnHook(string userId);
|
||||
|
||||
Task<bool> StartOnHook(string userId,string scene, long copper, long exp, string name, string award, decimal score,
|
||||
int time, int onHookTime);
|
||||
|
||||
Task<bool> StopOnHook(string userId);
|
||||
Task HandleHook();
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public interface IUnitUserAttrService
|
||||
#region BUFF状态
|
||||
|
||||
Task<List<unit_user_state>> GetUserStateData(string userId, string scene = "Default");
|
||||
|
||||
Task<decimal> GetUserStateDataTotal(string userId, string scene = "Default");
|
||||
Task<bool> AddUserState(string userId, string groupId, string name, string scene, string tips,
|
||||
List<AttrItem> attr, int time, int count = 1);
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
using Photon.Core.Timer;
|
||||
|
||||
namespace Application.Domain;
|
||||
|
||||
public class GameAutoJobService(ISqlSugarClient DbClient, IRedisCache redis,ITimerJobManager jobManager) : IGameAutoJobService, ITransient
|
||||
{
|
||||
public async Task<List<game_job>> GetJobData()
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_job>();
|
||||
return await db.Queryable<game_job>().Where(it => it.state == 1).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<game_job> GetJobInfo(string jobId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKey,"JobData");
|
||||
if (await redis.HExistsHashAsync(key, jobId))
|
||||
{
|
||||
return await redis.GetHashAsync<game_job>(key, jobId);
|
||||
}
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_job>();
|
||||
var data = await db.Queryable<game_job>().Where(it => it.jobId == jobId).SingleAsync();
|
||||
await redis.AddHashAsync(key, jobId, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task StartJob()
|
||||
{
|
||||
Console.WriteLine(">>>开始执行定时任务>>>");
|
||||
var jobData = await GetJobData();
|
||||
if (jobData.Count > 0)
|
||||
{
|
||||
foreach (var item in jobData)
|
||||
{
|
||||
await jobManager.CreateAndStartTask(item.jobId, item.code, item.cron);
|
||||
Console.WriteLine($"-已启动--->{item.name}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("<<<定时任务初始化完成<<<");
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task StopJob(string jobId)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_job>();
|
||||
bool result = await db.Updateable<game_job>().SetColumns(it => it.state == 0).Where(it => it.jobId == jobId)
|
||||
.ExecuteCommandAsync() > 0;
|
||||
if (result)
|
||||
{
|
||||
await jobManager.DeleteTask(jobId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleJob(game_job data)
|
||||
{
|
||||
if (data.code == nameof(GameEnum.JobCode.OnHook))//挂机
|
||||
{
|
||||
var _eventPublisher = App.GetService<IEventPublisher>();
|
||||
await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.HandleOnHook,
|
||||
data));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Application.Domain;
|
||||
|
||||
public class OnHookService(ISqlSugarClient DbClient, IRedisCache redis) : IOnHookService, ITransient
|
||||
{
|
||||
public async Task<game_onhook> GetUserOnHook(string userId)
|
||||
{
|
||||
string key = string.Format(UserCache.BaseCacheKey, "OnHook");
|
||||
if (await redis.HExistsHashAsync(key, userId))
|
||||
{
|
||||
return await redis.GetHashAsync<game_onhook>(key, userId);
|
||||
}
|
||||
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_onhook>();
|
||||
var data = await db.Queryable<game_onhook>().Where(it => it.userId == userId).SingleAsync();
|
||||
if (data == null)
|
||||
{
|
||||
data = new game_onhook();
|
||||
data.userId = userId;
|
||||
data.scene = "";
|
||||
data.copper = 0;
|
||||
data.exp = 0;
|
||||
data.status = 0;
|
||||
data.name = "";
|
||||
data.award = "";
|
||||
data.score = 0;
|
||||
data.time = 0;
|
||||
data.uptime = DateTime.Now;
|
||||
data.endTime = DateTime.Now;
|
||||
data.stopTime = TimeExtend.GetTimeStampSeconds;
|
||||
data.sumExp = 0;
|
||||
data.sumCopper = 0;
|
||||
await db.Insertable(data).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
await redis.AddHashAsync(key, userId, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private async Task ClearOnHookCache(string userId)
|
||||
{
|
||||
string key = string.Format(UserCache.BaseCacheKey, "OnHook");
|
||||
await redis.DelHashAsync(key, userId);
|
||||
}
|
||||
|
||||
public async Task<bool> StartOnHook(string userId, string scene, long copper, long exp, string name, string award,
|
||||
decimal score,
|
||||
int time, int onHookTime)
|
||||
{
|
||||
game_onhook data = new game_onhook();
|
||||
data.userId = userId;
|
||||
data.scene = scene;
|
||||
data.copper = copper;
|
||||
data.exp = exp;
|
||||
data.status = 1;
|
||||
data.name = name;
|
||||
data.award = award;
|
||||
data.score = score;
|
||||
data.time = time;
|
||||
data.uptime = DateTime.Now;
|
||||
DateTime end = DateTime.Now.AddHours(onHookTime);
|
||||
data.endTime = end;
|
||||
data.stopTime = TimeExtend.GetTimeStampBySeconds(end);
|
||||
data.sumExp = 0;
|
||||
data.sumCopper = 0;
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_onhook>();
|
||||
bool result = await db.Saveable(data).ExecuteCommandAsync() > 0;
|
||||
if (result)
|
||||
{
|
||||
await ClearOnHookCache(userId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> StopOnHook(string userId)
|
||||
{
|
||||
bool result = true;
|
||||
var onHook = await GetUserOnHook(userId);
|
||||
if (onHook.status == 1)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_onhook>();
|
||||
result = await db.Updateable<game_onhook>().SetColumns(it => it.status == 0)
|
||||
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
|
||||
if (result)
|
||||
{
|
||||
await ClearOnHookCache(userId);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateOnHook(string userId, long exp, long copper)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_onhook>();
|
||||
var result = await db.Updateable<game_onhook>()
|
||||
.SetColumnsIF(exp > 0, it => it.sumExp == it.sumExp + exp)
|
||||
.SetColumnsIF(copper > 0, it => it.sumCopper == it.sumCopper + copper)
|
||||
.SetColumns(it => it.uptime == DateTime.Now)
|
||||
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
|
||||
if (result)
|
||||
{
|
||||
await ClearOnHookCache(userId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task HandleHook()
|
||||
{
|
||||
long onTime = TimeExtend.GetTimeStampSeconds;
|
||||
var accService = App.GetService<IUnitUserAccService>();
|
||||
var attrService = App.GetService<IUnitUserAttrService>();
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_onhook>();
|
||||
var data = await db.Queryable<game_onhook>().Where(it => it.status == 1).ToListAsync();
|
||||
foreach (var hook in data)
|
||||
{
|
||||
if (hook.stopTime < onTime)
|
||||
{
|
||||
await StopOnHook(hook.userId);
|
||||
continue;
|
||||
}
|
||||
|
||||
var userAttr = await attrService.GetUserAttrModel(hook.userId, hook.scene);
|
||||
if (userAttr.score < hook.score)
|
||||
{
|
||||
await StopOnHook(hook.userId);
|
||||
continue;
|
||||
}
|
||||
|
||||
int allTime = TimeAssist.TimeDiffSeconds((DateTime)hook.uptime, DateTime.Now) * 1000;
|
||||
int opCount = Convert.ToInt32(allTime / hook.time);
|
||||
long exp = Convert.ToInt64(hook.exp * (1.0m + userAttr.addExp) * opCount);
|
||||
long copper = Convert.ToInt64(hook.copper * (1.0m + userAttr.addGold) * opCount);
|
||||
List<TowerGet> award = new List<TowerGet>();
|
||||
if (!string.IsNullOrEmpty(hook.award))
|
||||
{
|
||||
var awardModel = JsonConvert.DeserializeObject<MonsterAwardModel>(hook.award);
|
||||
if (awardModel.type == nameof(MonsterEnum.AwardCode.Default))
|
||||
{
|
||||
var getAward = GameBus.GetRandomGoods(awardModel.award, opCount, userAttr.burst);
|
||||
award.AddRange(getAward);
|
||||
}
|
||||
}
|
||||
|
||||
if (await UpdateOnHook(hook.userId, exp, copper))
|
||||
{
|
||||
if (exp > 0)
|
||||
{
|
||||
await attrService.UpdateUserExp(hook.userId, exp);
|
||||
}
|
||||
|
||||
if (copper > 0)
|
||||
{
|
||||
await accService.UpdateUserCopper(hook.userId, 1, copper, "挂机获得");
|
||||
}
|
||||
|
||||
if (award.Count > 0)
|
||||
{
|
||||
await GameBus.UpdateBag(hook.userId, 1, award, "挂机获得");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,17 +121,17 @@ public class GameChatService : IGameChatService, ITransient
|
||||
chat.sign = sign;
|
||||
chat.state = 1;
|
||||
chat.addTime = DateTime.Now;
|
||||
chat.sort = TimeExtend.GetTimeStampSeconds;
|
||||
chat.sort = TimeExtend.GetTimeStampMilliseconds;
|
||||
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddDays(3));
|
||||
chat.opUser = "";
|
||||
switch (code)
|
||||
{
|
||||
case "Region":
|
||||
chat.sort += 300; //五分钟
|
||||
chat.sort += 300 * 1000; //五分钟
|
||||
break;
|
||||
|
||||
case "Dress":
|
||||
chat.sort += 600; //10分钟
|
||||
chat.sort += 600 * 1000; //10分钟
|
||||
break;
|
||||
case "System":
|
||||
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddHours(6));
|
||||
|
||||
@@ -102,8 +102,8 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
|
||||
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;
|
||||
long addTime = TimeExtend.GetTimeStampMilliseconds;
|
||||
long endTime = TimeExtend.GetTimeStampSeconds + 24 * 60 * 60;
|
||||
|
||||
List<game_fight_data> fights = new List<game_fight_data>();
|
||||
|
||||
@@ -170,7 +170,7 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
|
||||
public async Task<bool> SetFightWin(game_fight_data fightData, string winUser,bool setDefMap=true)
|
||||
{
|
||||
bool result = false;
|
||||
long okTime = TimeExtend.GetTimeStampSeconds;
|
||||
long okTime = TimeExtend.GetTimeStampMilliseconds;
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_fight_data>();
|
||||
if (fightData.code == nameof(GameEnum.FightCode.PVE))
|
||||
{
|
||||
|
||||
@@ -243,6 +243,8 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
else
|
||||
{
|
||||
//更新挂机,结束挂机
|
||||
var hookService = App.GetService<IOnHookService>();
|
||||
await hookService.StopOnHook(userId);
|
||||
}
|
||||
|
||||
if (mapInfo == null)
|
||||
|
||||
@@ -649,6 +649,17 @@ public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) :
|
||||
await redis.DelHashAsync(key, userId);
|
||||
}
|
||||
|
||||
public async Task<decimal> GetUserStateDataTotal(string userId, string scene = "Default")
|
||||
{
|
||||
var data = await GetUserStateData(userId, scene);
|
||||
List<AttrItem> result = new List<AttrItem>();
|
||||
foreach (var item in data)
|
||||
{
|
||||
result.AddRange(item.attr);
|
||||
}
|
||||
return GameAttrTool.GetAttrItemValue(nameof(GameEnum.AttrCode.AddExp), result, 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 游戏资源储备
|
||||
|
||||
24
Service/Application.Domain/Timer/AutoJob.cs
Normal file
24
Service/Application.Domain/Timer/AutoJob.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Photon.Core.Timer;
|
||||
using Quartz;
|
||||
namespace Application.Domain;
|
||||
|
||||
public class AutoJob: ITimerAutoJob
|
||||
{
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
string jobId = context.JobDetail.Key.Name;
|
||||
if (!string.IsNullOrEmpty(jobId))
|
||||
{
|
||||
var jobService = App.GetService<IGameAutoJobService>();
|
||||
var jobData = await jobService.GetJobInfo(jobId);
|
||||
if (jobData != null)
|
||||
{
|
||||
await jobService.HandleJob(jobData);
|
||||
if (jobData.opType == nameof(GameEnum.JobType.single))
|
||||
{
|
||||
await jobService.StopJob(jobId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Service/Application.Domain/Timer/JobStart.cs
Normal file
69
Service/Application.Domain/Timer/JobStart.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Photon.Core.Timer;
|
||||
using Quartz;
|
||||
using Quartz.Spi;
|
||||
|
||||
namespace Application.Domain;
|
||||
public class JobStart: ITimerAutoStart
|
||||
{
|
||||
private readonly ISchedulerFactory _schedulerFactory;
|
||||
private readonly IJobFactory _jobFactory;
|
||||
|
||||
public JobStart(
|
||||
ISchedulerFactory schedulerFactory,
|
||||
IJobFactory jobFactory)
|
||||
{
|
||||
_schedulerFactory = schedulerFactory;
|
||||
_jobFactory = jobFactory;
|
||||
}
|
||||
|
||||
public IScheduler Scheduler { get; private set; }
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
|
||||
Scheduler.JobFactory = _jobFactory;
|
||||
|
||||
// 创建作业
|
||||
var job = JobBuilder.Create<AutoJob>()
|
||||
.WithIdentity("DayHandle", "Handle")
|
||||
.Build();
|
||||
|
||||
// 创建触发器
|
||||
var trigger = TriggerBuilder.Create()
|
||||
.WithIdentity($"DayHandle_trigger", "Handle")
|
||||
.WithCronSchedule("0 0 0 * * ? ")
|
||||
.Build();
|
||||
|
||||
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
|
||||
await Scheduler.Start(cancellationToken);
|
||||
|
||||
Console.WriteLine("----航海时代V3自动程序已启动-----");
|
||||
}
|
||||
|
||||
public async Task Begin()
|
||||
{
|
||||
Scheduler = await _schedulerFactory.GetScheduler();
|
||||
Scheduler.JobFactory = _jobFactory;
|
||||
|
||||
// 创建作业
|
||||
var job = JobBuilder.Create<AutoJob>()
|
||||
.WithIdentity("111", "test")
|
||||
.Build();
|
||||
|
||||
// 创建触发器
|
||||
var trigger = TriggerBuilder.Create()
|
||||
.WithIdentity($"111_trigger", "test")
|
||||
.WithCronSchedule("0/1 * * * * ? ")
|
||||
.Build();
|
||||
|
||||
await Scheduler.ScheduleJob(job, trigger);
|
||||
await Scheduler.Start();
|
||||
|
||||
Console.WriteLine("----探玩驿站自动程序已启动-----");
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await Scheduler?.Shutdown(cancellationToken);
|
||||
}
|
||||
}
|
||||
57
Service/Application.Domain/Timer/TimerJobManager.cs
Normal file
57
Service/Application.Domain/Timer/TimerJobManager.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Photon.Core.Timer;
|
||||
using Quartz;
|
||||
|
||||
namespace Application.Domain;
|
||||
|
||||
public class TimerJobManager : ITimerJobManager
|
||||
{
|
||||
private readonly IScheduler _scheduler;
|
||||
|
||||
public TimerJobManager(IScheduler scheduler)
|
||||
{
|
||||
_scheduler = scheduler;
|
||||
}
|
||||
|
||||
public async Task CreateAndStartTask(string jobId, string group, string cronExpression)
|
||||
{
|
||||
// 创建作业
|
||||
var job = JobBuilder.Create<AutoJob>()
|
||||
.WithIdentity(jobId, group)
|
||||
.Build();
|
||||
|
||||
// 创建触发器
|
||||
var trigger = TriggerBuilder.Create()
|
||||
.WithIdentity($"{jobId}_trigger", group)
|
||||
.WithCronSchedule(cronExpression)
|
||||
.Build();
|
||||
|
||||
// 安排作业
|
||||
await _scheduler.ScheduleJob(job, trigger);
|
||||
|
||||
// 启动调度器(如果尚未启动)
|
||||
if (!_scheduler.IsStarted)
|
||||
{
|
||||
await _scheduler.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PauseTask(string jobId)
|
||||
{
|
||||
await _scheduler.PauseJob(new JobKey(jobId, "default"));
|
||||
}
|
||||
|
||||
public async Task ResumeTask(string jobId, string group)
|
||||
{
|
||||
await _scheduler.ResumeJob(new JobKey(jobId, group));
|
||||
}
|
||||
|
||||
public async Task DeleteTask(string jobId, string group)
|
||||
{
|
||||
await _scheduler.DeleteJob(new JobKey(jobId, group));
|
||||
}
|
||||
|
||||
public async Task DeleteTask(string jobId)
|
||||
{
|
||||
await _scheduler.DeleteJob(new JobKey(jobId));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user