using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Channels;
using System.Linq;
using System.Net.Http;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using ProtoDataBuff;
using BossServer;
using pb = global::Google.Protobuf;
namespace clientTest.bossfight
{
class Program
{
static readonly Random r = new Random();
///
/// 消息分发
///
static private Dictionary> callbacks = new Dictionary>();
static void Main(string[] args)
{
callbacks.Add(eProtocalCommand.ScUpdateProperties, On_update);
callbacks.Add(eProtocalCommand.ScGameOver, On_GameOver);
var n = 1;
var list = new Task[n];
for (int i = 0; i < n; i++)
{
list[i] = Task.Run(async () => await send());
}
Task.Run(Dispatch);
Task.WaitAll(list);
}
///
/// 处理客户端上报伤害请求
///
static void On_update(sSocketData data)
{
var msg = SCUpdateProperties.Parser.ParseFrom(data._data);
Console.WriteLine("最新HP: " + msg.BossHp);
}
///
/// 处理客户端上报伤害请求
///
static void On_GameOver(sSocketData data)
{
var msg = SCGameOver.Parser.ParseFrom(data._data);
Console.WriteLine("战斗结束: " + msg.BossHp);
Task.Delay(3000).ContinueWith(t => Environment.Exit(0));
}
static async Task send()
{
var port = 6002;
var endPoint = new IPEndPoint(IPAddress.Parse("192.168.10.86"), port);
//var endPoint = new IPEndPoint(IPAddress.Parse("115.159.121.129"), port);
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
try
{
await client.ConnectAsync(endPoint);
}
catch (Exception ee)
{
Debug.WriteLine(ee.Message);
}
var t = Task.Run(() => recv(client));
await login(client);
while (true)
{
try
{
await ReportDamage(client);
Thread.Sleep(r.Next(1000, 3000));
}
catch (Exception e)
{
client.Close();
break;
}
}
}
}
async static Task login(Socket Sock)
{
try
{
var msg = new CSEnterFight() { Uid = Guid.NewGuid().ToString(), Zoneid = 1 };
var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsLogin, IMsg2Bytes(msg)));
await Sock.SendAsync(new ArraySegment(data), SocketFlags.None);
}
catch (Exception e)
{
Sock.Close();
}
}
async static Task ReportDamage(Socket sock)
{
var msg = new CSFightReportDamage() { Damage = r.Next(-320, 0) };
var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsReportDamage, IMsg2Bytes(msg)));
await sock.SendAsync(new ArraySegment(data), SocketFlags.None);
}
static byte[] IMsg2Bytes(pb::IMessage msg)
{
using var ms = new MemoryStream();
using var goutstream = new pb::CodedOutputStream(ms);
msg.WriteTo(goutstream);
goutstream.Flush();
ms.Seek(0, SeekOrigin.Begin);
return ms.ToArray();
}
static async void Dispatch()
{
while (true)
{
var msg = await recvDataBuffer.Reader.ReadAsync();
if (callbacks.ContainsKey(msg._protocallType))
{
callbacks[msg._protocallType](msg);
}
else
{
// 未找到消息处理逻辑
Console.WriteLine("未识别的消息类型:" + msg._protocallType.ToString());
}
}
}
///
/// 向客户端写入消息
///
static async void WriteToserver(Socket Sock)
{
while (true)
{
var msg = await sendDataBuffer.Reader.ReadAsync();
var data = SocketDataToBytes(msg);
await Sock.SendAsync(new ArraySegment(data), SocketFlags.None);
}
}
///
/// 网络结构转数据
///
///
///
static private byte[] SocketDataToBytes(sSocketData tmpSocketData)
{
byte[] _tmpBuff = new byte[tmpSocketData.PackLen];
byte[] _tmpBuffLength = BitConverter.GetBytes(tmpSocketData.PackLen);
byte[] _tmpDataLenght = BitConverter.GetBytes((UInt16)tmpSocketData._protocallType);
Array.Copy(_tmpBuffLength, 0, _tmpBuff, 0, Constants.HEAD_DATA_LEN);//缓存总长度
Array.Copy(_tmpDataLenght, 0, _tmpBuff, Constants.HEAD_DATA_LEN, Constants.HEAD_TYPE_LEN);//协议类型
Array.Copy(tmpSocketData._data, 0, _tmpBuff, Constants.HEAD_LEN, tmpSocketData.DataLen);//协议数据
return _tmpBuff;
}
///
/// 数据转网络结构
///
///
///
///
static private sSocketData BytesToSocketData(eProtocalCommand _protocalType, byte[] _data)
{
sSocketData tmpSocketData = new sSocketData();
tmpSocketData.PackLen = Constants.HEAD_LEN + _data.Length;
// tmpSocketData._dataLength = _data.Length;
tmpSocketData._protocallType = _protocalType;
tmpSocketData._data = _data;
return tmpSocketData;
}
///
/// 接收buffer
///
static private Channel recvDataBuffer = Channel.CreateUnbounded();
///
/// 发送buffer
///
static private Channel sendDataBuffer = Channel.CreateUnbounded();
///
/// 接收客户端发来的信息,客户端套接字对象
///
///
static async void recv(Socket socketServer)
{
socketServer.ReceiveTimeout = 800; // 接收等待超时时间设为800毫秒
var _databuffer = new DataBuffer();
byte[] arrServerRecMsg = new byte[4096]; // 创建一个内存缓冲区,其大小为4k字节
while (true)
{
try
{
var length = await socketServer.ReceiveAsync(new ArraySegment(arrServerRecMsg), SocketFlags.None); // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
if (length <= 0) // 视为客户端已经close连接
{
break;
}
_databuffer.AddBuffer(arrServerRecMsg, length); //将收到的数据添加到缓存器中
while (_databuffer.GetData(out sSocketData _socketData)) //取出一条完整数据
{
await recvDataBuffer.Writer.WriteAsync(_socketData); // 放入channel
}
Array.Clear(arrServerRecMsg, 0, length);
}
catch (SocketException e)
{
if (e.ErrorCode == 10060) // 超时的时候错误号码是10060
{
continue; // 继续等待
}
break;
}
catch (Exception)
{
break;
}
}
socketServer.Close(); // 关闭之前accept出来的和客户端进行通信的套接字
}
}
}