You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

702 lines
28 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Sog;
using ProtoCSStruct;
using System.Threading;
using TencentCloud.Cdn.V20180606.Models;
namespace Chat
{
public class SysNoticeSvc : BaseReloadableService
{
public static long m_lastTickTime = 0 ;
//配置文件被重新加载
public static void OnReloadConfig(string excelConfigFile)
{
if (string.IsNullOrEmpty(excelConfigFile) || excelConfigFile == "SysNoticeDesc.bin" || excelConfigFile == "SysNoticeDesc.txt")
{
//重新加载配置
LoadOnServerStart();
}
}
public static void LoadOnServerStart()
{
//清空老的
ChatServerUtils.GetChatServerData().m_sysNoticeList.Clear();
// SortedList<uint, SysNoticeDesc> descList = SysNoticeDescMgr.Instance.ItemTable;
// TraceLog.Debug("SysNoticeUtils.LoadOnServerStart begin, desc count {0}", descList.Count);
// foreach (SysNoticeDesc desc in descList.Values)
// {
// if (desc.state != 1) //未开启忽略
// {
// continue;
// }
// long startTime = ConfigStringTimeParse.ParseConfigTime(desc.startTime);
// long endTime = ConfigStringTimeParse.ParseConfigTime(desc.endTime);
// AddOneSysNotice(startTime, endTime, desc);
//
// }
ChatServerUtils.GetChatServerData().m_noticeBackgrounds.Clear();
}
public static void OnNoticeBackGgoundsTick(long nowMs)
{
if (nowMs - m_lastTickTime < 60000)
{
return;
}
m_lastTickTime = nowMs;
// 向 operationServer 请求背景图数据
SSNoticeBackGroundsReq backgroungdReq = new SSNoticeBackGroundsReq();
backgroungdReq.Language.SetString("");
ChatServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.NoticeBackgroundsReq, ref backgroungdReq, 0);
}
public static void ReloadByID(uint id)
{
}
/// <summary>
///检查公告是否有效
/// </summary>
/// <param name="notice"></param>
/// <returns></returns>
public static Tuple<bool, long, long> CheckSysNotice(int ID, int playerRealmID)
{
long timeSecond = ChatServerUtils.GetTimeSecond();
var noticeObj = ChatServerUtils.GetChatServerData().m_sysNoticeList.Find(f => f.notice.Id == ID);
var _ServerData = ChatServerUtils.GetChatServerData();
///服务器列表
var allRealm = _ServerData.m_allRealmMap;
RealmBriefInfo curRealm = null;
try
{
allRealm.TryGetValue(playerRealmID, out curRealm);
}
catch (Exception)
{
TraceLog.Error("SysNoticeSvc.CheckSysNotice get RealmBriefInfo by Id : playerRealmID :{0}", playerRealmID);
}
if (curRealm != null)
{
int realmTimeZone = curRealm.timeZone;
long diffTimeZone = (AppTime.TimeZone - realmTimeZone) * 3600;
timeSecond += diffTimeZone;
}
Tuple<bool, long, long> failres = new Tuple<bool, long, long>(false, 0, 0);
if (noticeObj == null || noticeObj.notice.Id == 0)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice not found id={0}", ID);
return failres;
}
//公告被禁用
if (noticeObj.notice.State != 1)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice id={0} state dont 1", ID);
return failres;
}
//公告不是针对全服
bool isRealm = true;
// 旧的公告判断方法
if (noticeObj.notice.Realmlist.Count != 0 && noticeObj.notice.Realmlist[0] != 0)
{
//在公告服务器列表中找到当前服
isRealm = false;
for(int i = 0; i < noticeObj.notice.Realmlist.Count; i++)
{
if (noticeObj.notice.Realmlist[i] == playerRealmID)
{
isRealm = true;
break;
}
}
}
else if (noticeObj.idInterValue != null)
{
isRealm = false;
// 全服
if (noticeObj.idInterValue.Count == 0)
{
isRealm = true;
}
for (int i = 0; i < noticeObj.idInterValue.Count; i++)
{
int beginRealm = RealmRule(noticeObj.idInterValue[i].Begin);
int endRealm = RealmRule(noticeObj.idInterValue[i].End);
int tempId = RealmRule(playerRealmID);
// 找到该服务器
if (beginRealm <= tempId && tempId <= endRealm)
{
isRealm = true;
break;
}
}
}
if (!isRealm)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} not all realm", ID);
return failres;
}
long m_startTime = 0;
long m_endTime = 0;
//##固定时间触发
if (noticeObj.notice.Triggertype == NoticeTriggerType.FixedTime)
{
//判断未开始的消息 过期的消息
if (timeSecond <= noticeObj.m_startTime || timeSecond >= noticeObj.m_endTime)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} time not march now={1},start={2},end={3}", ID,
timeSecond, noticeObj.m_startTime, noticeObj.m_endTime);
return failres;
}
else
{
return new Tuple<bool, long, long>(true, noticeObj.m_startTime, noticeObj.m_endTime);
}
}
//##开服时间触发
//开服时间计算应该不存在时区问题
else if (noticeObj.notice.Triggertype == NoticeTriggerType.OpeningTime)
{
//根据开服时间计算实际时间
if (curRealm == null)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} curRealm is null", ID);
return failres;
}
//开服时间大于等于 5点 按 当天5点计算开服时间 即 2021-07-10 06:00:00 =》 2021-07-10 05:00:00
//开服时间小于 5点 按 前天5点计算开服时间 即 2021-07-10 04:00:00 =》 2021-07-09 05:00:00
//再去计算偏移
var _openTime = ChatServerUtils.StampToDateTime(curRealm.openTime);
if (_openTime.Hour < 5)
{
_openTime = _openTime.AddDays(-1);
}
_openTime = new DateTime(_openTime.Year, _openTime.Month, _openTime.Day, 5, 0, 0);
////开始时间相对于开服时间偏移
AddTimes(ref _openTime, noticeObj.notice.Openserverstartday, noticeObj.notice.Openserverendtime.GetString());
m_startTime = ChatServerUtils.GetTimeStamp(_openTime);
//结束时间
AddTimes(ref _openTime, noticeObj.notice.Openserverendday, noticeObj.notice.Openserverendtime.GetString());
m_endTime = ChatServerUtils.GetTimeStamp(_openTime);
//无间隔天数,不循环
if (noticeObj.Intervaldays == 0)
{
//判断未开始和结束的消息
if (timeSecond <= m_startTime || timeSecond >= m_endTime)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} no open", ID);
return failres;
}
return new Tuple<bool, long, long>(true, m_startTime, m_endTime);
}
//有间隔天数 表示循环
else
{
//未开始的消息跳过
if (timeSecond < m_startTime)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} no start", ID);
return failres;
}
//已过结束时间 开始算循环 用结束时间往后推
if (timeSecond > m_endTime)
{
//0 间隔天数 1 持续时长
int timetype = 0;
long sTime = 0;
while (true)
{
//间隔天数
if (timetype == 0)
{
AddTimes(ref m_endTime, noticeObj.Intervaldays, "");
sTime = m_endTime;
}
//持续时长
else if (timetype == 1)
{
AddTimes(ref m_endTime, noticeObj.notice.Openserverendday, noticeObj.notice.Openserverendtime.GetString());
}
//在本次结束时间之内
if (timeSecond < m_endTime)
{
break;
}
else
{
timetype = timetype == 1 ? 0 : 1;
}
}
//在间隔期内则不展示
if (timetype == 0)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} type is 0", ID);
return failres;
}
else
{
return new Tuple<bool, long, long>(true, sTime, m_endTime);
}
}
else
{
return new Tuple<bool, long, long>(true, m_startTime, m_endTime);
}
}
}
// 定时触发
else
{
// 小于开始时间
if (timeSecond <= noticeObj.m_startTime || noticeObj.Intervaldays == 0)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} now no start", ID);
return failres;
}
// 从活动开始到现在天数
var duration = (timeSecond - noticeObj.m_startTime) / (24 * 60 * 60);
// 活动当天已经过了多少小时
var resHour = ((timeSecond - noticeObj.m_startTime) % (24 * 60 * 60)) / 60 * 60;
var resDay = duration % noticeObj.Intervaldays;
if (resDay >= noticeObj.notice.Openserverendday)
{
TraceLog.Trace("SysNoticeSvc.CheckSysNotice ID={0} resDay is long", ID);
return failres;
}
long endtime = noticeObj.m_startTime + (noticeObj.Intervaldays * 24 * 60 * 60);
return new Tuple<bool, long, long>(true, noticeObj.m_startTime, endtime);
}
}
/// <summary>
/// 添加或更新来自OperationServer的公告推送
/// </summary>
/// <param name="notice"></param>
public static void AddOneSysNotice(ref SSSysNotice notice)
{
List<SysNoticeObj> list = ChatServerUtils.GetChatServerData().m_sysNoticeList;
//重复的老的先删除,这样支持reload一个配置
foreach (var item in list)
{
if (item.noticeId == notice.NoticeId)
{
list.Remove(item);
TraceLog.Debug("SysNoticeUtils.AddOneSysNotice id {0} duplicate remove old desc", notice.Id);
break;
}
}
//update seq in chat server
ChatServerUtils.GetChatServerData().m_sysNoticeSeq =
Math.Max(notice.Seq, ChatServerUtils.GetChatServerData().m_sysNoticeSeq);
SysNoticeObj obj = new SysNoticeObj();
//obj.m_desc = new SysNoticeDesc().Pase(ref notice);
obj.notice = notice;
obj.m_seq = notice.Seq; //ChatServerUtils.GetChatServerData().m_sysNoticeSeq;
obj.m_startTime = notice.StartTime;
obj.sort = notice.Sort;
obj.m_endTime = notice.EndTime;
obj.m_upTime = notice.Uptime;
obj.Intervaldays = notice.Intervaldays;
obj.IsShowTimetext = notice.Showtimetext;
obj.IsAllSvr = notice.IsAllSvr;
obj.giftbagcustoms = notice.Giftbagcustoms;
obj.ext = notice.ExtNotice;
obj.noticeId = notice.NoticeId;
obj.language = notice.Language.GetString();
obj.pageType = notice.PageType;
obj.idInterValue = GetRealmPosList(notice.ExtNotice.RealmListStr.GetString());
list.Add(obj);
TraceLog.Debug("SysNoticeSvc.AddOneSysNotice seq {0} id {1} language {2} pic {3}"
, obj.m_seq, obj.noticeId, obj.language, notice.Title.ToString());
}
//
private static List<RealmPos> GetRealmPosList(string realmlistStr)
{
//realmlistStr exp:100001-100004#200001-200004#300001,300006#400005
List<RealmPos> posList = new List<RealmPos>();
try
{
var realmStrlist = realmlistStr.Split("#");
foreach (var realmlist in realmStrlist)
{
if (realmlist == "" && realmStrlist.Length != 1)
{
continue;
}
if (realmlist.Contains('-'))
{
var tempList = realmlist.Split("-");
RealmPos tempPos = new RealmPos();
tempPos.Begin = Convert.ToInt32(tempList[0]);
tempPos.End = Convert.ToInt32(tempList[1]);
posList.Add(tempPos);
}
else
{
if (realmlist.Contains(','))
{
var realms = realmlist.Split(',');
// 排序
List<int> sortRealmList = new List<int>();
foreach (var _RealmID in realms)
{
int tempId = Convert.ToInt32(_RealmID);
sortRealmList.Add(tempId);
}
sortRealmList.Sort((x, y) => x.CompareTo(y));
if (sortRealmList.Count == 1)
{
var realmPos = new RealmPos();
realmPos.Begin = sortRealmList[0];
realmPos.End = sortRealmList[0];
posList.Add(realmPos);
}
else if (sortRealmList.Count == 2)
{
if (sortRealmList[0] + 1 == sortRealmList[1])
{
var realmPos = new RealmPos();
realmPos.Begin = sortRealmList[0];
realmPos.End = sortRealmList[1];
posList.Add(realmPos);
}
else
{
var realmPos1 = new RealmPos();
realmPos1.Begin = sortRealmList[0];
realmPos1.End = sortRealmList[0];
posList.Add(realmPos1);
var realmPos2 = new RealmPos();
realmPos2.Begin = sortRealmList[1];
realmPos2.End = sortRealmList[1];
posList.Add(realmPos2);
}
}
else
{
for (int i = 0; i < sortRealmList.Count; i++)
{
var realmPos = new RealmPos();
realmPos.Begin = sortRealmList[i];
for (int j = i; j < sortRealmList.Count - 1; j++)
{
//列表连续
if (sortRealmList[j + 1] == sortRealmList[j] + 1)
{
continue;
}
else
{
realmPos.End = sortRealmList[j];
i = j;
break;
}
}
if (realmPos.End == 0)
{
realmPos.End = sortRealmList[i];
}
posList.Add(realmPos);
}
}
}
else
{
if (realmlist != "" && realmlist != null)
{
int RealmID = Convert.ToInt32(realmlist);
if (RealmID != 0)
{
var realmPos = new RealmPos();
realmPos.Begin = RealmID;
realmPos.End = RealmID;
posList.Add(realmPos);
}
}
}
}
}
}
catch (Exception ex)
{
TraceLog.Error("MailSendWithRule.ParseRealm error:{0}", ex.Message);
return posList;
}
return posList;
}
// private static void AddOneSysNotice(long startTime, long endTime, SysNoticeDesc desc)
// {
//
// List<SysNoticeObj> list = ChatServerUtils.GetChatServerData().m_sysNoticeList;
//
// //重复的老的先删除,这样支持reload一个配置
// foreach (var item in list)
// {
// if (item.m_desc.id == desc.id)
// {
// list.Remove(item);
//
// TraceLog.Debug("SysNoticeUtils.AddOneSysNotice id {0} duplicate remove old desc", desc.id);
//
// break;
// }
// }
//
// // ChatServerUtils.GetChatServerData().m_sysNoticeSeq++;
//
// SysNoticeObj obj = new SysNoticeObj();
// obj.m_desc = desc;
// obj.m_seq = ChatServerUtils.GetChatServerData().m_sysNoticeSeq;
// obj.m_startTime = startTime;
// obj.m_endTime = endTime;
// obj.language = desc.language.ToLower();
// obj.pageType = desc.pageType;
// list.Add(obj);
//
// TraceLog.Debug("SysNoticeUtils. seq {0} id {1} content {2}"
// , obj.m_seq, obj.m_desc.id, obj.m_desc.content);
// }
// private static void RemoveOneSysNoticeByID(uint id)
// {
// List<SysNoticeObj> list = ChatServerUtils.GetChatServerData().m_sysNoticeList;
//
// //重复的老的先删除,这样支持reload一个配置
// foreach (var item in list)
// {
// if (item.m_desc.id == id)
// {
// list.Remove(item);
// TraceLog.Debug("SysNoticeUtils.RemoveOneSysNoticeByID id {0} duplicate remove old desc", id);
// //ChatServerUtils.GetChatServerData().m_sysNoticeSeq++;
// break;
// }
// }
// }
/// <summary>
/// 时长转秒数
/// </summary>
/// <param name="day"></param>
/// <param name="hour"></param>
/// <param name="minute"></param>
/// <param name="second"></param>
/// <returns></returns>
///
private static void AddTimes(ref long date, int day, string time)
{
var dateobj = ChatServerUtils.StampToDateTime(date);
AddTimes(ref dateobj, day, time);
date = ChatServerUtils.GetTimeStamp(dateobj);
}
private static void AddTimes(ref DateTime date, int day, string time)
{
int hour; int minute; int second;
var times = time.Split(':');
if (day != 0)
{
date = date.AddDays(day);
}
if (times.Length == 3)
{
hour = int.Parse(times[0]);
if (hour != 0)
{
date = date.AddHours(hour);
}
minute = int.Parse(times[1]);
if (minute != 0)
{
date = date.AddMinutes(minute);
}
second = int.Parse(times[2]);
if (second != 0)
{
date = date.AddSeconds(second);
}
}
}
/// <summary>
/// type(公告类型): 0 - all, 1 - popUp, 2 - click
/// </summary>
/// <param name="res"></param>
/// <param name="player"></param>
/// <param name="seq"></param>
/// <param name="language"></param>
/// <param name="type"></param>
public static void FillSysNotices(ref CSQuerySysNoticeRes res, PlayerOnChat player, int seq, string language, int type=0)
{
res.LastSeq = ChatServerUtils.GetChatServerData().m_sysNoticeSeq;
if (seq >= ChatServerUtils.GetChatServerData().m_sysNoticeSeq)
{
return;
}
var _ServerData = ChatServerUtils.GetChatServerData();
///公告列表
List<SysNoticeObj> list = _ServerData.m_sysNoticeList;
//公告这里需要排序 暂时倒序sort
foreach (SysNoticeObj noticeObj in list.OrderByDescending(s => s.sort))
{
var Checkres = CheckSysNotice(noticeObj.notice.Id, player.RealmID);
if (!Checkres.Item1)
{
TraceLog.Trace("SysNoticeSvc.FillSysNotices id={0}, noticeId={1} ,check result false",
noticeObj.notice.Id, noticeObj.noticeId);
continue;
}
if (language.ToLower() != noticeObj.language.ToLower())
{
TraceLog.Trace("SysNoticeSvc.FillSysNotices id={0}, noticeId={1} ,language not march",noticeObj.notice.Id, noticeObj.noticeId);
continue;
}
var notice = new CSSysNotice();
notice.Seq = noticeObj.m_seq;
if (noticeObj.notice.Triggertype == 0)
{
notice.StartTime = noticeObj.m_startTime;
notice.EndTime = noticeObj.m_endTime;
}
else
{
notice.StartTime = Checkres.Item2;
notice.EndTime = Checkres.Item3;
}
notice.Title.SetString(player.GetPlayerLanguageStr(noticeObj.notice.Title.GetString()));
notice.Content.SetString(player.GetPlayerLanguageStr(noticeObj.notice.Content.GetString()));
notice.Icon.SetString(noticeObj.notice.Icon.GetString());
notice.Pic.SetString(noticeObj.notice.Pic.GetString());
notice.Jump = noticeObj.notice.Jump;
// notice.Popup = noticeObj.m_desc.popUp;
notice.Id = (int)noticeObj.notice.Id;
notice.Link.SetString(noticeObj.notice.Link.GetString());
notice.Dungeonid = noticeObj.notice.Dungeonid;
notice.Sort = noticeObj.sort;
notice.IsShow = noticeObj.notice.State == 1;
notice.Showtimetext = noticeObj.IsShowTimetext;
notice.IsAllSvr = noticeObj.IsAllSvr;
notice.Giftbagcustoms = noticeObj.giftbagcustoms;
notice.JumpParam = noticeObj.notice.JumpParam;
notice.PageType = noticeObj.pageType;
if (notice.PageType == 0)
{
notice.PageType = noticeObj.notice.PageType;
}
//扩展字段
if (noticeObj.ext.Havedata)
{
notice.Type = noticeObj.ext.Type;
notice.TextParams = noticeObj.ext.TextParams;
}
if (noticeObj.notice.Popup == 1)
{
if(type == 2)
{
TraceLog.Trace("SysNoticeSvc.FillSysNotices id={0}, noticeId={1} ,type={2} not march",noticeObj.notice.Id, noticeObj.noticeId,type);
continue;
}
if (res.PopupList.Count < res.PopupList.GetMaxCount())
{
res.PopupList.Add(notice);
}
else
{
TraceLog.Error("SysNoticeSvc.FillSysNotices CSSysNotice.List over MaxCount");
}
}
else
{
if (type == 1)
{
TraceLog.Trace("SysNoticeSvc.FillSysNotices id={0}, noticeId={1} ,type={2} not march",noticeObj.noticeId, noticeObj.noticeId,type);
continue;
}
if (res.ClickList.Count < res.ClickList.GetMaxCount())
{
res.ClickList.Add(notice);
}
else
{
TraceLog.Error("SysNoticeSvc.FillSysNotices CSSysNotice.List over MaxCount");
}
}
}
}
private static int RealmRule(int realmId)
{
string realmStr = realmId.ToString();
if (realmStr.Length < 6)
return realmId;
string area = realmStr.Substring(0, 1);
string reaml = realmStr.Substring(3);
Int32.TryParse(area + reaml, out int result);
return result;
}
public override int GetServiceType()
{
return ChatServiceType.SysNotice;
}
public override void Dispose()
{
ChatServerUtils.GetChatServerData().m_sysNoticeList.Clear();
}
}
}