PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/Fixer/Program.cs

https://github.com/db81/Zero-K-Infrastructure
C# | 1040 lines | 812 code | 135 blank | 93 comment | 201 complexity | 919cc23b603f5005fab8d3d32f85a0a5 MD5 | raw file
Possible License(s): GPL-3.0, MIT
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Entity;
  4. using System.Data.Linq;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Drawing.Imaging;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Net;
  12. using System.Net.NetworkInformation;
  13. using System.Net.Sockets;
  14. using System.Text;
  15. using System.Text.RegularExpressions;
  16. using System.Threading;
  17. using System.Threading.Tasks;
  18. using System.Xml.Serialization;
  19. //using LobbyClient;
  20. //using NightWatch;
  21. using CaTracker;
  22. using LobbyClient;
  23. using Microsoft.Linq.Translations;
  24. using PlasmaShared;
  25. using ZkData.UnitSyncLib;
  26. using ZeroKWeb;
  27. using ZkData;
  28. using Encoder = System.Drawing.Imaging.Encoder;
  29. namespace Fixer
  30. {
  31. public static class Program
  32. {
  33. const int MaxBanHours = 24 * 36525; // 100 years
  34. public static string GenerateMACAddress()
  35. {
  36. var sBuilder = new StringBuilder();
  37. var r = new Random();
  38. int number;
  39. byte b;
  40. for (int i = 0; i < 6; i++)
  41. {
  42. number = r.Next(0, 255);
  43. b = Convert.ToByte(number);
  44. if (i == 0)
  45. {
  46. b = setBit(b, 6); //--> set locally administered
  47. b = unsetBit(b, 7); // --> set unicast
  48. }
  49. sBuilder.Append(number.ToString("X2"));
  50. }
  51. return sBuilder.ToString().ToUpper();
  52. }
  53. private static byte setBit(byte b, int BitNumber)
  54. {
  55. if (BitNumber < 8 && BitNumber > -1)
  56. {
  57. return (byte)(b | (byte)(0x01 << BitNumber));
  58. }
  59. else
  60. {
  61. throw new InvalidOperationException(
  62. "Der Wert für BitNumber " + BitNumber.ToString() + " war nicht im zulässigen Bereich! (BitNumber = (min)0 - (max)7)");
  63. }
  64. }
  65. private static byte unsetBit(byte b, int BitNumber)
  66. {
  67. if (BitNumber < 8 && BitNumber > -1)
  68. {
  69. return (byte)(b | (byte)(0x00 << BitNumber));
  70. }
  71. else
  72. {
  73. throw new InvalidOperationException(
  74. "Der Wert für BitNumber " + BitNumber.ToString() + " war nicht im zulässigen Bereich! (BitNumber = (min)0 - (max)7)");
  75. }
  76. }
  77. static byte[] GetBytes(string str)
  78. {
  79. byte[] bytes = new byte[str.Length * sizeof(char)];
  80. System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
  81. return bytes;
  82. }
  83. public static void TestCRC()
  84. {
  85. for (int i = 0; i < 8192; i++)
  86. {
  87. string mac = GenerateMACAddress() + "lobby.springrts.com";
  88. byte[] mac2 = Encoding.ASCII.GetBytes(mac);
  89. uint hash1 = LobbyClient.Crc.Crc32(mac2);
  90. uint hash2 = LobbyClient.Crc.Crc32Old(mac2);
  91. if (hash1 != hash2)
  92. {
  93. Console.WriteLine("MISMATCH: {0} vs. {1} (MAC {2})", hash1, hash2, mac);
  94. }
  95. }
  96. }
  97. public static void GetNICs()
  98. {
  99. var nics = NetworkInterface.GetAllNetworkInterfaces();
  100. foreach (NetworkInterface nic in nics)
  101. {
  102. System.Console.WriteLine("{0} | type {1}", nic.GetPhysicalAddress(), nic.NetworkInterfaceType);
  103. }
  104. }
  105. public static void FixDuplicatedAccounts()
  106. {
  107. GlobalConst.Mode = ModeType.Test;
  108. var db = new ZkDataContext();
  109. var duplicates = db.Accounts.GroupBy(x => x.Name).Where(x => x.Count() > 1).ToList();
  110. foreach (var duplicateGroup in duplicates)
  111. {
  112. var keep = duplicateGroup.OrderByDescending(x => x.SpringBattlePlayers.Count()).ThenByDescending(x => x.LastLogin).First();
  113. foreach (var todel in duplicateGroup.ToList())
  114. if (keep.AccountID != todel.AccountID)
  115. {
  116. try
  117. {
  118. db.ForumThreadLastReads.DeleteAllOnSubmit(todel.ForumThreadLastReads.ToList());
  119. db.AccountBattleAwards.DeleteAllOnSubmit(todel.AccountBattleAwards.ToList());
  120. db.Accounts.DeleteOnSubmit(todel);
  121. db.SubmitChanges();
  122. Console.WriteLine("Deleted {0}", todel.Name);
  123. }
  124. catch (Exception ex)
  125. {
  126. using (var db2 = new ZkDataContext())
  127. {
  128. var acc = db2.Accounts.Find(todel.AccountID);
  129. acc.IsDeleted = true;
  130. acc.Name = string.Format("___DELETED___{0}", todel.AccountID); // hacky way to avoid duplicates
  131. db2.SubmitChanges();
  132. }
  133. Console.WriteLine("Failed to delete {0}", todel.Name);
  134. }
  135. }
  136. }
  137. }
  138. public enum OptionType
  139. {
  140. Undefined = 0,
  141. Bool = 1,
  142. List = 2,
  143. Number = 3,
  144. String = 4,
  145. Section = 5
  146. }
  147. public static OptionType Type { get; set; }
  148. public static bool GetPair(string Value, out string result)
  149. {
  150. result = "";
  151. Type = OptionType.Number;
  152. switch (Type)
  153. {
  154. case OptionType.Bool:
  155. if (Value != "0" && Value != "1") return false;
  156. return true;
  157. case OptionType.Number:
  158. double d;
  159. if (!double.TryParse(Value, out d)) return false;
  160. return true;
  161. case OptionType.String:
  162. return true;
  163. }
  164. return false;
  165. }
  166. public static void FixStuff()
  167. {
  168. //UpdateMissionProgression(13);
  169. /*
  170. var db = new ZkDataContext();
  171. int accountID = 5806;
  172. List<CampaignJournal> unlockedJournals = new List<CampaignJournal>();
  173. CampaignPlanet planet = db.CampaignPlanets.First(x => x.PlanetID == 13);
  174. int campID = planet.CampaignID;
  175. db.CampaignEvents.InsertOnSubmit(Global.CreateCampaignEvent(accountID, campID, "Planet completed: {0}", planet));
  176. //foreach (CampaignJournal journal in db.CampaignJournals.Where(x => x.CampaignID == campID && x.PlanetID == planet.PlanetID && x.UnlockOnPlanetCompletion))
  177. //{
  178. // unlockedJournals.Add(journal);
  179. //}
  180. //foreach (CampaignJournal uj in unlockedJournals)
  181. //{
  182. // db.CampaignEvents.InsertOnSubmit(Global.CreateCampaignEvent(accountID, campID, "{1} - Journal entry unlocked: {0}", uj, uj.CampaignPlanet));
  183. //}
  184. db.SubmitChanges();
  185. */
  186. }
  187. public static void AddClanLeader()
  188. {
  189. var db = new ZkDataContext();
  190. var role = db.RoleTypes.First(x => x.IsClanOnly);
  191. foreach (var clan in db.Clans.Where(x => !x.IsDeleted))
  192. {
  193. if (!clan.AccountRoles.Any(y => y.RoleType.IsClanOnly))
  194. {
  195. var picked = clan.Accounts.Where(x => x.LastLogin >= DateTime.UtcNow.AddDays(-7)).OrderByDescending(x => x.Level).FirstOrDefault();
  196. if (picked == null) clan.Accounts.OrderByDescending(x => x.LastLogin).FirstOrDefault();
  197. if (picked != null)
  198. {
  199. clan.AccountRoles.Add(new AccountRole()
  200. {
  201. AccountID = picked.AccountID,
  202. ClanID = clan.ClanID,
  203. Inauguration = DateTime.UtcNow,
  204. RoleTypeID = role.RoleTypeID
  205. });
  206. }
  207. }
  208. }
  209. db.SubmitAndMergeChanges();
  210. }
  211. public static void GetGameStats(DateTime from)
  212. {
  213. //GlobalConst.Mode = ModeType.Live;
  214. var db = new ZkDataContext();
  215. var bats = db.SpringBattles.Where(x => x.StartTime >= from && x.Duration >= 60*5).ToList();
  216. Console.WriteLine("Battles from {0}", from);
  217. var total = bats.Count;
  218. Console.WriteLine("Total: {0}",total);
  219. var breakdown = bats.GroupBy(x => x.PlayerCount).OrderBy(x => x.Key).Select(x => new {
  220. Size = x.Key,
  221. Count = x.Count()
  222. }).ToList();
  223. foreach (var b in breakdown) {
  224. Console.WriteLine("Size: {0} Battles: {1}",b.Size,b.Count);
  225. }
  226. }
  227. [STAThread]
  228. static void Main(string[] args)
  229. {
  230. //GetGameStats(new DateTime(2014,12,1));
  231. //var ns = new NubSimulator();
  232. //ns.SpawnMany();
  233. //Console.ReadLine();
  234. //MigrateDatabase();
  235. //FixDuplicatedAccounts();
  236. //BcryptPasswords();
  237. //var db = new ZkDataContext(true);
  238. //var test = db.Accounts.OrderByDescending(x => x.EffectiveElo).WithTranslations().Take(5).ToList();
  239. //MigrateDatabase();
  240. //var test = GlobalConst.GetContentService().DownloadFile("Zero-K v1.1.0");
  241. //var db = new ZkDataContext();
  242. //var post = db.ForumPosts.First(x => x.ForumPostID == 113893);
  243. //var db = new ZkDataContext(false);
  244. //db.Database.CreateIfNotExists();
  245. //PlanetwarsFixer.StartGalaxy(24,3919,3925);
  246. //AddClanLeader();
  247. //return;
  248. //TestPwMatch();
  249. FixStuff();
  250. //var guid = Guid.NewGuid().ToString();
  251. //var pp = new PayPalInterface();
  252. //pp.ImportPaypalHistory(Directory.GetCurrentDirectory());
  253. //Test1v1Elo();
  254. //GenerateTechs();
  255. //FixDemoEngineVersion();
  256. //ImportSpringiePlayers();
  257. //RecalculateBattleElo();
  258. //FixMaps();
  259. //PickHomworldOwners();
  260. //PlanetwarsFixer.PurgeGalaxy(24, false, true);
  261. //PlanetwarsFixer.RandomizeMaps(24);
  262. //SetPlanetTeamSizes();
  263. //RandomizePlanetOwners(24);
  264. //GenerateStructures(24);
  265. //PlanetwarsFixer.GenerateArtefacts(24, new int[] { 3940, 3949, 3954, 3929, 3956 });
  266. //SwapPlanetOwners(3948, 3955);
  267. //SwapPlanetOwners(3973, 3932);
  268. //PlanetwarsFixer.AddWormholes();
  269. //PlanetwarsFixer.RemoveTechStructures(true, true);
  270. //StartGalaxy(24);
  271. //TestPrediction();
  272. //FixMissionScripts();
  273. //AnalyzeModuleUsagePatterns();
  274. //AnalyzeCommUsagePatterns();
  275. //UpdateMissionProgression(12);
  276. //PrintNightwatchSubscriptions("zkadmin");
  277. //RecountForumVotes();
  278. //GetForumKarmaLadder();
  279. //GetForumKarmaVotes();
  280. //GetForumVotesByVoter(161294, 5340);
  281. //DeleteUserVotes(189201, null); //neon
  282. //GetClanStackWinRate(465, 2000); //Mean
  283. //GetForumVotesByUserVoterAgnostic(161294);
  284. //GetAverageElo();
  285. }
  286. static void CountPlayers()
  287. {
  288. var db = new ZkDataContext();
  289. var accs =
  290. db.SpringBattles.OrderByDescending(x => x.SpringBattleID)
  291. .Take(5000)
  292. .SelectMany(x => x.SpringBattlePlayers)
  293. .Where(x => !x.IsSpectator)
  294. .Select(x => new { x.Account, x.SpringBattle.Duration })
  295. .GroupBy(x => x.Account)
  296. .Select(x => new { Account = x.Key, Duration = x.Sum(y => y.Duration) })
  297. .ToList();
  298. var durOther = accs.Where(x => x.Account.LobbyVersion != null && !x.Account.LobbyVersion.StartsWith("ZK")).Sum(x => (long)x.Duration);
  299. var durZk = accs.Where(x => x.Account.LobbyVersion != null && x.Account.LobbyVersion.StartsWith("ZK")).Sum(x => (long)x.Duration);
  300. var cntOther = accs.Where(x => x.Account.LobbyVersion != null && !x.Account.LobbyVersion.StartsWith("ZK")).Count();
  301. var cntZk = accs.Where(x => x.Account.LobbyVersion != null && x.Account.LobbyVersion.StartsWith("ZK")).Count();
  302. }
  303. static void MigrateDatabase()
  304. {
  305. var cloner = new DbCloner("zero-k_ef", "zero-k_test",
  306. "Data Source=omega.licho.eu,100;Initial Catalog=zero-k_test;Persist Security Info=True;User ID=zero-k;Password=zkdevpass1;MultipleActiveResultSets=true");
  307. cloner.CloneAllTables();
  308. }
  309. static void SetPlanetTeamSizes()
  310. {
  311. var db = new ZkDataContext();
  312. var gal = db.Galaxies.First(x => x.IsDefault);
  313. var planets = gal.Planets.ToList().OrderBy(x => x.Resource.MapDiagonal).ToList();
  314. var cnt = planets.Count;
  315. int num = 0;
  316. foreach (var p in planets)
  317. {
  318. //if (num < cnt*0.15) p.TeamSize = 1;else
  319. if (num < cnt * 0.80) p.TeamSize = 2;
  320. //else if (num < cnt*0.85) p.TeamSize = 3;
  321. else p.TeamSize = 3;
  322. num++;
  323. }
  324. db.SubmitAndMergeChanges();
  325. }
  326. public static void RecalculateKudos()
  327. {
  328. var db = new ZkDataContext();
  329. foreach (var acc in db.Accounts.Where(x => x.KudosPurchases.Any() || x.ContributionsByAccountID.Any())) acc.Kudos = acc.KudosGained - acc.KudosSpent;
  330. db.SubmitAndMergeChanges();
  331. }
  332. public static void CountUserIDs()
  333. {
  334. var db = new ZkDataContext();
  335. var userIDs = db.AccountUserIDs.ToList();
  336. var uniqueIDs = userIDs.Select(x => x.UserID).Distinct().ToList();
  337. Dictionary<long, int> userIDCounts = new Dictionary<long, int>();
  338. System.Console.WriteLine("{0} userIDs, {1} uniques", userIDs.Count, uniqueIDs.Count);
  339. foreach (long userID in uniqueIDs)
  340. {
  341. int count = userIDs.Count(x => x.UserID == userID);
  342. userIDCounts[userID] = count;
  343. }
  344. var sortedIDs = uniqueIDs.OrderByDescending(x => userIDCounts[x]).Take(20).ToList();
  345. foreach (int userID in sortedIDs)
  346. {
  347. System.Console.WriteLine("{0}: {1}", userID, userIDCounts[userID]);
  348. }
  349. }
  350. public static void SetFFATeams()
  351. {
  352. var db = new ZkDataContext();
  353. foreach (var m in db.Resources.Where(x => x.FeaturedOrder != null && x.TypeID == ResourceType.Map))
  354. {
  355. var lg = m.SpringBattlesByMapResourceID.Take(100).ToList();
  356. double cnt = lg.Count;
  357. if (cnt == 0) continue;
  358. ;
  359. if (lg.Count(x => x.HasBots) / (double)cnt > 0.5)
  360. {
  361. m.MapIsChickens = true;
  362. }
  363. if (lg.Count(x => x.PlayerCount == 2) / cnt > 0.4)
  364. {
  365. m.MapIs1v1 = true;
  366. }
  367. var teams =
  368. m.SpringBattlesByMapResourceID.Take(100).GroupBy(
  369. x => x.SpringBattlePlayers.Where(y => !y.IsSpectator).Select(y => y.AllyNumber).Distinct().Count()).OrderByDescending(
  370. x => x.Count()).Select(x => x.Key).FirstOrDefault();
  371. if (teams > 2)
  372. {
  373. m.MapIsFfa = true;
  374. m.MapFFAMaxTeams = teams;
  375. }
  376. else { }
  377. }
  378. db.SubmitChanges();
  379. }
  380. public static void FixMissionScripts()
  381. {
  382. var db = new ZkDataContext();
  383. var missions = db.Missions.ToList();
  384. foreach (Mission mission in missions)
  385. {
  386. mission.Script = Regex.Replace(mission.Script, "GameType=([^;]+);", (m) => { return string.Format("GameType={0};", mission.NameWithVersion); });
  387. }
  388. db.SubmitChanges();
  389. }
  390. static void GetModuleUsage(int moduleID, List<Commander> comms, ZkDataContext db)
  391. {
  392. var modules = db.CommanderModules.Where(x => comms.Contains(x.Commander) && x.ModuleUnlockID == moduleID).ToList();
  393. int numModules = 0;
  394. Unlock wantedModule = db.Unlocks.FirstOrDefault(x => x.UnlockID == moduleID);
  395. int moduleCost = (int)wantedModule.MetalCost;
  396. numModules = modules.Count;
  397. System.Console.WriteLine("MODULE: " + wantedModule.Name);
  398. System.Console.WriteLine("Instances: " + numModules);
  399. System.Console.WriteLine("Total cost: " + numModules * moduleCost);
  400. System.Console.WriteLine();
  401. }
  402. public static void AnalyzeModuleUsagePatterns()
  403. {
  404. var db = new ZkDataContext();
  405. var modules = db.Unlocks.Where(x => x.UnlockType == UnlockTypes.Weapon).ToList();
  406. var players = db.Accounts.Where(x => x.Elo >= 1700 && DateTime.Compare(x.LastLogin.AddMonths(3), DateTime.UtcNow) > 0).ToList();
  407. System.Console.WriteLine("Number of accounts to process: " + players.Count);
  408. var comms = db.Commanders.Where(x => players.Contains(x.AccountByAccountID)).ToList();
  409. System.Console.WriteLine("Number of comms to process: " + comms.Count);
  410. System.Console.WriteLine();
  411. foreach (Unlock module in modules)
  412. {
  413. GetModuleUsage(module.UnlockID, comms, db);
  414. }
  415. }
  416. public static void AnalyzeCommUsagePatterns()
  417. {
  418. var db = new ZkDataContext();
  419. var chasses = db.Unlocks.Where(x => x.UnlockType == UnlockTypes.Chassis).ToList();
  420. var players = db.Accounts.Where(x => x.Elo >= 1700 && DateTime.Compare(x.LastLogin.AddMonths(3), DateTime.UtcNow) > 0).ToList();
  421. System.Console.WriteLine("Number of accounts to process: " + players.Count);
  422. System.Console.WriteLine();
  423. foreach (Unlock chassis in chasses)
  424. {
  425. var comms = db.Commanders.Where(x => players.Contains(x.AccountByAccountID) && x.ChassisUnlockID == chassis.UnlockID).ToList();
  426. int chassisCount = comms.Count;
  427. System.Console.WriteLine("CHASSIS " + chassis.Name + " : " + chassisCount);
  428. }
  429. }
  430. public static void ProgressCampaign(ZkDataContext db, Account acc, Mission mission, bool completeNext = false, string missionVars = "")
  431. {
  432. CampaignPlanet planet = db.CampaignPlanets.FirstOrDefault(p => p.MissionID == mission.MissionID);
  433. if (planet != null)
  434. {
  435. AccountCampaignProgress progress = acc.AccountCampaignProgress.FirstOrDefault(x => x.PlanetID == planet.PlanetID && x.CampaignID == planet.CampaignID);
  436. bool alreadyCompleted = false;
  437. int accountID = acc.AccountID;
  438. int campID = planet.CampaignID;
  439. Campaign camp = planet.Campaign;
  440. List<CampaignPlanet> unlockedPlanets = new List<CampaignPlanet>();
  441. List<CampaignJournal> unlockedJournals = new List<CampaignJournal>();
  442. // start with processing the mission vars, if there are any
  443. byte[] missionVarsAsByteArray = System.Convert.FromBase64String(missionVars);
  444. string missionVarsDecoded = System.Text.Encoding.UTF8.GetString(missionVarsAsByteArray);
  445. foreach (string kvpRaw in missionVarsDecoded.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
  446. {
  447. string kvpRaw2 = kvpRaw.Trim();
  448. string key = "", value = "";
  449. string[] kvpSplit = kvpRaw2.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
  450. if (kvpSplit.Length == 2)
  451. {
  452. key = kvpSplit[0].Trim();
  453. value = kvpSplit[1].Trim();
  454. }
  455. else
  456. {
  457. throw new Exception("Invalid key-value pair in decoded mission vars: " + missionVarsDecoded);
  458. }
  459. if (!(string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)))
  460. {
  461. CampaignVar cv = camp.CampaignVars.First(x => x.KeyString == key);
  462. AccountCampaignVar acv = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == cv.VarID);
  463. if (acv == null)
  464. {
  465. db.AccountCampaignVars.InsertOnSubmit(new AccountCampaignVar() { AccountID = accountID, CampaignID = campID, VarID = cv.VarID, Value = value });
  466. }
  467. else acv.Value = value;
  468. }
  469. }
  470. //reload DB - this allows the vars submitted this session to be used by the following code
  471. db.SubmitChanges();
  472. db = new ZkDataContext();
  473. acc = db.Accounts.First(x => x.AccountID == accountID);
  474. // now we unlock planets and journal entries
  475. // first mark this planet as completed - but only if it's already unlocked
  476. if (progress != null)
  477. {
  478. alreadyCompleted = progress.IsCompleted;
  479. }
  480. else if (planet.StartsUnlocked)
  481. {
  482. progress = new AccountCampaignProgress() { AccountID = accountID, CampaignID = campID, PlanetID = planet.PlanetID, IsCompleted = false, IsUnlocked = true };
  483. db.AccountCampaignProgress.InsertOnSubmit(progress);
  484. }
  485. if (progress != null && planet.IsUnlocked(accountID))
  486. {
  487. progress.IsCompleted = true;
  488. // unlock planets made available by completing this one
  489. var links = camp.CampaignLinks.Where(x => x.UnlockingPlanetID == planet.PlanetID);
  490. foreach (CampaignLink link in links)
  491. {
  492. CampaignPlanet toUnlock = link.PlanetToUnlock;
  493. bool proceed = true;
  494. var requiredVars = toUnlock.CampaignPlanetVars;
  495. if (requiredVars.Count() == 0) proceed = true;
  496. else
  497. {
  498. foreach (CampaignPlanetVar variable in requiredVars)
  499. {
  500. AccountCampaignVar accountVar = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == variable.RequiredVarID);
  501. if (!(accountVar != null && accountVar.Value == variable.RequiredValue))
  502. {
  503. proceed = false;
  504. break; // failed to meet var requirement, stop here
  505. }
  506. }
  507. }
  508. if (proceed) // met requirements for unlocking planet
  509. {
  510. AccountCampaignProgress progress2 = toUnlock.AccountCampaignProgress.FirstOrDefault(x => x.CampaignID == campID && x.AccountID == accountID);
  511. if (progress2 == null)
  512. {
  513. progress2 = new AccountCampaignProgress() { AccountID = accountID, CampaignID = campID, PlanetID = toUnlock.PlanetID, IsCompleted = completeNext, IsUnlocked = true };
  514. db.AccountCampaignProgress.InsertOnSubmit(progress2);
  515. unlockedPlanets.Add(toUnlock);
  516. }
  517. else if (!progress2.IsUnlocked)
  518. {
  519. progress2.IsUnlocked = true;
  520. unlockedPlanets.Add(toUnlock);
  521. }
  522. }
  523. }
  524. }
  525. // unlock journals
  526. var journalsWithVars = db.CampaignJournals.Where(x => x.CampaignID == campID && x.CampaignJournalVars.Any());
  527. foreach (CampaignJournal journal in journalsWithVars)
  528. {
  529. bool proceed = true;
  530. var requiredVars = journal.CampaignJournalVars.Where(x => x.CampaignID == campID).ToList();
  531. foreach (CampaignJournalVar variable in requiredVars)
  532. {
  533. AccountCampaignVar accountVar = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == variable.RequiredVarID);
  534. if (!(accountVar != null && accountVar.Value == variable.RequiredValue))
  535. {
  536. proceed = false;
  537. break; // failed to meet var requirement, stop here
  538. }
  539. }
  540. if (proceed) // met requirements for unlocking journal
  541. {
  542. AccountCampaignJournalProgress jp = journal.AccountCampaignJournalProgress.FirstOrDefault(x => x.AccountID == accountID);
  543. if (jp == null)
  544. {
  545. jp = new AccountCampaignJournalProgress() { AccountID = accountID, CampaignID = campID, JournalID = journal.JournalID, IsUnlocked = true };
  546. db.AccountCampaignJournalProgress.InsertOnSubmit(jp);
  547. unlockedJournals.Add(journal);
  548. }
  549. else if (!jp.IsUnlocked)
  550. {
  551. jp.IsUnlocked = true;
  552. unlockedJournals.Add(journal);
  553. }
  554. }
  555. }
  556. if (!alreadyCompleted)
  557. {
  558. System.Console.WriteLine("Planet completed: {0}", planet);
  559. foreach (CampaignJournal journal in db.CampaignJournals.Where(x => x.CampaignID == campID && x.CampaignPlanet.PlanetID == planet.PlanetID && x.UnlockOnPlanetCompletion))
  560. {
  561. unlockedJournals.Add(journal);
  562. }
  563. }
  564. foreach (CampaignPlanet unlocked in unlockedPlanets)
  565. {
  566. System.Console.WriteLine("Planet unlocked: {0}", unlocked);
  567. foreach (CampaignJournal journal in db.CampaignJournals.Where(x => x.CampaignID == campID && x.CampaignPlanet.PlanetID == unlocked.PlanetID && x.UnlockOnPlanetUnlock))
  568. {
  569. unlockedJournals.Add(journal);
  570. }
  571. }
  572. foreach (CampaignJournal uj in unlockedJournals)
  573. {
  574. System.Console.WriteLine("{1} - Journal entry unlocked: {0}", uj, uj.CampaignPlanet);
  575. }
  576. db.SubmitChanges();
  577. }
  578. }
  579. public static void UpdateMissionProgression(int planetID, bool completeNext = false, string missionVars = "")
  580. {
  581. ZkDataContext db = new ZkDataContext();
  582. var accp = db.AccountCampaignProgress.Where(x => x.PlanetID == planetID && x.IsCompleted).ToList();
  583. foreach (var prog in accp)
  584. {
  585. Account acc = prog.Account;
  586. System.Console.WriteLine(acc);
  587. ProgressCampaign(db, acc, prog.CampaignPlanet.Mission, completeNext, missionVars);
  588. }
  589. }
  590. public static void PrintNightwatchSubscriptions(string channel)
  591. {
  592. ZkDataContext db = new ZkDataContext();
  593. var subscriptions = db.LobbyChannelSubscriptions.Where(x => x.Channel == channel);
  594. foreach (var entry in subscriptions)
  595. {
  596. Account acc = entry.Account;
  597. System.Console.WriteLine(acc);
  598. }
  599. }
  600. public static void GetClanStackWinRate(int clanID, int minElo)
  601. {
  602. int won = 0, lost = 0;
  603. ZkDataContext db = new ZkDataContext();
  604. Clan clan = db.Clans.FirstOrDefault(x => x.ClanID == clanID);
  605. var battles = db.SpringBattles.Where(x => x.SpringBattlePlayers.Count(p => p.Account.ClanID == clanID && p.Account.Elo >= minElo && !p.IsSpectator) >= 2
  606. && x.StartTime.CompareTo(DateTime.Now.AddMonths(-1)) > 0 && x.ResourceByMapResourceID.MapIsSpecial != true && !x.IsFfa).ToList();
  607. System.Console.WriteLine(clan.ClanName + ", " + battles.Count);
  608. foreach (SpringBattle battle in battles)
  609. {
  610. int onWinners = 0, onLosers = 0;
  611. var players = battle.SpringBattlePlayers.Where(p => p.Account.ClanID == clanID && p.Account.Elo >= minElo && !p.IsSpectator).ToList();
  612. foreach (SpringBattlePlayer player in players)
  613. {
  614. if (player.IsInVictoryTeam) onWinners++;
  615. else onLosers++;
  616. }
  617. if (onWinners > onLosers)
  618. {
  619. won++;
  620. System.Console.WriteLine("won " + battle.SpringBattleID);
  621. }
  622. else if (onLosers > onWinners)
  623. {
  624. lost++;
  625. System.Console.WriteLine("lost " + battle.SpringBattleID);
  626. }
  627. //else System.Console.WriteLine("OMG, B" + battle.SpringBattleID);
  628. }
  629. System.Console.WriteLine(won + ", " + lost);
  630. }
  631. public static void GetAverageElo()
  632. {
  633. int count = 0;
  634. double eloSum = 0;
  635. ZkDataContext db = new ZkDataContext();
  636. foreach (Account acc in db.Accounts.Where(x => x.SpringBattlePlayers.Any(g => g.SpringBattle.StartTime > DateTime.UtcNow.AddMonths(-1)) && x.EloWeight == GlobalConst.EloWeightMax))
  637. {
  638. System.Console.WriteLine(String.Format("{0}: {1}", acc.Name, acc.EffectiveElo));
  639. eloSum += acc.EffectiveElo;
  640. count++;
  641. }
  642. double average = eloSum / count;
  643. System.Console.WriteLine(String.Format("Average: {0}, Total players: {1}", average, count));
  644. }
  645. static void FixDemoEngineVersion()
  646. {
  647. var db = new ZkDataContext();
  648. foreach (var b in db.SpringBattles.Where(x => x.Title.Contains("[engine")))
  649. {
  650. var match = Regex.Match(b.Title, @"\[engine([^\]]+)\]");
  651. if (match.Success)
  652. {
  653. var eng = match.Groups[1].Value;
  654. if (eng != b.EngineVersion) b.EngineVersion = eng;
  655. }
  656. }
  657. db.SubmitChanges();
  658. }
  659. public class EloEntry
  660. {
  661. public double Elo = 1500;
  662. public int Cnt = 0;
  663. }
  664. public static void Test1v1Elo()
  665. {
  666. var db = new ZkDataContext();
  667. Dictionary<Account, EloEntry> PlayerElo = new Dictionary<Account, EloEntry>();
  668. int cnt = 0;
  669. foreach (var sb in db.SpringBattles.Where(x => !x.IsMission && !x.HasBots && !x.IsFfa && x.PlayerCount == 2).OrderBy(x => x.SpringBattleID))
  670. {
  671. cnt++;
  672. double winnerElo = 0;
  673. double loserElo = 0;
  674. var losers = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList();
  675. var winners = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList();
  676. if (losers.Count != 1 || winners.Count != 1)
  677. {
  678. continue;
  679. }
  680. foreach (var r in winners)
  681. {
  682. EloEntry el;
  683. if (!PlayerElo.TryGetValue(r.Account, out el)) el = new EloEntry();
  684. winnerElo += el.Elo;
  685. }
  686. foreach (var r in losers)
  687. {
  688. EloEntry el;
  689. if (!PlayerElo.TryGetValue(r.Account, out el)) el = new EloEntry();
  690. loserElo += el.Elo;
  691. }
  692. winnerElo = winnerElo / winners.Count;
  693. loserElo = loserElo / losers.Count;
  694. var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400));
  695. var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400));
  696. var sumCount = losers.Count + winners.Count;
  697. var scoreWin = Math.Sqrt(sumCount / 2.0) * 32 * (1 - eWin);
  698. var scoreLose = Math.Sqrt(sumCount / 2.0) * 32 * (0 - eLose);
  699. foreach (var r in winners)
  700. {
  701. var change = (float)(scoreWin);
  702. EloEntry elo;
  703. if (!PlayerElo.TryGetValue(r.Account, out elo))
  704. {
  705. elo = new EloEntry();
  706. PlayerElo[r.Account] = elo;
  707. }
  708. elo.Elo += change;
  709. elo.Cnt++;
  710. }
  711. foreach (var r in losers)
  712. {
  713. var change = (float)(scoreLose);
  714. EloEntry elo;
  715. if (!PlayerElo.TryGetValue(r.Account, out elo))
  716. {
  717. elo = new EloEntry();
  718. PlayerElo[r.Account] = elo;
  719. }
  720. elo.Elo += change;
  721. elo.Cnt++;
  722. }
  723. }
  724. Console.WriteLine("Total battles: {0}", cnt);
  725. Console.WriteLine("Name;1v1Elo;TeamElo;1v1Played;TeamPlayed");
  726. foreach (var entry in PlayerElo.Where(x => x.Value.Cnt > 40).OrderByDescending(x => x.Value.Elo))
  727. {
  728. Console.WriteLine("{0};{1:f0};{2:f0};{3};{4}", entry.Key.Name, entry.Value.Elo, entry.Key.EffectiveElo, entry.Value.Cnt, entry.Key.SpringBattlePlayers.Count(x => !x.IsSpectator && x.SpringBattle.PlayerCount > 2));
  729. }
  730. }
  731. public static void TestPrediction()
  732. {
  733. var db = new ZkDataContext();
  734. var cnt = 0;
  735. var winPro = 0;
  736. var winLessNub = 0;
  737. var winMoreVaried = 0;
  738. var winPredicted = 0;
  739. foreach (var sb in db.SpringBattles.Where(x => !x.IsMission && !x.HasBots && !x.IsFfa && x.IsEloProcessed && x.PlayerCount >= 8 && !x.Events.Any()).OrderByDescending(x => x.SpringBattleID))
  740. {
  741. var losers = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList();
  742. var winners = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList();
  743. if (losers.Count == 0 || winners.Count == 0 || losers.Count == winners.Count) continue;
  744. if (winners.Select(x => x.Account.EffectiveElo).Max() > losers.Select(x => x.Account.EffectiveElo).Max()) winPro++;
  745. if (winners.Select(x => x.Account.EffectiveElo).Min() > losers.Select(x => x.Account.EffectiveElo).Min()) winLessNub++;
  746. if (winners.Select(x => x.Account.EffectiveElo).StdDev() > losers.Select(x => x.Account.EffectiveElo).StdDev()) winMoreVaried++;
  747. var winnerElo = winners.Select(x => x.Account.EffectiveElo).Average();
  748. var loserElo = losers.Select(x => x.Account.EffectiveElo).Average();
  749. var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400));
  750. var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400));
  751. if (eWin > eLose) winPredicted++;
  752. cnt++;
  753. if (cnt == 200) break;
  754. }
  755. Console.WriteLine("prwin: {0}, lessnubwin: {1}, morevaried: {2}, count: {3}, predicted:{4}", winPro, winLessNub, winMoreVaried, cnt, winPredicted);
  756. }
  757. static void RecalculateBattleElo()
  758. {
  759. using (var db = new ZkDataContext())
  760. {
  761. foreach (var b in db.SpringBattles.Where(x => !x.IsEloProcessed).ToList())
  762. {
  763. Console.WriteLine(b.SpringBattleID);
  764. b.CalculateAllElo();
  765. }
  766. db.SubmitChanges();
  767. }
  768. }
  769. static void ImportSpringiePlayers()
  770. {
  771. var db = new ZkDataContext();
  772. foreach (var line in File.ReadLines("springie.csv").AsParallel())
  773. {
  774. var m = Regex.Match(line, "\"[0-9]+\";\"([^\"]+)\";\"[0-9]+\";\"[0-9]+\";\"([^\"]+)\";\"([^\"]+)\"");
  775. if (m.Success)
  776. {
  777. string name = m.Groups[1].Value;
  778. double elo = double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture);
  779. double w = double.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
  780. if (elo != 1500 || w != 1)
  781. {
  782. foreach (var a in db.Accounts.Where(x => x.Name == name))
  783. {
  784. a.Elo = (float)elo;
  785. a.EloWeight = (float)w;
  786. }
  787. Console.WriteLine(name);
  788. }
  789. }
  790. }
  791. db.SubmitChanges();
  792. }
  793. static void FixMaps()
  794. {
  795. try
  796. {
  797. var db = new ZkDataContext();
  798. foreach (var r in db.Resources.Where(x => x.LastChange == null)) r.LastChange = DateTime.UtcNow;
  799. db.SubmitChanges();
  800. return;
  801. foreach (var resource in db.Resources.Where(x => x.TypeID == ResourceType.Map))//&&x.MapSizeSquared == null))
  802. {
  803. var file = String.Format("{0}/{1}.metadata.xml.gz", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath());
  804. var map = (Map)new XmlSerializer(typeof(Map)).Deserialize(new MemoryStream(File.ReadAllBytes(file).Decompress()));
  805. resource.MapWidth = map.Size.Width / 512;
  806. resource.MapHeight = map.Size.Height / 512;
  807. if (string.IsNullOrEmpty(resource.AuthorName))
  808. {
  809. if (!string.IsNullOrEmpty(map.Author)) resource.AuthorName = map.Author;
  810. else
  811. {
  812. Console.WriteLine("regex test");
  813. var m = Regex.Match(map.Description, "by ([\\w]+)", RegexOptions.IgnoreCase);
  814. if (m.Success) resource.AuthorName = m.Groups[1].Value;
  815. }
  816. }
  817. Console.WriteLine("author: " + resource.AuthorName);
  818. if (resource.MapIsSpecial == null) resource.MapIsSpecial = map.ExtractorRadius > 120 || map.MaxWind > 40;
  819. resource.MapSizeSquared = (map.Size.Width / 512) * (map.Size.Height / 512);
  820. resource.MapSizeRatio = (float)map.Size.Width / map.Size.Height;
  821. var minimap = String.Format("{0}/{1}.minimap.jpg", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath());
  822. using (var im = Image.FromFile(minimap))
  823. {
  824. int w, h;
  825. if (resource.MapSizeRatio > 1)
  826. {
  827. w = 96;
  828. h = (int)(w / resource.MapSizeRatio);
  829. }
  830. else
  831. {
  832. h = 96;
  833. w = (int)(h * resource.MapSizeRatio);
  834. }
  835. using (var correctMinimap = new Bitmap(w, h, PixelFormat.Format24bppRgb))
  836. {
  837. using (var graphics = Graphics.FromImage(correctMinimap))
  838. {
  839. graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
  840. graphics.DrawImage(im, 0, 0, w, h);
  841. }
  842. var jgpEncoder = ImageCodecInfo.GetImageEncoders().First(x => x.FormatID == ImageFormat.Jpeg.Guid);
  843. var encoderParams = new EncoderParameters(1);
  844. encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
  845. var target = String.Format("{0}/{1}.thumbnail.jpg", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath());
  846. correctMinimap.Save(target, jgpEncoder, encoderParams);
  847. }
  848. }
  849. Console.WriteLine(string.Format("{0}", resource.InternalName));
  850. }
  851. db.SubmitChanges();
  852. }
  853. catch (Exception ex)
  854. {
  855. Console.WriteLine(ex);
  856. }
  857. }
  858. public static void MassBan(string name, int startIndex, int endIndex, string reason, int banHours, bool banSite = false, bool banLobby = true, bool banIP = false, bool banID = false)
  859. {
  860. ZkDataContext db = new ZkDataContext();
  861. for (int i = startIndex; i <= endIndex; i++)
  862. {
  863. Account acc = db.Accounts.FirstOrDefault(x => x.Name == name + i);
  864. if (acc != null)
  865. {
  866. int? userID = banID ? (int?)acc.AccountUserIDs.OrderByDescending(x => x.LastLogin).FirstOrDefault().UserID : null;
  867. string userIP = banIP ? acc.AccountIPs.OrderByDescending(x => x.LastLogin).FirstOrDefault().IP : null;
  868. System.Console.WriteLine(acc.Name, userID, userIP);
  869. Punishment punishment = new Punishment
  870. {
  871. Time = DateTime.UtcNow,
  872. Reason = reason,
  873. BanSite = banSite,
  874. BanLobby = banLobby,
  875. BanExpires = DateTime.UtcNow.AddHours(banHours),
  876. BanIP = userIP,
  877. CreatedAccountID = 5806,
  878. UserID = userID,
  879. };
  880. acc.PunishmentsByAccountID.Add(punishment);
  881. }
  882. }
  883. db.SubmitChanges();
  884. }
  885. public static void TestPwMatch()
  886. {
  887. Global.Nightwatch = new Nightwatch();
  888. Global.Nightwatch.Start();
  889. Global.PlanetWarsMatchMaker = new PlanetWarsMatchMaker(Global.Nightwatch.Tas);
  890. var db = new ZkDataContext();
  891. var gal = db.Galaxies.First(x => x.IsDefault);
  892. Global.PlanetWarsMatchMaker.AddAttackOption(gal.Planets.Skip(1).First());
  893. /*
  894. Utils.StartAsync(() =>
  895. {
  896. Thread.Sleep(30000);
  897. challenge = new AttackOption();
  898. challenge.Attackers.Add(tas.ExistingUsers["Licho"]);
  899. challenge.Defenders.Add(tas.ExistingUsers["gajop"]);
  900. AcceptChallenge();
  901. });*/
  902. Console.ReadLine();
  903. }
  904. }
  905. }