This commit is contained in:
Putoo
2026-07-16 17:52:33 +08:00
parent 2cd2ed02f8
commit 00c2758df2
43 changed files with 897 additions and 72 deletions

View File

@@ -0,0 +1,39 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Game")]
public class game_magic
{
/// <summary>
/// userId
/// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string userId { get; set; }
/// <summary>
/// areaId
/// </summary>
[SugarColumn(IsNullable = true)]
public int? areaId { get; set; }
/// <summary>
/// time
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? time { get; set; }
/// <summary>
/// isWin
/// </summary>
[SugarColumn(IsNullable = true)]
public int? isWin { get; set; }
/// <summary>
/// uptime
/// </summary>
[SugarColumn(IsNullable = true)]
public long? uptime { get; set; }
}
}

View File

@@ -39,8 +39,8 @@ namespace Application.Domain.Entity
/// <summary> /// <summary>
/// attr /// attr
/// </summary> /// </summary>
[SugarColumn(Length = 1000, IsNullable = true)] [SugarColumn(IsNullable = true, IsJson = true)]
public string attr { get; set; } public List<AttrItem> attr { get; set; }
/// <summary> /// <summary>
/// count /// count

View File

@@ -5,4 +5,5 @@ public class NpcBus
public string code { get; set; } public string code { get; set; }
public string name { get; set; } public string name { get; set; }
public string url { get; set; } public string url { get; set; }
public string parms { get; set; }
} }

View File

@@ -0,0 +1,8 @@
namespace Application.Domain.Entity;
public class RankAwardModel
{
public int min { get; set; }
public int max { get; set; }
public List<TowerGet> award { get; set; }
}

View File

@@ -0,0 +1,51 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Resource")]
public class game_cdk
{
/// <summary>
/// cdkId
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public int cdkId { get; set; }
/// <summary>
/// area
/// </summary>
[SugarColumn(IsNullable = true)]
public int? area { get; set; }
/// <summary>
/// cdkName
/// </summary>
[SugarColumn(Length = 255, IsNullable = true)]
public string? cdkName { get; set; }
/// <summary>
/// award
/// </summary>
[SugarColumn(IsNullable = true,IsJson = true)]
public List<TowerGet> award { get; set; }
/// <summary>
/// limit
/// </summary>
[SugarColumn(IsNullable = true)]
public int? limit { get; set; }
/// <summary>
/// addTime
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime? addTime { get; set; }
/// <summary>
/// endTime
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime? endTime { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Resource")]
public class game_cdk_item
{
/// <summary>
/// ciId
/// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string ciId { get; set; }
/// <summary>
/// cdkId
/// </summary>
[SugarColumn(IsNullable = true)]
public int? cdkId { get; set; }
/// <summary>
/// userId
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? userId { get; set; }
/// <summary>
/// upTime
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime? upTime { get; set; }
}
}

View File

@@ -27,8 +27,8 @@ namespace Application.Domain.Entity
/// <summary> /// <summary>
/// attr /// attr
/// </summary> /// </summary>
[SugarColumn(Length = 1000, IsNullable = true)] [SugarColumn(IsNullable = true, IsJson = true)]
public string attr { get; set; } public List<AttrItem> attr { get; set; }
/// <summary> /// <summary>
/// remark /// remark

View File

@@ -22,6 +22,7 @@ namespace Application.Domain
HandelTaskUser,//处理角色任务 HandelTaskUser,//处理角色任务
HandleClearChat,//清理频道信息 HandleClearChat,//清理频道信息
HandleMessageData,//处理消息类 HandleMessageData,//处理消息类
HandleMagicData,//处理魔城争霸赛
} }
} }

View File

@@ -122,5 +122,11 @@
var messageService = App.GetService<IMessageService>(); var messageService = App.GetService<IMessageService>();
await messageService.HandleMessageData(); await messageService.HandleMessageData();
} }
[EventSubscribe(BusEventsEnum.BusEventsName.HandleMagicData, NumRetries = 0,RetryTimeout = 999999999)]
public async Task HandleMagicData(EventHandlerExecutingContext context)
{
var magicService = App.GetService<IGameMagicService>();
await magicService.HandleMagicData();
}
} }
} }

View File

@@ -20,4 +20,6 @@ public static class GameConfig
public const int GameEquApprGoods = 10019;//鉴定装备道具 public const int GameEquApprGoods = 10019;//鉴定装备道具
public const int GameGetTaskGoods =10034 ;//引路蜂 public const int GameGetTaskGoods =10034 ;//引路蜂
public const int GameRetTaskGoods =10033 ;//领路蝶 public const int GameRetTaskGoods =10033 ;//领路蝶
public const string GameMagicMapId = "257_18";//魔城地图ID
public const string GameMagicInMapId = "260_15";//魔城进入地图ID
} }

View File

@@ -19,6 +19,7 @@ public static class GameEnum
UpdateTaskUser,//更新角色任务 UpdateTaskUser,//更新角色任务
ClearChat,//清理频道信息 ClearChat,//清理频道信息
ClearMessage,//清理个人消息信息 ClearMessage,//清理个人消息信息
UpdateMagicData,//处理魔城数据
} }
public enum PropCode//游戏资源编码 public enum PropCode//游戏资源编码
{ {
@@ -84,6 +85,8 @@ public static class GameEnum
{ {
Awaken,//觉醒配置 Awaken,//觉醒配置
Quality,//洗练配置 Quality,//洗练配置
MagicAward,//魔城奖励
} }
public enum ComputeType public enum ComputeType
{ {

View File

@@ -14,14 +14,18 @@ public class MapEnum
public enum MapCode public enum MapCode
{ {
DEF_MAP, DEF_MAP,
Dup_Map Dup_Map,
Magic_Map,
} }
public enum NpcCode public enum NpcCode
{ {
Default, Default,
Task, Task,
Dup_In, Event,
Dup_Exit }
public enum NpcEventCode
{
Magic_Event,
} }
} }

View File

@@ -0,0 +1,14 @@
namespace Application.Domain;
public interface IGameCdkService
{
Task<game_cdk> GetCdkInfo(int cdkId);
Task<game_cdk_item> GetCdkItemInfo(string cdk);
Task<bool> UpdateCdkUser(string cdk, string userId);
Task<int> GetUserCdkCount(int cdkId, string userId);
Task<bool> AddCdkItem(List<game_cdk_item> data);
}

View File

@@ -0,0 +1,9 @@
namespace Application.Domain;
public interface IGameMagicService
{
Task UpdateUserMagicTime(string userId,int areaId);
Task UpdateUserMagicEndTime(string userId, bool isWin);
Task<bool> CheckInMagic(string userId);
Task HandleMagicData();
}

View File

@@ -21,7 +21,7 @@ public interface IGameMapService
Task<string> GetUserOnMapId(string userId); Task<string> GetUserOnMapId(string userId);
Task<game_city_map> GetUserOnToMapInfo(string userId); Task<game_city_map> GetUserOnToMapInfo(string userId);
Task<unit_user_online> GetUserOnMap(string userId); Task<unit_user_online> GetUserOnMap(string userId);
Task UpdateUserOnMap(string userId); Task UpdateUserOnMap(string userId, string mapId = "");
Task UpdateUserOnMap(string userId, string ip, string mapId); Task UpdateUserOnMap(string userId, string ip, string mapId);
Task<bool> UpdateUserOnMap(unit_user_online data, string mapId); Task<bool> UpdateUserOnMap(unit_user_online data, string mapId);
Task<UserOnMap> GetUserOnMapInfo(string userId); Task<UserOnMap> GetUserOnMapInfo(string userId);
@@ -34,6 +34,8 @@ public interface IGameMapService
#region #region
Task<List<UserModel>> GetMapUserByAll(string mapId, int area, int showArea, List<string> noUser);
Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser);
Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int take); Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int take);
Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int page, Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int page,

View File

@@ -3,4 +3,5 @@
public interface IGameDicService public interface IGameDicService
{ {
Task<game_dic> GetDicInfo(string code); Task<game_dic> GetDicInfo(string code);
Task<string> GetDicInfoContent(string code);
} }

View File

@@ -2,9 +2,19 @@
public interface IGameMaxNameService public interface IGameMaxNameService
{ {
#region
Task<game_maxname> GetMaxNameInfo(string mnId);
#endregion
#region unit_user_maxname #region unit_user_maxname
Task<bool> AddMaxName(string userId, string mnId, int addCount);
Task<bool> UpdateUserMaxname(unit_user_maxname name); Task<bool> UpdateUserMaxname(unit_user_maxname name);
Task<unit_user_maxname> GetUserMaxnameInfo(string umnId); Task<unit_user_maxname> GetUserMaxnameInfo(string umnId);
Task<List<unit_user_maxname>> GetUserMaxnameList(string userId, int page, int limit, RefAsync<int> total); Task<List<unit_user_maxname>> GetUserMaxnameList(string userId, int page, int limit, RefAsync<int> total);
Task<List<unit_user_maxname>> GetUserMaxNameData(string userId);
#endregion #endregion
} }

View File

@@ -50,7 +50,7 @@ public interface IMessageService
#region 广 #region 广
Task<List<game_broadcast>> GetBroadcastData(int area); Task<List<game_broadcast>> GetBroadcastData(int area);
Task<bool> SendBroadcast(string userId, string code, string msg); Task<bool> SendBroadcast(string userId, string code, string msg, int area = 0);
#endregion #endregion

View File

@@ -0,0 +1,36 @@
namespace Application.Domain;
public class GameCdkService(ISqlSugarClient DbClient, IRedisCache redis) : IGameCdkService, ITransient
{
public async Task<game_cdk> GetCdkInfo(int cdkId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_cdk>();
return await db.Queryable<game_cdk>().Where(it => it.cdkId == cdkId).SingleAsync();
}
public async Task<game_cdk_item> GetCdkItemInfo(string cdk)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_cdk_item>();
return await db.Queryable<game_cdk_item>().Where(it => it.ciId == cdk).SingleAsync();
}
public async Task<bool> UpdateCdkUser(string cdk, string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_cdk_item>();
return await db.Updateable<game_cdk_item>().SetColumns(it => it.userId == userId)
.SetColumns(it => it.upTime == DateTime.Now)
.Where(it => it.ciId == cdk).ExecuteCommandAsync() > 0;
}
public async Task<int> GetUserCdkCount(int cdkId, string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_cdk_item>();
return await db.Queryable<game_cdk_item>().Where(it => it.cdkId == cdkId && it.userId == userId).CountAsync();
}
public async Task<bool> AddCdkItem(List<game_cdk_item> data)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_cdk_item>();
return await db.Insertable(data).ExecuteCommandAsync() > 0;
}
}

View File

@@ -0,0 +1,138 @@
using Newtonsoft.Json;
namespace Application.Domain;
public class GameMagicService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMagicService, ITransient
{
public async Task UpdateUserMagicTime(string userId, int areaId)
{
string time = TimeAssist.GetDateTimeYMDString(0);
long upTime = TimeExtend.GetTimeStampMilliseconds;
game_magic data = new game_magic()
{
userId = userId,
areaId = areaId,
time = time,
isWin = 0,
uptime = upTime
};
var db = DbClient.AsTenant().GetConnectionWithAttr<game_magic>();
await db.Storageable(data).ExecuteCommandAsync();
}
public async Task UpdateUserMagicEndTime(string userId, bool isWin)
{
long upTime = TimeExtend.GetTimeStampMilliseconds;
if (isWin)
{
upTime = TimeExtend.GetTimeStampByMilliseconds(TimeAssist.GetDateTimeYMD(7));
}
var db = DbClient.AsTenant().GetConnectionWithAttr<game_magic>();
await db.Updateable<game_magic>().SetColumns(it => it.uptime == upTime)
.SetColumns(it => it.isWin == (isWin ? 1 : 0))
.Where(it => it.userId == userId)
.ExecuteCommandAsync();
}
public async Task<bool> CheckInMagic(string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_magic>();
var myInfo = await db.Queryable<game_magic>().Where(it => it.userId == userId).SingleAsync();
if (myInfo == null)
{
return true;
}
if (myInfo.isWin == 0)
{
return true;
}
long time = TimeExtend.GetTimeStampMilliseconds;
if (myInfo.uptime < time)
{
return true;
}
return false;
}
public async Task HandleMagicData()
{
List<RankAwardModel> magicAward = new List<RankAwardModel>();
var mapService = App.GetService<IGameMapService>();
var userService = App.GetService<IUnitUserService>();
var areaService = App.GetService<IAreaService>();
var dicService = App.GetService<IGameDicService>();
var messageService = App.GetService<IMessageService>();
string time = TimeAssist.GetDateTimeYMDString(0);
var dicData = await dicService.GetDicInfoContent(nameof(GameEnum.DicCode.MagicAward));
if (!string.IsNullOrEmpty(dicData))
{
magicAward = JsonConvert.DeserializeObject<List<RankAwardModel>>(dicData);
}
var areaData = await areaService.GetAreaData();
foreach (var area in areaData)
{
//清退处理
var users = await mapService.GetMapUserByAll(GameConfig.GameMagicMapId, area.areaId, 1, []);
if (users.Count > 0)
{
for (int i = 1; i <= users.Count; i++)
{
string userId = users[i - 1].userId;
bool isWin = false;
if (i == users.Count)
{
isWin = true;
}
await UpdateUserMagicEndTime(userId, isWin);
await mapService.UpdateUserOnMap(userId, GameConfig.GameMagicInMapId);
}
}
//发放奖励
if (magicAward.Count > 0)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_magic>();
var userData = await db.Queryable<game_magic>().Where(it => it.areaId == area.areaId && it.time == time)
.OrderByDescending(it => it
.isWin).OrderByDescending(it => it.uptime).ToListAsync();
if (userData.Any(it => it.isWin == 1))
{
string msg = "魔城争霸赛已结束,前三名分别是:";
int rank = 1;
foreach (var user in userData)
{
var onAward = magicAward.Find(it => it.min <= rank && it.max >= rank);
if (onAward != null)
{
string mailContent = $"恭喜您获得魔城争霸赛第【{rank}】名奖励,再接再厉噢!";
await messageService.SendMaill(user.userId, "魔城争霸赛奖励发放通知", mailContent, onAward.award);
if (rank <= 3)
{
var userInfo = await userService.GetUserInfoByUserId(user.userId);
msg += $"{UbbTool.HomeUbb(userInfo.userNo, userInfo.nick)}、";
}
rank++;
}
else
{
break;
}
}
msg = msg.TrimEnd('、');
await messageService.SendBroadcast("0", nameof(MessageEnum.BroadcastCode.System), msg, area.areaId);
}
}
}
}
}

View File

@@ -233,6 +233,7 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
{ {
await UserStateTool.SetUserMapDefault(lowUser); await UserStateTool.SetUserMapDefault(lowUser);
} }
//战败后,结束挂机 //战败后,结束挂机
var hookService = App.GetService<IOnHookService>(); var hookService = App.GetService<IOnHookService>();
await hookService.StopOnHook(lowUser); await hookService.StopOnHook(lowUser);
@@ -427,7 +428,7 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
string noticeMsg = string noticeMsg =
$"您在{cityInfo.cityName}·{mapInfo.mapName}被[{UbbTool.HomeUbb(winUserInfo.userNo, winUserInfo.nick)}]击杀!"; $"您在{cityInfo.cityName}·{mapInfo.mapName}被[{UbbTool.HomeUbb(winUserInfo.userNo, winUserInfo.nick)}]击杀!";
await chatService.SendChat(lowUser, (int)lowUserInfo.areaId, nameof(GameChatEnum.Code.Notice), noticeMsg); await chatService.SendChat(lowUser, (int)lowUserInfo.areaId, nameof(GameChatEnum.Code.Notice), noticeMsg);
if (mapInfo.isPk == 1 && fightData.userId == winUser) if (mapInfo.isPk == 1 && fightData.userId == winUser && fightData.scene == nameof(MapEnum.MapCode.DEF_MAP))
{ {
var relationService = App.GetService<IUnitUserRelationService>(); var relationService = App.GetService<IUnitUserRelationService>();
if (await relationService.CheckUserEnemy(winUser, lowUser) == false) if (await relationService.CheckUserEnemy(winUser, lowUser) == false)
@@ -436,6 +437,16 @@ public class GameFightService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
await accService.UpdateUserData(winUser, 1, nameof(AccEnum.AccType.enemy), 5, "击杀玩家"); //加罪恶 await accService.UpdateUserData(winUser, 1, nameof(AccEnum.AccType.enemy), 5, "击杀玩家"); //加罪恶
} }
} }
#region
if (fightData.scene == nameof(MapEnum.MapCode.Magic_Map)) //魔城
{
var magicService = App.GetService<IGameMagicService>();
await magicService.UpdateUserMagicEndTime(lowUser, false);
}
#endregion
} }
#endregion #endregion

View File

@@ -218,9 +218,14 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
}; };
} }
public async Task UpdateUserOnMap(string userId) public async Task UpdateUserOnMap(string userId, string mapId = "")
{ {
unit_user_online onLine = await GetUserOnMap(userId); unit_user_online onLine = await GetUserOnMap(userId);
if (!string.IsNullOrEmpty(mapId))
{
onLine.mapId = mapId;
}
onLine.upTime = TimeExtend.GetTimeStampSeconds; onLine.upTime = TimeExtend.GetTimeStampSeconds;
string key = string.Format(UserCache.BaseCacheKey, "UserOnline"); string key = string.Format(UserCache.BaseCacheKey, "UserOnline");
if (await redis.AddHashAsync(key, userId, onLine)) if (await redis.AddHashAsync(key, userId, onLine))
@@ -400,7 +405,28 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
#region #region
private async Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser) public async Task<List<UserModel>> GetMapUserByAll(string mapId, int area, int showArea, List<string> noUser)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
var data = await db.Queryable<unit_user_online>().Where(it => it.mapId == mapId)
.WhereIF(noUser.Count > 0, it => !noUser.Contains(it.userId))
.OrderByDescending(it => it.upTime)
.ToListAsync();
List<UserModel> result = new List<UserModel>();
data.ForEach(async it =>
{
var temp = await UserModelTool.GetUserView(it.userId);
bool isAdd = showArea == 1 && area != temp.area ? false : true;
if (isAdd)
{
result.Add(temp);
}
});
return result;
}
public async Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser)
{ {
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>(); var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
long time = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime)); long time = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime));

View File

@@ -15,5 +15,15 @@ public class GameDicService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
await redis.AddHashAsync(key, code, data); await redis.AddHashAsync(key, code, data);
return data; return data;
} }
public async Task<string> GetDicInfoContent(string code)
{
string result = string.Empty;
var data = await GetDicInfo(code);
if (data != null)
{
result = data.sign;
}
return result;
}
} }

View File

@@ -2,39 +2,127 @@
public class GameMaxNameService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMaxNameService, ITransient public class GameMaxNameService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMaxNameService, ITransient
{ {
#region
public async Task<game_maxname> GetMaxNameInfo(string mnId)
{
string key = string.Format(BaseCache.BaseCacheKey, "GameMaxName");
if (await redis.HExistsHashAsync(key, mnId))
{
return await redis.GetHashAsync<game_maxname>(key, mnId);
}
var db = DbClient.AsTenant().GetConnectionWithAttr<game_maxname>();
var data = await db.Queryable<game_maxname>().Where(i => i.mnId == mnId).SingleAsync();
if (data != null)
{
await redis.AddHashAsync(key, mnId, data);
}
return data;
}
#endregion
#region unit_user_maxname #region unit_user_maxname
public async Task<bool> AddMaxName(string userId, string mnId, int addCount)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>();
bool isok = false;
string umnId = $"{userId}_{mnId}";
var data = await GetUserMaxnameInfo(umnId);
if (data == null)
{
var mnInfo = await GetMaxNameInfo(mnId);
if (mnInfo != null)
{
unit_user_maxname mu = new unit_user_maxname();
mu.umnId = umnId;
mu.userId = userId;
mu.mnId = mnId;
mu.name = mnInfo.name;
mu.img = mnInfo.img;
mu.attr = mnInfo.attr;
mu.count = 1;
mu.addTime = DateTime.Now;
mu.endTime = DateTime.Now.AddDays(addCount);
mu.show = 0;
isok = db.Insertable(mu).ExecuteCommand() > 0;
}
}
else
{
data.count = data.count + 1;
if (data.endTime > DateTime.Now)
{
data.endTime = Convert.ToDateTime(data.endTime).AddDays(addCount);
}
else
{
data.show = 0;
data.endTime = DateTime.Now.AddDays(addCount);
}
isok = db.Updateable(data).IgnoreColumns(true, true).Where(i => i.umnId == data.umnId).ExecuteCommand() > 0;
}
if (isok)
{
await ClearUserMaxNameCache(userId);
}
return isok;
}
public async Task<bool> UpdateUserMaxname(unit_user_maxname name) public async Task<bool> UpdateUserMaxname(unit_user_maxname name)
{ {
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>(); var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>();
bool isok = await db.Updateable(name).ExecuteCommandAsync() > 0; bool isok = await db.Updateable(name).ExecuteCommandAsync() > 0;
if (isok)
{
string key = string.Format(BaseCache.BaseCacheKeys, "UserMaxname", "MaxnameInfo");
await redis.DelHashAsync(key, name.umnId);
}
return isok; return isok;
} }
public async Task<unit_user_maxname> GetUserMaxnameInfo(string umnId) public async Task<unit_user_maxname> GetUserMaxnameInfo(string umnId)
{
string key = string.Format(BaseCache.BaseCacheKeys, "UserMaxname", "MaxnameInfo");
var data = await redis.GetHashAsync<unit_user_maxname>(key, umnId);
if (data == null)
{ {
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>(); var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>();
data = await db.Queryable<unit_user_maxname>().Where(i => i.umnId == umnId).SingleAsync(); return await db.Queryable<unit_user_maxname>().Where(i => i.umnId == umnId).SingleAsync();
if (data != null)
{
await redis.AddHashAsync(key, umnId, data);
} }
}
return data; public async Task<List<unit_user_maxname>> GetUserMaxnameList(string userId, int page, int limit,
} RefAsync<int> total)
public async Task<List<unit_user_maxname>> GetUserMaxnameList(string userId, int page, int limit, RefAsync<int> total)
{ {
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>(); var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>();
return await db.Queryable<unit_user_maxname>().Where(i => i.userId == userId).OrderBy(i => i.addTime) return await db.Queryable<unit_user_maxname>().Where(i => i.userId == userId).OrderBy(i => i.addTime)
.ToPageListAsync(page, limit, total); .ToPageListAsync(page, limit, total);
} }
public async Task<List<unit_user_maxname>> GetUserMaxNameData(string userId)
{
string key = string.Format(UserCache.BaseCacheKey, "UserMaxName");
List<unit_user_maxname> data = new List<unit_user_maxname>();
if (await redis.HExistsHashAsync(key, userId))
{
data = await redis.GetHashAsync<List<unit_user_maxname>>(key, userId);
}
else
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_maxname>();
data = await db.Queryable<unit_user_maxname>().Where(i => i.userId == userId).ToListAsync();
if (data == null)
{
data = new List<unit_user_maxname>();
}
await redis.AddHashAsync(key, userId, data);
}
return data.FindAll(it=>it.endTime > DateTime.Now);
}
private async Task ClearUserMaxNameCache(string userId)
{
string key = string.Format(UserCache.BaseCacheKey, "UserMaxName");
await redis.DelHashAsync(key,userId);
}
#endregion #endregion
} }

View File

@@ -404,17 +404,16 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
return data; return data;
} }
public async Task<bool> SendBroadcast(string userId, string code, string msg) public async Task<bool> SendBroadcast(string userId, string code, string msg, int area = 0)
{ {
game_broadcast add = new game_broadcast(); game_broadcast add = new game_broadcast();
add.Id = StringAssist.NewGuid; add.Id = StringAssist.NewGuid;
add.userId = userId; add.userId = userId;
add.code = code; add.code = code;
add.msg = msg; add.msg = msg;
int area = 0;
if (add.userId == "0") if (add.userId == "0")
{ {
add.area = 0; add.area = area;
add.userNo = "0"; add.userNo = "0";
add.nick = "海精灵"; add.nick = "海精灵";
} }
@@ -425,7 +424,6 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
add.area = (int)userInfo.areaId; add.area = (int)userInfo.areaId;
add.userNo = userInfo.userNo; add.userNo = userInfo.userNo;
add.nick = userInfo.nick; add.nick = userInfo.nick;
area = add.area;
} }
add.endTime = TimeExtend.GetTimeStampSeconds + 300; add.endTime = TimeExtend.GetTimeStampSeconds + 300;

View File

@@ -83,6 +83,16 @@ public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) :
#endregion #endregion
#region
var maxNameService = App.GetService<IGameMaxNameService>();
var userMaxName = await maxNameService.GetUserMaxNameData(userId);
foreach (var maxName in userMaxName)
{
ExtendAttrData.AddRange(maxName.attr);
}
#endregion
#region Buff加层 #region Buff加层

View File

@@ -74,6 +74,11 @@ public static class GameBus
var skillService = App.GetService<IGameSkillService>(); var skillService = App.GetService<IGameSkillService>();
isok = await skillService.UpdateUserSkill(userId, Convert.ToInt32(parameter)); isok = await skillService.UpdateUserSkill(userId, Convert.ToInt32(parameter));
} }
else if (goodsType.Equals(nameof(GameEnum.PropCode.maxName)))
{
var maxNameService = App.GetService<IGameMaxNameService>();
isok = await maxNameService.AddMaxName(userId, parameter, Convert.ToInt32(count));
}
return isok; return isok;
} }

View File

@@ -19,6 +19,9 @@
<Content Update="applicationsettings.json"> <Content Update="applicationsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="applicationsettings.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -117,5 +117,11 @@ public class GameAutoJobService(ISqlSugarClient DbClient, IRedisCache redis, ITi
await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.HandleMessageData, await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.HandleMessageData,
data)); data));
} }
else if (data.code == nameof(GameEnum.JobCode.UpdateMagicData)) //处理魔城数据
{
var _eventPublisher = App.GetService<IEventPublisher>();
await _eventPublisher.PublishAsync(new ChannelEventSource(BusEventsEnum.BusEventsName.HandleMagicData,
data));
}
} }
} }

View File

@@ -52,8 +52,8 @@ namespace Application.Web.Controllers.Login
[HttpGet] [HttpGet]
public async Task<string> HandleError() public async Task<string> HandleError()
{ {
var attrService = App.GetService<IUnitUserAttrService>(); var magicService = App.GetService<IGameMagicService>();
var model = await attrService.GetUserAttrModel("32cd4777-e523-4cf9-b8f1-de13235f6170"); await magicService.HandleMagicData();
return "1"; return "1";

View File

@@ -11,10 +11,13 @@ public class MapBusController : ControllerBase
{ {
private readonly IGameMapService _mapService; private readonly IGameMapService _mapService;
private readonly IMessageService _messageService; private readonly IMessageService _messageService;
public MapBusController(IGameMapService mapService,IMessageService messageService) private readonly IGameMagicService _magicService;
public MapBusController(IGameMapService mapService, IMessageService messageService, IGameMagicService magicService)
{ {
_mapService = mapService; _mapService = mapService;
_messageService = messageService; _messageService = messageService;
_magicService = magicService;
} }
/// <summary> /// <summary>
@@ -52,6 +55,7 @@ public class MapBusController : ControllerBase
public async Task<IPoAction> MapBusTo(int id, int num) public async Task<IPoAction> MapBusTo(int id, int num)
{ {
string userId = StateHelper.userId; string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
var busData = await _mapService.GetMapBusInfo(id); var busData = await _mapService.GetMapBusInfo(id);
if (busData == null) if (busData == null)
{ {
@@ -68,17 +72,32 @@ public class MapBusController : ControllerBase
{ {
return PoAction.Message("业务不存在!"); return PoAction.Message("业务不存在!");
} }
var onMap = await _mapService.GetUserOnMapId(userId); var onMap = await _mapService.GetUserOnMapId(userId);
if (busData.busCode != onMap) if (busData.busCode != onMap)
{ {
return PoAction.Message("业务不存在!"); return PoAction.Message("业务不存在!");
} }
var mapToData = toData[num]; var mapToData = toData[num];
if (TimeAssist.GetHourNum < mapToData.sTime || TimeAssist.GetHourNum > mapToData.eTime) if (TimeAssist.GetHourNum < mapToData.sTime || TimeAssist.GetHourNum > mapToData.eTime)
{ {
return PoAction.Message($"当前时间不允许进入"); return PoAction.Message($"当前时间不允许进入");
} }
#region
if (mapToData.code == nameof(MapEnum.MapCode.Magic_Map)) //魔城场景,验证否否进入过
{
if (await _magicService.CheckInMagic(userId) == false)
{
return PoAction.Message($"您的魔城记录冷却中,冷却时间为7天!");
}
}
#endregion
var checkResult = await GameBus.CheckNeed(userId, busData.busNeed, 1); var checkResult = await GameBus.CheckNeed(userId, busData.busNeed, 1);
if (checkResult.result == false) if (checkResult.result == false)
{ {
@@ -91,6 +110,11 @@ public class MapBusController : ControllerBase
var ResultMap = await _mapService.GetToMapInfo(userId, mapToData.mapId, true, true); var ResultMap = await _mapService.GetToMapInfo(userId, mapToData.mapId, true, true);
if (ResultMap != null) if (ResultMap != null)
{ {
if (mapToData.code == nameof(MapEnum.MapCode.Magic_Map)) //魔城场景
{
await _magicService.UpdateUserMagicTime(userId,areaId);
}
return PoAction.Ok(true); return PoAction.Ok(true);
} }
else else
@@ -158,6 +182,7 @@ public class MapBusController : ControllerBase
{ {
message = "空空如也,什么也没有得到!"; message = "空空如也,什么也没有得到!";
} }
return PoAction.Ok(true, message); return PoAction.Ok(true, message);
} }
else else

View File

@@ -1,4 +1,6 @@
namespace Application.Web.Controllers.Map; using Newtonsoft.Json;
namespace Application.Web.Controllers.Map;
/// <summary> /// <summary>
/// 地图接口 /// 地图接口
@@ -214,6 +216,7 @@ public class MapController : ControllerBase
var onMap = await _mapService.GetUserOnMap(userId); var onMap = await _mapService.GetUserOnMap(userId);
var mapInfo = await _mapService.GetMapInfo(onMap.mapId); var mapInfo = await _mapService.GetMapInfo(onMap.mapId);
var data = await _mapService.GetCityMap((int)mapInfo.cityId); var data = await _mapService.GetCityMap((int)mapInfo.cityId);
data = data.FindAll(it => it.code == nameof(MapEnum.MapCode.DEF_MAP));
if (!string.IsNullOrEmpty(search)) if (!string.IsNullOrEmpty(search))
{ {
data = data.FindAll(it => it.mapName.Contains(search)); data = data.FindAll(it => it.mapName.Contains(search));
@@ -672,6 +675,66 @@ public class MapController : ControllerBase
return PoAction.Ok(new { data, task }); return PoAction.Ok(new { data, task });
} }
/// <summary>
/// 处理Npc事务
/// </summary>
/// <param name="npcId"></param>
/// <param name="code"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> HandleNpcEvent(int npcId, string code, string? parms)
{
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
var data = await _mapService.GetNpcInfo(npcId);
if (data == null)
{
return PoAction.Message("Npc不存在!");
}
if (data.status != 1)
{
return PoAction.Message("Npc不存在!");
}
if (data.code != nameof(MapEnum.NpcCode.Event))
{
return PoAction.Message("无法处理该业务!");
}
if (data.bus.Any(it => it.code == code) == false)
{
return PoAction.Message("无法处理该业务!");
}
var onMap = await _mapService.GetUserOnMap(userId);
if (data.mapId != onMap.mapId)
{
return PoAction.Message("Npc不存在!");
}
if (code == nameof(MapEnum.NpcEventCode.Magic_Event)) //魔城
{
bool isWin = false;
if (TimeAssist.GetHourNum > 221000)
{
var onMapUser = await _mapService.GetMapUser(GameConfig.GameMagicMapId, areaId, 1, [userId], 1);
if (onMapUser.Count == 0)
{
isWin = true;
}
}
var magicService = App.GetService<IGameMagicService>();
await magicService.UpdateUserMagicEndTime(userId, isWin);
await _mapService.UpdateUserOnMap(onMap, GameConfig.GameMagicInMapId);//设置地图
return PoAction.Ok(0, "魔城成功退出!");
}
return PoAction.Message("非处理的游戏项!");
}
#endregion #endregion
#region #region

View File

@@ -0,0 +1,88 @@
using Microsoft.AspNetCore.Mvc;
namespace Application.Web.Controllers.Pub;
/// <summary>
/// Cdk接口
/// </summary>
[Route("[controller]/[action]")]
[ApiController]
[Authorize]
public class CdkController : ControllerBase
{
private readonly IGameCdkService _cdkService;
public CdkController(IGameCdkService cdkService)
{
_cdkService = cdkService;
}
/// <summary>
/// 兑换CDK
/// </summary>
/// <param name="cdk"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> Exchange(string cdk)
{
if (string.IsNullOrEmpty(cdk))
{
return PoAction.Message("CDK不能为空!");
}
var cdkItem = await _cdkService.GetCdkItemInfo(cdk);
if (cdkItem == null)
{
return PoAction.Message("CDK无效!");
}
if (cdkItem.userId != "0")
{
return PoAction.Message("CDK已被使用!");
}
var cdkInfo = await _cdkService.GetCdkInfo((int)cdkItem.cdkId);
if (cdkInfo == null)
{
return PoAction.Message("CDK无效!");
}
if (cdkInfo.endTime < DateTime.Now)
{
return PoAction.Message("CDK已过期!");
}
if (cdkInfo.area != 0)
{
if (cdkInfo.area != StateHelper.areaId)
{
return PoAction.Message($"该CDK仅可在{cdkInfo.area}区使用!");
}
}
string userId = StateHelper.userId;
if (cdkInfo.limit > 0)
{
int onCount = await _cdkService.GetUserCdkCount(cdkInfo.cdkId, userId);
if (onCount >= cdkInfo.limit)
{
return PoAction.Message($"该类型CDK限制兑换{cdkInfo.limit}个!");
}
}
if (await _cdkService.UpdateCdkUser(cdk, userId))
{
if (await GameBus.UpdateBag(userId, 1, cdkInfo.award, "CDK获得"))
{
string message = "兑换成功,获得:";
foreach (var item in cdkInfo.award)
{
message += $"{item.name}+{item.count},";
}
message = message.TrimEnd(',');
return PoAction.Ok(true,message);
}
else
{
return PoAction.Message("兑换失败,请稍后尝试!");
}
}
else
{
return PoAction.Message("兑换失败,请稍后尝试!");
}
}
}

View File

@@ -250,6 +250,7 @@ public class RecoverController : ControllerBase
var needData = data.FindAll(it => var needData = data.FindAll(it =>
it.isAppr == 1 && it.durability < it.maxdurability && it.useEndTime > TimeExtend.GetTimeStampSeconds); it.isAppr == 1 && it.durability < it.maxdurability && it.useEndTime > TimeExtend.GetTimeStampSeconds);
need = needData.Sum(it => (int)it.maxdurability - (int)it.durability); need = needData.Sum(it => (int)it.maxdurability - (int)it.durability);
need = need * 500;
return PoAction.Ok(new { data, need }); return PoAction.Ok(new { data, need });
} }

View File

@@ -0,0 +1,43 @@
{
"AutoProgram": 0,
"Redis": {
"connection": "127.0.0.1:6379,password=,defaultdatabase=5"
},
"SqlData": [
{
"type": 0,
"name": "Kg.SeaTime.Game",
"connect": "data source=81.70.212.61;database=kg.seatime.game;user id=root;password=1f5ozxRGE3Y;pooling=true;port=3306;sslmode=Required;charset=utf8mb4;"
},
{
"type": 0,
"name": "Kg.SeaTime.Resource",
"connect": "data source=81.70.212.61;database=kg.seatime.resource;user id=root;password=1f5ozxRGE3Y;pooling=true;port=3306;sslmode=Required;charset=utf8mb4;"
},
{
"type": 0,
"name": "Kg.SeaTime.Log",
"connect": "data source=81.70.212.61;database=kg.seatime.log;user id=root;password=1f5ozxRGE3Y;pooling=true;port=3306;sslmode=Required;charset=utf8mb4;"
}
],
"JwtTokenOptions": {
"Issuer": "kx.seatime",
"Audience": "kx.seatime",
"SecurityKey": "46055HR0n7FeNHhDKAYD2i9ZsdsYn4jn"
},
"ResUrl": {
"local": "http://192.168.0.142:5298",
"resUrl": "http://localhost:12206",
"imgCDN": "/",
"videoCDN": "/"
},
"Sms": {
"SmsType": 1,
"AccessKey": "AKIDVptgCRP5UcT4PTGm1yf5E6pKYVBajeKn",
"Secret": "FG2atxlKflcEclgKhnc9XeU3LM6YjdGf",
"signName": "探玩驿站",
"TemplateCode": "963929",
"SmsSdkAppId": "1400523979",
"SmsOnTime": 300
}
}

View File

@@ -2,8 +2,8 @@
统一配置中心 统一配置中心
*/ */
export class BaseConfig { export class BaseConfig {
public static BaseUrl: string = 'https://localhost:7198' // public static BaseUrl: string = 'https://localhost:7198'
public static BaseMediaUrl: string = 'https://localhost:7198/' // public static BaseMediaUrl: string = 'https://localhost:7198/'
// public static BaseUrl:string="http://v3.pccsh.com"; public static BaseUrl:string="http://v3.pccsh.com";
// public static BaseMediaUrl:string="http://v3.pccsh.com"; public static BaseMediaUrl:string="http://v3.pccsh.com";
} }

View File

@@ -0,0 +1,51 @@
<template>
<div class="module-title">
CDK兑换
</div>
<div class="module-content tips" style="font-size:14px;">
亲爱的航海家,CDK码可以在这里兑换奖励哦!
</div>
<div class="module-content">
<div class="input">
CDK码:<input name="cdk" placeholder="请输入CDK" class="ipt" type="text" v-model="no">
</div>
<div class="input" style="margin-top: 10px;">
<input type="button" value="立即兑换" class="btn btn-danger" @click="exchange" />
</div>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const no = ref('');
onMounted(async () => {
try {
}
finally {
PageLoading.Close();
}
})
const exchange = async () => {
if (no.value == '') {
MessageExtend.ShowToast("CDK不能为空!");
return;
}
MessageExtend.LoadingToast("兑换中...");
let result = await CdkService.Exchange(no.value);
MessageExtend.LoadingClose();
if (result.code == 0) {
no.value = '';
MessageExtend.Notify(result.msg, "success", 5000);
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
}
</script>

View File

@@ -12,6 +12,11 @@
<Abar :href="item.url">{{ item.name }}</Abar> <Abar :href="item.url">{{ item.name }}</Abar>
</div> </div>
</div> </div>
<div class="content" v-if="data.code == 'Event'">
<div class="item" v-for="item in data.bus">
<Abutton @click="HandleEvent(item)">{{ item.name }}</Abutton>
</div>
</div>
<div class="content" v-if="data.code == 'Task'"> <div class="content" v-if="data.code == 'Task'">
<div class="common" v-if="task.length > 0"> <div class="common" v-if="task.length > 0">
当前任务:<br> 当前任务:<br>
@@ -61,4 +66,20 @@ const BindData = async (): Promise<void> => {
} }
}; };
const HandleEvent = async (item: any) => {
let npc = PageExtend.QueryString("npc");
MessageExtend.LoadingToast("处理中...");
let result = await MapService.HandleNpcEvent(Number(npc), item.code, item.parms)
MessageExtend.LoadingClose();
if (result.code == 0) {
MessageExtend.Notify(result.msg, "success");
if (result.data == 0) {
PageExtend.RedirectTo("/map");
}
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
}
</script> </script>

View File

@@ -46,7 +46,7 @@
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<div class="content"> <div class="content">
<Abar href="/user/friend/search">添加好友</Abar> <Abar href="/user/search">添加好友</Abar>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@@ -4,9 +4,9 @@
</div> </div>
<div class="content"> <div class="content">
<div class="item" v-for="item in maxList" :key="item.umnId"> <div class="item" v-for="item in maxList" :key="item.umnId">
<Aimage :url="item.img"></Aimage> <Aimage :url="item.img"></Aimage><br>
<span @click="getDetail(item.umnId)" style="margin: 0 4px;">{{ item.name }} ×{{ item.count }}</span> <Abutton @click="getDetail(item.umnId)">{{ item.name }}</Abutton>({{ item.count }})
<Abutton @click="updown(item.umnId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton> [<Abutton @click="updown(item.umnId)"> {{ item.show == 0 ? '佩戴' : '卸下' }} </Abutton>]
</div> </div>
<span v-if="maxList.length == 0"> <span v-if="maxList.length == 0">
暂无称号. 暂无称号.
@@ -22,11 +22,12 @@
<div class="mapList" style="max-height: 300px;margin-top: 15px;"> <div class="mapList" style="max-height: 300px;margin-top: 15px;">
<div> <div>
<Aimage :url="maxDetail.img"></Aimage> <Aimage :url="maxDetail.img"></Aimage><br>
到期时间:{{TimeExtend.Format(maxDetail.endTime,"yyyy-MM-dd HH:mm")}}
</div> </div>
<div class="forum-title" style="padding: 0;"> <div class="forum-title" style="padding: 0;">
装备属性 称号属性
</div> </div>
<div v-for="(tipItem, index) in JSON.parse(maxDetail.attr)" :key="index"> <div v-for="(tipItem, index) in JSON.parse(maxDetail.attr)" :key="index">
{{ Number(index) + 1 }}: {{ tipItem.tip }} {{ Number(index) + 1 }}: {{ tipItem.tip }}

View File

@@ -7,8 +7,8 @@
<div class="input"> <div class="input">
玩家ID:<input name="no" type="number" placeholder="输入玩家ID" maxlength="12" class="ipt" v-model="no" /> 玩家ID:<input name="no" type="number" placeholder="输入玩家ID" maxlength="12" class="ipt" v-model="no" />
</div> </div>
<div class="input"> <div class="input" style="margin-top: 5px;">
<input type="button"" class=" btn btn-danger" value="查找玩家" @click="search" /> <input type="button" class=" btn btn-danger" value="查找玩家" @click="search" />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,9 @@
export class CdkService {
/**
* 兑换CDK
* GET /Cdk/Exchange
*/
static async Exchange(cdk: string) {
return await ApiService.Request("get", "/Cdk/Exchange", { cdk });
}
}

View File

@@ -87,6 +87,14 @@ export class MapService {
return await ApiService.Request("get", "/Map/Map/GetNpcInfo", { npcId }); return await ApiService.Request("get", "/Map/Map/GetNpcInfo", { npcId });
} }
/**
* 处理Npc事务
* GET /Map/Map/HandleNpcEvent
*/
static async HandleNpcEvent(npcId: number, code: string, parms: string) {
return await ApiService.Request("get", "/Map/Map/HandleNpcEvent", { npcId, code, parms });
}
/** /**
* 采集接口 * 采集接口
* GET /Map/Map/CollectMapRes * GET /Map/Map/CollectMapRes