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 @@