This commit is contained in:
Putoo
2026-05-23 18:36:37 +08:00
parent 05e340801f
commit dbace8a8b2
27 changed files with 729 additions and 52 deletions

View File

@@ -0,0 +1,45 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Game")]
public class unit_user_ship
{
/// <summary>
/// usId
/// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string usId { get; set; }
/// <summary>
/// userId
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? userId { get; set; }
/// <summary>
/// goodsId
/// </summary>
[SugarColumn(IsNullable = true)]
public int? goodsId { get; set; }
/// <summary>
/// name
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? name { get; set; }
/// <summary>
/// speed
/// </summary>
[SugarColumn(IsNullable = true)]
public int? speed { get; set; }
/// <summary>
/// weight
/// </summary>
[SugarColumn(IsNullable = true)]
public int? weight { get; set; }
}
}

View File

@@ -23,5 +23,11 @@ namespace Application.Domain.Entity
/// </summary>
[SugarColumn(IsNullable = true)]
public int? maxWeight { get; set; }
/// <summary>
/// 船只当前负重
/// </summary>
[SugarColumn(IsNullable = true)]
public int? shipOnWeight { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace Application.Domain;
public static class GameConfig
{
public const int OnLineTime = 30;//在线延迟时间(分钟)
public const int SendChatGoodsBase = 10014;//小海螺
public const int SendChatGoodsArea = 10001;//大海螺
public const int SendChatGoodsService = 10002;//金海螺
}

View File

@@ -0,0 +1,11 @@
namespace Application.Domain;
public static class GoodsEnum
{
public enum Code
{
Drug,//药品
Prop,//物品
Cargo,//货物
}
}

View File

@@ -19,4 +19,13 @@ public interface IGameMapService
Task UpdateUserOnMap(string userId, string ip, string mapId);
#endregion
#region
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,
int limit, RefAsync<int> total);
#endregion
}

View File

@@ -24,5 +24,12 @@ public interface IUnitUserService
Task<bool> RegisterUserInfo(string userId, string nick, string sex);
#endregion
#region
Task<int> GetOnlineCount();
#endregion
}

View File

@@ -0,0 +1,22 @@
namespace Application.Domain;
public interface IUnitUserWeight
{
Task<unit_user_weight> GetUserWeightInfo(string userId);
Task<bool> UpdateUserWeight(string userId, int op, int weight);
Task<bool> UpdateUserMaxWeight(string userId, int op, int weight);
Task<bool> AddUserWeightLog(string userId, int goodsId, string goodsName, int weight, int count);
Task<bool> CheakUserWeight(string userId, int useWeight);
#region
Task<List<unit_user_ship>> GetUserShip(string userId);
Task<int> GetUserShipMaxWeight(string userId);
Task<bool> UpdateUserShipOnWeight(string userId, int op, int weight);
Task<bool> CheakUserShipWeight(string userId, int useWeight);
Task<bool> DeleteUserShip(string usId, string userId);
Task<bool> AddUserShip(string userId, string name, int goodsId, int speed, int weight);
#endregion
}

View File

@@ -2,7 +2,7 @@
namespace Application.Domain;
public class GameGoodsService(ISqlSugarClient DbClient, IRedisCache redis) : IGameEquService, ITransient
public class GameGoodsService(ISqlSugarClient DbClient, IRedisCache redis) : IGameGoodsService, ITransient
{
#region
@@ -120,10 +120,21 @@ public class GameGoodsService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
if (isOk)
{
//更新负重
int weightCount = Convert.ToInt32(UserGoods.weight) * count;
if (weightCount > 0)
{
var weightService = App.GetService<IUnitUserWeight>();
if (UserGoods.code == nameof(GoodsEnum.Code.Cargo))//跑商物品处理
{
await weightService.UpdateUserShipOnWeight(userId, op, weightCount);
}
else
{
await weightService.UpdateUserWeight(userId, op, weightCount);
}
}
//添加日志
await AddGoodsLog(userId, goodsId, op, count, remark);
await AddGoodsLog(userId, goodsId, op, count, remark); //添加日志
}
return isOk;

View File

@@ -1,6 +1,6 @@
namespace Application.Domain;
public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGameMapService, ITransient
public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMapService, ITransient
{
#region
@@ -31,6 +31,7 @@ public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGame
return data;
}
public async Task<List<game_city_map>> GetMapCity(int cityId)
{
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "CityShowMap");
@@ -41,8 +42,10 @@ public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGame
data = await db.Queryable<game_city_map>().Where(it => it.cityId == cityId && it.show == 1).ToListAsync();
await redis.AddHashAsync(key, cityId.ToString(), data);
}
return data;
}
public async Task<int> GetMapCityByMapId(string mapId)
{
var data = await GetMapInfo(mapId);
@@ -69,6 +72,7 @@ public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGame
return data;
}
public async Task<game_city_npc> GetNpcInfo(int npcId)
{
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "NpcInfo");
@@ -77,8 +81,9 @@ public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGame
{
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_npc>();
data = await db.Queryable<game_city_npc>().Where(it => it.npcId == npcId).SingleAsync();
await redis.AddHashAsync(key, npcId.ToString(),data);
await redis.AddHashAsync(key, npcId.ToString(), data);
}
return data;
}
@@ -126,5 +131,48 @@ public class GameMapService (ISqlSugarClient DbClient, IRedisCache redis): IGame
}
}
#endregion
#region
private async Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
long time = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime));
var data = await db.Queryable<unit_user_online>().Where(it => it.upTime > time && 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, int take)
{
var data = await GetMapUser(mapId, area, showArea, noUser);
return data.Take(take).ToList();
}
public async Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int page,
int limit, RefAsync<int> total)
{
var data = await GetMapUser(mapId, area, showArea, noUser);
total = data.Count;
return data.Skip((page - 1) * limit) // 跳过前面的页
.Take(limit) // 取当前页
.ToList();
}
#endregion
}

View File

@@ -90,7 +90,6 @@ public class UnitUserService : IUnitUserService, ITransient
await _redisClient.DelHashAsync(string.Format(UserCache.BaseCacheKeys, "UserInfo", "UserNo"), result.userNo);
await _redisClient.DelHashAsync(string.Format(UserCache.BaseCacheKeys, "UserInfo", "Sid"), result.token);
}
#endregion
@@ -144,8 +143,8 @@ public class UnitUserService : IUnitUserService, ITransient
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserInfo(0, userId);//清理个人信息表缓存
await ClearUserInfo(0, userId); //清理个人信息表缓存
//注册账户
unit_user_acc acc = new unit_user_acc();
acc.userId = userId;
@@ -159,7 +158,7 @@ public class UnitUserService : IUnitUserService, ITransient
copper.userId = userId;
copper.copper = 0;
db.Insertable(copper).AddQueue();
//注册个人基础属性
unit_user_attr userAttr = GameTool.GetAttrData(1);
userAttr.userId = userId;
@@ -175,14 +174,14 @@ public class UnitUserService : IUnitUserService, ITransient
morale.userId = userId;
morale.morale = userAttr.upMorale;
db.Insertable(morale).AddQueue();
//注册等级经验
unit_user_exp exp = new unit_user_exp();
exp.userId = userId;
exp.exp = 0;
exp.upExp = GameTool.GetUserUpExp(1);
db.Insertable(exp).AddQueue();
//注册负重
unit_user_weight weight = new unit_user_weight();
weight.userId = userId;
@@ -196,7 +195,7 @@ public class UnitUserService : IUnitUserService, ITransient
vitality.upVitality = 50;
vitality.upTime = TimeAssist.GetDateTimeYMDString(0);
db.Insertable(vitality).AddQueue();
//注册在线
unit_user_online online = new unit_user_online();
online.userId = userId;
@@ -204,9 +203,8 @@ public class UnitUserService : IUnitUserService, ITransient
online.mapId = "16_27";
online.upTime = TimeAssist.GetTimeStampNum;
db.Insertable(online).AddQueue();
await db.SaveQueuesAsync(false);
}
return result;
@@ -245,4 +243,15 @@ public class UnitUserService : IUnitUserService, ITransient
}
#endregion
#region
public async Task<int> GetOnlineCount()
{
long time = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0-GameConfig.OnLineTime));
var db = _dbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
return await db.Queryable<unit_user_online>().Where(it => it.upTime > time).CountAsync();
}
#endregion
}

View File

@@ -0,0 +1,177 @@
namespace Application.Domain;
public class UnitUserWeight(ISqlSugarClient DbClient, IRedisCache redis) : IUnitUserWeight, ITransient
{
public async Task<unit_user_weight> GetUserWeightInfo(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "WeightData", "Weight");
var data = await redis.GetHashAsync<unit_user_weight>(key, userId);
if (data == null)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_weight>();
data = await db.Queryable<unit_user_weight>().Where(it => it.userId == userId).SingleAsync();
await redis.AddHashAsync(key, userId, data);
}
data.maxWeight = await GetUserMaxWeight(data);
return data;
}
private async Task<int> GetUserMaxWeight(unit_user_weight data)
{
int result = (int)data.maxWeight;
//其他属性加层
return result;
}
private async Task ClearUserWeightInfo(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "WeightData", "Weight");
await redis.DelHashAsync(key, userId);
}
public async Task<bool> UpdateUserWeight(string userId, int op, int weight)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_weight>();
bool result = await db.Updateable<unit_user_weight>()
.SetColumnsIF(op == 0, it => it.onWeight == it.onWeight - weight)
.SetColumnsIF(op == 1, it => it.onWeight == it.onWeight + weight)
.SetColumnsIF(op == 2, it => it.onWeight == weight)
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserWeightInfo(userId);
}
return result;
}
public async Task<bool> UpdateUserMaxWeight(string userId, int op, int weight)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_weight>();
bool result = await db.Updateable<unit_user_weight>()
.SetColumnsIF(op == 0, it => it.maxWeight == it.maxWeight - weight)
.SetColumnsIF(op == 1, it => it.maxWeight == it.maxWeight + weight)
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserWeightInfo(userId);
}
return result;
}
public async Task<bool> AddUserWeightLog(string userId, int goodsId, string goodsName, int weight, int count)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_weight_log>();
unit_user_weight_log log = new unit_user_weight_log();
log.logId = StringAssist.NewGuid;
log.userId = userId;
log.goodsId = goodsId;
log.goodsName = goodsName;
log.weight = weight;
log.count = count;
log.sum = weight * count;
log.addTime = DateTime.Now;
return await db.Insertable(log).ExecuteCommandAsync() > 0;
}
public async Task<bool> CheakUserWeight(string userId, int useWeight)
{
bool result = false;
var weightInfo = await GetUserWeightInfo(userId);
if (weightInfo != null)
{
result = (useWeight + weightInfo.onWeight) <= weightInfo.maxWeight;
}
return result;
}
#region
public async Task<List<unit_user_ship>> GetUserShip(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "WeightData", "Ship");
var data = await redis.GetHashAsync<List<unit_user_ship>>(key, userId);
if (data == null)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_ship>();
data = await db.Queryable<unit_user_ship>().Where(it => it.userId == userId).ToListAsync();
await redis.AddHashAsync(key, userId, data);
}
return data;
}
public async Task<int> GetUserShipMaxWeight(string userId)
{
var data = await GetUserShip(userId);
return data.Sum(it => (int)it.weight);
}
private async Task ClearUserShipData(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "WeightData", "Ship");
await redis.DelHashAsync(key, userId);
}
public async Task<bool> UpdateUserShipOnWeight(string userId, int op, int weight)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_weight>();
bool result = await db.Updateable<unit_user_weight>()
.SetColumnsIF(op == 0, it => it.shipOnWeight == it.shipOnWeight - weight)
.SetColumnsIF(op == 1, it => it.shipOnWeight == it.shipOnWeight + weight)
.Where(it => it.userId == userId).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserWeightInfo(userId);
}
return result;
}
public async Task<bool> CheakUserShipWeight(string userId, int useWeight)
{
bool result = false;
var weightInfo = await GetUserWeightInfo(userId);
var maxShipWeight = await GetUserShipMaxWeight(userId);
if (weightInfo != null)
{
result = (useWeight + weightInfo.onWeight) <= maxShipWeight;
}
return result;
}
public async Task<bool> DeleteUserShip(string usId,string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_ship>();
bool result = await db.Deleteable<unit_user_ship>().Where(it => it.usId == usId).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserShipData(userId);
}
return result;
}
public async Task<bool> AddUserShip(string userId,string name,int goodsId,int speed,int weight)
{
unit_user_ship ship = new unit_user_ship();
ship.usId = StringAssist.NewGuid;
ship.userId = userId;
ship.goodsId = goodsId;
ship.name = name;
ship.speed = speed;
ship.weight = weight;
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_ship>();
bool result = await db.Insertable(ship).ExecuteCommandAsync() > 0;
if (result)
{
await ClearUserShipData(userId);
}
return result;
}
#endregion
}

View File

@@ -11,10 +11,11 @@ namespace Application.Web.Controllers.Chat;
public class ChatController : ControllerBase
{
private readonly IGameChatService _chatService;
public ChatController(IGameChatService chatService)
private readonly IGameGoodsService _goodsService;
public ChatController(IGameChatService chatService,IGameGoodsService goodsService)
{
_chatService = chatService;
_goodsService = goodsService;
}
/// <summary>
@@ -26,6 +27,7 @@ public class ChatController : ControllerBase
[HttpGet]
public async Task<IPoAction> GetChatData(int type, int page)
{
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
string teamId = "";
string groupId = "";
@@ -37,15 +39,15 @@ public class ChatController : ControllerBase
switch (type)
{
case 0:
sendGoodsCount = 199;
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsBase);
sendGoodsName = "小海螺";
break;
case 3:
sendGoodsCount = 15;
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsArea);
sendGoodsName = "大海螺";
break;
case 4:
sendGoodsCount = 9;
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsService);
sendGoodsName = "金海螺";
break;
}
@@ -71,12 +73,14 @@ public class ChatController : ControllerBase
int areaId = StateHelper.areaId;
string par = string.Empty;
string code = GameChatEnum.Code.Public.ToString();
int goodsId = 0;
bool isSend = false;
switch (pars.type)
{
case 0:
isSend = true;
code =nameof(GameChatEnum.Code.Public);
goodsId = GameConfig.SendChatGoodsBase;
break;
case 1:
isSend = true;
@@ -90,23 +94,39 @@ public class ChatController : ControllerBase
break;
case 3:
isSend = true;
goodsId = GameConfig.SendChatGoodsArea;
code = nameof(GameChatEnum.Code.Region);
break;
case 4:
isSend = true;
goodsId = GameConfig.SendChatGoodsService;
code = nameof(GameChatEnum.Code.Dress);
break;
}
if (isSend == false)
{
return PoAction.Message("无法发言!");
}
if (goodsId != 0)
{
var myCount = await _goodsService.GetUserGoodsCount(userId, goodsId);
if (myCount < 1)
{
return PoAction.Message("暂无发言道具,去商城购买海螺才可以发言哦!");
}
}
string sign = StringAssist.NoHTML(pars.sign);
bool result = await _chatService.SendChat(userId, areaId, code, sign, par);
if (result)
{
if (goodsId != 0)//扣除道具
{
await _goodsService.UpdateUserGoods(userId, 0, goodsId, 1, "发言");
}
return PoAction.Ok(true);
}
else

View File

@@ -47,13 +47,17 @@ public class MapController : ControllerBase
string teamId = "";
string groupId = "";
var chatData = await _chatService.GetChatTop(area, 2, teamId, groupId);
//NPC信息
var npcData = await _mapService.GetMapNpc(mapInfo.mapId);
var npcData = await _mapService.GetMapNpc(mapInfo.mapId); //NPC信息
npcData = npcData.FindAll(it => GameTool.AreaVerify(StateHelper.areaId, it.areaId));
//城市信息
var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId);
var cityShow = await _mapService.GetMapCity(cityInfo.cityId);
var nearUser =
await _mapService.GetMapUser(mapInfo.mapId, area, (int)mapInfo.lookArea, new List<string> { userId },
3); //获取附近的人
var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId); //城市信息
var cityShow = await _mapService.GetMapCity(cityInfo.cityId); //城内地图
#region 线
string ip = ComHelper.GetClientUserIp(HttpContext);
@@ -61,8 +65,34 @@ public class MapController : ControllerBase
#endregion
object ret = new { mapInfo, cityInfo, npcData, chatData,cityShow };
object ret = new { mapInfo, cityInfo, npcData, chatData, cityShow, nearUser };
return PoAction.Ok(ret);
}
/// <summary>
/// 获取地图在线玩家
/// </summary>
/// <param name="map"></param>
/// <param name="page"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetMapUser(int page)
{
RefAsync<int> Total = 0;
string userId = StateHelper.userId;
int areaId = StateHelper.areaId;
var onMap = await _mapService.GetUserOnMap(userId);
var mapInfo = await _mapService.GetMapInfo(onMap.mapId);
if (mapInfo == null)
{
return PoAction.Message("地图不存在!");
}
var data = await _mapService.GetMapUser(onMap.mapId, areaId, (int)mapInfo.lookArea, new List<string> { userId }, page,
10, Total);
return PoAction.Ok(new { data, total = Total.Value});
}
}

View File

@@ -52,7 +52,7 @@ namespace Application.Web.Controllers.Pub
var notice = await _noticeService.GetNoticeDataByTake(5);
int OnCount = 100;
int OnCount = await _userService.GetOnlineCount();
return PoAction.Ok(new { area = areaData, notice, isOnline, onCount = OnCount, account,userData });
}

View File

@@ -0,0 +1,38 @@
namespace Application.Web.Controllers.User;
/// <summary>
/// 用户背包信息
/// </summary>
[ApiExplorerSettings(GroupName = "User")]
[Route("User/[controller]/[action]")]
[ApiController]
[Authorize]
public class BagController : ControllerBase
{
private readonly IUnitUserWeight _weightService;
public BagController(IUnitUserWeight weightService)
{
_weightService = weightService;
}
/// <summary>
/// 获取背包信息
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetUserBagData()
{
string userId = StateHelper.userId;
int onWeight = 0;
int maxWeight = 0;
int gold = 0;
int cowry = 0;
long copper = 0;
var userWeight = await _weightService.GetUserWeightInfo(userId);
onWeight = (int)userWeight.onWeight;
maxWeight = (int)userWeight.maxWeight;
return PoAction.Ok(new { onWeight, maxWeight,cowry, gold, copper });
}
}