663 lines
22 KiB
C#
663 lines
22 KiB
C#
using Plane.Copters;
|
||
using GalaSoft.MvvmLight;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Plane.FormationCreator.Util;
|
||
using Microsoft.Practices.ServiceLocation;
|
||
using Plane.FormationCreator.ViewModels;
|
||
using System.Threading;
|
||
using Plane.Communication;
|
||
using Plane.Util;
|
||
using System.Windows;
|
||
using Plane.Windows.Messages;
|
||
using System.Reflection;
|
||
using System.IO;
|
||
|
||
namespace Plane.FormationCreator.Formation
|
||
{
|
||
|
||
public class CopterCollection : ObservableCollection<ICopter>
|
||
{
|
||
|
||
public int EnCopterNumber = 0;
|
||
|
||
public int EnVCopterNumber = 0;
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 实现排序插入
|
||
/// </summary>
|
||
/// <param name="baseSemObjects"></param>
|
||
public int AddCopter(ICopter entityObject,bool sortbyid=true)
|
||
{
|
||
////给第三方时候限制数量和时间用
|
||
DateTime dateTime2019 = DateTime.Parse("2020-06-01");
|
||
|
||
//新增飞机区域限制:内蒙
|
||
// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756
|
||
// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856)
|
||
// return 0;
|
||
|
||
if (DateTime.UtcNow > dateTime2019)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
/*
|
||
if (this.Count >= VersionControl.CopterUpperLimit)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
|
||
//网络登录限制
|
||
// if (!VersionControl.IsFullVersion)
|
||
{
|
||
if (entityObject is FakeCopter)
|
||
{
|
||
if (this.Count >= EnVCopterNumber)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
if (this.Count >= EnCopterNumber)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
*/
|
||
|
||
|
||
|
||
|
||
int _index = 0;
|
||
if (this.Count == 0)
|
||
{
|
||
Add(entityObject);
|
||
_index = 0;
|
||
}
|
||
else
|
||
{
|
||
bool isInsret = false;
|
||
for (int i = 0; i < this.Count; i++)
|
||
{
|
||
//按ID排序插入
|
||
if (sortbyid)
|
||
{
|
||
if (int.Parse(this[i].Id) > int.Parse(entityObject.Id))
|
||
{
|
||
InsertItem(i, entityObject);
|
||
isInsret = true;
|
||
_index = i;
|
||
break;
|
||
|
||
}
|
||
}else
|
||
//按VID排序插入
|
||
{
|
||
|
||
if (this[i].VirtualId > entityObject.VirtualId)
|
||
{
|
||
InsertItem(i, entityObject);
|
||
isInsret = true;
|
||
_index = i;
|
||
break;
|
||
|
||
}
|
||
}
|
||
}
|
||
if (!isInsret)
|
||
{
|
||
Add(entityObject);
|
||
_index = this.Count()-1 ;
|
||
}
|
||
}
|
||
return _index;
|
||
}
|
||
}
|
||
|
||
|
||
public class CopterManager : ObservableObject
|
||
{
|
||
|
||
const string LoginPage = "checkforapp.php";
|
||
const string supername = "admin";
|
||
const string superpass = "fxmf0622";
|
||
const string TEMP_MISSIONFILE = @".\gcs.dat";
|
||
//用户级别
|
||
const int LEVEL_NORMAL = 1;
|
||
const int LEVEL_ADMIN = 0;
|
||
|
||
|
||
private string superDispname = "超级用户";
|
||
public CopterManager()
|
||
{
|
||
AppEx.Current.AppModeChanged += (sender, e) =>
|
||
{
|
||
RaisePropertyChanged(nameof(Copters));
|
||
};
|
||
App.Current.Exit += (sender, e) =>
|
||
{
|
||
Task.WhenAll(Copters.Select(c => c.DisconnectAsync()));
|
||
};
|
||
|
||
}
|
||
|
||
public List<ICopter> ShowCopter = new List<ICopter>();
|
||
|
||
|
||
//3维视图显示比例,有些大的图案显示不出来可以缩小
|
||
private float _scale3d = 1.0f;
|
||
public float scale3d
|
||
{
|
||
get { return _scale3d; }
|
||
set { Set(nameof(scale3d), ref _scale3d, value); }
|
||
}
|
||
|
||
public delegate void NetStatusChanged(bool Logined, string status);
|
||
public event NetStatusChanged netStatusChanged;
|
||
|
||
public CopterCollection Copters { get;} = new CopterCollection();
|
||
|
||
//标记某飞机是否需要跳过
|
||
public ArrayList CopterStatus = new ArrayList();
|
||
//public ObservableCollection<ICopter> Copters
|
||
//{
|
||
// get
|
||
// {
|
||
// switch (AppEx.Instance.CurrentMode)
|
||
// {
|
||
// case AppMode.ControllingCopters:
|
||
// default:
|
||
// return CoptersForControlling;
|
||
// case AppMode.PreparedForRunningTasks:
|
||
// case AppMode.ModifyingTask:
|
||
// return CoptersForModifyingTask;
|
||
// case AppMode.RunningTasks:
|
||
// throw new NotImplementedException();
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
|
||
|
||
private string _Loginstate = "未登录";
|
||
public string Loginstate
|
||
{
|
||
get { return _Loginstate; }
|
||
set
|
||
{
|
||
Set(nameof(Loginstate), ref _Loginstate, value);
|
||
netStatusChanged(Logined,Loginstate);
|
||
}
|
||
}
|
||
|
||
|
||
private int _EnCopterNumber = 0;
|
||
public int EnCopterNumber
|
||
{
|
||
get { return _EnCopterNumber; }
|
||
set
|
||
{
|
||
Set(nameof(EnCopterNumber), ref _EnCopterNumber, value);
|
||
Copters.EnCopterNumber = EnCopterNumber;
|
||
}
|
||
}
|
||
|
||
private int _EnVCopterNumber = 0;
|
||
public int EnVCopterNumber
|
||
{
|
||
get { return _EnVCopterNumber; }
|
||
set
|
||
{
|
||
Set(nameof(EnVCopterNumber), ref _EnVCopterNumber, value);
|
||
Copters.EnVCopterNumber = EnVCopterNumber;
|
||
}
|
||
}
|
||
|
||
private bool _Logined = false;
|
||
public bool Logined
|
||
{
|
||
get { return _Logined; }
|
||
set
|
||
{
|
||
Set(nameof(Logined), ref _Logined, value);
|
||
netStatusChanged(Logined, Loginstate);
|
||
}
|
||
}
|
||
|
||
private string _UserName = "";
|
||
private string _UserDisplayName = "";
|
||
|
||
public void NetLogined(string UserName,string UserDisplayName,int vEnCopterNumber,int vEnVCopterNumber,int userlever=1)
|
||
{
|
||
_UserName = UserName;
|
||
EnCopterNumber = vEnCopterNumber;
|
||
EnVCopterNumber = vEnVCopterNumber;
|
||
_UserDisplayName = UserDisplayName;
|
||
string dis_EnCopterNumber ="<"+ EnCopterNumber.ToString()+">";
|
||
string dis_EnVCopterNumber = "<" + EnVCopterNumber.ToString() + ">";
|
||
if (EnCopterNumber == -1) dis_EnCopterNumber = "<无限>";
|
||
if (EnVCopterNumber == -1) dis_EnVCopterNumber = "<无限>";
|
||
Loginstate ="["+ UserDisplayName + "]已登录,模拟飞机:"+ dis_EnVCopterNumber + "架,真实飞机:"+ dis_EnCopterNumber + "架";
|
||
Logined = true;
|
||
VersionControl.SetUserLever(userlever);
|
||
if (UserName != supername)
|
||
{
|
||
Task.Run(async () =>
|
||
{
|
||
while (Logined)
|
||
{
|
||
NetActivePost();
|
||
//30秒一次保持活跃
|
||
await Task.Delay(30 * 1000).ConfigureAwait(false);
|
||
}
|
||
}).ConfigureAwait(false);
|
||
}
|
||
}
|
||
private void NetActivePost()
|
||
{
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL+ LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + _UserName);
|
||
sbUrl.Append("&type=Active");
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
new AsynDataUtils().AsynGetData(strUrl, null,out errorstr);
|
||
}
|
||
|
||
private void NetLogoutPost()
|
||
{
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL + LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + _UserName);
|
||
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
|
||
sbUrl.Append("&type=Logout");
|
||
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
|
||
}
|
||
public void NetLogout()
|
||
{
|
||
if (Logined)
|
||
NetLogoutPost();
|
||
|
||
|
||
Logined = false;
|
||
EnCopterNumber = 0;
|
||
EnVCopterNumber = 0;
|
||
_UserDisplayName = "";
|
||
_UserName = "";
|
||
VersionControl.SetUserLever(LEVEL_NORMAL);
|
||
Loginstate = "未登录";
|
||
}
|
||
|
||
//本地飞行任务日志 提交到服务器
|
||
public void Net_PostTempMission()
|
||
{
|
||
string filePath = TEMP_MISSIONFILE;
|
||
string[] Missionstrs = { };
|
||
try
|
||
{
|
||
if (File.Exists(filePath))
|
||
{
|
||
Missionstrs = File.ReadAllLines(filePath);
|
||
List<String> Mlist = new List<string>(Missionstrs);
|
||
string upstr = "";
|
||
foreach (var mstr in Mlist)
|
||
upstr = upstr + mstr + "|";
|
||
Net_PostTempMission(upstr);
|
||
Mlist.Clear();
|
||
File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//保存飞行任务日志临时到本地
|
||
public void Net_WriteTempMission(DateTime MissionTime, double OriginLng, double OriginLat)
|
||
{
|
||
string filePath = TEMP_MISSIONFILE;
|
||
string[] Missionstrs = { };
|
||
try
|
||
{
|
||
if (File.Exists(filePath))
|
||
Missionstrs = File.ReadAllLines(filePath);
|
||
List<String> Mlist = new List<string>(Missionstrs);
|
||
Mlist.Add(MissionTime.ToString() + ";" + OriginLng.ToString() + ";" + OriginLat.ToString() + ";" + Copters.Count().ToString()
|
||
+ ";" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||
|
||
File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
//提交飞行记录
|
||
public void Net_LogStartMission(DateTime MissionTime,double OriginLng, double OriginLat)
|
||
{
|
||
Net_WriteTempMission(MissionTime, OriginLng, OriginLat);
|
||
Net_PostStartMission(MissionTime, OriginLng, OriginLat);
|
||
}
|
||
|
||
|
||
//提交飞行记录
|
||
public void Net_PostStartMission(DateTime MissionTime, double OriginLng, double OriginLat)
|
||
{
|
||
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL + LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + _UserName);
|
||
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
|
||
sbUrl.Append("&type=StartMission");
|
||
sbUrl.Append("&mtime=" + MissionTime.ToString());
|
||
sbUrl.Append("&orgLng=" + OriginLng.ToString());
|
||
sbUrl.Append("&orgLat=" + OriginLat.ToString());
|
||
sbUrl.Append("&coptercount=" + Copters.Count().ToString());
|
||
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
|
||
}
|
||
|
||
//提交本地飞行记录
|
||
public void Net_PostTempMission(string missstr)
|
||
{
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL + LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + _UserName);
|
||
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
|
||
sbUrl.Append("&type=TempMission");
|
||
sbUrl.Append("&Mission=" + missstr);
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
private string tempuser;
|
||
private string tempPassword;
|
||
private bool tempSavePassword;
|
||
|
||
//在这个方法里面接收回调的返回信息
|
||
private void DataResultCallBack(string data,bool haveerror)
|
||
{
|
||
if (haveerror)
|
||
{
|
||
Loginstate = "登录失败,"+ data;
|
||
return;
|
||
}
|
||
if (data == "")
|
||
{
|
||
Loginstate = "登录失败,请检查网络连接";
|
||
return;
|
||
}
|
||
string[] arr = data.Split(';');
|
||
string loginret = arr[0];
|
||
if (loginret == "Login ok")
|
||
{
|
||
if (arr.Length!= 5)
|
||
{
|
||
Alert.Show("系统版本不正确!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
return;
|
||
}
|
||
|
||
|
||
string UserDisplayName = arr[1];
|
||
int vEnCopterNumber = int.Parse(arr[2]);
|
||
int vEnVCopterNumber = int.Parse(arr[3]);
|
||
int userlevel = int.Parse(arr[4]);
|
||
NetLogined(tempuser, UserDisplayName, vEnCopterNumber, vEnVCopterNumber, userlevel);
|
||
VersionControl.SaveLogininfoToIni(tempuser, tempPassword, tempSavePassword);
|
||
Net_PostTempMission();
|
||
//MessageBox.Show(UserDisplayName + " 登录成功!", "登录提示");
|
||
}
|
||
else
|
||
if (loginret == "username error")
|
||
{
|
||
NetLogout();
|
||
Alert.Show("账号错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
}
|
||
else
|
||
if (loginret == "password error")
|
||
{
|
||
NetLogout();
|
||
Alert.Show("密码错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
}
|
||
else
|
||
if (loginret == "replogin error")
|
||
{
|
||
NetLogout();
|
||
Alert.Show("该账号已在其他地方登录!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
}else
|
||
{
|
||
NetLogout();
|
||
Alert.Show("登录失败:"+ data, "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
}
|
||
}
|
||
public void NetLogoin(string username,string password,bool savepassword)
|
||
{
|
||
Logined = false;
|
||
//超级用户,无限制
|
||
if ((username== supername) && (password== superpass))
|
||
{
|
||
NetLogined(supername, superDispname, -1, -1, LEVEL_ADMIN);
|
||
return;
|
||
}
|
||
|
||
tempuser = username;
|
||
tempPassword = password;
|
||
tempSavePassword = savepassword;
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL + LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + username);
|
||
sbUrl.Append("&" + "password=" + password);
|
||
sbUrl.Append("&type=Login");
|
||
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
if (new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack, out errorstr))
|
||
Loginstate = "登录中...";
|
||
else Loginstate = "登录失败,"+ errorstr;
|
||
}
|
||
|
||
|
||
|
||
//在这个方法里面接收回调的返回信息
|
||
private void DataResultCallBack_changepassword(string data, bool haveerror)
|
||
{
|
||
if (haveerror)
|
||
{
|
||
MessageBox.Show("更改失败," + data, "提示");
|
||
return;
|
||
}
|
||
if (data == "")
|
||
{
|
||
MessageBox.Show("更改失败,请检查网络", "提示");
|
||
return;
|
||
}
|
||
string[] arr = data.Split(';');
|
||
string loginret = arr[0];
|
||
if (loginret == "chpassword ok")
|
||
{
|
||
MessageBox.Show( "密码更改成功!", "提示");
|
||
}
|
||
else
|
||
if (loginret == "username error")
|
||
{
|
||
|
||
MessageBox.Show("账号错误!", "提示");
|
||
}
|
||
else
|
||
if (loginret == "password error")
|
||
{
|
||
MessageBox.Show("原密码错误!", "提示");
|
||
}
|
||
|
||
}
|
||
|
||
public void NetChangePassword(string username, string oldpassword, string newpassword)
|
||
{
|
||
tempuser = username;
|
||
tempPassword = oldpassword;
|
||
// 发送请求
|
||
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
|
||
sbUrl.Append(VersionControl.ServerURL + LoginPage);
|
||
sbUrl.Append("?");
|
||
sbUrl.Append("username=" + username);
|
||
sbUrl.Append("&password=" + oldpassword);
|
||
sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
|
||
sbUrl.Append("&type=Chpassword");
|
||
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||
sbUrl.Append("&newpassword=" + newpassword);
|
||
String strUrl = sbUrl.ToString();
|
||
string errorstr;
|
||
if (!new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack_changepassword, out errorstr))
|
||
MessageBox.Show("更改失败," + errorstr, "提示");
|
||
}
|
||
|
||
public bool shiftkeydown;
|
||
public IEnumerable<ICopter> SelectedCopters { get { return _selectedCoptersGetter().Cast<ICopter>(); } }
|
||
|
||
/// <summary>
|
||
/// 注意:为避免多线程操作出问题,每次使用此属性时都会新建一个 List!
|
||
/// </summary>
|
||
public IEnumerable<ICopter> AcceptingControlCopters { get { return SelectedCopters.ToList(); } }
|
||
private int _SeletedCopterCount;
|
||
public int SeletedCopterCount
|
||
{
|
||
get { return _SeletedCopterCount; }
|
||
set { Set(nameof(SeletedCopterCount), ref _SeletedCopterCount, value); }
|
||
}
|
||
|
||
private Func<IList> _selectedCoptersGetter;
|
||
|
||
private Action<ICopter> _selectCopterAction;
|
||
|
||
public void SetSelectionDelegates(Func<IList> selectedCoptersGetter, Action<ICopter> selectCopterAction)
|
||
{
|
||
_selectedCoptersGetter = selectedCoptersGetter;
|
||
_selectCopterAction = selectCopterAction;
|
||
}
|
||
|
||
public event EventHandler<SelectedCoptersChangedEventArgs> SelectedCoptersChanged;
|
||
|
||
public void RaiseSelectedCoptersChanged(IEnumerable<ICopter> addedCopters, IEnumerable<ICopter> removedCopters)
|
||
{
|
||
SelectedCoptersChanged?.Invoke(this, new SelectedCoptersChangedEventArgs { AddedCopters = addedCopters, RemovedCopters = removedCopters });
|
||
SeletedCopterCount = SelectedCopters.Count();
|
||
}
|
||
|
||
|
||
|
||
public async Task ClearCopters()
|
||
{
|
||
foreach (var copter in Copters)
|
||
{
|
||
await copter.DisconnectAsync();
|
||
}
|
||
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
|
||
Copters.Clear();
|
||
CopterStatus.Clear();
|
||
//wifi
|
||
if (VersionControl.ConType==1)
|
||
UdpServerConnectionManager.Instance.ClearConnections();
|
||
}
|
||
|
||
|
||
public bool EnAddCopter_Real()
|
||
{
|
||
if (EnCopterNumber == -1) return true;
|
||
else
|
||
return Copters.Count < EnCopterNumber;
|
||
}
|
||
|
||
public bool EnAddCopter_Fake()
|
||
{
|
||
if (EnVCopterNumber == -1) return true;
|
||
else
|
||
return Copters.Count < EnVCopterNumber;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 选择飞机
|
||
/// </summary>
|
||
/// <param name="copter">Null表示清除所有选择</param>
|
||
public void Select(ICopter copter)
|
||
{
|
||
_selectCopterAction(copter);
|
||
}
|
||
/// <summary>
|
||
/// 按VID重新排序飞机
|
||
/// </summary>
|
||
public void sortbyvid()
|
||
{
|
||
List<ICopter> tempCopters = new List<ICopter>();
|
||
tempCopters.AddRange(Copters);
|
||
Copters.Clear();
|
||
foreach (var copter in tempCopters)
|
||
Copters.AddCopter(copter,false);
|
||
}
|
||
/// <summary>
|
||
/// 按原始ID重新排序飞机
|
||
/// </summary>
|
||
public void sortbyid()
|
||
{
|
||
List<ICopter> tempCopters = new List<ICopter>();
|
||
tempCopters.AddRange(Copters);
|
||
Copters.Clear();
|
||
foreach (var copter in tempCopters)
|
||
Copters.AddCopter(copter);
|
||
}
|
||
|
||
}
|
||
|
||
public class SelectedCoptersChangedEventArgs : EventArgs
|
||
{
|
||
public IEnumerable<ICopter> AddedCopters { get; set; }
|
||
public IEnumerable<ICopter> RemovedCopters { get; set; }
|
||
}
|
||
}
|