forked from powerfun/udpservice
187 lines
7.4 KiB
C#
187 lines
7.4 KiB
C#
using OnlineUserPool.Api;
|
||
using OnlineUserPool.Model;
|
||
using OnlineUserPool.Unility;
|
||
|
||
using Serilog;
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Timers;
|
||
|
||
namespace OnlineUserPool.Hander
|
||
{
|
||
public class MapRecordRankingHander : IHandle
|
||
{
|
||
private static List<MapRecordRanking> mapRecordRankings = new List<MapRecordRanking>();
|
||
private static object locker = new object();//防止服务端响应慢,多次加载
|
||
//private int top = ConfigHelp.Top;
|
||
|
||
public MapRecordRankingHander()
|
||
{
|
||
Init();
|
||
//var timer = new Timer();
|
||
//timer
|
||
}
|
||
|
||
private void Init()
|
||
{
|
||
if (ConfigHelp.Top > 0)
|
||
{
|
||
var records = WebService.GetMapRouteRandomRecord(START, null);
|
||
mapRecordRankings.AddRange(WebService.GetRecordFileFromServer(records.Select(n => n.Id).ToList()));
|
||
UpdateVirtualTime = DateTime.Now;
|
||
//var pageSize = 10;
|
||
//var pageCount = (int)Math.Ceiling(records.Count / (double)pageSize);
|
||
//for (int i = 0; i < pageCount; i++)
|
||
//{
|
||
// mapRecordRankings.AddRange(WebService.GetRecordFileFromServer(records.Skip(i * pageSize).Take(pageSize).Select(n => n.Id).ToList()));
|
||
//}
|
||
}
|
||
}
|
||
|
||
private const int START = 15;
|
||
private const int SMALL = 30;
|
||
private const int MEDIUM = 50;
|
||
private const int LARGE = 80;
|
||
private const int OFFSET = 30;
|
||
|
||
//根据当前时段计算虚拟总人数
|
||
private int ComputeTop()
|
||
{
|
||
var rand = new Random();
|
||
|
||
var hour = DateTime.Now.Hour;//当前点数
|
||
int offset = 1;//少:1 中:3 多:10
|
||
if (hour <= 6)
|
||
{
|
||
offset = rand.Next((int)(0.8 * START), (int)(1.2 * START));
|
||
}
|
||
if (hour > 6 && hour <= 18)
|
||
{
|
||
offset = rand.Next((int)(0.8 * OFFSET), (int)(1.2 * MEDIUM));
|
||
}
|
||
if (hour >= 18 && hour <= 22)
|
||
{
|
||
offset = rand.Next((int)(0.8 * LARGE), (int)(1.2 * LARGE));
|
||
}
|
||
if (hour > 22 && hour <= 24)
|
||
{
|
||
offset = rand.Next((int)(0.8 * SMALL), (int)(1.2 * SMALL));
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取虚拟人物数据
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public List<MsgModel> GetVirtualUserData()
|
||
{
|
||
List<MsgModel> msgModels = new List<MsgModel>();
|
||
if(ConfigHelp.ShowVirtualUser == false)
|
||
{
|
||
return msgModels;
|
||
}
|
||
if (mapRecordRankings != null)
|
||
{
|
||
for (int i = 0; i < mapRecordRankings.Count; i++)
|
||
{
|
||
try
|
||
{
|
||
var item = mapRecordRankings[i];
|
||
item.CurrentIndex++;
|
||
TargetData targetData = item.GetCurrentTargetData();
|
||
//List<string> prop = new List<string>()
|
||
//{
|
||
// Math.Round(targetData._Speed, 2).ToString(),
|
||
// targetData._Power.ToString(),
|
||
// targetData._Cadence.ToString()
|
||
//};
|
||
var weightKg = 0.0D;
|
||
if(targetData._Power >= 0)
|
||
{
|
||
weightKg = Math.Round(targetData._Power / item.Weight, 2);
|
||
}
|
||
|
||
if (item.CurrentIndex == 0)
|
||
{
|
||
//机器人上线
|
||
var loginInfo = new MsgModel()
|
||
{
|
||
exit = item.End,
|
||
IsCompleted = item.End,
|
||
MemberId = item.UserId,//虚拟的人Id变为负数
|
||
Point = new double[] { -1d, -1d },
|
||
//Prop = string.Join(',', prop),
|
||
RouteId = item.RouteId,
|
||
EndDistance = Math.Round(targetData._Distance, 6),
|
||
//ShowVirtual = true,
|
||
CommandType = 1,
|
||
//IsVirtual = true,
|
||
Speed = targetData._Speed,
|
||
WeightKg = weightKg,
|
||
PreDistance = item.GetPreDistance()
|
||
};
|
||
msgModels.Add(loginInfo);
|
||
}
|
||
var info = new MsgModel()
|
||
{
|
||
exit = item.End,
|
||
IsCompleted = item.End,
|
||
MemberId = item.UserId,//虚拟的人Id变为负数
|
||
Point = new double[] { Math.Round(targetData._Lat, 6), Math.Round(targetData._Lon, 6) },
|
||
//Prop = string.Join(',', prop),
|
||
RouteId = item.RouteId,
|
||
EndDistance = Math.Round(targetData._Distance, 6),
|
||
//ShowVirtual = true,
|
||
CommandType = 1,
|
||
//IsVirtual = true,
|
||
Speed = targetData._Speed,
|
||
WeightKg = weightKg,
|
||
PreDistance = item.GetPreDistance()
|
||
};
|
||
msgModels.Add(info);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error("加载虚拟人物错误:" + e.Message + "\r\n" + e.StackTrace);
|
||
}
|
||
}
|
||
}
|
||
return msgModels;
|
||
}
|
||
const int offset = 1;
|
||
const int timeInterval = 15;
|
||
private DateTime UpdateVirtualTime { get; set; }
|
||
/// <summary>
|
||
/// 删除已经骑行完的人,添加新的人物进去
|
||
/// </summary>
|
||
public void RemoveEndAndAddNewVirtualUser(int customerCount)
|
||
{
|
||
lock (locker)
|
||
{
|
||
//var offlineCount = mapRecordRankings.Where(c => c.End).Count();//下线人数
|
||
var top = ComputeTop();//理论上当前时间段虚拟用户的总数
|
||
mapRecordRankings.RemoveAll(n => n.End);//移除骑行结束的人
|
||
var routeIds = mapRecordRankings.Select(n => n.RouteId).Distinct().ToList();
|
||
|
||
var currentVirtualCount = mapRecordRankings.Count(d => d.UserId < 0);//实际虚拟用户数
|
||
if (top - currentVirtualCount > 0)
|
||
{
|
||
var interval = DateTime.Now - UpdateVirtualTime;
|
||
if (interval.TotalSeconds > timeInterval)
|
||
{
|
||
UpdateVirtualTime = DateTime.Now;
|
||
var needUpdateCount = offset;//这一秒需要上线的人数
|
||
var randomUser = WebService.GetMapRouteRandomRecord(needUpdateCount, routeIds);
|
||
var addRankings = WebService.GetRecordFileFromServer(randomUser.Select(n => n.Id).ToList());
|
||
mapRecordRankings.AddRange(addRankings);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|