1001 lines
34 KiB
C#
1001 lines
34 KiB
C#
using Newtonsoft.Json;
|
|
|
|
namespace Application.Domain;
|
|
|
|
public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGameMapService, ITransient
|
|
{
|
|
#region 城市地图数据
|
|
|
|
public async Task<game_city> GetCityInfo(int cityId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInfo");
|
|
var data = await redis.GetHashAsync<game_city>(key, cityId.ToString());
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city>();
|
|
data = await db.Queryable<game_city>().Where(it => it.cityId == cityId).SingleAsync();
|
|
await redis.AddHashAsync(key, cityId.ToString(), data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public async Task<game_city> GetCityInfoByMapId(string mapId)
|
|
{
|
|
var data = await GetMapInfo(mapId);
|
|
if (data != null)
|
|
{
|
|
return await GetCityInfo((int)data.cityId);
|
|
}
|
|
else
|
|
{
|
|
return new game_city();
|
|
}
|
|
}
|
|
|
|
public async Task<List<game_city>> GetCityData()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityData");
|
|
var data = await redis.GetAsync<List<game_city>>(key);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city>();
|
|
data = await db.Queryable<game_city>().ToListAsync();
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
public async Task<List<game_city_map>> GetCityMap(int cityId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityMap");
|
|
var data = await redis.GetHashAsync<List<game_city_map>>(key, cityId.ToString());
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
|
data = await db.Queryable<game_city_map>().Where(it => it.cityId == cityId).ToListAsync();
|
|
await redis.AddHashAsync(key, cityId.ToString(), data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public async Task<List<game_city_map>> GetCityShowMap(int cityId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityShowMap");
|
|
var data = await redis.GetHashAsync<List<game_city_map>>(key, cityId.ToString());
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
|
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<game_city_map> GetMapInfo(string mapId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapData");
|
|
var data = await redis.GetHashAsync<game_city_map>(key, mapId);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
|
data = await db.Queryable<game_city_map>().Where(it => it.mapId == mapId).SingleAsync();
|
|
await redis.AddHashAsync(key, mapId, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
public async Task<int> GetMapCityByMapId(string mapId)
|
|
{
|
|
var data = await GetMapInfo(mapId);
|
|
if (data != null)
|
|
{
|
|
return (int)data.cityId;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<List<game_city_npc>> GetMapNpc(string mapId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcData");
|
|
var data = await redis.GetHashAsync<List<game_city_npc>>(key, mapId);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_npc>();
|
|
data = await db.Queryable<game_city_npc>().Where(it => it.mapId == mapId && it.status == 1).ToListAsync();
|
|
await redis.AddHashAsync(key, mapId, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public async Task<game_city_npc> GetNpcInfo(int npcId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcInfo");
|
|
var data = await redis.GetHashAsync<game_city_npc>(key, npcId.ToString());
|
|
if (data == null)
|
|
{
|
|
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);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 用户地图
|
|
|
|
public async Task<string> GetUserOnMapId(string userId)
|
|
{
|
|
var data = await GetUserOnMap(userId);
|
|
if (data == null)
|
|
{
|
|
return "16_27";
|
|
}
|
|
|
|
return data.mapId;
|
|
}
|
|
|
|
public async Task<unit_user_online> GetUserOnMap(string userId)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserOnline");
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
return await redis.GetHashAsync<unit_user_online>(key, userId);
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
|
|
var data = await db.Queryable<unit_user_online>().Where(it => it.userId == userId).SingleAsync();
|
|
await redis.AddHashAsync(key, userId, data);
|
|
return data;
|
|
}
|
|
|
|
public async Task<UserOnMap> GetUserOnMapInfo(string userId)
|
|
{
|
|
var onMap = await GetUserOnMap(userId);
|
|
var mapInfo = await GetMapInfo(onMap.mapId);
|
|
var cityInfo = await GetCityInfo((int)mapInfo.cityId);
|
|
int isOnline =
|
|
onMap.upTime > (TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime)))
|
|
? 1
|
|
: 0;
|
|
return new UserOnMap()
|
|
{
|
|
mapId = mapInfo.mapId, mapName = mapInfo.mapName, cityId = cityInfo.cityId, cityName = cityInfo.cityName,
|
|
isOnline = isOnline
|
|
};
|
|
}
|
|
|
|
public async Task UpdateUserOnMap(string userId, string ip, string mapId)
|
|
{
|
|
unit_user_online onLine = new unit_user_online();
|
|
onLine.userId = userId;
|
|
onLine.mapId = mapId;
|
|
onLine.ip = ip;
|
|
onLine.upTime = TimeExtend.GetTimeStampSeconds;
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserOnline");
|
|
if (await redis.AddHashAsync(key, userId, onLine))
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
|
|
await db.Updateable<unit_user_online>(onLine).ExecuteCommandAsync();
|
|
}
|
|
}
|
|
|
|
public async Task<bool> UpdateUserOnMap(unit_user_online data, string mapId)
|
|
{
|
|
data.mapId = mapId;
|
|
data.upTime = TimeExtend.GetTimeStampSeconds;
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserOnline");
|
|
if (await redis.AddHashAsync(key, data.userId, data))
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_online>();
|
|
await db.Updateable<unit_user_online>(data).ExecuteCommandAsync();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public async Task SetUserMapDefult(string userId)
|
|
{
|
|
var userMap = await GetUserOnMap(userId);
|
|
var MapInfo = await GetMapInfo(userMap.mapId);
|
|
if (MapInfo != null)
|
|
{
|
|
await UpdateUserOnMap(userMap, MapInfo.retMap);
|
|
}
|
|
}
|
|
|
|
public async Task<game_city_map> GetToMapInfo(string userId, string toMap, bool isUpUserMap = true,
|
|
bool isChangeCity = false)
|
|
{
|
|
bool result = false;
|
|
var onMapUser = await GetUserOnMap(userId);
|
|
var onMap = onMapUser.mapId;
|
|
var onMapInfo = await GetMapInfo(onMap);
|
|
var mapInfo = await GetMapInfo(toMap);
|
|
if (onMap == toMap) //相同地图不更新
|
|
{
|
|
if (isUpUserMap)
|
|
{
|
|
await UpdateUserOnMap(onMapUser, toMap);
|
|
}
|
|
|
|
return mapInfo;
|
|
}
|
|
else
|
|
{
|
|
//更新挂机,结束挂机
|
|
}
|
|
|
|
if (mapInfo == null)
|
|
{
|
|
var myOnMap = await GetMapInfo(onMap);
|
|
return myOnMap;
|
|
}
|
|
|
|
if (isChangeCity)
|
|
{
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
if (mapInfo.show == 1)
|
|
{
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
string[] onMaps = onMap.Split('_');
|
|
int onMapX = Convert.ToInt32(onMaps[0]);
|
|
int onMapY = Convert.ToInt32(onMaps[1]);
|
|
if (onMapX == mapInfo.x)
|
|
{
|
|
if (onMapY == (mapInfo.y - 1) || onMapY == (mapInfo.y + 1))
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (onMapY == mapInfo.y)
|
|
{
|
|
if (onMapX == (mapInfo.x - 1) || onMapX == (mapInfo.x + 1))
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//当传送有效时,此处判断是否跨城市
|
|
if (result)
|
|
{
|
|
result = onMapInfo.cityId == mapInfo.cityId;
|
|
}
|
|
}
|
|
|
|
if (isUpUserMap && result)
|
|
{
|
|
result = await UpdateUserOnMap(onMapUser, toMap);
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
if (mapInfo.lockTime > 0)
|
|
{
|
|
// await SetUserMapLock(userId, (int)mapInfo.lockTime); //增加地图锁定
|
|
}
|
|
|
|
return mapInfo;
|
|
}
|
|
else
|
|
{
|
|
return onMapInfo;
|
|
}
|
|
}
|
|
|
|
public async Task<List<unit_user_map>> GetUserCityMapData(string userId)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserCityMap");
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
return await redis.GetHashAsync<List<unit_user_map>>(key, userId);
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_map>();
|
|
var data = await db.Queryable<unit_user_map>().Where(it => it.userId == userId).ToListAsync();
|
|
await redis.AddHashAsync(key, userId, data);
|
|
return data;
|
|
}
|
|
|
|
private async Task ClearUserCityMapCache(string userId)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserCityMap");
|
|
await redis.DelHashAsync(key, userId);
|
|
}
|
|
|
|
public async Task<bool> AddUserCityMap(string userId, int cityId)
|
|
{
|
|
unit_user_map map = new unit_user_map();
|
|
map.umId = $"{userId}_{cityId}";
|
|
map.userId = userId;
|
|
map.cityId = cityId;
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_map>();
|
|
bool result = await db.Storageable(map).ExecuteCommandAsync() > 0;
|
|
if (result)
|
|
{
|
|
await ClearUserCityMapCache(userId);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#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
|
|
|
|
#region 自动寻路
|
|
|
|
private async Task<List<game_city>> GetCityDataExcludeParent()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityParent");
|
|
var data = await redis.GetAsync<List<game_city>>(key);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city>();
|
|
data = await db.Queryable<game_city>().Where(it => it.parent != 0).ToListAsync();
|
|
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private async Task<List<game_city_map>> GetAllMaoToData()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityInterCityPortal");
|
|
if (await redis.ExistsAsync(key))
|
|
{
|
|
return await redis.GetAsync<List<game_city_map>>(key);
|
|
}
|
|
|
|
List<game_city_map> result = new List<game_city_map>();
|
|
|
|
var cityData = await GetCityDataExcludeParent();
|
|
foreach (var item in cityData)
|
|
{
|
|
if (!string.IsNullOrEmpty(item.toMap))
|
|
{
|
|
var map = await GetMapInfo(item.toMap);
|
|
if (map != null)
|
|
{
|
|
result.Add(map);
|
|
}
|
|
}
|
|
}
|
|
|
|
await redis.SetAsync(key, result);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 城市信息
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task<List<CityNode>> GetCityNode()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityNode");
|
|
var data = await redis.GetAsync<List<CityNode>>(key);
|
|
if (data == null)
|
|
{
|
|
data = new List<CityNode>();
|
|
var cityData = await GetCityDataExcludeParent(); //获取所有城市
|
|
foreach (var city in cityData)
|
|
{
|
|
var mdMap = await GetMapInfo(city.toMap);
|
|
if (mdMap != null)
|
|
{
|
|
var cityTemp = new CityNode(city.cityId, city.cityName, new Point((int)mdMap.x, (int)mdMap.y),
|
|
mdMap.mapName, (int)city.x_s, (int)city.x_e, (int)city.y_s, (int)city.y_e);
|
|
data.Add(cityTemp);
|
|
}
|
|
}
|
|
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 城市网络
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task<Dictionary<int, List<game_city_map>>> GetCityRoadNetwork()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityRoadNetwork");
|
|
var data = await redis.GetAsync<Dictionary<int, List<game_city_map>>>(key);
|
|
if (data == null)
|
|
{
|
|
data = new Dictionary<int, List<game_city_map>>();
|
|
var cityData = await GetCityDataExcludeParent(); //获取所有城市
|
|
foreach (var city in cityData)
|
|
{
|
|
//添加地图
|
|
var mapData = await GetCityMap(city.cityId);
|
|
data.Add(city.cityId, mapData);
|
|
}
|
|
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 传送点信息
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task<List<InterCityPortal>> GetCityInterCityPortal()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInterCityPortal");
|
|
var data = await redis.GetAsync<List<InterCityPortal>>(key);
|
|
if (data == null)
|
|
{
|
|
data = new List<InterCityPortal>();
|
|
var toAddr = await GetAllMaoToData(); //获取所有传送点
|
|
var cityData = await GetCityDataExcludeParent(); //获取所有城市
|
|
foreach (var item in toAddr)
|
|
{
|
|
var toMapInfo = await GetMapInfo(item.retMap);
|
|
//获取反向传送点
|
|
var retAddr = cityData.Find(it => it.cityId == (int)item.cityId);
|
|
|
|
data.Add(new InterCityPortal(item.mapId, (int)item.cityId, new Point((int)item.x, (int)item.y),
|
|
(int)toMapInfo.cityId, item.mapName, 1, retAddr.toMap));
|
|
}
|
|
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private async Task<List<MapLine>> FinderMapLine(Point start, Point end)
|
|
{
|
|
//初始化
|
|
var globalNetwork = new GlobalRoadNetwork();
|
|
//注册城市
|
|
var NodeData = await GetCityNode();
|
|
NodeData.ForEach(item => { globalNetwork.AddCity(item); });
|
|
//注册传送点
|
|
var CityInterCityPortal = await GetCityInterCityPortal();
|
|
CityInterCityPortal.ForEach(item => { globalNetwork.AddPortal(item); });
|
|
var pathFinder = new CrossCityPathFinder(globalNetwork); //初始化寻找器
|
|
//注册城市网络
|
|
List<CityRoadNetwork> NetworkData = new List<CityRoadNetwork>();
|
|
var NetworkCityData = await GetCityRoadNetwork();
|
|
foreach (var cityNet in NetworkCityData)
|
|
{
|
|
var cityNetwork = new CityRoadNetwork(cityNet.Key);
|
|
foreach (var map in cityNet.Value)
|
|
{
|
|
cityNetwork.AddWalkablePoint((int)map.x, (int)map.y);
|
|
}
|
|
|
|
NetworkData.Add(cityNetwork);
|
|
}
|
|
|
|
NetworkData.ForEach(item => { pathFinder.AddCityRoadNetwork(item); });
|
|
|
|
//获取所有城市ID
|
|
var cityData = await GetCityDataExcludeParent();
|
|
List<int> cityRoute = cityData.Select(it => it.cityId).ToList();
|
|
var path = pathFinder.FindCrossCityPath(start, end);
|
|
List<MapLine> result = new List<MapLine>();
|
|
if (path != null)
|
|
{
|
|
foreach (var item in path)
|
|
{
|
|
if (item.StepType == PathStepType.Move)
|
|
{
|
|
MapLine line = new MapLine();
|
|
line.x = item.Position.X;
|
|
line.y = item.Position.Y;
|
|
line.mapId = $"{line.x}_{line.y}";
|
|
result.Add(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public async Task<List<MapLine>> CreateAutoMap(string start, string end)
|
|
{
|
|
//获取所有起始点
|
|
var startMap = await GetMapInfo(start);
|
|
var endMap = await GetMapInfo(end);
|
|
Point startPoint = new Point((int)startMap.x, (int)startMap.y);
|
|
Point endPoint = new Point((int)endMap.x, (int)endMap.y);
|
|
var result = await FinderMapLine(startPoint, endPoint);
|
|
if (result.Count > 0)
|
|
{
|
|
result.RemoveAt(0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 航海
|
|
|
|
public async Task<unit_user_run> GetUserRun(string userId)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserMapRun");
|
|
if (await redis.HExistsHashAsync(key, userId))
|
|
{
|
|
return await redis.GetHashAsync<unit_user_run>(key, userId);
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_run>();
|
|
var data = await db.Queryable<unit_user_run>().Where(it => it.userId == userId).SingleAsync();
|
|
if (data == null)
|
|
{
|
|
data = await ResetUserRun(userId, false);
|
|
}
|
|
|
|
await redis.AddHashAsync(key, userId, data);
|
|
return data;
|
|
}
|
|
|
|
private async Task ClearUserRunCache(string userId)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserMapRun");
|
|
await redis.DelHashAsync(key, userId);
|
|
}
|
|
|
|
private async Task<unit_user_run> ResetUserRun(string userId, bool ClearCache = true)
|
|
{
|
|
unit_user_run runInfo = new unit_user_run();
|
|
runInfo.userId = userId;
|
|
runInfo.areaId = 0;
|
|
runInfo.lineCode = "";
|
|
runInfo.onMap = "";
|
|
runInfo.toMap = "";
|
|
runInfo.distance = 0;
|
|
runInfo.position = 0;
|
|
runInfo.depth = 0;
|
|
runInfo.status = 0;
|
|
runInfo.upTime = TimeExtend.GetTimeStampSeconds;
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_run>();
|
|
bool result = await db.Saveable(runInfo).ExecuteCommandAsync() > 0;
|
|
if (result)
|
|
{
|
|
if (ClearCache)
|
|
{
|
|
await ClearUserRunCache(userId);
|
|
}
|
|
|
|
return runInfo;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<bool> StopUserRun(string userId)
|
|
{
|
|
var data = await ResetUserRun(userId, true);
|
|
return data == null ? false : true;
|
|
}
|
|
|
|
public async Task<bool> SaveUserRunInfo(string userId, int areaId, string onMap, string toMap)
|
|
{
|
|
unit_user_run runInfo = new unit_user_run();
|
|
runInfo.userId = userId;
|
|
runInfo.areaId = areaId;
|
|
runInfo.lineCode = StringAssist.GetSortKey(onMap, toMap);
|
|
runInfo.onMap = onMap;
|
|
runInfo.toMap = toMap;
|
|
int mile = GameTool.ComputeMile(onMap, toMap);
|
|
runInfo.distance = mile;
|
|
runInfo.position = 0;
|
|
runInfo.depth = 0;
|
|
runInfo.status = 1;
|
|
runInfo.upTime = TimeExtend.GetTimeStampSeconds;
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_run>();
|
|
bool result = await db.Saveable(runInfo).ExecuteCommandAsync() > 0;
|
|
if (result)
|
|
{
|
|
await ClearUserRunCache(userId);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> UpdateUserRunInfo(unit_user_run data)
|
|
{
|
|
string key = string.Format(UserCache.BaseCacheKey, "UserMapRun");
|
|
bool result = await redis.AddHashAsync(key, data.userId, data);
|
|
if (result)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_run>();
|
|
await db.Updateable(data).ExecuteCommandAsync();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<game_city_map_event> GetRandomOneMapRunEvent()
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKey, "CityRunEvent");
|
|
var data = await redis.GetAsync<List<game_city_map_event>>(key);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map_event>();
|
|
data = await db.Queryable<game_city_map_event>().ToListAsync();
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
int index = RandomAssist.UnitRandomNum(0, data.Count);
|
|
return data[index];
|
|
}
|
|
|
|
public async Task<string> GetUserRunEvent(string userId)
|
|
{
|
|
string result = string.Empty;
|
|
if (RandomAssist.CheakRandom(30))
|
|
{
|
|
var data = await GetRandomOneMapRunEvent();
|
|
if (data != null)
|
|
{
|
|
if (string.IsNullOrEmpty(data.eventData))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
var eventData = JsonConvert.DeserializeObject<MapEventData>(data.eventData);
|
|
if (data.evType == nameof(MapEnum.RunEvent.reduce_goods))
|
|
{
|
|
var goodsService = App.GetService<IGameGoodsService>();
|
|
var cagioData = await goodsService.GetUserGoodsData(userId, nameof(GoodsEnum.Code.Cargo));
|
|
if (cagioData.Count > 0)
|
|
{
|
|
bool isOp = await CheckOpEvent(userId, data.offsetData);
|
|
if (isOp)
|
|
{
|
|
int index = RandomAssist.UnitRandomNum(0, cagioData.Count);
|
|
int count = RandomAssist.UnitRandomNum((int)eventData.minCount,
|
|
(int)eventData.maxCount + 1);
|
|
var onGoods = cagioData[index];
|
|
|
|
if (onGoods.count >= count)
|
|
{
|
|
if (await goodsService.UpdateUserGoods(userId, 0, (int)onGoods.goodsId, count,
|
|
"航海事件触发"))
|
|
{
|
|
result = String.Format(eventData.tips, onGoods.goodsName, count);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = eventData.offSetTips;
|
|
}
|
|
}
|
|
}
|
|
else if (data.evType == nameof(MapEnum.RunEvent.reduce_blood))
|
|
{
|
|
bool isOp = await CheckOpEvent(userId, data.offsetData);
|
|
if (isOp)
|
|
{
|
|
int count = RandomAssist.UnitRandomNum((int)eventData.minCount, (int)eventData.maxCount + 1);
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
var myAttr = await attrService.GetUserAttrModel(userId);
|
|
myAttr.blood = myAttr.blood - count;
|
|
myAttr.blood = myAttr.blood < 1 ? 0 : myAttr.blood;
|
|
if (await attrService.UpdateUserBlood(userId, 2, myAttr.blood))
|
|
{
|
|
if (myAttr.blood == 0)
|
|
{
|
|
if (await StopUserRun(userId))
|
|
{
|
|
var mapService = App.GetService<IGameMapService>();
|
|
await mapService.SetUserMapDefult(userId);
|
|
}
|
|
}
|
|
}
|
|
|
|
result = String.Format(eventData.tips, count);
|
|
}
|
|
else
|
|
{
|
|
result = eventData.offSetTips;
|
|
}
|
|
}
|
|
else if (data.evType == nameof(MapEnum.RunEvent.add_blood))
|
|
{
|
|
bool isOp = await CheckOpEvent(userId, data.offsetData);
|
|
if (isOp)
|
|
{
|
|
int count = RandomAssist.UnitRandomNum((int)eventData.minCount, (int)eventData.maxCount + 1);
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
var myAttr = await attrService.GetUserAttrModel(userId);
|
|
myAttr.blood = myAttr.blood + count;
|
|
myAttr.blood = myAttr.blood > myAttr.upBlood ? myAttr.upBlood : myAttr.blood;
|
|
|
|
await attrService.UpdateUserBlood(userId, 2, myAttr.blood);
|
|
result = String.Format(eventData.tips, count);
|
|
}
|
|
else
|
|
{
|
|
result = eventData.offSetTips;
|
|
}
|
|
}
|
|
else if (data.evType == nameof(MapEnum.RunEvent.reduce_vigour))
|
|
{
|
|
bool isOp = await CheckOpEvent(userId, data.offsetData);
|
|
if (isOp)
|
|
{
|
|
int count = RandomAssist.UnitRandomNum((int)eventData.minCount, (int)eventData.maxCount + 1);
|
|
var attrService = App.GetService<IUnitUserAttrService>();
|
|
var myVigour = await attrService.GetUserVigourInfo(userId);
|
|
myVigour.vitality = myVigour.vitality - count;
|
|
myVigour.vitality = myVigour.vitality < 1 ? 0 : myVigour.vitality;
|
|
await attrService.UpdateUserVigour(userId, 2, (long)myVigour.vitality);
|
|
result = String.Format(eventData.tips, count);
|
|
}
|
|
else
|
|
{
|
|
result = eventData.offSetTips;
|
|
}
|
|
}
|
|
else if (data.evType == nameof(MapEnum.RunEvent.add_copper))
|
|
{
|
|
bool isOp = await CheckOpEvent(userId, data.offsetData);
|
|
if (isOp)
|
|
{
|
|
int count = RandomAssist.UnitRandomNum((int)eventData.minCount, (int)eventData.maxCount + 1);
|
|
var accService = App.GetService<IUnitUserAccService>();
|
|
await accService.UpdateUserCopper(userId, 1, count, "航海事件");
|
|
result = String.Format(eventData.tips, count);
|
|
}
|
|
else
|
|
{
|
|
result = eventData.offSetTips;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<bool> CheckOpEvent(string userId, string offSet)
|
|
{
|
|
bool isOp = true;
|
|
if (!string.IsNullOrEmpty(offSet))
|
|
{
|
|
var offsetData = JsonConvert.DeserializeObject<TowerNeed>(offSet);
|
|
var chekResult = await GameBus.CheakNeed(userId, offsetData, "");
|
|
if (chekResult.result)
|
|
{
|
|
if (offsetData.isOp == 0)
|
|
{
|
|
isOp = false;
|
|
}
|
|
else
|
|
{
|
|
var result = await GameBus.UpdateBag(userId, 0, offsetData.code, offsetData.parameter,
|
|
offsetData.count,
|
|
"航海事件");
|
|
isOp = !result;
|
|
}
|
|
}
|
|
}
|
|
|
|
return isOp;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 地图业务
|
|
|
|
public async Task<List<game_city_map_bus>> GetMapBus(string BusCode, int v, int l)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CITY_MAP_BUS", BusCode);
|
|
var data = await redis.GetAsync<List<game_city_map_bus>>(key);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map_bus>();
|
|
data = await db.Queryable<game_city_map_bus>().Where(it => it.busCode == BusCode).ToListAsync();
|
|
await redis.SetAsync(key, data);
|
|
}
|
|
|
|
if (data != null)
|
|
{
|
|
data = data.FindAll(it => it.bus_s <= v && it.bus_e >= v && it.bus_l == l);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public async Task<game_city_map_bus> GetMapBusInfo(int busId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CITY_MAP_BUS", "BUS_INFO");
|
|
if (await redis.HExistsHashAsync(key, busId.ToString()))
|
|
{
|
|
return await redis.GetHashAsync<game_city_map_bus>(key, busId.ToString());
|
|
}
|
|
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map_bus>();
|
|
var data = await db.Queryable<game_city_map_bus>().Where(it => it.busId == busId).SingleAsync();
|
|
await redis.AddHashAsync(key, busId.ToString(), data);
|
|
return data;
|
|
}
|
|
|
|
public async Task<bool> CheckBusPower(game_city_map_bus bus, string userId)
|
|
{
|
|
bool result = false;
|
|
var onMap = await GetUserOnMapId(userId);
|
|
var runInfo = await GetUserRun(userId);
|
|
if (onMap == bus.busCode)
|
|
{
|
|
if (runInfo == null)
|
|
{
|
|
result = true;
|
|
}
|
|
else if (runInfo.status == 0)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
if (result == false)
|
|
{
|
|
if (runInfo != null)
|
|
{
|
|
if (bus.busCode == String.Format("{0}_{1}", runInfo.onMap, runInfo.toMap) &&
|
|
runInfo.position >= bus.bus_s && runInfo.position <= bus.bus_e && bus.bus_l == runInfo.depth &&
|
|
runInfo.status == 1)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 地图资源
|
|
public async Task<game_city_map_res> GetMapResInfo(string resId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapResInfo");
|
|
var data = await redis.GetHashAsync<game_city_map_res>(key, resId);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map_res>();
|
|
data = await db.Queryable<game_city_map_res>().Where(it => it.resId == resId).SingleAsync();
|
|
await redis.AddHashAsync(key, resId, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
public async Task<List<game_city_map_res>> GetMapRes(string mapId)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapRes");
|
|
var data = await redis.GetHashAsync<List<game_city_map_res>>(key, mapId);
|
|
if (data == null)
|
|
{
|
|
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map_res>();
|
|
data = await db.Queryable<game_city_map_res>().Where(it => it.mapId == mapId).ToListAsync();
|
|
await redis.AddHashAsync(key, mapId, data);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
public async Task<List<MapResModel>> GetMapResData(string mapId, int area)
|
|
{
|
|
var data = await GetMapRes(mapId);
|
|
List<MapResModel> result = new List<MapResModel>();
|
|
foreach (var item in data)
|
|
{
|
|
long lockTime = await GetMapResLockTime(item.resId, area);
|
|
MapResModel temp = new MapResModel()
|
|
{
|
|
resId = item.resId,
|
|
resName = item.resName,
|
|
lev = (int)item.lev,
|
|
lockTime = lockTime,
|
|
needVigour = (int)item.needVigour,
|
|
gather = (int)item.gatherTime
|
|
};
|
|
result.Add(temp);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<long> GetMapResLockTime(string resId, int area)
|
|
{
|
|
long result = 0;
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapResLockTime");
|
|
string field = $"{area}_{resId}";
|
|
if (await redis.HExistsHashAsync(key, field))
|
|
{
|
|
long lockTime = await redis.GetHashAsync<long>(key, field);
|
|
result = lockTime - TimeExtend.GetTimeStampSeconds;
|
|
result = result <= 0 ? 0 : result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task SetMapResLockTime(string resId, int area, int lockTime)
|
|
{
|
|
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapResLockTime");
|
|
string field = $"{area}_{resId}";
|
|
long atTime = TimeExtend.GetTimeStampSeconds + lockTime;
|
|
await redis.AddHashAsync(key, field, atTime);
|
|
}
|
|
|
|
#endregion
|
|
} |