Advertisement
zjqyf

MonstersCountPlugin

Mar 8th, 2017 (edited)
10,080
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.47 KB | None | 0 0
  1. using SharpDX.DirectInput;
  2. using System.Linq;
  3. using System;
  4. using System.Collections.Generic;
  5. using Turbo.Plugins.Default;
  6.  
  7. namespace Turbo.Plugins.glq
  8. {
  9. using System.Text;
  10. public class MonstersCountPlugin : BasePlugin, IInGameTopPainter, IInGameWorldPainter, IKeyEventHandler
  11. {
  12. public IFont DefaultTextFont { get; set; }
  13. public IFont OrangeTextFont { get; set; }
  14. public IFont RedTextFont { get; set; }
  15. public WorldDecoratorCollection StatisticalRangeDecorator { get; set; }
  16. public WorldDecoratorCollection MaxStatisticalRangeDecorator { get; set; }
  17. private float currentYard;
  18. public float yard
  19. {
  20. get { return baseMapShapeDecorator.Radius; }
  21. set
  22. {
  23. baseMapShapeDecorator.Radius = value;
  24. currentYard = yard;
  25. }
  26. }
  27. public float MaxYard
  28. {
  29. get { return maxMapShapeDecorator.Radius; }
  30. set { maxMapShapeDecorator.Radius = value; }
  31. }
  32. public bool ShowCircle { get; set; }
  33. public IKeyEvent ToggleKeyEvent { get; set; }
  34. public bool ShowMonstersCount { get; set; }
  35.  
  36. public bool ShowTotalProgression { get; set; }
  37. public bool ShowTrashProgression { get; set; }
  38. public bool ShowEliteProgression { get; set; }
  39. public bool ShowRareMinionProgression { get; set; }
  40. public bool ShowRiftGlobeProgression { get; set; }
  41.  
  42. public bool ShowLlocustCount { get; set; }
  43. public bool ShowHauntedCount { get; set; }
  44. public bool ShowPalmedCount { get; set; }
  45. public bool ShowPhoenixedCount { get; set; }
  46. public bool ShowStrongarmedCount { get; set; }
  47. public bool ShowCursedCount { get; set; }
  48. public bool ShowPiranhasCount { get; set; }
  49. public bool ShowKrysbinCount { get; set; }
  50. public bool ShowPainEnhancerCount { get; set; }
  51. public bool ShowEntanglingShotCount { get; set; }
  52. public bool ShowTime { get; set; }
  53. public bool ToggleEnable { get; set; }
  54. public float XWidth { get; set; }
  55. public float YHeight { get; set; }
  56.  
  57. private IFont currentFont;
  58. private bool TurnedOn;
  59.  
  60. private MapShapeDecorator baseMapShapeDecorator;
  61. private MapShapeDecorator maxMapShapeDecorator;
  62.  
  63. private StringBuilder textBuilder;
  64. private string str_YardmonstersCount;
  65. private string str_Elite;
  66. private string str_Minion;
  67. private string str_TotalRP;
  68. private string str_TrashRP;
  69. private string str_EliteRP;
  70. private string str_MinionRP;
  71. private string str_GlobeRP;
  72. private string str_ToElite;
  73. private string str_Locust;
  74. private string str_haunted;
  75. private string str_Palmed;
  76. private string str_Phoenixed;
  77. private string str_Strongarmed;
  78. private string str_Cursed;
  79. private string str_Piranhas;
  80. private string str_Krysbin;
  81. private string str_bleedCount;
  82. private string str_Attackspeedbonus;
  83. private string str_EntanglingShot;
  84. public MonstersCountPlugin()
  85. {
  86. Enabled = true;
  87. ShowCircle = true;
  88. ToggleEnable = false;
  89. }
  90.  
  91. public override void Load(IController hud)
  92. {
  93. base.Load(hud);
  94. str_YardmonstersCount = "Monster Count In {0} Yards: {1}";
  95. str_Elite = "Elite: {0}(Pack: {1})";
  96. str_Minion = "Minion: {0}";
  97. str_TotalRP = "TotalRP:";
  98. str_TrashRP = "TrashRP:";
  99. str_EliteRP = "EliteRP:";
  100. str_MinionRP = "MinionRP:";
  101. str_GlobeRP = "GlobeRP:";
  102. str_ToElite = " (Elite: {0}/{1})";
  103. str_Locust = "Locust:";
  104. str_haunted = "Haunted:";
  105. str_Palmed = "Palmed:";
  106. str_Phoenixed = "Phoenixed:";
  107. str_Strongarmed = "Strongarmed";
  108. str_Cursed = "Cursed:";
  109. str_Piranhas = "Piranhas:";
  110. str_Krysbin = "Krysbin:";
  111. str_bleedCount = "Pain Enhancer: {0} Monsters Bleeding In 20 Yards";
  112. str_Attackspeedbonus = "Attack Speed Bonus: {0}%";
  113. str_EntanglingShot = "Entangling:";
  114. ToggleKeyEvent = Hud.Input.CreateKeyEvent(true, Key.LeftControl, true, false, false);
  115. DefaultTextFont = Hud.Render.CreateFont("tahoma", 9, 255, 180, 147, 109, false, false, 250, 0, 0, 0, true);
  116. OrangeTextFont = Hud.Render.CreateFont("tahoma", 9, 255, 255, 128, 0, false, false, 250, 0, 0, 0, true);
  117. RedTextFont = Hud.Render.CreateFont("tahoma", 9, 255, 255, 0, 0, false, false, 250, 0, 0, 0, true);
  118.  
  119. TurnedOn = false;
  120. ShowMonstersCount = true;
  121. ShowTotalProgression = true;
  122. ShowTrashProgression = true;
  123. ShowEliteProgression = true;
  124. ShowRareMinionProgression = true;
  125. ShowRiftGlobeProgression = true;
  126. ShowTime = true;
  127. ShowLlocustCount = true;
  128. ShowHauntedCount = true;
  129. ShowPalmedCount = true;
  130. ShowPhoenixedCount = false;
  131. ShowStrongarmedCount = true;
  132. ShowPiranhasCount = true;
  133. ShowCursedCount = true;
  134. ShowKrysbinCount = true;
  135. ShowPainEnhancerCount = true;
  136. ShowEntanglingShotCount = true;
  137. XWidth = 0.84f;
  138. YHeight = 0.645f;
  139.  
  140. textBuilder = new StringBuilder();
  141.  
  142. baseMapShapeDecorator = new MapShapeDecorator(Hud)
  143. {
  144. Brush = Hud.Render.CreateBrush(150, 180, 147, 109, 1),
  145. ShapePainter = new CircleShapePainter(Hud),
  146. Radius = 40,
  147. };
  148. StatisticalRangeDecorator = new WorldDecoratorCollection(baseMapShapeDecorator);
  149. currentYard = yard;
  150. maxMapShapeDecorator = new MapShapeDecorator(Hud)
  151. {
  152. Brush = Hud.Render.CreateBrush(150, 180, 147, 109, 1),
  153. ShapePainter = new CircleShapePainter(Hud),
  154. Radius = 120,
  155. };
  156. MaxStatisticalRangeDecorator = new WorldDecoratorCollection(maxMapShapeDecorator);
  157. }
  158.  
  159. public void OnKeyEvent(IKeyEvent keyEvent)
  160. {
  161. if (keyEvent.IsPressed && ToggleKeyEvent.Matches(keyEvent) && ToggleEnable)
  162. {
  163. TurnedOn = !TurnedOn;
  164. currentYard = TurnedOn ? MaxYard : yard;
  165. }
  166. }
  167. private bool isKrysbin(IMonster Mob)
  168. {
  169. var Players = Hud.Game.Players.Where(player => player.HeroClassDefinition.HeroClass == HeroClass.Necromancer);
  170. bool EKrysbin = false;
  171. foreach (var player in Players)
  172. {
  173. if (player.Powers.BuffIsActive(475241))
  174. {
  175. EKrysbin = true;
  176. break;
  177. }
  178. }
  179. if (!EKrysbin) return false;
  180. if (Mob.Slow || Mob.Chilled)
  181. {
  182. if (Mob.Frozen || Mob.Stunned || Mob.Blind)
  183. return true;
  184. }
  185.  
  186. return false;
  187. }
  188. public void PaintWorld(WorldLayer layer)
  189. {
  190. if (Hud.Game.IsInTown || !ShowCircle) return;
  191. if (TurnedOn)
  192. {
  193. MaxStatisticalRangeDecorator.Paint(layer, null, Hud.Game.Me.FloorCoordinate, null);
  194. }
  195. else
  196. {
  197. StatisticalRangeDecorator.Paint(layer, null, Hud.Game.Me.FloorCoordinate, null);
  198. }
  199. }
  200.  
  201. public void PaintTopInGame(ClipState clipState)
  202. {
  203. if (clipState != ClipState.BeforeClip) return;
  204. var inRift = Hud.Game.SpecialArea == SpecialArea.Rift || Hud.Game.SpecialArea == SpecialArea.GreaterRift;
  205. var inGR = Hud.Game.SpecialArea == SpecialArea.GreaterRift;
  206. if (DefaultTextFont == null)
  207. {
  208. return;
  209. }
  210.  
  211. double totalMonsterRiftProgression = 0;
  212. double TrashMonsterRiftProgression = 0;
  213. double EliteProgression = 0;
  214. double RareMinionProgression = 0;
  215. double RiftGlobeProgression = 0;
  216.  
  217. int monstersCount = 0;
  218. int EliteCount = 0;
  219. int RareMinionCount = 0;
  220. int ElitePackCount = 0;
  221. // locust
  222. int locustCount = 0;
  223. int ElitelocustCount = 0;
  224. // haunted
  225. int hauntedCount = 0;
  226. int ElitehauntedCount = 0;
  227. //Palmed
  228. int palmedCount = 0;
  229. int ElitepalmedCount = 0;
  230. //Phoenixed
  231. int phoenixedCount = 0;
  232. int ElitephoenixedCount = 0;
  233. //Strongarmed Obsolete
  234. int strongarmedCount = 0;
  235. int ElitestrongarmedCount = 0;
  236. int KrysbinCount = 0;
  237. int EliteKrysbinCount = 0;
  238. //Cursed
  239. int CursedCount = 0;
  240. int EliteCursedCount = 0;
  241. //Piranhas
  242. int PiranhasCount = 0;
  243. int ElitePiranhasCount = 0;
  244. //EntanglingShot
  245. int EntanglingShotCount = 0;
  246. int EliteEntanglingShotCount = 0;
  247. float XPos = Hud.Window.Size.Width * XWidth;
  248. float YPos = Hud.Window.Size.Height * YHeight;
  249. var Allmonsters = Hud.Game.AliveMonsters;
  250. var bleedCount = Allmonsters.Where(m => m.Bleeding && m.NormalizedXyDistanceToMe <= 20).ToList().Count;
  251. var monsters = Allmonsters.Where(m => ((m.SummonerAcdDynamicId == 0 && m.IsElite) || !m.IsElite) && m.FloorCoordinate.XYDistanceTo(Hud.Game.Me.FloorCoordinate) <= currentYard);
  252. Dictionary<IMonster, string> eliteGroup = new Dictionary<IMonster, string>();
  253. foreach (var monster in monsters)
  254. {
  255. var Elite = monster.Rarity == ActorRarity.Rare || monster.Rarity == ActorRarity.Champion || monster.Rarity == ActorRarity.Unique || monster.Rarity == ActorRarity.Boss;
  256. monstersCount++;
  257. if (isKrysbin(monster) && ShowKrysbinCount) KrysbinCount++;
  258. if (!monster.IsElite)
  259. {
  260. if (inRift) TrashMonsterRiftProgression += monster.SnoMonster.RiftProgression * 100.0d / this.Hud.Game.MaxQuestProgress;
  261. }
  262. else
  263. {
  264. if (monster.Rarity == ActorRarity.RareMinion)
  265. {
  266. RareMinionCount++;
  267. if (inRift) RareMinionProgression += monster.SnoMonster.RiftProgression * 100.0d / this.Hud.Game.MaxQuestProgress;
  268. }
  269. else
  270. {
  271. if (isKrysbin(monster) && ShowKrysbinCount) EliteKrysbinCount++;
  272. if (monster.Rarity == ActorRarity.Unique || monster.Rarity == ActorRarity.Boss)
  273. {
  274. EliteCount++;
  275. ElitePackCount++;
  276. }
  277.  
  278. if (monster.Rarity == ActorRarity.Champion)
  279. {
  280. EliteCount++;
  281. eliteGroup.Add(monster, String.Join(", ", monster.AffixSnoList));
  282. if (inRift) EliteProgression += monster.SnoMonster.RiftProgression * 100.0d / this.Hud.Game.MaxQuestProgress;
  283. }
  284.  
  285. if (monster.Rarity == ActorRarity.Rare)
  286. {
  287. EliteCount++;
  288. ElitePackCount++;
  289. if (inRift)
  290. {
  291. EliteProgression += 4 * 1.15d;
  292. EliteProgression += monster.SnoMonster.RiftProgression * 100.0d / this.Hud.Game.MaxQuestProgress;
  293. }
  294. }
  295. }
  296. }
  297. if (monster.Locust && ShowLlocustCount)
  298. {
  299. locustCount++;
  300. if (Elite) ElitelocustCount++;
  301. }
  302. if (monster.Haunted && ShowHauntedCount)
  303. {
  304. hauntedCount++;
  305. if (Elite) ElitehauntedCount++;
  306. }
  307. if (monster.Palmed && ShowPalmedCount)
  308. {
  309. palmedCount++;
  310. if (Elite) ElitepalmedCount++;
  311. }
  312. if (monster.Piranhas && ShowPiranhasCount)
  313. {
  314. PiranhasCount++;
  315. if (Elite) ElitePiranhasCount++;
  316. }
  317. if (monster.Cursed && ShowCursedCount)
  318. {
  319. CursedCount++;
  320. if (Elite) EliteCursedCount++;
  321. }
  322. if (monster.Phoenixed && ShowPhoenixedCount)
  323. {
  324. phoenixedCount++;
  325. if (Elite) ElitephoenixedCount++;
  326. }
  327. if (monster.Strongarmed && ShowStrongarmedCount)
  328. {
  329. strongarmedCount++;
  330. if (Elite) ElitestrongarmedCount++;
  331. }
  332. if (ShowEntanglingShotCount)
  333. {//缠绕
  334. if (monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_None, 361936) == 1 || monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_A, 361936) == 1 || monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_B, 361936) == 1 || monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_C, 361936) == 1 || monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_D, 361936) == 1 || monster.GetAttributeValue(Hud.Sno.Attributes.Power_Buff_0_Visual_Effect_E, 361936) == 1)
  335. {
  336. EntanglingShotCount++;
  337. if (Elite) EliteEntanglingShotCount++;
  338. }
  339. }
  340. }
  341. Dictionary<IMonster, string> eliteGroup1 = eliteGroup.OrderBy(p => p.Value).ToDictionary(p => p.Key, o => o.Value);
  342. if (monstersCount == 0) return;
  343. var actors = Hud.Game.Actors.Where(x => x.SnoActor.Kind == ActorKind.RiftOrb);
  344. foreach (var actor in actors)
  345. {
  346. RiftGlobeProgression += 1.15d;
  347. }
  348. string preStr = null;
  349. foreach (var elite in eliteGroup1)
  350. {
  351. if (elite.Key.Rarity == ActorRarity.Champion)
  352. {
  353. if (preStr != elite.Value)
  354. {
  355.  
  356. EliteProgression += 3 * 1.15f;
  357. ElitePackCount++;
  358. }
  359. preStr = elite.Value;
  360. }
  361. }
  362. textBuilder.Clear();
  363. if (ShowMonstersCount)
  364. {
  365. textBuilder.AppendFormat(str_YardmonstersCount, currentYard, monstersCount);
  366. textBuilder.AppendLine();
  367. if (EliteCount > 0) textBuilder.AppendFormat(str_Elite, EliteCount, ElitePackCount);
  368. if (RareMinionCount > 0) textBuilder.AppendFormat(str_Minion, RareMinionCount);
  369. textBuilder.AppendLine();
  370. textBuilder.AppendLine();
  371. }
  372.  
  373. if (inRift)
  374. {
  375. totalMonsterRiftProgression = TrashMonsterRiftProgression + EliteProgression + RareMinionProgression + RiftGlobeProgression;
  376. long totalTime = (long)totalMonsterRiftProgression * 90000000;
  377. long TrashTime = (long)TrashMonsterRiftProgression * 90000000;
  378. long EliteTime = (long)EliteProgression * 90000000;
  379. long RareMinionTime = (long)RareMinionProgression * 90000000;
  380. long RiftGlobeTime = (long)RiftGlobeProgression * 90000000;
  381. if (totalMonsterRiftProgression > 0 && ShowTotalProgression)
  382. {
  383. if (ShowTime && inGR)
  384. {
  385. textBuilder.AppendFormat(str_TotalRP + " {0}% = {1}", totalMonsterRiftProgression.ToString("f2"), ValueToString((long)totalTime, ValueFormat.LongTime));
  386. }
  387. else
  388. {
  389. textBuilder.AppendFormat(str_TotalRP + " {0}%", totalMonsterRiftProgression.ToString("f2"));
  390. }
  391. textBuilder.AppendLine();
  392. }
  393.  
  394. if (TrashMonsterRiftProgression > 0 && ShowTrashProgression)
  395. {
  396. if (ShowTime && inGR)
  397. {
  398. textBuilder.AppendFormat(str_TrashRP + " {0}% = {1}", TrashMonsterRiftProgression.ToString("f2"), ValueToString((long)TrashTime, ValueFormat.LongTime));
  399. }
  400. else
  401. {
  402. textBuilder.AppendFormat(str_TrashRP + " {0}%", TrashMonsterRiftProgression.ToString("f2"));
  403. }
  404. textBuilder.AppendLine();
  405. }
  406. if (EliteProgression > 0 && ShowEliteProgression)
  407. {
  408. if (ShowTime && inGR)
  409. {
  410. textBuilder.AppendFormat(str_EliteRP + " {0}% = {1}", EliteProgression.ToString("f2"), ValueToString((long)EliteTime, ValueFormat.LongTime));
  411. }
  412. else
  413. {
  414. textBuilder.AppendFormat(str_EliteRP + " {0}%", EliteProgression.ToString("f2"));
  415. }
  416. textBuilder.AppendLine();
  417. }
  418. if (RareMinionProgression > 0 && ShowRareMinionProgression)
  419. {
  420. if (ShowTime && inGR)
  421. {
  422. textBuilder.AppendFormat(str_MinionRP + " {0}% = {1}", RareMinionProgression.ToString("f2"), ValueToString((long)RareMinionTime, ValueFormat.LongTime));
  423. }
  424. else
  425. {
  426. textBuilder.AppendFormat(str_MinionRP + " {0}%", RareMinionProgression.ToString("f2"));
  427. }
  428. textBuilder.AppendLine();
  429. }
  430. if (RiftGlobeProgression > 0 && ShowRiftGlobeProgression)
  431. {
  432. if (ShowTime && inGR)
  433. {
  434. textBuilder.AppendFormat(str_GlobeRP + " {0}% = {1}", RiftGlobeProgression.ToString("f2"), ValueToString((long)RiftGlobeTime, ValueFormat.LongTime));
  435. }
  436. else
  437. {
  438. textBuilder.AppendFormat(str_GlobeRP + " {0}%", RiftGlobeProgression.ToString("f2"));
  439. }
  440. textBuilder.AppendLine();
  441. }
  442. textBuilder.AppendLine();
  443. }
  444. if (locustCount > 0 && ShowLlocustCount)
  445. {
  446. textBuilder.AppendFormat(str_Locust + " {0}/{1}", locustCount, monstersCount);
  447. if (ElitelocustCount > 0) textBuilder.AppendFormat(str_ToElite, ElitelocustCount, EliteCount);
  448. textBuilder.AppendLine();
  449. }
  450. if (hauntedCount > 0 && ShowHauntedCount)
  451. {
  452. textBuilder.AppendFormat(str_haunted + " {0}/{1}", hauntedCount, monstersCount);
  453. if (ElitehauntedCount > 0) textBuilder.AppendFormat(str_ToElite, ElitehauntedCount, EliteCount);
  454. textBuilder.AppendLine();
  455. }
  456. if (CursedCount > 0 && ShowCursedCount)
  457. {
  458. textBuilder.AppendFormat(str_Cursed + " {0}/{1}", CursedCount, monstersCount);
  459. if (ElitehauntedCount > 0) textBuilder.AppendFormat(str_ToElite, EliteCursedCount, EliteCount);
  460. textBuilder.AppendLine();
  461. }
  462. if (PiranhasCount > 0 && ShowPiranhasCount)
  463. {
  464. textBuilder.AppendFormat(str_Piranhas + " {0}/{1}", PiranhasCount, monstersCount);
  465. if (ElitehauntedCount > 0) textBuilder.AppendFormat(str_ToElite, ElitePiranhasCount, EliteCount);
  466. textBuilder.AppendLine();
  467. }
  468. if (palmedCount > 0 && ShowPalmedCount)
  469. {
  470. textBuilder.AppendFormat(str_Palmed + " {0}/{1}", palmedCount, monstersCount);
  471. if (ElitepalmedCount > 0) textBuilder.AppendFormat(str_ToElite, ElitepalmedCount, EliteCount);
  472. textBuilder.AppendLine();
  473. }
  474. if (phoenixedCount > 0 && ShowPhoenixedCount)
  475. {
  476. textBuilder.AppendFormat(str_Phoenixed + " {0}/{1}", phoenixedCount, monstersCount);
  477. if (ElitephoenixedCount > 0) textBuilder.AppendFormat(str_ToElite, ElitephoenixedCount, EliteCount);
  478. textBuilder.AppendLine();
  479. }
  480. if (strongarmedCount > 0 && ShowStrongarmedCount)
  481. {
  482. textBuilder.AppendFormat(str_Strongarmed + " {0}/{1}", strongarmedCount, monstersCount);
  483. if (ElitestrongarmedCount > 0) textBuilder.AppendFormat(str_ToElite, ElitestrongarmedCount, EliteCount);
  484. textBuilder.AppendLine();
  485. }
  486. if (KrysbinCount > 0 && ShowKrysbinCount)
  487. {
  488. textBuilder.AppendFormat(str_Krysbin + " {0}/{1}", KrysbinCount, monstersCount);
  489. if (EliteKrysbinCount > 0) textBuilder.AppendFormat(str_ToElite, EliteKrysbinCount, EliteCount);
  490. textBuilder.AppendLine();
  491. }
  492. if (EntanglingShotCount > 0 && ShowEntanglingShotCount)
  493. {
  494. textBuilder.AppendFormat(str_EntanglingShot + " {0}/{1}", EntanglingShotCount, monstersCount);
  495. if (EliteEntanglingShotCount > 0) textBuilder.AppendFormat(str_ToElite, EliteEntanglingShotCount, EliteCount);
  496. textBuilder.AppendLine();
  497. }
  498. if (ShowPainEnhancerCount && Hud.Game.Me.Powers.UsedLegendaryGems.PainEnhancerPrimary?.Active == true)
  499. {
  500. if (bleedCount > 0)
  501. {
  502. textBuilder.AppendLine();
  503. textBuilder.AppendFormat(str_bleedCount, bleedCount);
  504. textBuilder.AppendLine();
  505. textBuilder.AppendFormat(str_Attackspeedbonus, bleedCount * 3);
  506. textBuilder.AppendLine();
  507. }
  508. }
  509.  
  510. if (totalMonsterRiftProgression >= 100d - Hud.Game.RiftPercentage && Hud.Game.RiftPercentage != 100 || TrashMonsterRiftProgression >= 100d - Hud.Game.RiftPercentage && Hud.Game.RiftPercentage != 100)
  511. {
  512. if (totalMonsterRiftProgression >= 100d - Hud.Game.RiftPercentage && Hud.Game.RiftPercentage != 100) currentFont = OrangeTextFont;
  513. if (TrashMonsterRiftProgression >= 100d - Hud.Game.RiftPercentage && Hud.Game.RiftPercentage != 100) currentFont = RedTextFont;
  514. }
  515. else
  516. {
  517. currentFont = DefaultTextFont;
  518. }
  519. var layout = currentFont.GetTextLayout(textBuilder.ToString());
  520. currentFont.DrawText(layout, XPos, YPos);
  521. }
  522. }
  523. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement