using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MSGer.tk
{
partial class Networking
{
public class PacketSender
{ //2015.05.14.
private static int NextID = 0;
private object Lock = new object();
private PacketFormat Response;
private IPEndPoint RemoteEP;
public int ID { get; private set; }
public PacketFormat Packet { get; private set; }
///
/// PacketSender
///
/// PacketData
/// Response ID
public PacketSender(PacketData data, int respid = -1)
{
if (NextID >= Int32.MaxValue)
NextID = 0;
if (respid == -1)
ID = NextID++;
else
ID = respid;
Packet = new PacketFormat(respid != -1, data, ID);
if (respid == -1)
Senders.Add(ID, this);
}
public void OnReceiveResponse(PacketFormat response, IPEndPoint remoteep)
{
lock (Lock)
{
Response = response;
RemoteEP = remoteep;
Monitor.Pulse(Lock);
}
}
public PacketFormat[] Send(IPEndPoint onlythisep = null)
{
return SendUpdate(onlythisep);
}
public async Task SendAsync(IPEndPoint onlythisep = null)
{
return await Task.Run(() => Send(onlythisep));
}
private PacketFormat[] SendUpdate(IPEndPoint onlythisep = null)
{
if (Program.MainF != null && Program.MainF.IsHandleCreated)
{
if (Program.MainF.InvokeRequired)
{
Program.MainF.Invoke(new Action(Program.MainF.UpdateStats),
MainForm.StatType.Servers, UserInfo.IPs.Count);
Program.MainF.Invoke(new Action(Program.MainF.UpdateStats),
MainForm.StatType.OnlineServers, UserInfo.IPs.Count - UserInfo.BannedIPs.Count);
}
else
{
MessageBox.Show("Internal error: Network call was made in the same thread as the UI. This could lead to freezes.\nNetwork update canceled.");
return null;
}
}
if ((UserInfo.IPs.Count == 0
//&& !UserInfo.IPs.Any(entry => entry.Address.Equals(RemoteEP.Address))
|| (RemoteEP == null) ? false : !UserInfo.IPs.Any(entry => entry.Address.Equals(RemoteEP.Address))) //<-- 2015.06.16.
&& Packet.PacketType != Networking.UpdateType.LoginUser)
return null;
byte[] senddata = Packet.ToBytes();
if (UserInfo.BanTime < Environment.TickCount - 1000 * 10)
UserInfo.BannedIPs = new List();
if (onlythisep == null)
{
foreach (var item in UserInfo.IPs)
{ //Elküldi az összes ismert címre
try
{
if (!UserInfo.BannedIPs.Contains(item))
SenderConnection.Send(senddata, senddata.Length, item);
}
catch (ObjectDisposedException)
{
return null;
}
catch (Exception e)
{
MessageBox.Show("Network error:\n" + e.Message + "\n\n" + e.StackTrace);
}
}
}
else
{
try
{
SenderConnection.Send(senddata, senddata.Length, onlythisep);
}
catch (ObjectDisposedException)
{
return null;
}
}
if (!Packet.Response)
{
int lasttick = Environment.TickCount;
//List Ret = new List();
List Ret = new List();
List ResponsedIPs = new List();
int count = 1;
while (Environment.TickCount - 1000 * 10 < lasttick && (
(onlythisep == null) ?
ResponsedIPs.Count < UserInfo.IPs.Count - UserInfo.BannedIPs.Count :
ResponsedIPs.Count == 0))
{
/*if (MainForm.PartnerListUpdateThread != null)
{
while (DataBuffer == null && Environment.TickCount - 1000 * count * 2 < lasttick) ; //Várakozik, amíg a másik thread át nem adja a választ - 2014.10.09. - 10 mp --> 2 mp
}*/
lock (Lock)
{
while (Response == null && Monitor.Wait(Lock, 1000))
;
}
if (Response == null)
{
//Console.WriteLine("Didn't get a response in time. Retrying...");
foreach (var item in UserInfo.IPs.Except(UserInfo.BannedIPs).Except(ResponsedIPs))
{ //Elküldi az összes ismert címre
try
{
SenderConnection.Send(senddata, senddata.Length, item);
}
catch (ObjectDisposedException)
{
return null;
}
}
count++;
continue;
}
if (!(!UserInfo.IPs.Any(entry => entry.Address.Equals(RemoteEP.Address))
&& Packet.PacketType != Networking.UpdateType.LoginUser))
{
foreach (var item in UserInfo.IPs.Where(entry => entry.Address.Equals(RemoteEP.Address) && entry.Port == Response.Port))
ResponsedIPs.Add(item);
//var rpacket = PacketFormat.FromBytes(DataBuffer);
if (Response.KeyIndex != CurrentUser.KeyIndex && Response.PacketType != UpdateType.SetKey)
{
Response = null;
continue;
}
/*int i;
for (i = 0; i < Ret.Count; i++)
{
if (DataBuffer.SequenceEqual(Ret[i]))
break;
}
if (i == Ret.Count)
Ret.Add(DataBuffer);*/
Ret.Add(Response);
}
Response = null;
}
Response = null;
RemoteEP = null;
//return Ret.Select(entry => PacketFormat.FromBytes(entry)).ToArray();
return Ret.ToArray();
}
return null;
}
}
}
}