276 lines
11 KiB
C#
276 lines
11 KiB
C#
using Fleck;
|
|
|
|
namespace BattleServer
|
|
{
|
|
/// <summary>
|
|
/// 客户端链接对象
|
|
/// </summary>
|
|
class Client
|
|
{
|
|
private IWebSocketConnection socket;
|
|
|
|
public Client(IWebSocketConnection _socket)
|
|
{
|
|
socket = _socket;
|
|
socket.OnBinary = doBinary;
|
|
// socket.OnClose = close;
|
|
socket.OnError = onError;
|
|
}
|
|
private void onError(Exception e)
|
|
{
|
|
Console.WriteLine("onError {0}", e.Message);
|
|
socket.Close();
|
|
Service.Instance.Shutdown(this);
|
|
}
|
|
// private void close()
|
|
// {
|
|
// Console.WriteLine("close !");
|
|
// Service.Instance.Shutdown(this);
|
|
// }
|
|
|
|
/// <summary>
|
|
/// 接收rpc数据
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
private void doBinary(byte[] message)
|
|
{
|
|
BattleRpcMessage msg = ProtoDeSerialize<BattleRpcMessage>(message);
|
|
// if (msg.method != "Heartbeat")
|
|
// Console.WriteLine("接收到消息 {0}", msg.method);
|
|
// Pb.BattleRpcMessage msg = Deserialize<Pb.BattleRpcMessage>(message);
|
|
Task t = Task.Run(() =>
|
|
{
|
|
handle(msg);
|
|
});
|
|
|
|
t.ContinueWith(r =>
|
|
{
|
|
string Exception = Convert.ToString(t.Exception);
|
|
Console.WriteLine("消息处理异常:" + Exception);
|
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 处理远程请求
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
private void handle(BattleRpcMessage msg)
|
|
{
|
|
byte[] _msg;
|
|
// long ts = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
|
|
// Console.WriteLine("接收到战斗消息 1 {0}|{1}",msg.method,ts);
|
|
|
|
switch (msg.method)
|
|
{
|
|
case "Check": //校验战报
|
|
BattleReport report = ProtoDeSerialize<BattleReport>(msg.data.value);
|
|
// DateTime startTime = DateTime.Now;
|
|
bool issucc = HotUpdateScripts.FightRunnerMgr.Instance.VerifyOnceFight(report);
|
|
// DateTime endTime = DateTime.Now;
|
|
// Console.WriteLine($"耗时: {(endTime - startTime).TotalMilliseconds} 毫秒");
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleCheckResults",
|
|
value = ProtoSerialize(new BattleCheckResults { ischeck = issucc }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
// ts = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
|
|
// Console.WriteLine("接收到战斗消息 4 |{0}",ts);
|
|
socket.Send(_msg);
|
|
break;
|
|
case "Run": //运行战斗
|
|
BattleRunReq runreq = ProtoDeSerialize<BattleRunReq>(msg.data.value);
|
|
BattleReport[] reports = new BattleReport[runreq.info.Count];
|
|
for (int i = 0; i < runreq.info.Count; i++)
|
|
{
|
|
|
|
var respaction = () =>
|
|
{
|
|
bool isfinsh = true;
|
|
for (int i = 0; i < reports.Length; i++)
|
|
{
|
|
if (reports[i] == null)
|
|
{
|
|
isfinsh = false;
|
|
}
|
|
}
|
|
if (isfinsh)
|
|
{
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleRunResp",
|
|
value = ProtoSerialize(new BattleRunResp { reports = reports.ToList() }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
socket.Send(_msg);
|
|
}
|
|
};
|
|
|
|
HotUpdateScripts.FightRunnerMgr.Instance.RunOnceFight(runreq.info[i], (issucc) =>
|
|
{
|
|
if (!issucc)
|
|
{
|
|
int index = i;
|
|
reports[index] = new BattleReport()
|
|
{
|
|
info = runreq.info[index],
|
|
winSide = 2,
|
|
};
|
|
respaction();
|
|
}
|
|
|
|
}, (report) =>
|
|
{
|
|
int index = i;
|
|
reports[index] = report;
|
|
respaction();
|
|
});
|
|
}
|
|
break;
|
|
case "GetInfo": //获取战斗场景
|
|
// Console.WriteLine("处理GetInfoPVP !");
|
|
BattleGetInfoReq req = ProtoDeSerialize<BattleGetInfoReq>(msg.data.value);
|
|
BattleStateInfo info = HotUpdateScripts.FightRunnerMgr.Instance.GetPvpStateInfo(req.battleid);
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleGetInfoResp",
|
|
value = ProtoSerialize(new BattleGetInfoResp { battleid = req.battleid, info = info, }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
socket.Send(_msg);
|
|
// Console.WriteLine("处理GetInfo end !");
|
|
break;
|
|
case "Create": //创建战斗场景
|
|
// Console.WriteLine("处理CreatePVP !");
|
|
BattleCreateServerReq CreateReq = ProtoDeSerialize<BattleCreateServerReq>(msg.data.value);
|
|
HotUpdateScripts.FightRunnerMgr.Instance.StartPvp(CreateReq.info, this.OnOutCmd, this.OnFinish, (issucc) =>
|
|
{
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleCreateServerResp",
|
|
value = ProtoSerialize(new BattleCreateServerResp { issucc = issucc }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
socket.Send(_msg);
|
|
// Console.WriteLine("处理CreatePVP end !");
|
|
});
|
|
break;
|
|
case "InCmd": //向战斗场景输入指令
|
|
// Console.WriteLine("处理InCmd !");
|
|
BattleInCmdReq InCmdReq = ProtoDeSerialize<BattleInCmdReq>(msg.data.value);
|
|
HotUpdateScripts.FightRunnerMgr.Instance.PvpInput(InCmdReq.battleid, InCmdReq.side, InCmdReq.@in, (issucc) =>
|
|
{
|
|
// Console.WriteLine("处理InCmd 1------- end !");
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleInCmdResp",
|
|
value = ProtoSerialize(new BattleInCmdResp { issucc = issucc }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
socket.Send(_msg);
|
|
// Console.WriteLine("处理InCmd 1------- end !");
|
|
});
|
|
|
|
break;
|
|
case "Concede": //向战斗场景输入指令
|
|
// Console.WriteLine("处理 Concede !");
|
|
BattleConcedeReq ConcedeReq = ProtoDeSerialize<BattleConcedeReq>(msg.data.value);
|
|
HotUpdateScripts.FightRunnerMgr.Instance.InitiativeFail(ConcedeReq.battleid, ConcedeReq.side, (issucc) =>
|
|
{
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleConcedeResp",
|
|
value = ProtoSerialize(new BattleConcedeResp { issucc = issucc }),
|
|
};
|
|
_msg = ProtoSerialize(msg);
|
|
socket.Send(_msg);
|
|
// Console.WriteLine("处理 Concede end !");
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
private void OnOutCmd(string bid, List<BattleCmd> cmd)
|
|
{
|
|
// Console.WriteLine("----------------------OnOutCmd {0}:{1}", bid, cmd.cmdtype);
|
|
// foreach (var item in cmd)
|
|
// {
|
|
// Console.WriteLine("----------------------OnOutCmd {0}:{1}", bid, item.cmdtype);
|
|
// }
|
|
|
|
BattleRpcMessage msg = new BattleRpcMessage();
|
|
msg.method = "BattleOutCmd";
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleOutCmdPush",
|
|
value = ProtoSerialize(new BattleOutCmdPush { battleid = bid, cmd = cmd, }),
|
|
};
|
|
byte[] data = ProtoSerialize(msg);
|
|
socket.Send(data);
|
|
}
|
|
|
|
private void OnFinish(BattleCmd cmd)
|
|
{
|
|
|
|
ComEndFight _cmd = HotUpdateScripts.FightCmdUtil.PasreCmd(cmd) as ComEndFight;
|
|
// Console.WriteLine("----------------------OnFinish {0}", _cmd.fightId);
|
|
BattleRpcMessage msg = new BattleRpcMessage();
|
|
msg.method = "BattleFished";
|
|
msg.data = new Google.Protobuf.WellKnownTypes.Any
|
|
{
|
|
type_url = "type.googleapis.com/BattleFinishPush",
|
|
value = ProtoSerialize(new BattleFinishPush { battleid = _cmd.fightId, winSide = _cmd.winSide }),
|
|
};
|
|
|
|
byte[] data = ProtoSerialize(msg);
|
|
Task t = Task.Run(() =>
|
|
{
|
|
Thread.Sleep(1000);
|
|
socket.Send(data);
|
|
});
|
|
|
|
t.ContinueWith(r =>
|
|
{
|
|
string Exception = Convert.ToString(t.Exception);
|
|
// Console.WriteLine("OnFinish 异常处理:" + Exception);
|
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 序列化并返回二进制
|
|
/// Serialize an Object and return byte[]
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
public static byte[] ProtoSerialize<T>(T obj) where T : class
|
|
{
|
|
using (var stream = new MemoryStream())
|
|
{
|
|
ProtoBuf.Serializer.Serialize(stream, obj);
|
|
return stream.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 通过二进制反序列化
|
|
/// Deserialize with byte[]
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
public static T ProtoDeSerialize<T>(byte[] msg) where T : class
|
|
{
|
|
msg = msg == null ? new byte[] { } : msg;
|
|
using (var ms = new MemoryStream(msg))
|
|
{
|
|
var data = ProtoBuf.Serializer.Deserialize<T>(ms);
|
|
return data;
|
|
}
|
|
}
|
|
}
|
|
} |