You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Model.cs 65 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. using COSXML.Auth;
  2. using COSXML.CosException;
  3. using COSXML.Model.Object;
  4. using COSXML;
  5. using Newtonsoft.Json;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.IO;
  9. using System.Security.Cryptography;
  10. using System.Text;
  11. using System;
  12. using COSXML.Model.Bucket;
  13. using System.Runtime.InteropServices;
  14. using System.Text.Json.Nodes;
  15. using System.Net.Http.Json;
  16. using System.Text.Json;
  17. using System.Xml.Schema;
  18. using static Downloader.Program;
  19. using System.Threading.Tasks;
  20. using System.Net.Http;
  21. using System.Windows;
  22. using System.Windows.Shapes;
  23. //using System.Windows.Forms;
  24. using System.Threading.Tasks;
  25. using System.Threading;
  26. using MessageBox = System.Windows.MessageBox;
  27. using Downloader;
  28. using COSXML.Transfer;
  29. using WebConnect;
  30. namespace starter.viewmodel.settings
  31. {
  32. /// <summary>
  33. /// Settings Window Model
  34. /// </summary>
  35. public class SettingsModel
  36. {
  37. /// <summary>
  38. /// downloader function
  39. /// </summary>
  40. private Data configData = new Data("");
  41. private Tencent_cos_download cloud = new Tencent_cos_download();
  42. private HttpClient client = new HttpClient();
  43. private WebConnect.Web web = new WebConnect.Web();
  44. public SettingsModel()
  45. {
  46. Route = Data.FilePath;
  47. Username = "";
  48. Password = "";
  49. updates = "";
  50. CodeRoute = "";
  51. PlayerNum = "nSelect";
  52. UploadReady = false;
  53. LoginFailed = false;
  54. launchLanguage = LaunchLanguage.cpp;
  55. }
  56. /// <summary>
  57. /// save settings
  58. /// </summary>
  59. public bool install()
  60. {
  61. if (Tencent_cos_download.CheckAlreadyDownload())
  62. {
  63. MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
  64. // ask if abort install, with warning sign, defalut move instead of abort;
  65. if (repeatOption == MessageBoxResult.No)
  66. {
  67. Route = Data.FilePath;
  68. return false;
  69. }
  70. else
  71. {
  72. Downloader.Program.Tencent_cos_download.MoveProgram(Route);
  73. return true;
  74. }
  75. }
  76. else
  77. {
  78. Data.ResetFilepath(Route);
  79. Tencent_cos_download.DownloadAll();
  80. return true;
  81. }
  82. }
  83. public int move()
  84. {
  85. int state = Tencent_cos_download.MoveProgram(Route);
  86. if (state != 0)
  87. Route = Data.FilePath;
  88. return state;
  89. }
  90. ///<summary>
  91. ///check for update
  92. /// </summary>
  93. static bool ProfileAvailable
  94. {
  95. get; set;
  96. }
  97. /// <summary>
  98. /// 检查更新
  99. /// </summary>
  100. /// <returns></returns>
  101. public Status checkUpdate()
  102. {
  103. UpdateInfo updateInfo = Tencent_cos_download.Check();
  104. if (updateInfo.newFileCount == -1)
  105. {
  106. if (updateInfo.changedFileCount == -1)
  107. {
  108. return Status.error;
  109. }
  110. else
  111. {
  112. return Status.disconnected;
  113. }
  114. }
  115. else
  116. {
  117. if (updateInfo.changedFileCount != 0 || updateInfo.newFileCount != 0)
  118. {
  119. Updates = $"{updateInfo.newFileCount}个新文件,{updateInfo.changedFileCount}个文件变化";
  120. }
  121. return Status.menu;
  122. }
  123. }
  124. public async Task<int> Login()
  125. {
  126. return await web.LoginToEEsast(client, Username, Password);
  127. }
  128. public bool RememberUser()
  129. {
  130. int result = 0;
  131. result |= Web.WriteUserEmail(Username);
  132. result |= Web.WriteUserPassword(Password);
  133. return result == 0;
  134. }
  135. public bool RecallUser()
  136. {
  137. Username = Web.ReadUserEmail();
  138. if (Username == null || Username.Equals(""))
  139. {
  140. Username = "";
  141. return false;
  142. }
  143. Password = Web.ReadUserPassword();
  144. if (Password == null || Username.Equals(""))
  145. {
  146. Password = "";
  147. return false;
  148. }
  149. return true;
  150. }
  151. public bool ForgetUser()
  152. {
  153. int result = 0;
  154. result |= Web.WriteUserEmail("");
  155. result |= Web.WriteUserPassword("");
  156. return result == 0;
  157. }
  158. public bool Update()
  159. {
  160. return Tencent_cos_download.Update();
  161. }
  162. public int Uninst()
  163. {
  164. return Tencent_cos_download.DeleteAll();
  165. }
  166. public bool Launch()
  167. {
  168. if (Tencent_cos_download.CheckAlreadyDownload())
  169. {
  170. Process.Start(System.IO.Path.Combine(Data.FilePath, startName));
  171. return true;
  172. }
  173. else
  174. {
  175. MessageBox.Show($"文件还不存在,请安装主体文件", "文件不存在", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
  176. return false;
  177. }
  178. }
  179. public async Task<int> Upload()
  180. {
  181. switch (CodeRoute.Substring(CodeRoute.LastIndexOf('.') + 1))
  182. {
  183. case "cpp":
  184. Language = "cpp";
  185. break;
  186. case "h":
  187. Language = "cpp";
  188. break;
  189. case "py":
  190. Language = "python";
  191. break;
  192. default:
  193. return -8;
  194. }
  195. if (PlayerNum.Equals("nSelect"))
  196. return -9;
  197. return await web.UploadFiles(client, CodeRoute, Language, PlayerNum);
  198. }
  199. /// <summary>
  200. /// Route of files
  201. /// </summary>
  202. public string Route
  203. {
  204. get; set;
  205. }
  206. public string Username
  207. {
  208. get; set;
  209. }
  210. public string Password
  211. {
  212. get; set;
  213. }
  214. public string CodeRoute
  215. {
  216. get; set;
  217. }
  218. public string Language
  219. {
  220. get; set;
  221. }
  222. public string PlayerNum
  223. {
  224. get; set;
  225. }
  226. /// <summary>
  227. /// 关于更新的屏幕显示信息
  228. /// </summary>
  229. private string updates;
  230. public string Updates
  231. {
  232. get
  233. {
  234. return updates;
  235. }
  236. set
  237. {
  238. updates = value;
  239. }
  240. }
  241. /// <summary>
  242. /// 关于介绍的屏幕显示信息
  243. /// </summary>
  244. public enum Status { newUser, menu, move, working, disconnected, error, successful, login, web };
  245. public Status status
  246. {
  247. get; set;
  248. }
  249. public bool Working
  250. {
  251. get; set;
  252. }
  253. /// <summary>
  254. /// if an update is planned
  255. /// </summary>
  256. public bool UpdatePlanned
  257. {
  258. get
  259. {
  260. return Program.UpdatePlanned;
  261. }
  262. }
  263. public bool CombatCompleted
  264. {
  265. get
  266. {
  267. return false;
  268. }
  269. }
  270. public bool LoginFailed
  271. {
  272. get; set;
  273. }
  274. public bool UploadReady
  275. {
  276. get; set;
  277. }
  278. public bool RememberMe
  279. {
  280. get; set;
  281. }
  282. public enum LaunchLanguage { cpp, python };
  283. public LaunchLanguage launchLanguage
  284. {
  285. get; set;
  286. }
  287. }
  288. }
  289. namespace Downloader
  290. {
  291. class UserInfo
  292. {
  293. static public string _id = "";
  294. static public string email = "";
  295. }
  296. class Program
  297. {
  298. static List<string> newFileName = new List<string>(); // 新文件名
  299. static List<string> updateFileName = new List<string>(); // 更新文件名
  300. public static string ProgramName = "THUAI6"; // 要运行或下载的程序名称
  301. public static string playerFolder = "player"; // 选手代码保存文件夹路径
  302. public static string startName = "maintest.exe"; // 启动的程序名
  303. public struct UpdateInfo // 更新信息,包括新版本版本号、更改文件数和新文件数
  304. {
  305. public string status;
  306. public int changedFileCount;
  307. public int newFileCount;
  308. }
  309. public static bool UpdatePlanned
  310. {
  311. get; set;
  312. }
  313. static int filenum = 0; // 总文件个数
  314. public class Data
  315. {
  316. public static string path = ""; // 标记路径记录文件THUAI6.json的路径
  317. public static string FilePath = ""; // 最后一级为THUAI6文件夹所在目录
  318. public static string dataPath = ""; // C盘的文档文件夹
  319. public Data(string path)
  320. {
  321. dataPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
  322. //dataPath = new DirectoryInfo(".").FullName;
  323. Data.path = System.IO.Path.Combine(dataPath, "THUAI6.json");
  324. if (File.Exists(Data.path))
  325. {
  326. var dict = new Dictionary<string, string>();
  327. using (StreamReader r = new StreamReader(Data.path))
  328. {
  329. string json = r.ReadToEnd();
  330. if (json == null || json == "")
  331. {
  332. json += @"{""THUAI6""" + ":" + @"""2023""}";
  333. }
  334. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  335. if (dict != null && dict.ContainsKey("installpath"))
  336. {
  337. FilePath = dict["installpath"].Replace('\\', '/');
  338. } //读取安装路径
  339. }
  340. dict?.TryAdd("installpath", @path);
  341. using FileStream fs = new FileStream(Data.path, FileMode.Create, FileAccess.ReadWrite);
  342. using StreamWriter sw = new StreamWriter(fs);
  343. sw.Write(JsonConvert.SerializeObject(dict));
  344. sw.Flush();
  345. }
  346. else
  347. {
  348. FilePath = System.IO.Path.GetDirectoryName(@path);
  349. //将dat文件写入程序运行路径
  350. string json;
  351. Dictionary<string, string> dict = new Dictionary<string, string>();
  352. using FileStream fs = new FileStream(Data.path, FileMode.Create, FileAccess.ReadWrite);
  353. using (StreamReader r = new StreamReader(fs))
  354. {
  355. json = r.ReadToEnd();
  356. if (json == null || json == "")
  357. {
  358. json += @"{""THUAI6""" + ":" + @"""2023""}";
  359. }
  360. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  361. dict?.Add("installpath", path);
  362. }
  363. using FileStream fs2 = new FileStream(Data.path, FileMode.Create, FileAccess.ReadWrite);
  364. using StreamWriter sw = new StreamWriter(fs2);
  365. sw.Write(JsonConvert.SerializeObject(dict));
  366. sw.Flush();
  367. }
  368. }
  369. public static void ResetFilepath(string newPath)
  370. {
  371. string json;
  372. Dictionary<string, string> dict = new Dictionary<string, string>();
  373. FilePath = newPath.Replace('\\', '/');
  374. path = System.IO.Path.Combine(dataPath, "THUAI6.json");
  375. using FileStream fs = new FileStream(Data.path, FileMode.Create, FileAccess.ReadWrite);
  376. using (StreamReader r = new StreamReader(fs))
  377. {
  378. json = r.ReadToEnd();
  379. if (json == null || json == "")
  380. {
  381. json += @"{""THUAI6""" + ":" + @"""2023""}";
  382. }
  383. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  384. if (dict != null && dict.ContainsKey("installpath"))
  385. {
  386. dict["installpath"] = newPath;
  387. }
  388. else
  389. {
  390. dict.Add("installpath", newPath);
  391. }
  392. if (dict == null || !dict.ContainsKey("download"))
  393. {
  394. dict?.Add("download", "true");
  395. }
  396. else
  397. {
  398. dict["download"] = "true";
  399. }
  400. }
  401. using FileStream fs2 = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
  402. using StreamWriter sw = new StreamWriter(fs2);
  403. fs2.SetLength(0);
  404. sw.Write(JsonConvert.SerializeObject(dict));
  405. sw.Flush();
  406. }
  407. }
  408. public class Tencent_cos_download
  409. {
  410. public void download(string download_dir, string key)
  411. {
  412. // download_dir标记根文件夹路径,key为相对根文件夹的路径(不带./)
  413. // 初始化CosXmlConfig(提供配置SDK接口)
  414. string appid = "1314234950"; // 设置腾讯云账户的账户标识(APPID)
  415. string region = "ap-beijing"; // 设置一个默认的存储桶地域
  416. CosXmlConfig config = new CosXmlConfig.Builder()
  417. .IsHttps(true) // 设置默认 HTTPS 请求
  418. .SetAppid(appid) // 设置腾讯云账户的账户标识 APPID
  419. .SetRegion(region) // 设置一个默认的存储桶地域
  420. .SetDebugLog(true) // 显示日志
  421. .Build(); // 创建 CosXmlConfig 对象
  422. // 永久密钥访问凭证
  423. string secretId = "AKIDvhEVXN4cv0ugIlFYiniV6Wk1McfkplYA"; //"云 API 密钥 SecretId";
  424. string secretKey = "YyGLGCJG4f5VsEUddnz9JSRPSSK8sYBo"; //"云 API 密钥 SecretKey";
  425. long durationSecond = 1000; // 每次请求签名有效时长,单位为秒
  426. QCloudCredentialProvider cosCredentialProvider = new DefaultQCloudCredentialProvider(
  427. secretId, secretKey, durationSecond
  428. );
  429. // 初始化 CosXmlServer
  430. CosXmlServer cosXml = new CosXmlServer(config, cosCredentialProvider);
  431. // 创建存储桶
  432. try
  433. {
  434. string bucket = "thuai6-1314234950"; // 格式:BucketName-APPID
  435. string localDir = System.IO.Path.GetDirectoryName(download_dir); // 本地文件夹
  436. string localFileName = System.IO.Path.GetFileName(download_dir); // 指定本地保存的文件名
  437. GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName);
  438. Dictionary<string, string> test = request.GetRequestHeaders();
  439. request.SetCosProgressCallback(delegate (long completed, long total)
  440. {
  441. //Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));
  442. });
  443. // 执行请求
  444. GetObjectResult result = cosXml.GetObject(request);
  445. // 请求成功
  446. }
  447. catch (CosClientException clientEx)
  448. {
  449. throw clientEx;
  450. }
  451. catch (CosServerException serverEx)
  452. {
  453. throw serverEx;
  454. }
  455. }
  456. public static void GetNewHash()
  457. {
  458. Tencent_cos_download Downloader = new Tencent_cos_download();
  459. Downloader.download(System.IO.Path.Combine(Data.FilePath, "hash.json"), "hash.json");
  460. }
  461. public static string GetFileMd5Hash(string strFileFullPath)
  462. {
  463. FileStream fst = null;
  464. try
  465. {
  466. fst = new FileStream(strFileFullPath, FileMode.Open);
  467. byte[] data = MD5.Create().ComputeHash(fst);
  468. StringBuilder sBuilder = new StringBuilder();
  469. for (int i = 0; i < data.Length; i++)
  470. {
  471. sBuilder.Append(data[i].ToString("x2"));
  472. }
  473. fst.Close();
  474. return sBuilder.ToString().ToLower();
  475. }
  476. catch (Exception)
  477. {
  478. if (fst != null)
  479. fst.Close();
  480. if (File.Exists(strFileFullPath))
  481. return "conflict";
  482. return "";
  483. }
  484. finally
  485. {
  486. }
  487. }
  488. public static UpdateInfo Check()
  489. {
  490. string json, MD5, jsonName;
  491. int newFile = 0, updateFile = 0;
  492. newFileName.Clear();
  493. updateFileName.Clear();
  494. jsonName = "hash.json";
  495. UpdateInfo updateInfo;
  496. Tencent_cos_download Downloader = new Tencent_cos_download();
  497. try
  498. {
  499. // 如果json存在就删了重新下
  500. if (File.Exists(System.IO.Path.Combine(Data.FilePath, jsonName)))
  501. {
  502. File.Delete(System.IO.Path.Combine(Data.FilePath, jsonName));
  503. Downloader.download(System.IO.Path.Combine(Data.FilePath, jsonName), jsonName);
  504. }
  505. else
  506. {
  507. Downloader.download(System.IO.Path.Combine(Data.FilePath, jsonName), jsonName);
  508. }
  509. }
  510. catch (CosClientException clientEx)
  511. {
  512. // 请求失败
  513. updateInfo.status = "ClientEx: " + clientEx.ToString();
  514. updateInfo.newFileCount = -1;
  515. updateInfo.changedFileCount = 0;
  516. return updateInfo;
  517. }
  518. catch (CosServerException serverEx)
  519. {
  520. // 请求失败
  521. updateInfo.status = "ServerEx: " + serverEx.ToString();
  522. updateInfo.newFileCount = -1;
  523. updateInfo.changedFileCount = 0;
  524. return updateInfo;
  525. }
  526. using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, jsonName)))
  527. json = r.ReadToEnd();
  528. json = json.Replace("\r", string.Empty).Replace("\n", string.Empty);
  529. Dictionary<string, string> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  530. foreach (KeyValuePair<string, string> pair in jsonDict)
  531. {
  532. if (System.IO.Path.GetFileName(pair.Key) != "AI.cpp" && System.IO.Path.GetFileName(pair.Key) != "AI.py")
  533. {
  534. MD5 = GetFileMd5Hash(System.IO.Path.Combine(Data.FilePath, pair.Key));
  535. if (MD5.Length == 0) // 文档不存在
  536. newFileName.Add(pair.Key);
  537. else if (MD5.Equals("conflict"))
  538. MessageBox.Show($"文件{pair.Key}已打开,无法检查是否为最新,若需要,请关闭文件稍后手动检查更新", "文件正在使用", MessageBoxButton.OK, MessageBoxImage.Warning);
  539. else if (MD5 != pair.Value) // MD5不匹配
  540. updateFileName.Add(pair.Key);
  541. }
  542. }
  543. newFile = newFileName.Count;
  544. updateFile = updateFileName.Count;
  545. filenum = newFile + updateFile;
  546. //Console.WriteLine("----------------------" + Environment.NewLine);
  547. if (newFile + updateFile == 0)
  548. {
  549. updateInfo.status = "latest";
  550. updateInfo.newFileCount = 0;
  551. updateInfo.changedFileCount = 0;
  552. newFileName.Clear();
  553. updateFileName.Clear();
  554. }
  555. else
  556. {
  557. updateInfo.status = "old";
  558. //TODO:获取版本号
  559. updateInfo.newFileCount = newFile;
  560. /*
  561. foreach (string filename in newFileName)
  562. {
  563. Console.WriteLine(filename);
  564. }
  565. */
  566. updateInfo.changedFileCount = updateFile;
  567. /*
  568. foreach (string filename in updateFileName)
  569. {
  570. Console.WriteLine(filename);
  571. }
  572. Console.Write(Environment.NewLine + "是否下载新文件? y/n:");
  573. if (Console.Read() != 'y')
  574. Console.WriteLine("下载取消!");
  575. else
  576. Download();
  577. */
  578. UpdatePlanned = true;
  579. }
  580. return updateInfo;
  581. }
  582. public static bool Update()
  583. {
  584. if (UpdatePlanned)
  585. {
  586. Download();
  587. UpdatePlanned = false;
  588. return true;
  589. }
  590. return false;
  591. }
  592. private static void Download()
  593. {
  594. Tencent_cos_download Downloader = new Tencent_cos_download();
  595. int newFile = 0, updateFile = 0;
  596. int totalnew = newFileName.Count, totalupdate = updateFileName.Count;
  597. filenum = totalnew + totalupdate;
  598. if (newFileName.Count > 0 || updateFileName.Count > 0)
  599. {
  600. try
  601. {
  602. foreach (string filename in newFileName)
  603. {
  604. //Console.WriteLine(newFile + 1 + "/" + totalnew + ":开始下载" + filename);
  605. Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename);
  606. //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine);
  607. newFile++;
  608. }
  609. foreach (string filename in updateFileName)
  610. {
  611. //Console.WriteLine(updateFile + 1 + "/" + totalupdate + ":开始下载" + filename);
  612. File.Delete(System.IO.Path.Combine(@Data.FilePath, filename));
  613. Downloader.download(System.IO.Path.Combine(@Data.FilePath, filename), filename);
  614. //Console.WriteLine(filename + "下载完毕!" + Environment.NewLine);
  615. updateFile++;
  616. }
  617. }
  618. catch (CosClientException clientEx)
  619. {
  620. // 请求失败
  621. Console.WriteLine("CosClientException: " + clientEx.ToString() + Environment.NewLine);
  622. return;
  623. }
  624. catch (CosServerException serverEx)
  625. {
  626. // 请求失败
  627. Console.WriteLine("CosClientException: " + serverEx.ToString() + Environment.NewLine);
  628. return;
  629. }
  630. catch (Exception)
  631. {
  632. throw;
  633. }
  634. }
  635. else
  636. Console.WriteLine("当前平台已是最新版本!" + Environment.NewLine);
  637. newFileName.Clear();
  638. updateFileName.Clear();
  639. }
  640. public static bool CheckAlreadyDownload() // 检查是否已经下载
  641. {
  642. string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  643. if (!File.Exists(existpath)) // 文件不存在
  644. {
  645. using FileStream fs = new FileStream(existpath, FileMode.Create, FileAccess.ReadWrite);
  646. return false;
  647. }
  648. else // 文件存在
  649. {
  650. using FileStream fs = new FileStream(existpath, FileMode.Open, FileAccess.Read);
  651. using StreamReader sr = new StreamReader(fs);
  652. string json = sr.ReadToEnd();
  653. if (json == null || json == "")
  654. {
  655. json += @"{""THUAI6""" + ":" + @"""2023""}";
  656. }
  657. var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  658. if (dict == null || !dict.ContainsKey("download") || "false" == dict["download"])
  659. {
  660. return false;
  661. }
  662. else if (dict["download"] == "true")
  663. {
  664. return true;
  665. }
  666. else
  667. {
  668. return false;
  669. }
  670. }
  671. }
  672. public static void DownloadAll() // 下载全部文件
  673. {
  674. string jsonName = "hash.json";
  675. string json;
  676. Tencent_cos_download Downloader = new Tencent_cos_download();
  677. try
  678. {
  679. // 如果json存在就删了重新下
  680. if (File.Exists(System.IO.Path.Combine(Data.FilePath, jsonName)))
  681. {
  682. File.Delete(System.IO.Path.Combine(Data.FilePath, jsonName));
  683. Downloader.download(System.IO.Path.Combine(Data.FilePath, jsonName), jsonName);
  684. }
  685. else
  686. {
  687. Downloader.download(System.IO.Path.Combine(Data.FilePath, jsonName), jsonName);
  688. }
  689. }
  690. catch (CosClientException clientEx)
  691. {
  692. // 请求失败
  693. Console.WriteLine("CosClientException: " + clientEx.ToString() + Environment.NewLine);
  694. return;
  695. }
  696. catch (CosServerException serverEx)
  697. {
  698. // 请求失败
  699. Console.WriteLine("CosClientException: " + serverEx.ToString() + Environment.NewLine);
  700. return;
  701. }
  702. using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, jsonName)))
  703. json = r.ReadToEnd();
  704. json = json.Replace("\r", string.Empty).Replace("\n", string.Empty);
  705. Dictionary<string, string> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  706. newFileName.Clear();
  707. updateFileName.Clear();
  708. foreach (KeyValuePair<string, string> pair in jsonDict)
  709. {
  710. newFileName.Add(pair.Key);
  711. }
  712. Download();
  713. string json2;
  714. Dictionary<string, string> dict = new Dictionary<string, string>();
  715. string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  716. using FileStream fs = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite);
  717. using (StreamReader r = new StreamReader(fs))
  718. {
  719. json2 = r.ReadToEnd();
  720. if (json2 == null || json2 == "")
  721. {
  722. json2 += @"{""THUAI6""" + ":" + @"""2023""}";
  723. }
  724. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json2);
  725. if (dict == null || !dict.ContainsKey("download"))
  726. {
  727. dict?.Add("download", "true");
  728. }
  729. else
  730. {
  731. dict["download"] = "true";
  732. }
  733. }
  734. using FileStream fs2 = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite);
  735. using StreamWriter sw = new StreamWriter(fs2);
  736. fs2.SetLength(0);
  737. sw.Write(JsonConvert.SerializeObject(dict));
  738. }
  739. public static void Change_all_hash(string topDir, Dictionary<string, string> jsonDict) // 更改HASH
  740. {
  741. DirectoryInfo theFolder = new DirectoryInfo(@topDir);
  742. bool ifexist = false;
  743. // 遍历文件
  744. foreach (FileInfo NextFile in theFolder.GetFiles())
  745. {
  746. string filepath = topDir + @"/" + NextFile.Name; // 文件路径
  747. //Console.WriteLine(filepath);
  748. foreach (KeyValuePair<string, string> pair in jsonDict)
  749. {
  750. if (System.IO.Path.Equals(filepath, System.IO.Path.Combine(Data.FilePath, pair.Key).Replace('\\', '/')))
  751. {
  752. ifexist = true;
  753. string MD5 = GetFileMd5Hash(filepath);
  754. jsonDict[pair.Key] = MD5;
  755. }
  756. }
  757. if (!ifexist && NextFile.Name != "hash.json")
  758. {
  759. string MD5 = GetFileMd5Hash(filepath);
  760. string relapath = filepath.Replace(Data.FilePath + '/', string.Empty);
  761. jsonDict.Add(relapath, MD5);
  762. }
  763. ifexist = false;
  764. }
  765. // 遍历文件夹
  766. foreach (DirectoryInfo NextFolder in theFolder.GetDirectories())
  767. {
  768. if (System.IO.Path.Equals(NextFolder.FullName, System.IO.Path.GetFullPath(System.IO.Path.Combine(Data.FilePath, playerFolder))))
  769. {
  770. foreach (FileInfo NextFile in NextFolder.GetFiles())
  771. {
  772. if (NextFile.Name == "README.md")
  773. {
  774. string MD5 = GetFileMd5Hash(NextFile.FullName);
  775. string relapath = NextFile.FullName.Replace('\\', '/').Replace(Data.FilePath + '/', string.Empty);
  776. jsonDict.Add(relapath, MD5);
  777. }
  778. }
  779. continue; // 如果是选手文件夹就忽略
  780. }
  781. Change_all_hash(NextFolder.FullName.Replace('\\', '/'), jsonDict);
  782. }
  783. }
  784. public static void UpdateHash()
  785. {
  786. while (true)
  787. {
  788. if (Directory.Exists(Data.FilePath))
  789. {
  790. string json;
  791. if (!File.Exists(System.IO.Path.Combine(Data.FilePath, "hash.json")))
  792. {
  793. Console.WriteLine("hash.json文件丢失!即将重新下载该文件!");
  794. GetNewHash();
  795. }
  796. using (StreamReader r = new StreamReader(System.IO.Path.Combine(Data.FilePath, "hash.json")))
  797. json = r.ReadToEnd();
  798. json = json.Replace("\r", string.Empty).Replace("\n", string.Empty).Replace("/", @"\\");
  799. Dictionary<string, string> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  800. Change_all_hash(Data.FilePath, jsonDict);
  801. OverwriteHash(jsonDict);
  802. break;
  803. }
  804. else
  805. {
  806. Console.WriteLine("读取路径失败!请重新输入文件路径:");
  807. Data.ResetFilepath(Console.ReadLine());
  808. }
  809. }
  810. }
  811. public static int DeleteAll()
  812. {
  813. DirectoryInfo di = new DirectoryInfo(Data.FilePath);
  814. DirectoryInfo player = new DirectoryInfo(System.IO.Path.GetFullPath(System.IO.Path.Combine(Data.FilePath, playerFolder)));
  815. try
  816. {
  817. foreach (FileInfo file in di.GetFiles())
  818. {
  819. file.Delete();
  820. }
  821. if (Directory.Exists(Data.FilePath + playerFolder))
  822. {
  823. foreach (FileInfo file in player.GetFiles())
  824. {
  825. if (file.Name == "AI.cpp" || file.Name == "AI.py")
  826. {
  827. continue;
  828. }
  829. string filename = System.IO.Path.GetFileName(file.FullName);
  830. file.MoveTo(System.IO.Path.Combine(Data.FilePath, filename));
  831. }
  832. }
  833. foreach (DirectoryInfo subdi in di.GetDirectories())
  834. {
  835. subdi.Delete(true);
  836. }
  837. }
  838. catch (UnauthorizedAccessException)
  839. {
  840. Console.WriteLine("权限不足,无法删除!");
  841. return -2;
  842. }
  843. catch (DirectoryNotFoundException)
  844. {
  845. Console.WriteLine("文件夹没有找到,请检查是否已经手动更改路径");
  846. return -3;
  847. }
  848. catch (IOException)
  849. {
  850. Console.WriteLine("文件已经打开,请关闭后再删除");
  851. return -1;
  852. }
  853. string json2;
  854. Dictionary<string, string> dict = new Dictionary<string, string>();
  855. string existpath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  856. using FileStream fs = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite);
  857. using (StreamReader r = new StreamReader(fs))
  858. {
  859. json2 = r.ReadToEnd();
  860. if (json2 == null || json2 == "")
  861. {
  862. json2 += @"{""THUAI6""" + ":" + @"""2023""}";
  863. }
  864. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json2);
  865. if (dict == null || !dict.ContainsKey("download"))
  866. {
  867. dict?.Add("download", "false");
  868. }
  869. else
  870. {
  871. dict["download"] = "false";
  872. }
  873. }
  874. using FileStream fs2 = new FileStream(existpath, FileMode.Open, FileAccess.ReadWrite);
  875. using StreamWriter sw = new StreamWriter(fs2);
  876. fs2.SetLength(0);
  877. sw.Write(JsonConvert.SerializeObject(dict));
  878. sw.Close();
  879. fs2.Close();
  880. try
  881. {
  882. File.Delete(Data.path);
  883. }
  884. catch (UnauthorizedAccessException)
  885. {
  886. Console.WriteLine("权限不足,无法删除!");
  887. return -2;
  888. }
  889. catch (DirectoryNotFoundException)
  890. {
  891. Console.WriteLine("文件夹没有找到,请检查是否已经手动更改路径");
  892. return -3;
  893. }
  894. catch (IOException)
  895. {
  896. Console.WriteLine("文件已经打开,请关闭后再删除");
  897. return -1;
  898. }
  899. return 0;
  900. }
  901. public static void OverwriteHash(Dictionary<string, string> jsonDict)
  902. {
  903. string Contentjson = JsonConvert.SerializeObject(jsonDict);
  904. Contentjson = Contentjson.Replace("\r", String.Empty).Replace("\n", String.Empty).Replace(@"\\", "/");
  905. File.WriteAllText(@System.IO.Path.Combine(Data.FilePath, "hash.json"), Contentjson);
  906. }
  907. public static int MoveProgram(string newPath)
  908. {
  909. DirectoryInfo newdi = new DirectoryInfo(newPath);
  910. DirectoryInfo olddi = new DirectoryInfo(Data.FilePath);
  911. try
  912. {
  913. foreach (DirectoryInfo direct in olddi.GetDirectories())
  914. {
  915. direct.MoveTo(System.IO.Path.Combine(newPath, direct.Name));
  916. }
  917. foreach (FileInfo file in olddi.GetFiles())
  918. {
  919. file.MoveTo(System.IO.Path.Combine(newPath, file.Name));
  920. }
  921. }
  922. catch (DirectoryNotFoundException)
  923. {
  924. Console.WriteLine("原路径未找到!请检查文件是否损坏");
  925. foreach (DirectoryInfo newdirect in newdi.GetDirectories())
  926. {
  927. newdirect.MoveTo(System.IO.Path.Combine(Data.FilePath, newdirect.Name));
  928. }
  929. foreach (FileInfo file in newdi.GetFiles())
  930. {
  931. file.MoveTo(System.IO.Path.Combine(Data.FilePath, file.Name));
  932. }
  933. Console.WriteLine("移动失败!");
  934. return -2;
  935. }
  936. catch (IOException)
  937. {
  938. Console.WriteLine("文件已打开或者目标路径下有同名文件!");
  939. foreach (DirectoryInfo newdirect in newdi.GetDirectories())
  940. {
  941. newdirect.MoveTo(System.IO.Path.Combine(Data.FilePath, newdirect.Name));
  942. }
  943. foreach (FileInfo file in newdi.GetFiles())
  944. {
  945. file.MoveTo(System.IO.Path.Combine(Data.FilePath, file.Name));
  946. }
  947. Console.WriteLine("移动失败!");
  948. return -1;
  949. }
  950. Data.ResetFilepath(newPath);
  951. Console.WriteLine("更改路径成功!");
  952. return 0;
  953. }
  954. public static async Task main(string[] args)
  955. {
  956. var client = new HttpClient();
  957. var web = new WebConnect.Web();
  958. Data date = new Data("");
  959. while (true)
  960. {
  961. Console.WriteLine($"1. 更新hash.json 2. 检查更新 3.下载{ProgramName} 4.删除{ProgramName} 5.启动进程 6.移动{ProgramName}到其它路径");
  962. string choose = Console.ReadLine();
  963. if (choose == "1")
  964. {
  965. if (!CheckAlreadyDownload())
  966. {
  967. Console.WriteLine($"未下载{ProgramName},请先执行下载操作!");
  968. continue;
  969. }
  970. UpdateHash();
  971. }
  972. else if (choose == "2")
  973. {
  974. if (!CheckAlreadyDownload())
  975. {
  976. Console.WriteLine($"未下载{ProgramName},请先执行下载操作!");
  977. continue;
  978. }
  979. while (true)
  980. {
  981. if (Data.FilePath != null && Directory.Exists(Data.FilePath))
  982. {
  983. Check();
  984. break;
  985. }
  986. else
  987. {
  988. Console.WriteLine("读取路径失败!请重新输入文件路径:");
  989. Data.ResetFilepath(Console.ReadLine());
  990. }
  991. }
  992. }
  993. else if (choose == "3")
  994. {
  995. if (CheckAlreadyDownload())
  996. {
  997. Console.WriteLine($"已经将{ProgramName}下载到{Data.FilePath}!若要重新下载请先完成删除操作!");
  998. }
  999. else
  1000. {
  1001. string newpath;
  1002. Console.WriteLine("请输入下载路径:");
  1003. newpath = Console.ReadLine();
  1004. Data.ResetFilepath(newpath);
  1005. DownloadAll();
  1006. }
  1007. }
  1008. else if (choose == "4")
  1009. {
  1010. DeleteAll();
  1011. }
  1012. else if (choose == "5")
  1013. {
  1014. if (CheckAlreadyDownload())
  1015. {
  1016. Process.Start(System.IO.Path.Combine(Data.FilePath, startName));
  1017. }
  1018. else
  1019. {
  1020. Console.WriteLine($"未下载{ProgramName},请先执行下载操作!");
  1021. }
  1022. }
  1023. else if (choose == "6")
  1024. {
  1025. string newPath;
  1026. newPath = Console.ReadLine();
  1027. MoveProgram(newPath);
  1028. }
  1029. else if (choose == "7")
  1030. {
  1031. Console.WriteLine("请输入email:");
  1032. string username = Console.ReadLine();
  1033. Console.WriteLine("请输入密码:");
  1034. string password = Console.ReadLine();
  1035. await web.LoginToEEsast(client, username, password);
  1036. }
  1037. else if (choose == "8")
  1038. {
  1039. await web.UserDetails(client);
  1040. }
  1041. else if (choose == "9")
  1042. {
  1043. await web.UploadFiles(client, "", "", "");
  1044. }
  1045. else if (choose == "exit")
  1046. {
  1047. return;
  1048. }
  1049. }
  1050. }
  1051. }
  1052. }
  1053. }
  1054. namespace WebConnect
  1055. {
  1056. class Web
  1057. {
  1058. public enum language { cpp, py };
  1059. public static string logintoken = "";
  1060. async public Task<int> LoginToEEsast(HttpClient client, string useremail, string password)
  1061. {
  1062. string token = "";
  1063. try
  1064. {
  1065. using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new
  1066. {
  1067. email = useremail,
  1068. password = password,
  1069. })))
  1070. {
  1071. switch (response.StatusCode)
  1072. {
  1073. case System.Net.HttpStatusCode.OK:
  1074. //Console.WriteLine("Success login");
  1075. token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions()
  1076. {
  1077. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  1078. }) as LoginResponse)
  1079. ?.Token ??
  1080. throw new Exception("no token!");
  1081. logintoken = token;
  1082. SaveToken();
  1083. var info = JsonConvert.DeserializeObject<Dictionary<string, string>>(await response.Content.ReadAsStringAsync());
  1084. Downloader.UserInfo._id = info["_id"];
  1085. Downloader.UserInfo.email = info["email"];
  1086. break;
  1087. default:
  1088. int code = ((int)response.StatusCode);
  1089. //Console.WriteLine(code);
  1090. if (code == 401)
  1091. {
  1092. //Console.WriteLine("邮箱或密码错误!");
  1093. return -1;
  1094. }
  1095. break;
  1096. }
  1097. return 0;
  1098. }
  1099. }
  1100. catch
  1101. {
  1102. return -2;
  1103. }
  1104. }
  1105. /// <summary>
  1106. ///
  1107. /// </summary>
  1108. /// <param name="client">http client</param>
  1109. /// <param name="tarfile">代码源位置</param>
  1110. /// <param name="type">编程语言,格式为"cpp"或"python"</param>
  1111. /// <param name="plr">第x位玩家,格式为"player_x"</param>
  1112. /// <returns>-1:tokenFail;-2:FileNotExist;-3:CosFail;-4:loginTimeout;-5:Fail;-6:ReadFileFail;-7:networkError</returns>
  1113. async public Task<int> UploadFiles(HttpClient client, string tarfile, string type, string plr) //用来上传文件
  1114. {
  1115. if (!ReadToken()) //读取token失败
  1116. {
  1117. return -1;
  1118. }
  1119. try
  1120. {
  1121. string content;
  1122. client.DefaultRequestHeaders.Authorization = new("Bearer", logintoken);
  1123. if (!File.Exists(tarfile))
  1124. {
  1125. //Console.WriteLine("文件不存在!");
  1126. return -2;
  1127. }
  1128. using FileStream fs = new FileStream(tarfile, FileMode.Open, FileAccess.Read);
  1129. using StreamReader sr = new StreamReader(fs);
  1130. content = sr.ReadToEnd();
  1131. string targetUrl = $"https://api.eesast.com/static/player?team_id={await GetTeamId()}";
  1132. using (var response = await client.GetAsync(targetUrl))
  1133. {
  1134. switch (response.StatusCode)
  1135. {
  1136. case System.Net.HttpStatusCode.OK:
  1137. var res = JsonConvert.DeserializeObject<Dictionary<string, string>>(await response.Content.ReadAsStringAsync());
  1138. string appid = "1255334966"; // 设置腾讯云账户的账户标识(APPID)
  1139. string region = "ap-beijing"; // 设置一个默认的存储桶地域
  1140. CosXmlConfig config = new CosXmlConfig.Builder()
  1141. .IsHttps(true) // 设置默认 HTTPS 请求
  1142. .SetAppid(appid) // 设置腾讯云账户的账户标识 APPID
  1143. .SetRegion(region) // 设置一个默认的存储桶地域
  1144. .SetDebugLog(true) // 显示日志
  1145. .Build(); // 创建 CosXmlConfig 对象
  1146. string tmpSecretId = res["TmpSecretId"]; //"临时密钥 SecretId";
  1147. string tmpSecretKey = res["TmpSecretKey"]; //"临时密钥 SecretKey";
  1148. string tmpToken = res["SecurityToken"]; //"临时密钥 token";
  1149. long tmpExpiredTime = Convert.ToInt64(res["ExpiredTime"]);//临时密钥有效截止时间,精确到秒
  1150. QCloudCredentialProvider cosCredentialProvider = new DefaultSessionQCloudCredentialProvider(
  1151. tmpSecretId, tmpSecretKey, tmpExpiredTime, tmpToken
  1152. );
  1153. // 初始化 CosXmlServer
  1154. CosXmlServer cosXml = new CosXmlServer(config, cosCredentialProvider);
  1155. // 初始化 TransferConfig
  1156. TransferConfig transferConfig = new TransferConfig();
  1157. // 初始化 TransferManager
  1158. TransferManager transferManager = new TransferManager(cosXml, transferConfig);
  1159. string bucket = "eesast-1255334966"; //存储桶,格式:BucketName-APPID
  1160. string cosPath = $"/THUAI6/{GetTeamId()}/{type}/{plr}"; //对象在存储桶中的位置标识符,即称对象键
  1161. string srcPath = tarfile;//本地文件绝对路径
  1162. // 上传对象
  1163. COSXMLUploadTask uploadTask = new COSXMLUploadTask(bucket, cosPath);
  1164. uploadTask.SetSrcPath(srcPath);
  1165. uploadTask.progressCallback = delegate (long completed, long total)
  1166. {
  1167. //Console.WriteLine(string.Format("progress = {0:##.##}%", completed * 100.0 / total));
  1168. };
  1169. try
  1170. {
  1171. COSXMLUploadTask.UploadTaskResult result = await transferManager.UploadAsync(uploadTask);
  1172. //Console.WriteLine(result.GetResultInfo());
  1173. string eTag = result.eTag;
  1174. //到这里应该是成功了,但是因为我没有试过,也不知道具体情况,可能还要根据result的内容判断
  1175. }
  1176. catch (Exception)
  1177. {
  1178. return -3;
  1179. }
  1180. break;
  1181. case System.Net.HttpStatusCode.Unauthorized:
  1182. //Console.WriteLine("您未登录或登录过期,请先登录");
  1183. return -4;
  1184. default:
  1185. //Console.WriteLine("上传失败!");
  1186. return -5;
  1187. }
  1188. }
  1189. }
  1190. catch (IOException)
  1191. {
  1192. //Console.WriteLine("文件读取错误!请检查文件是否被其它应用占用!");
  1193. return -6;
  1194. }
  1195. catch
  1196. {
  1197. //Console.WriteLine("请求错误!请检查网络连接!");
  1198. return -7;
  1199. }
  1200. return 0;
  1201. }
  1202. async public Task UserDetails(HttpClient client) // 用来测试访问网站
  1203. {
  1204. if (!ReadToken()) // 读取token失败
  1205. {
  1206. return;
  1207. }
  1208. try
  1209. {
  1210. client.DefaultRequestHeaders.Authorization = new("Bearer", logintoken);
  1211. Console.WriteLine(logintoken);
  1212. using (var response = await client.GetAsync("https://api.eesast.com/application/info")) // JsonContent.Create(new
  1213. //{
  1214. //})))
  1215. {
  1216. switch (response.StatusCode)
  1217. {
  1218. case System.Net.HttpStatusCode.OK:
  1219. Console.WriteLine("Require OK");
  1220. Console.WriteLine(await response.Content.ReadAsStringAsync());
  1221. break;
  1222. default:
  1223. int code = ((int)response.StatusCode);
  1224. if (code == 401)
  1225. {
  1226. Console.WriteLine("您未登录或登录过期,请先登录");
  1227. }
  1228. return;
  1229. }
  1230. }
  1231. }
  1232. catch
  1233. {
  1234. Console.WriteLine("请求错误!请检查网络连接!");
  1235. }
  1236. }
  1237. public void SaveToken() // 保存token
  1238. {
  1239. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1240. try
  1241. {
  1242. string json;
  1243. Dictionary<string, string> dict = new Dictionary<string, string>();
  1244. using FileStream fs = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  1245. using (StreamReader r = new StreamReader(fs))
  1246. {
  1247. json = r.ReadToEnd();
  1248. if (json == null || json == "")
  1249. {
  1250. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1251. }
  1252. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1253. if (dict.ContainsKey("token"))
  1254. {
  1255. dict.Remove("token");
  1256. }
  1257. dict?.Add("token", logintoken);
  1258. }
  1259. using FileStream fs2 = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  1260. using StreamWriter sw = new StreamWriter(fs2);
  1261. fs2.SetLength(0);
  1262. sw.Write(JsonConvert.SerializeObject(dict)); //将token写入文件
  1263. }
  1264. catch (DirectoryNotFoundException)
  1265. {
  1266. Console.WriteLine("保存token时未找到下载器地址!请检查下载器是否被移动!");
  1267. }
  1268. catch (PathTooLongException)
  1269. {
  1270. Console.WriteLine("下载器的路径名太长!请尝试移动下载器!");
  1271. }
  1272. catch (ArgumentNullException)
  1273. {
  1274. Console.WriteLine("下载器路径初始化失败!");
  1275. }
  1276. catch (IOException)
  1277. {
  1278. Console.WriteLine("写入token.dat发生冲突!请检查token.dat是否被其它程序占用!");
  1279. }
  1280. }
  1281. public static int WriteUserEmail(string email)
  1282. {
  1283. try
  1284. {
  1285. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1286. FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.ReadWrite);
  1287. StreamReader sr = new StreamReader(fs);
  1288. string json = sr.ReadToEnd();
  1289. if (json == null || json == "")
  1290. {
  1291. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1292. }
  1293. Dictionary<string, string> dict = new Dictionary<string, string>();
  1294. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1295. if (!dict.ContainsKey("email"))
  1296. {
  1297. dict.Add("email", email);
  1298. }
  1299. else
  1300. {
  1301. dict["email"] = email;
  1302. }
  1303. sr.Close();
  1304. fs.Close();
  1305. FileStream fs2 = new FileStream(savepath, FileMode.Open, FileAccess.ReadWrite);
  1306. StreamWriter sw = new StreamWriter(fs2);
  1307. sw.WriteLine(JsonConvert.SerializeObject(dict));
  1308. sw.Close();
  1309. fs2.Close();
  1310. return 0;//成功
  1311. }
  1312. catch
  1313. {
  1314. return -1;//失败
  1315. }
  1316. }
  1317. public static int WriteUserPassword(string password)
  1318. {
  1319. try
  1320. {
  1321. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1322. FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.ReadWrite);
  1323. StreamReader sr = new StreamReader(fs);
  1324. string json = sr.ReadToEnd();
  1325. if (json == null || json == "")
  1326. {
  1327. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1328. }
  1329. Dictionary<string, string> dict = new Dictionary<string, string>();
  1330. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1331. if (!dict.ContainsKey("password"))
  1332. {
  1333. dict.Add("password", password);
  1334. }
  1335. else
  1336. {
  1337. dict["password"] = password;
  1338. }
  1339. sr.Close();
  1340. fs.Close();
  1341. FileStream fs2 = new FileStream(savepath, FileMode.Open, FileAccess.ReadWrite);
  1342. StreamWriter sw = new StreamWriter(fs2);
  1343. sw.WriteLine(JsonConvert.SerializeObject(dict));
  1344. sw.Close();
  1345. fs2.Close();
  1346. return 0;//成功
  1347. }
  1348. catch
  1349. {
  1350. return -1;//失败,THUAI6.json 文件不存在或者已被占用
  1351. }
  1352. }
  1353. public static string ReadUserPassword()
  1354. {
  1355. try
  1356. {
  1357. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1358. FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.Read);
  1359. StreamReader sr = new StreamReader(fs);
  1360. string json = sr.ReadToEnd();
  1361. Dictionary<string, string> dict = new Dictionary<string, string>();
  1362. if (json == null || json == "")
  1363. {
  1364. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1365. }
  1366. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1367. return dict["password"];
  1368. }
  1369. catch
  1370. {
  1371. return null; //文件不存在或者已被占用
  1372. }
  1373. }
  1374. public static string ReadUserEmail()
  1375. {
  1376. try
  1377. {
  1378. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1379. FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.Read);
  1380. StreamReader sr = new StreamReader(fs);
  1381. string json = sr.ReadToEnd();
  1382. Dictionary<string, string> dict = new Dictionary<string, string>();
  1383. if (json == null || json == "")
  1384. {
  1385. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1386. }
  1387. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1388. return dict["email"];
  1389. }
  1390. catch
  1391. {
  1392. return null;
  1393. }
  1394. }
  1395. public bool ReadToken() // 读取token
  1396. {
  1397. try
  1398. {
  1399. string json;
  1400. Dictionary<string, string> dict = new Dictionary<string, string>();
  1401. string savepath = System.IO.Path.Combine(Data.dataPath, "THUAI6.json");
  1402. using FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.Read);
  1403. using StreamReader sr = new StreamReader(fs);
  1404. json = sr.ReadToEnd();
  1405. if (json == null || json == "")
  1406. {
  1407. json += @"{""THUAI6""" + ":" + @"""2023""}";
  1408. }
  1409. dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  1410. if (!dict.ContainsKey("token"))
  1411. {
  1412. return false;
  1413. }
  1414. else
  1415. {
  1416. logintoken = dict["token"];
  1417. return true;
  1418. }
  1419. }
  1420. catch (DirectoryNotFoundException)
  1421. {
  1422. Console.WriteLine("读取token时未找到下载器地址!请检查下载器是否被移动!");
  1423. return false;
  1424. }
  1425. catch (FileNotFoundException)
  1426. {
  1427. //没有登陆
  1428. Console.WriteLine("请先登录!");
  1429. return false;
  1430. }
  1431. catch (PathTooLongException)
  1432. {
  1433. Console.WriteLine("下载器的路径名太长!请尝试移动下载器!");
  1434. return false;
  1435. }
  1436. catch (ArgumentNullException)
  1437. {
  1438. Console.WriteLine("下载器路径初始化失败!");
  1439. return false;
  1440. }
  1441. catch (IOException)
  1442. {
  1443. Console.WriteLine("写入token.dat发生冲突!请检查token.dat是否被其它程序占用!");
  1444. return false;
  1445. }
  1446. }
  1447. async public Task<string> GetTeamId()
  1448. {
  1449. var client = new HttpClient();
  1450. var request = new HttpRequestMessage(HttpMethod.Post, "https://api.eesast.com/dev/v1/graphql");
  1451. request.Headers.Add("x-hasura-admin-secret", "hasuraDevAdminSecret");
  1452. //var content = new StringContent($@"
  1453. // {{
  1454. // ""query"": ""query MyQuery {{contest_team_member(where: {{user_id: {{_eq: \""{Downloader.UserInfo._id}\""}}}}) {{ team_id }}}}"",
  1455. // ""variables"": {{}},
  1456. // }}", null, "application/json");
  1457. var content = new StringContent("{\"query\":\"query MyQuery {\\r\\n contest_team_member(where: {user_id: {_eq: \\\"" + Downloader.UserInfo._id + "\\\"}}) {\\r\\n team_id\\r\\n }\\r\\n}\",\"variables\":{}}", null, "application/json");
  1458. request.Content = content;
  1459. var response = await client.SendAsync(request);
  1460. response.EnsureSuccessStatusCode();
  1461. var info = await response.Content.ReadAsStringAsync();
  1462. var s1 = JsonConvert.DeserializeObject<Dictionary<string, object>>(info)["data"];
  1463. var s2 = JsonConvert.DeserializeObject<Dictionary<string, List<object>>>(s1.ToString())["contest_team_member"];
  1464. var sres = JsonConvert.DeserializeObject<Dictionary<string, string>>(s2[0].ToString())["team_id"];
  1465. return sres;
  1466. }
  1467. async public Task<string> GetUserId(string learnNumber)
  1468. {
  1469. var client = new HttpClient();
  1470. var request = new HttpRequestMessage(HttpMethod.Post, "https://api.eesast.com/dev/v1/graphql");
  1471. request.Headers.Add("x-hasura-admin-secret", "hasuraDevAdminSecret");
  1472. var content = new StringContent("{\"query\":\"query MyQuery {\r\n user(where: {id: {_eq: \""
  1473. + learnNumber + "\"}}) {\r\n _id\r\n }\r\n}\r\n\",\"variables\":{}}", null, "application/json");
  1474. request.Content = content;
  1475. var response = await client.SendAsync(request);
  1476. response.EnsureSuccessStatusCode();
  1477. return await response.Content.ReadAsStringAsync();
  1478. }
  1479. }
  1480. [Serializable]
  1481. record LoginResponse
  1482. {
  1483. // Map `Token` to `token` when serializing
  1484. public string Token { get; set; } = "";
  1485. }
  1486. }