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.
425 lines
16 KiB
425 lines
16 KiB
/*
|
|
Sog 游戏基础库
|
|
2016 by zouwei
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
using Sog;
|
|
using Sog.Gate;
|
|
|
|
using ProtoCSStruct;
|
|
|
|
namespace Version
|
|
{
|
|
public class VersionMsgHandler
|
|
{
|
|
private ServerApp m_app;
|
|
|
|
private VersionSvc m_versionSvc;
|
|
|
|
public VersionMsgHandler(ServerApp app)
|
|
{
|
|
m_app = app;
|
|
|
|
m_versionSvc = new VersionSvc(app);
|
|
|
|
}
|
|
|
|
public VersionSvc GetVersionSvcObj()
|
|
{
|
|
return m_versionSvc;
|
|
}
|
|
|
|
public ServerApp GetApp()
|
|
{
|
|
return m_app;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_app = null;
|
|
m_versionSvc.Dispose();
|
|
m_versionSvc = null;
|
|
}
|
|
|
|
|
|
public void HandlerMessage(uint remoteAppID, MessageData message)
|
|
{
|
|
int iServerType = ServerIDUtils.GetServerType(remoteAppID);
|
|
|
|
if (iServerType == (int)ServerType.VersionGate)
|
|
{
|
|
TraceLog.Trace("VersionMsgHandler.HandlerMessage recv msg from gate length {0}", message.Header.Length);
|
|
HandlerGateMessage(remoteAppID, message);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Trace("VersionMsgHandler.HandlerMessage recv msg from server type {0} length {1}", iServerType, message.Header.Length);
|
|
HandlerOtherServerMessage(remoteAppID, message);
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void HandlerGateMessage(uint remoteAppID, MessageData message)
|
|
{
|
|
GateMsgHeader header = new GateMsgHeader();
|
|
GateMsgHeaderPacker.UnPack(message.Buffer.Data, ref header);
|
|
|
|
// trans msg to client
|
|
if (header.OpCode == (int)GateMsgOpCode.Trans)
|
|
{
|
|
HandlerClientGateMessage(remoteAppID, message);
|
|
return;
|
|
}
|
|
|
|
if (header.OpCode == (int)GateMsgOpCode.ConnectedReq)
|
|
{
|
|
OnSessionConnected(remoteAppID, header.SessionID);
|
|
return;
|
|
}
|
|
|
|
if (header.OpCode == (int)GateMsgOpCode.DisconnectedReq)
|
|
{
|
|
OnSessionDisconnected(remoteAppID, header.SessionID);
|
|
return;
|
|
}
|
|
|
|
//int headLength = GateMsgHeaderPacker.GetLength();
|
|
|
|
}
|
|
|
|
private void OnSessionConnected(uint gateServerID, long sessionID)
|
|
{
|
|
TraceLog.Trace("VersionMsgHandler.OnSessionConnected session {0} connected, new PlayerSession", sessionID);
|
|
|
|
//回应
|
|
GateMsgHeader gateHeader;
|
|
|
|
gateHeader.OpCode = (int)GateMsgOpCode.ConnectedRes;
|
|
gateHeader.SessionID = sessionID;
|
|
|
|
GateService.NotifyGateServer(m_app,gateServerID, ref gateHeader);
|
|
|
|
m_versionSvc.AddClientConnectData(gateServerID, sessionID);
|
|
}
|
|
|
|
private void OnSessionDisconnected(uint gateServerID, long sessionID)
|
|
{
|
|
TraceLog.Debug("VersionMsgHandler.OnSessionDisconnected session {0} disconnected, delete PlayerSession"
|
|
, sessionID);
|
|
m_versionSvc.RemoveClientConnectData(gateServerID, sessionID);
|
|
}
|
|
|
|
private void HandlerClientGateMessage(uint gateServerID, MessageData gateMessage)
|
|
{
|
|
long sessionID = gateMessage.Header.ObjectID;
|
|
|
|
int headLength = GateMsgHeaderPacker.GetLength();
|
|
|
|
MessageData message = new MessageData();
|
|
message.Header.Type = gateMessage.Header.Type;
|
|
message.Header.Length = gateMessage.Header.Length - headLength;
|
|
|
|
if (message.Header.Length < 0)
|
|
{
|
|
TraceLog.Trace("VersionMsgHandler.HandlerClientGateMessage recv session {0} message ,gateMessage length error ", sessionID);
|
|
return;
|
|
}
|
|
|
|
message.MallocData(message.Header.Length);
|
|
//message.Data = new byte[message.Header.Length];
|
|
Buffer.BlockCopy(gateMessage.Buffer.Data, headLength, message.Buffer.Data, 0, message.Buffer.Length);
|
|
try
|
|
{
|
|
HandlerClientMessage(gateServerID, sessionID, message);
|
|
}
|
|
finally
|
|
{
|
|
message.FreeData();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void HandlerClientMessage(uint gateServerID, long sessionID, MessageData message)
|
|
{
|
|
try
|
|
{
|
|
StructPacket packet;
|
|
bool result = VersionServerUtils.GetProtoPacker().UnpackMessage(message, out packet);
|
|
if (result)
|
|
{
|
|
//预先判断,提高效率
|
|
if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail
|
|
&& TraceLog.IsSkipLogMsgID(packet.MsgID) == false)
|
|
{
|
|
// log message
|
|
TraceLog.TraceDetail("VersionMsgHandler.HandlerClientMessage recv from session {0} from gateServer {1}, message type {2} length {3} : {4}->{5}"
|
|
, sessionID
|
|
, ServerIDUtils.IDToString(gateServerID)
|
|
, message.Header.Type
|
|
, message.Header.Length
|
|
, packet.MessageName()
|
|
, packet.ToString());
|
|
}
|
|
|
|
|
|
ProcessClientPacket(gateServerID, sessionID, packet);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TraceLog.Error("VersionMsgHandler.HandlerClientMessage Received from session:{0} error:{1}", sessionID, ex.Message);
|
|
TraceLog.Exception(ex);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void HandlerOtherServerMessage(uint remoteAppID, MessageData message)
|
|
{
|
|
|
|
try
|
|
{
|
|
StructPacket packet;
|
|
bool result = VersionServerUtils.GetProtoPacker().UnpackMessage(message, out packet);
|
|
if (result)
|
|
{
|
|
if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail
|
|
&& TraceLog.IsSkipLogMsgID(packet.MsgID) == false)
|
|
{
|
|
// log message
|
|
TraceLog.TraceDetail("VersionMsgHandler.HandlerOtherServerMessage recv message from server {0}, message type {1} length {2} : {3}->{4}"
|
|
, ServerIDUtils.IDToString(remoteAppID)
|
|
, message.Header.Type
|
|
, message.Header.Length
|
|
, packet.MessageName()
|
|
, packet.ToString());
|
|
}
|
|
|
|
|
|
ProcessServerPacket(remoteAppID, packet);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TraceLog.Error("VersionMsgHandler.HandlerOtherServerMessage Received from server:{0} error:{1}", ServerIDUtils.IDToString(remoteAppID), ex.Message);
|
|
TraceLog.Exception(ex);
|
|
}
|
|
}
|
|
|
|
private void ProcessClientPacket(uint gateServerID, long sessionID, StructPacket packet)
|
|
{
|
|
if(packet.MsgID == (int)CSMsgID.VersionReq)
|
|
{
|
|
ProcessVersionReq(gateServerID,sessionID,packet);
|
|
}
|
|
}
|
|
|
|
private void ProcessVersionReq(uint gateServerID, long sessionID, StructPacket packet)
|
|
{
|
|
ref CSVersionCheckReq req = ref packet.GetMessage<CSVersionCheckReq>();
|
|
|
|
//非法消息可以不用管
|
|
if (m_versionSvc.CheckValidVersionInfo(ref req.Version) == false)
|
|
{
|
|
TraceLog.Error("VersionMsgHandler.ProcessVersionReq versioninfo invalid! session {0}", sessionID);
|
|
return;
|
|
}
|
|
|
|
long reqVersion = AppVersion.ToIntVersion(req.Version.AppVersion.GetString());
|
|
if(reqVersion == 0)
|
|
{
|
|
TraceLog.Error("VersionMsgHandler.ProcessVersionReq versioninfo invalid, session {0}, version {1}", sessionID, req.Version.AppVersion);
|
|
return;
|
|
}
|
|
|
|
// 强行把windows版本修改成android版本, 方便unity下测试
|
|
if (req.Version.Os.Equals("win"))
|
|
{
|
|
req.Version.Os.SetString("android");
|
|
}
|
|
|
|
long currVer = m_versionSvc.GetCurrentVersion(ref req.Version);
|
|
|
|
CSVersionCheckRes res = new CSVersionCheckRes();
|
|
|
|
//最先判断服务器是否在维护
|
|
if (m_versionSvc.IsMaintenanceMode())
|
|
{
|
|
res.Ret = 0;
|
|
res.MaintenanceMode = 1;
|
|
res.MaintenanceNotice.SetString( m_versionSvc.GetMaintenanceNotice());
|
|
|
|
TraceLog.Trace("VersionMsgHandler.ProcessVersionReq server maintenance now, session {0} version {1}"
|
|
, sessionID, req.Version.AppVersion);
|
|
|
|
GateService.SendToGate(0, m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.VersionRes, ref res);
|
|
return;
|
|
}
|
|
|
|
// 当前版本有热更包, 客户端在更新完upk后再更新hotPatch
|
|
if (m_versionSvc.HasHotPatch())
|
|
{
|
|
string currVerStr = AppVersion.ToStringVersion(currVer);
|
|
int hotPatchSize = m_versionSvc.GetHotPatchFileSizeAndMd5(ref req.Version, currVerStr, out string hotMd5);
|
|
if (hotPatchSize > 0)
|
|
{
|
|
res.HotPatchFileMd5.SetString(hotMd5);
|
|
res.HotPatchFileSize = hotPatchSize;
|
|
string hotUrl = m_versionSvc.GetHotPatchFileUrl(ref req.Version, currVerStr);
|
|
res.HotPatchDownloadUrl.SetString(hotUrl);
|
|
|
|
TraceLog.Trace("VersionMsgHandler.ProcessVersionReq hot url {0} size {1} md5 {2}"
|
|
, hotUrl, hotPatchSize, hotMd5);
|
|
}
|
|
}
|
|
|
|
int forReview = 0;
|
|
// 版本服务器配置了不更新, win版本由客户端屏蔽更新, 方便unity下测试
|
|
//if (m_versionSvc.IsSkipCheckVersion() || req.Version.Os.Equals( "win"))
|
|
if (m_versionSvc.IsSkipCheckVersion())
|
|
{
|
|
res.Ret = 0;
|
|
res.NewVersion.SetString(req.Version.AppVersion.GetPtr());
|
|
res.GateUrl.SetString( m_versionSvc.SelectGateUrl(ref req, out forReview));
|
|
res.ForReview = forReview;
|
|
|
|
TraceLog.Trace("VersionMsgHandler.ProcessVersionReq version is need not check {0} , need not update, gateUrl {1}", req.Version, res.GateUrl);
|
|
|
|
GateService.SendToGate(0,m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.VersionRes, ref res);
|
|
return;
|
|
}
|
|
|
|
TraceLog.Debug("VersionMsgHandler.ProcessVersionReq versioninfo session {0}, Appversion {1} Os {2}, Language {3}, currVer {4}, reqVersion {5}",
|
|
sessionID, req.Version.AppVersion, req.Version.Os, req.Version.Language, currVer, reqVersion);
|
|
|
|
//版本号比当前版本大, 不需要更新
|
|
if (reqVersion >= currVer)
|
|
{
|
|
res.Ret = 0;
|
|
res.NewVersion.SetString( AppVersion.ToStringVersion(currVer));
|
|
res.GateUrl.SetString( m_versionSvc.SelectGateUrl(ref req, out forReview));
|
|
res.ForReview = forReview;
|
|
|
|
TraceLog.Trace("VersionMsgHandler.ProcessVersionReq reqVersion {0} >= curVersion {1}, need not udpate, gateUrl {2}"
|
|
, req.Version, res.NewVersion, res.GateUrl);
|
|
|
|
GateService.SendToGate(0,m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.VersionRes, ref res);
|
|
return;
|
|
}
|
|
|
|
string strPathUrl = m_versionSvc.GetPatchFileUrl(ref req.Version, currVer, reqVersion);
|
|
int patchFileSize = m_versionSvc.GetPatchFileSizeAndMd5(ref req.Version, currVer, reqVersion, out string md5);
|
|
|
|
// 更新包不存在, 告诉客户端去商店更新apk
|
|
if (patchFileSize <= 0)
|
|
{
|
|
res.Ret = 0;
|
|
res.NewVersion.SetString(AppVersion.ToStringVersion(currVer));
|
|
res.GateUrl.SetString(m_versionSvc.SelectGateUrl(ref req, out forReview));
|
|
res.ForReview = forReview;
|
|
res.NeedUpdateApk = 1;
|
|
|
|
GateService.SendToGate(0, m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.VersionRes, ref res);
|
|
return;
|
|
}
|
|
|
|
foreach (var item in VersionUpdateCompensateDescMgr.Instance.ItemTable)
|
|
{
|
|
long updateVer = AppVersion.ToIntVersion(item.appVersion);
|
|
|
|
TraceLog.Debug("VersionMsgHandler.ProcessVersionReq session {0} updateVer {1} currVer {2}"
|
|
, sessionID, updateVer, currVer);
|
|
|
|
long endTime = ConfigStringTimeParse.ParseConfigTime(item.endTime);
|
|
|
|
if (updateVer == currVer)
|
|
{
|
|
//没过期则有奖励
|
|
if (endTime == 0 || endTime > VersionServerUtils.GetTimeSecond())
|
|
{
|
|
res.Chip = item.chip;
|
|
res.Diamond = item.diamond;
|
|
res.ItemID = item.itemid;
|
|
res.ItemCount = item.itemcount;
|
|
}
|
|
|
|
//更新内容
|
|
if (! string.IsNullOrWhiteSpace(item.content))
|
|
{
|
|
res.Content.SetString(Sog.Lang.LanguageUtils.GetLanguageString(item.content, req.Version.Language.GetString()));
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
res.Ret = 0;
|
|
res.NewVersion.SetString( AppVersion.ToStringVersion(currVer));
|
|
res.GateUrl.SetString( m_versionSvc.SelectGateUrl(ref req, out forReview));
|
|
res.ForReview = forReview;
|
|
res.DownloadUrl.SetString( strPathUrl);
|
|
res.PatchFileSize = patchFileSize;
|
|
res.PatchFileMd5.SetString( md5);
|
|
|
|
TraceLog.Trace("VersionMsgHandler.ProcessVersionReq path url is {0}, gateUrl {1} size {2} md5 {3}"
|
|
, strPathUrl, res.GateUrl, res.PatchFileSize, res.PatchFileMd5);
|
|
|
|
GateService.SendToGate(0,m_app.GetCluster(), gateServerID, sessionID, (int)CSMsgID.VersionRes, ref res);
|
|
}
|
|
|
|
private void ProcessServerPacket(uint remoteAppID, StructPacket packet)
|
|
{
|
|
switch (packet.MsgID)
|
|
{
|
|
case (int) SSMsgID.GetClientVerionReq:
|
|
OnServerGetClientVersion(remoteAppID, packet);
|
|
break;
|
|
|
|
default:
|
|
TraceLog.Error("VersionMsgHandler.ProcessServerPacket MsgID {0} not handle", packet.MsgID);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void OnServerGetClientVersion(uint remoteAppID, StructPacket packet)
|
|
{
|
|
ref SSGetClientVersionReq req = ref packet.GetMessage<SSGetClientVersionReq>();
|
|
|
|
SSGetClientVersionRes res = new SSGetClientVersionRes();
|
|
res.Version = req.Version;
|
|
res.CurrVer = m_versionSvc.GetCurrentVersion(ref req.Version);
|
|
res.CurrVerStr.SetString(AppVersion.ToStringVersion(res.CurrVer));
|
|
VersionServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.GetClientVerionRes, ref res, 0);
|
|
}
|
|
|
|
public void UpdateClientConnect()
|
|
{
|
|
var clientConnData = VersionServerUtils.GetVersionServerData().m_ClientConnectDict;
|
|
|
|
foreach (KeyValuePair<long, ClientConnectInfo> pair in clientConnData)
|
|
{
|
|
uint gateServerID = pair.Value.uGateServerID;
|
|
long sessionID = pair.Value.iConnectSessionID;
|
|
long iConnectTime = pair.Value.iConnectTime;
|
|
|
|
if (AppTime.GetNowSysMs() - iConnectTime >= 10 * 1000)
|
|
{
|
|
TraceLog.Debug("VersionMsgHandler.UpdateClientConnect TimeOut Disconnect:{0} ", sessionID);
|
|
|
|
GateService.NotifyGateServerDisconnect(GetApp(), gateServerID, sessionID);
|
|
|
|
m_versionSvc.RemoveClientConnectData(gateServerID, sessionID);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|