From 037e8456228a2f69d49e7a13b92a29afa1f011e2 Mon Sep 17 00:00:00 2001 From: Putoo <290555932@qq.com> Date: Tue, 7 Jul 2026 18:43:01 +0800 Subject: [PATCH] 1212121 --- Kx.SeaTime.sln.DotSettings.user | 2 + .../game/game/game_onhook.cs | 93 ++++++++++ .../resource/game/game_job.cs | 63 +++++++ .../BusEvents/BusEventsEnum.cs | 1 + .../BusEvents/BusEventsSubscriber.cs | 7 + Service/Application.Domain/Enum/GameEnum.cs | 9 + Service/Application.Domain/Enum/MapEnum.cs | 6 + .../Interface/Business/IGameAutoJobService.cs | 10 ++ .../Interface/Business/IOnHookService.cs | 12 ++ .../Interface/User/IUnitUserAttrService.cs | 2 +- .../Service/Business/GameAutoJobService.cs | 64 +++++++ .../Service/Business/OnHookService.cs | 167 ++++++++++++++++++ .../Services/Service/Chat/GameChatService.cs | 6 +- .../Service/Fight/GameFightService.cs | 6 +- .../Services/Service/Map/GameMapService.cs | 2 + .../Service/User/UnitUserAttrService.cs | 11 ++ Service/Application.Domain/Timer/AutoJob.cs | 24 +++ .../Timer/JobStart.cs | 5 +- .../Timer/TimerJobManager.cs | 7 +- .../Common/AppBackgroundService.cs | 25 +++ .../Controllers/Map/MapController.cs | 13 +- .../Controllers/Pub/FightController.cs | 109 +++++++++++- .../Controllers/User/UserController.cs | 17 +- Service/Application.Web/Plug/Timer/AutoJob.cs | 22 --- Service/Application.Web/Program.cs | 20 ++- .../Application.Web/applicationsettings.json | 2 +- Web/public/images/site/dup.gif | Bin 0 -> 2690 bytes Web/src/app.vue | 2 +- Web/src/assets/css/style.css | 13 +- Web/src/components/Page/Footer.vue | 2 +- Web/src/config/BaseConfig.ts | 8 +- Web/src/pages/fight/result.vue | 19 ++ Web/src/pages/map/index.vue | 8 + Web/src/pages/user/attr.vue | 95 +++++----- Web/src/pages/user/onhook.vue | 76 ++++++++ Web/src/services/Index/FightService.ts | 24 +++ Web/src/services/user/UserService.ts | 8 + 37 files changed, 854 insertions(+), 106 deletions(-) create mode 100644 Service/Application.Domain.Entity/game/game/game_onhook.cs create mode 100644 Service/Application.Domain.Entity/resource/game/game_job.cs create mode 100644 Service/Application.Domain/Services/Interface/Business/IGameAutoJobService.cs create mode 100644 Service/Application.Domain/Services/Interface/Business/IOnHookService.cs create mode 100644 Service/Application.Domain/Services/Service/Business/GameAutoJobService.cs create mode 100644 Service/Application.Domain/Services/Service/Business/OnHookService.cs create mode 100644 Service/Application.Domain/Timer/AutoJob.cs rename Service/{Application.Web/Plug => Application.Domain}/Timer/JobStart.cs (96%) rename Service/{Application.Web/Plug => Application.Domain}/Timer/TimerJobManager.cs (94%) create mode 100644 Service/Application.Web/Common/AppBackgroundService.cs delete mode 100644 Service/Application.Web/Plug/Timer/AutoJob.cs create mode 100644 Web/public/images/site/dup.gif create mode 100644 Web/src/pages/user/onhook.vue diff --git a/Kx.SeaTime.sln.DotSettings.user b/Kx.SeaTime.sln.DotSettings.user index ce45a72..98f86ea 100644 --- a/Kx.SeaTime.sln.DotSettings.user +++ b/Kx.SeaTime.sln.DotSettings.user @@ -1,6 +1,7 @@  ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -15,4 +16,5 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded \ No newline at end of file diff --git a/Service/Application.Domain.Entity/game/game/game_onhook.cs b/Service/Application.Domain.Entity/game/game/game_onhook.cs new file mode 100644 index 0000000..52153cd --- /dev/null +++ b/Service/Application.Domain.Entity/game/game/game_onhook.cs @@ -0,0 +1,93 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Game")] + public class game_onhook + { + /// + /// userId + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string userId { get; set; } + + /// + /// 场景 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? scene { get; set; } + + /// + /// copper + /// + [SugarColumn(IsNullable = true)] + public long? copper { get; set; } + + /// + /// exp + /// + [SugarColumn(IsNullable = true)] + public long? exp { get; set; } + + /// + /// status + /// + [SugarColumn(IsNullable = true)] + public int? status { get; set; } + + /// + /// name + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? name { get; set; } + + /// + /// award + /// + [SugarColumn(IsNullable = true)] + public string? award { get; set; } + + /// + /// 平分 + /// + [SugarColumn(Length = 60, IsNullable = true)] + public decimal? score { get; set; } + + /// + /// 时间/秒 + /// + [SugarColumn(IsNullable = true)] + public int? time { get; set; } + + /// + /// uptime + /// + [SugarColumn(IsNullable = true)] + public DateTime? uptime { get; set; } + + /// + /// endTime + /// + [SugarColumn(IsNullable = true)] + public DateTime? endTime { get; set; } + + /// + /// 停止时间 + /// + [SugarColumn(IsNullable = true)] + public long? stopTime { get; set; } + + /// + /// sumCopper + /// + [SugarColumn(IsNullable = true)] + public long? sumCopper { get; set; } + + /// + /// sumExp + /// + [SugarColumn(IsNullable = true)] + public long? sumExp { get; set; } + } +} diff --git a/Service/Application.Domain.Entity/resource/game/game_job.cs b/Service/Application.Domain.Entity/resource/game/game_job.cs new file mode 100644 index 0000000..60d8472 --- /dev/null +++ b/Service/Application.Domain.Entity/resource/game/game_job.cs @@ -0,0 +1,63 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Resource")] + public class game_job + { + /// + /// jobId + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? jobId { get; set; } + + /// + /// name + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? name { get; set; } + + /// + /// code + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? code { get; set; } + + /// + /// par + /// + [SugarColumn(IsNullable = true)] + public string? par { get; set; } + + /// + /// opType + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? opType { get; set; } + + /// + /// cron + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? cron { get; set; } + + /// + /// state + /// + [SugarColumn(IsNullable = true)] + public int? state { get; set; } + + /// + /// addTime + /// + [SugarColumn(IsNullable = true)] + public DateTime? addTime { get; set; } + + /// + /// remark + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? remark { get; set; } + } +} \ No newline at end of file diff --git a/Service/Application.Domain/BusEvents/BusEventsEnum.cs b/Service/Application.Domain/BusEvents/BusEventsEnum.cs index 5e23a03..9891303 100644 --- a/Service/Application.Domain/BusEvents/BusEventsEnum.cs +++ b/Service/Application.Domain/BusEvents/BusEventsEnum.cs @@ -10,6 +10,7 @@ namespace Application.Domain { public enum BusEventsName { + HandleOnHook,//处理挂机 PutFightAward,//战斗奖励事件 } } diff --git a/Service/Application.Domain/BusEvents/BusEventsSubscriber.cs b/Service/Application.Domain/BusEvents/BusEventsSubscriber.cs index ceffe71..4bc67a5 100644 --- a/Service/Application.Domain/BusEvents/BusEventsSubscriber.cs +++ b/Service/Application.Domain/BusEvents/BusEventsSubscriber.cs @@ -13,5 +13,12 @@ var fightService = App.GetService(); await fightService.HandleFight(data); } + + [EventSubscribe(BusEventsEnum.BusEventsName.HandleOnHook, NumRetries = 0,RetryTimeout = 999999999)] + public async Task HandleOnHook(EventHandlerExecutingContext context) + { + var hookService = App.GetService(); + await hookService.HandleHook(); + } } } \ No newline at end of file diff --git a/Service/Application.Domain/Enum/GameEnum.cs b/Service/Application.Domain/Enum/GameEnum.cs index 1c76ba3..3a5e2f0 100644 --- a/Service/Application.Domain/Enum/GameEnum.cs +++ b/Service/Application.Domain/Enum/GameEnum.cs @@ -2,6 +2,15 @@ public static class GameEnum { + public enum JobType + { + single,//1次 + alway,//永久 + } + public enum JobCode + { + OnHook,//定时任务 + } public enum PropCode//游戏资源编码 { Monster,//怪物 diff --git a/Service/Application.Domain/Enum/MapEnum.cs b/Service/Application.Domain/Enum/MapEnum.cs index 01faa29..b93a5f8 100644 --- a/Service/Application.Domain/Enum/MapEnum.cs +++ b/Service/Application.Domain/Enum/MapEnum.cs @@ -10,4 +10,10 @@ public class MapEnum add_blood, add_copper, } + + public enum MapCode + { + DEF_MAP, + Dup_Map + } } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Business/IGameAutoJobService.cs b/Service/Application.Domain/Services/Interface/Business/IGameAutoJobService.cs new file mode 100644 index 0000000..e434f19 --- /dev/null +++ b/Service/Application.Domain/Services/Interface/Business/IGameAutoJobService.cs @@ -0,0 +1,10 @@ +namespace Application.Domain; + +public interface IGameAutoJobService +{ + Task> GetJobData(); + Task GetJobInfo(string jobId); + Task StartJob(); + Task StopJob(string jobId); + Task HandleJob(game_job data); +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Business/IOnHookService.cs b/Service/Application.Domain/Services/Interface/Business/IOnHookService.cs new file mode 100644 index 0000000..2f2dd9f --- /dev/null +++ b/Service/Application.Domain/Services/Interface/Business/IOnHookService.cs @@ -0,0 +1,12 @@ +namespace Application.Domain; + +public interface IOnHookService +{ + Task GetUserOnHook(string userId); + + Task StartOnHook(string userId,string scene, long copper, long exp, string name, string award, decimal score, + int time, int onHookTime); + + Task StopOnHook(string userId); + Task HandleHook(); +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs b/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs index f0f3480..b0aa88d 100644 --- a/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs +++ b/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs @@ -57,7 +57,7 @@ public interface IUnitUserAttrService #region BUFF状态 Task> GetUserStateData(string userId, string scene = "Default"); - + Task GetUserStateDataTotal(string userId, string scene = "Default"); Task AddUserState(string userId, string groupId, string name, string scene, string tips, List attr, int time, int count = 1); diff --git a/Service/Application.Domain/Services/Service/Business/GameAutoJobService.cs b/Service/Application.Domain/Services/Service/Business/GameAutoJobService.cs new file mode 100644 index 0000000..9b3e04e --- /dev/null +++ b/Service/Application.Domain/Services/Service/Business/GameAutoJobService.cs @@ -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> GetJobData() + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + return await db.Queryable().Where(it => it.state == 1).ToListAsync(); + } + + public async Task GetJobInfo(string jobId) + { + string key = string.Format(BaseCache.BaseCacheKey,"JobData"); + if (await redis.HExistsHashAsync(key, jobId)) + { + return await redis.GetHashAsync(key, jobId); + } + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().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(); + bool result = await db.Updateable().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(); + await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.HandleOnHook, + data)); + } + + } +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/Business/OnHookService.cs b/Service/Application.Domain/Services/Service/Business/OnHookService.cs new file mode 100644 index 0000000..78c49ec --- /dev/null +++ b/Service/Application.Domain/Services/Service/Business/OnHookService.cs @@ -0,0 +1,167 @@ +using Newtonsoft.Json; + +namespace Application.Domain; + +public class OnHookService(ISqlSugarClient DbClient, IRedisCache redis) : IOnHookService, ITransient +{ + public async Task GetUserOnHook(string userId) + { + string key = string.Format(UserCache.BaseCacheKey, "OnHook"); + if (await redis.HExistsHashAsync(key, userId)) + { + return await redis.GetHashAsync(key, userId); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().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 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(); + bool result = await db.Saveable(data).ExecuteCommandAsync() > 0; + if (result) + { + await ClearOnHookCache(userId); + } + + return result; + } + + public async Task StopOnHook(string userId) + { + bool result = true; + var onHook = await GetUserOnHook(userId); + if (onHook.status == 1) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + result = await db.Updateable().SetColumns(it => it.status == 0) + .Where(it => it.userId == userId).ExecuteCommandAsync() > 0; + if (result) + { + await ClearOnHookCache(userId); + } + } + + return result; + } + + private async Task UpdateOnHook(string userId, long exp, long copper) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var result = await db.Updateable() + .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(); + var attrService = App.GetService(); + var db = DbClient.AsTenant().GetConnectionWithAttr(); + var data = await db.Queryable().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 award = new List(); + if (!string.IsNullOrEmpty(hook.award)) + { + var awardModel = JsonConvert.DeserializeObject(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, "挂机获得"); + } + } + } + } +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/Chat/GameChatService.cs b/Service/Application.Domain/Services/Service/Chat/GameChatService.cs index 49e6e9e..1f03e17 100644 --- a/Service/Application.Domain/Services/Service/Chat/GameChatService.cs +++ b/Service/Application.Domain/Services/Service/Chat/GameChatService.cs @@ -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)); diff --git a/Service/Application.Domain/Services/Service/Fight/GameFightService.cs b/Service/Application.Domain/Services/Service/Fight/GameFightService.cs index 3a3c538..31fdbbe 100644 --- a/Service/Application.Domain/Services/Service/Fight/GameFightService.cs +++ b/Service/Application.Domain/Services/Service/Fight/GameFightService.cs @@ -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 fights = new List(); @@ -170,7 +170,7 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa public async Task 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(); if (fightData.code == nameof(GameEnum.FightCode.PVE)) { diff --git a/Service/Application.Domain/Services/Service/Map/GameMapService.cs b/Service/Application.Domain/Services/Service/Map/GameMapService.cs index 19ed8f8..27b9e79 100644 --- a/Service/Application.Domain/Services/Service/Map/GameMapService.cs +++ b/Service/Application.Domain/Services/Service/Map/GameMapService.cs @@ -243,6 +243,8 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame else { //更新挂机,结束挂机 + var hookService = App.GetService(); + await hookService.StopOnHook(userId); } if (mapInfo == null) diff --git a/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs b/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs index 3dfa3b5..2a62a68 100644 --- a/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs +++ b/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs @@ -649,6 +649,17 @@ public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) : await redis.DelHashAsync(key, userId); } + public async Task GetUserStateDataTotal(string userId, string scene = "Default") + { + var data = await GetUserStateData(userId, scene); + List result = new List(); + foreach (var item in data) + { + result.AddRange(item.attr); + } + return GameAttrTool.GetAttrItemValue(nameof(GameEnum.AttrCode.AddExp), result, 0); + } + #endregion #region 游戏资源储备 diff --git a/Service/Application.Domain/Timer/AutoJob.cs b/Service/Application.Domain/Timer/AutoJob.cs new file mode 100644 index 0000000..9c23e17 --- /dev/null +++ b/Service/Application.Domain/Timer/AutoJob.cs @@ -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(); + var jobData = await jobService.GetJobInfo(jobId); + if (jobData != null) + { + await jobService.HandleJob(jobData); + if (jobData.opType == nameof(GameEnum.JobType.single)) + { + await jobService.StopJob(jobId); + } + } + } + } +} \ No newline at end of file diff --git a/Service/Application.Web/Plug/Timer/JobStart.cs b/Service/Application.Domain/Timer/JobStart.cs similarity index 96% rename from Service/Application.Web/Plug/Timer/JobStart.cs rename to Service/Application.Domain/Timer/JobStart.cs index 8be7cd5..da2fb3a 100644 --- a/Service/Application.Web/Plug/Timer/JobStart.cs +++ b/Service/Application.Domain/Timer/JobStart.cs @@ -1,7 +1,8 @@ -using Quartz; +using Photon.Core.Timer; +using Quartz; using Quartz.Spi; -namespace Application.Web; +namespace Application.Domain; public class JobStart: ITimerAutoStart { private readonly ISchedulerFactory _schedulerFactory; diff --git a/Service/Application.Web/Plug/Timer/TimerJobManager.cs b/Service/Application.Domain/Timer/TimerJobManager.cs similarity index 94% rename from Service/Application.Web/Plug/Timer/TimerJobManager.cs rename to Service/Application.Domain/Timer/TimerJobManager.cs index a301aab..a275a20 100644 --- a/Service/Application.Web/Plug/Timer/TimerJobManager.cs +++ b/Service/Application.Domain/Timer/TimerJobManager.cs @@ -1,6 +1,7 @@ -using Quartz; +using Photon.Core.Timer; +using Quartz; -namespace Application.Web; +namespace Application.Domain; public class TimerJobManager : ITimerJobManager { @@ -33,7 +34,7 @@ public class TimerJobManager : ITimerJobManager await _scheduler.Start(); } } - + public async Task PauseTask(string jobId) { await _scheduler.PauseJob(new JobKey(jobId, "default")); diff --git a/Service/Application.Web/Common/AppBackgroundService.cs b/Service/Application.Web/Common/AppBackgroundService.cs new file mode 100644 index 0000000..ca81019 --- /dev/null +++ b/Service/Application.Web/Common/AppBackgroundService.cs @@ -0,0 +1,25 @@ +namespace Application.Web; + +public class AppBackgroundService:BackgroundService +{ + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + Console.WriteLine("应用启动完成,开始执行初始化后台任务"); + + // ========== 你要执行的启动方法写在这里 ========== + var jobService = App.GetService(); + await jobService.StartJob(); + // ========================================== + Console.WriteLine("启动初始化任务执行完成"); + + // 如果只需要执行一次,直接退出;如果是常驻定时任务就写while循环 + return; + } + catch (Exception ex) + { + Console.WriteLine("启动后台任务执行异常"); + } + } +} \ No newline at end of file diff --git a/Service/Application.Web/Controllers/Map/MapController.cs b/Service/Application.Web/Controllers/Map/MapController.cs index 3b35e4e..161bbc5 100644 --- a/Service/Application.Web/Controllers/Map/MapController.cs +++ b/Service/Application.Web/Controllers/Map/MapController.cs @@ -23,11 +23,13 @@ public class MapController : ControllerBase private readonly IGameTeamService _teamService; private readonly IGameMonsterService _monsterService; private readonly IGameFightService _fightService; + private readonly IOnHookService _hookService; public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService, IUnitUserAttrService attrService, IMessageService messageService, IUnitUserWeight weightService, IUnitUserAccService accService, IGameSkillService skillService, IGameGoodsService goodsService, - IGameTeamService teamService, IGameMonsterService monsterService, IGameFightService fightService) + IGameTeamService teamService, IGameMonsterService monsterService, IGameFightService fightService, + IOnHookService hookService) { _userService = userService; _mapService = mapService; @@ -41,6 +43,7 @@ public class MapController : ControllerBase _teamService = teamService; _monsterService = monsterService; _fightService = fightService; + _hookService = hookService; } #region 地图相关 @@ -150,6 +153,10 @@ public class MapController : ControllerBase var mapGoods = await _fightService.GetMapFightGoods(mapInfo.mapId); mapGoods = mapGoods.FindAll(it => it.userId == "0" || it.userId == userId).Take(3).ToList(); + int isHook = 0; //挂机处理 + var onHook = await _hookService.GetUserOnHook(userId); + isHook = (int)onHook.status; + object ret = new { mapInfo, @@ -165,9 +172,11 @@ public class MapController : ControllerBase broadcast, monster = monsterData, fightId, - gameTips + gameTips, + isHook }; + return PoAction.Ok(ret); } diff --git a/Service/Application.Web/Controllers/Pub/FightController.cs b/Service/Application.Web/Controllers/Pub/FightController.cs index bd2054f..4020489 100644 --- a/Service/Application.Web/Controllers/Pub/FightController.cs +++ b/Service/Application.Web/Controllers/Pub/FightController.cs @@ -18,10 +18,11 @@ public class FightController : ControllerBase private readonly IUnitUserAccService _accService; private readonly IGameGoodsService _goodsService; private readonly IUnitUserService _userService; + private readonly IOnHookService _hookService; public FightController(IGameFightService fightService, IGameMonsterService monsterService, IUnitUserAttrService attrService, IGameMapService mapService, IUnitUserAccService accService, - IGameGoodsService goodsService, IUnitUserService userService) + IGameGoodsService goodsService, IUnitUserService userService,IOnHookService hookService) { _fightService = fightService; _monsterService = monsterService; @@ -30,6 +31,7 @@ public class FightController : ControllerBase _accService = accService; _goodsService = goodsService; _userService = userService; + _hookService = hookService; } /// @@ -99,6 +101,7 @@ public class FightController : ControllerBase copper, petExp, award, pars); if (result) { + await _hookService.StopOnHook(userId); return PoAction.Ok(fightId); } else @@ -398,8 +401,6 @@ public class FightController : ControllerBase public async Task GetFightMsg(string fightId) { string userId = StateHelper.userId; - var myFight = await _fightService.GetUserFight(userId); - var fight = await _fightService.GetFightInfo(fightId); if (fight == null) { @@ -430,6 +431,7 @@ public class FightController : ControllerBase isWin = 2; } + int isCopy = 0; string otName = string.Empty; if (isWin == 0) { @@ -455,6 +457,7 @@ public class FightController : ControllerBase { var monsterInfo = await _monsterService.GetMonsterInfo(fight.mainId); otName = monsterInfo.name; + isCopy = (int)monsterInfo.isCopy; } } else @@ -474,6 +477,104 @@ public class FightController : ControllerBase var myAttr = await _attrService.GetUserAttrModel(userId, fight.scene); - return PoAction.Ok(new { isWin, otName, blood = myAttr.blood, upBlood = myAttr.upBlood, fight }); + return PoAction.Ok(new { isWin, otName, blood = myAttr.blood, upBlood = myAttr.upBlood, fight, isCopy }); } + + #region 挂机相关 + + /// + /// 个人挂机信息 + /// + /// + [HttpGet] + public async Task GetUserHook() + { + string userId = StateHelper.userId; + var onHook = await _hookService.GetUserOnHook(userId); + decimal expAdd = 0; + decimal copperAdd = 0; + if (onHook.status == 1) + { + var myAttr = await _attrService.GetUserAttrModel(userId, onHook.scene); + expAdd = myAttr.addExp; + copperAdd = myAttr.addGold; + onHook.exp = Convert.ToInt32(onHook.exp * (1.0M + expAdd)); + onHook.copper = Convert.ToInt32(onHook.copper * (1.0M + copperAdd)); + } + + return PoAction.Ok(new { data = onHook, expAdd, copperAdd }); + } + + /// + /// 挂机 + /// + /// + /// + [HttpGet] + public async Task OnHook(string fightId) + { + string userId = StateHelper.userId; + var fight = await _fightService.GetFightInfo(fightId); + if (fight == null) + { + return PoAction.Message("战斗不存在!"); + } + + if (fight.userId != userId) + { + return PoAction.Message("战斗不存在!"); + } + + if (fight.code != nameof(GameEnum.FightCode.PVE)) + { + return PoAction.Message("该战斗不可复刻挂机!"); + } + + var monster = await _monsterService.GetMonsterInfo(fight.mainId); + if (monster == null) + { + return PoAction.Message("该战斗不可复刻挂机!"); + } + + if (monster.isCopy == 0) + { + return PoAction.Message("该战斗不可复刻挂机!"); + } + + var myAttr = await _attrService.GetUserAttrModel(userId, fight.scene); + int diffTime = Convert.ToInt32(fight.okTime - fight.addTime); + decimal score = myAttr.score * 0.7M; + bool result = await _hookService.StartOnHook(userId, fight.scene, (long)monster.copper, (long)monster.exp, + monster.name, + monster.award, score, diffTime, 6); + if (result) + { + return PoAction.Ok("挂机成功!"); + } + else + { + return PoAction.Message("挂机失败,请稍后尝试!"); + } + } + + /// + /// 结束挂机 + /// + /// + [HttpGet] + public async Task StopOnHook() + { + string userId = StateHelper.userId; + bool result = await _hookService.StopOnHook(userId); + if (result) + { + return PoAction.Ok(true); + } + else + { + return PoAction.Message("操作失败,请稍后尝试!"); + } + } + + #endregion } \ No newline at end of file diff --git a/Service/Application.Web/Controllers/User/UserController.cs b/Service/Application.Web/Controllers/User/UserController.cs index e1874d0..151d512 100644 --- a/Service/Application.Web/Controllers/User/UserController.cs +++ b/Service/Application.Web/Controllers/User/UserController.cs @@ -130,6 +130,21 @@ public class UserController : ControllerBase return PoAction.Ok(model); } + /// + /// 获取个人特性 + /// + /// + [HttpGet] + public async Task GetUserBaseAttrData() + { + string userId = StateHelper.userId; + var model = await _attrService.GetUserAttrModel(userId); + + var unitExp = await _attrService.GetUserStateDataTotal(userId, nameof(MapEnum.MapCode.DEF_MAP)); + var dupExp = await _attrService.GetUserStateDataTotal(userId, nameof(MapEnum.MapCode.Dup_Map)); + return PoAction.Ok(new { data = model, unitExp, dupExp }); + } + /// /// 获取用户资料 /// @@ -405,7 +420,7 @@ public class UserController : ControllerBase temp.id = StringAssist.NewGuid; temp.goodsId = goodsId; temp.name = myGoods.goodsName; - temp.code =Convert.ToString(_drugConfig.cls); + temp.code = Convert.ToString(_drugConfig.cls); temp.count = count; myDrug.drug.Add(temp); } diff --git a/Service/Application.Web/Plug/Timer/AutoJob.cs b/Service/Application.Web/Plug/Timer/AutoJob.cs deleted file mode 100644 index 2fdfca2..0000000 --- a/Service/Application.Web/Plug/Timer/AutoJob.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Quartz; -namespace Application.Web; - -public class AutoJob: ITimerAutoJob -{ - public async Task Execute(IJobExecutionContext context) - { - string jobId = context.JobDetail.Key.Name; - if (jobId == "DayHandle") - { - - ////处理日红包 - //await businessService.HandleRedPack(); - //Console.WriteLine($"{DateTime.Now.ToString("yyyy-MMMM-dd")}:红包奖金池已处理!"); - - } - else - { - Console.WriteLine("定时程序测试执行"); - } - } -} \ No newline at end of file diff --git a/Service/Application.Web/Program.cs b/Service/Application.Web/Program.cs index 050b8c4..df53e11 100644 --- a/Service/Application.Web/Program.cs +++ b/Service/Application.Web/Program.cs @@ -1,5 +1,6 @@ using Microsoft.OpenApi.Models; using Photon.Core.Redis; +using Photon.Core.Timer; var builder = WebApplication.CreateBuilder(args); @@ -45,14 +46,19 @@ builder.Services.InjectJwt(builder.Configuration, new OpenApiInfo }, groups); #endregion - -//定时功能 -builder.Services.InjectTimer(services => +//自动程序 +string autoConfig = builder.Configuration["AutoProgram"]!; +if (autoConfig == "1") { - services.AddTransient();//注册管理器 - services.AddSingleton(); - services.AddHostedService(); -}); + //定时功能 + builder.Services.InjectTimer(services => + { + services.AddTransient();//注册管理器 + services.AddSingleton(); + }); + builder.Services.AddHostedService(); +} + //日志 builder.Logging.InjectLog(); diff --git a/Service/Application.Web/applicationsettings.json b/Service/Application.Web/applicationsettings.json index 87b360a..768baea 100644 --- a/Service/Application.Web/applicationsettings.json +++ b/Service/Application.Web/applicationsettings.json @@ -1,5 +1,5 @@ { - "AutoProgram": 0, + "AutoProgram": 1, "Redis": { "connection": "127.0.0.1:6379,password=,defaultdatabase=5" }, diff --git a/Web/public/images/site/dup.gif b/Web/public/images/site/dup.gif new file mode 100644 index 0000000000000000000000000000000000000000..f72290624291255adb1d4a5b841607344c166967 GIT binary patch literal 2690 zcmbVNc~}$o7M&4LQ4kPRsOTF9FbH905<)fs69Py;5P`bAY6(e{RFhy54T2g?f`l~+ zs1&8LLkNmmMXNC^jOJ-siJy{olZNu@q5Dtfh-m`qrpR7MT_v_0~-k)r2TNgRGBP2vOV@5ZXR*NA00fCoSTReNy|C_IG zXJFtGcgGvPlvR`oevmW6&u=H4K0u@0(&_qX^luS_3PI-r0}r9-o)W`cgt&cew7<9a zGdiuGPBZoQT#u3roLkn@*IV9U+OgH}=k2b0&wDzzA-^luo37=sAn1BWN@qXUc)Zip z5p4Pp-qZW?^?>O_Yx~ZYuCi0_t{{i1e|>zgsq<2G$cZw$H`~tl7+W=q78~`Mk65h7 z%|MxWg97oo`09?S3%E(AAHuLimPgR6Stbt0WHL=Njg1P4i{-GRL&ykb0RjMkA1#cG zhJtwt9{%e;D>;eBUm;XL3Bu(fNdWx(*a;XC2?F2+evw#Y5=WRQ3QLg*V^gBy_$e#+ z3;{eV5b{rECX18ALIn>>7O#}ZnaKe#PasVYGVyEkF$zP2A&M0NFx&h9GIMgIG9g4m zFdsgKVGxah2zUuRenJ8fB4cC{icwG!#RtQfz6>UX0)6_xIGs$ej2ROg`iTs`3xE?9 ziX5E8Z%TW@8!9X!GN+$c@5kB&@5(O{WMe;jIjo@>h$65(PIn0LGsn0+E18!)O?ZP9^&Y zX>^_sg-)UP@JPNiA09^L2}lXccyxi^5YCtKL;dI&mBirCgE*liQV56POQo}eC~Pd) zkK%{XqOB``hJT|8wc$h4bfrIeX^xskW1?EzM0QjyL{%?C4KN4mTV+_~U{7 z`|9`ZsWa9ZYO1R$E6U4COLqTIylZFC_k}yQZ!5^p+qy-co0FZDnW0PHoTk;NH*HjH zSidecWo@!@&1!{Qwkk;~5wBeFohWhnGNFKEKO>5^~$y?D{W1@pg-i;bBVJvSbPsnocpCJtsZ(4hf92vl zY2pMY$MFvKcH?Yq#*VQbJ!+(trNs#Rbu;a)r4<0E03!b8!T%Cm0AQ49;|8@xo3>dS z5S|$x78aMAt=ETz$7L3T2UyPBRs6&5l3kVxi`ZC;%Bsqm>S~Kfze!+?qN3*Tk(zyL z7LO6FT;z9<&1vJLoJlz~X51nSl(X1nVL9M@x$ASXg!#46YJx{Kd zvcT2{V|LLgWgFMNi04?sch72Ec2CW8nm%WI#funt#JhpM*R4C?G>dfDVOeSK-osD;;q1ISuRH{+cegmOiZKF{(>>)%% z>}krfGuX8@H@VI^eVV*=)88{>30MFV@GmfGwwWVVvpHR-W@luls2PmxJOf|12#g;C{I)is9N45k6q$g1Ib9YJ-lwxMdWI>Km-Khbg`MmG!_#Ic=$i8yu; zjvX7TR#|M$$jr*l$yKo#`h2wqw?NP3f`vItiN*Q2{>njYqYBO;5DX|GqOLB!(yqZk zK2{T&Jq#AWZJ9J^OE?az(Xh4YIt{2MX5^-Odg}92v-0(+8hiU4=CLm=%XcjCDuY!@ zwN069j~XVZ(I3lIZiaH(!?|{iO-*x}$mHfznqlxG083o61FkyE46jn)@M?w%1T*wn zuIH8lB7zVLG5{5KX;FrKx~!zK$iE7AUCpdB*wm{lR0LFexXMjqYn-f!P&FT@jUR4_ z*>0ynOYoLjsPL6d$6LA?%*ypdax*EEy!2F}=k`3Co!&cf?d26($L%PpRiet0VwIAx zS4-Gw>!yt;wN*`4H8xh3#J5(sR=S=kClBYaz&R!k`h&L==TOC_;T&e$bGe@S90URL zGXRiVn3Gzp^DoKrn_aGDR@WLcl!m$z7*12V>Ch5e?NJq>{O5hmEw!$hn}C^r0oRlv AG5`Po literal 0 HcmV?d00001 diff --git a/Web/src/app.vue b/Web/src/app.vue index 1308f2e..c24b179 100644 --- a/Web/src/app.vue +++ b/Web/src/app.vue @@ -57,6 +57,6 @@ onMounted(() => { /* 全局样式已移至 src/assets/css/style.css */ :root { - --van-base-font: initial !important; + --van-base-font: initial !important; } diff --git a/Web/src/assets/css/style.css b/Web/src/assets/css/style.css index 5f7ee99..9cfacc4 100644 --- a/Web/src/assets/css/style.css +++ b/Web/src/assets/css/style.css @@ -143,9 +143,10 @@ a:focus { } .search-ipt { - width: 80px; - font-size: 11px; + width: 80px; padding: 0; + font:caption; + font-size: 16px; } .ipt-btn { @@ -351,4 +352,12 @@ a:focus { .equ_glod { color: #e6b020; +} +.dup { + background-image: url(/images/site/dup.gif); + background-repeat: no-repeat; + display: inline-block; + width: 18px; + height: 18px; + background-size: 18px; } \ No newline at end of file diff --git a/Web/src/components/Page/Footer.vue b/Web/src/components/Page/Footer.vue index 886a951..22ffc3a 100644 --- a/Web/src/components/Page/Footer.vue +++ b/Web/src/components/Page/Footer.vue @@ -3,7 +3,7 @@
首页- - 挂机- + 挂机- 反馈
diff --git a/Web/src/config/BaseConfig.ts b/Web/src/config/BaseConfig.ts index 8f881cf..a0b3de6 100644 --- a/Web/src/config/BaseConfig.ts +++ b/Web/src/config/BaseConfig.ts @@ -2,8 +2,8 @@ 统一配置中心 */ export class BaseConfig { - public static BaseUrl: string = 'https://localhost:7198' - public static BaseMediaUrl: string = 'https://localhost:7198/' - // public static BaseUrl:string="http://kx.iyba.cn:5291"; - // public static BaseMediaUrl:string="http://kx.iyba.cn:5291"; + // public static BaseUrl: string = 'https://localhost:7198' + // public static BaseMediaUrl: string = 'https://localhost:7198/' + public static BaseUrl:string="http://kx.iyba.cn:5291"; + public static BaseMediaUrl:string="http://kx.iyba.cn:5291"; } diff --git a/Web/src/pages/fight/result.vue b/Web/src/pages/fight/result.vue index ffd8e6d..59d036f 100644 --- a/Web/src/pages/fight/result.vue +++ b/Web/src/pages/fight/result.vue @@ -8,6 +8,9 @@
继续
+
+ [立即挂机] +
你体力:{{ blood }}/{{ upBlood }}
@@ -38,6 +41,7 @@ const blood = ref(0); const upBlood = ref(0); const fight = ref({}); const AwardTips = ref(''); +const isCopy = ref(0); let fightId = PageExtend.QueryString("f"); onMounted(async () => { @@ -57,6 +61,7 @@ const BindData = async (): Promise => { blood.value = result.data.blood; upBlood.value = result.data.upBlood; fight.value = result.data.fight; + isCopy.value = result.data.isCopy; if (fight.value.award != '') { AwardTips.value = awardTipsStr(JSON.parse(fight.value.award)) } @@ -89,4 +94,18 @@ const awardTipsStr = (data: any) => { return result; } +/**挂机 */ +const onHook = async () => { + MessageExtend.LoadingToast("正在进行挂机..."); + let result = await FightService.OnHook(fightId); + MessageExtend.LoadingClose(); + if (result.code == 0) { + isCopy.value = 0; + MessageExtend.Notify("挂机成功!", "success"); + } + else { + MessageExtend.Notify(result.msg, "danger"); + } +} + \ No newline at end of file diff --git a/Web/src/pages/map/index.vue b/Web/src/pages/map/index.vue index 73c551b..d58d2a0 100644 --- a/Web/src/pages/map/index.vue +++ b/Web/src/pages/map/index.vue @@ -1,5 +1,11 @@