Advertisement
Guest User

Untitled

a guest
Oct 15th, 2017
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 200.23 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Text.RegularExpressions;
  8. using System.Threading;
  9. using System.IO;
  10. using Server.MirDatabase;
  11. using Server.MirNetwork;
  12. using Server.MirObjects;
  13. using S = ServerPackets;
  14. using System.Drawing;
  15. using System.Reflection;
  16. using MySql.Data.MySqlClient;
  17. using System.Data;
  18. using System.Text;
  19. using System.Security.Cryptography;
  20.  
  21. namespace Server.MirEnvir
  22. {
  23. public class MobThread
  24. {
  25. public int Id = 0;
  26. public long LastRunTime = 0;
  27. public long StartTime = 0;
  28. public long EndTime = 0;
  29. public LinkedList<MapObject> ObjectsList = new LinkedList<MapObject>();
  30. public LinkedListNode<MapObject> current = null;
  31. public Boolean Stop = false;
  32. }
  33.  
  34. public class RandomProvider
  35. {
  36. private static int seed = Environment.TickCount;
  37. private static ThreadLocal<Random> RandomWrapper = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
  38.  
  39. public static Random GetThreadRadom()
  40. {
  41. return RandomWrapper.Value;
  42. }
  43.  
  44. public int Next()
  45. {
  46. return RandomWrapper.Value.Next();
  47. }
  48. public int Next(int maxValue)
  49. {
  50. return RandomWrapper.Value.Next(maxValue);
  51. }
  52. public int Next(int minValue, int maxValue)
  53. {
  54. return RandomWrapper.Value.Next(minValue, maxValue);
  55. }
  56. }
  57.  
  58. public class Envir
  59. {
  60. public static object AccountLock = new object();
  61. public static object LoadLock = new object();
  62.  
  63. public const int Version = 80;
  64. public const int CustomVersion = 96;
  65. public const string DatabasePath = @".\Server.MirDB";
  66. public const string AccountPath = @".\Server.MirADB";
  67. public const string ParagonInfo = @".\Server.ParagonInfoDB";
  68. public const string BackUpPath = @".\Back Up\";
  69. public bool ResetGS = false;
  70. public bool SaveDBFlag = false;
  71. private static readonly Regex AccountIDReg, PasswordReg, EMailReg, CharacterReg;
  72.  
  73. public static int LoadVersion;
  74. public static int LoadCustomVersion;
  75.  
  76. private readonly DateTime _startTime = DateTime.Now;
  77. public readonly Stopwatch Stopwatch = Stopwatch.StartNew();
  78.  
  79. public long Time { get; private set; }
  80. public RespawnTimer RespawnTick = new RespawnTimer();
  81. public DateTime Now
  82. {
  83. get { return _startTime.AddMilliseconds(Time); }
  84. }
  85.  
  86. public bool Running { get; private set; }
  87.  
  88. private static uint _objectID;
  89. public uint ObjectID
  90. {
  91. get { return ++_objectID; }
  92. }
  93.  
  94. public static int _playerCount;
  95. public int PlayerCount
  96. {
  97. get { return Players.Count; }
  98. }
  99.  
  100. public RandomProvider Random = new RandomProvider();
  101.  
  102.  
  103. private Thread _thread;
  104. private TcpListener _listener;
  105. private bool StatusPortEnabled = true;
  106. public List<MirStatusConnection> StatusConnections = new List<MirStatusConnection>();
  107. private TcpListener _StatusPort;
  108. private int _sessionID;
  109. public List<MirConnection> Connections = new List<MirConnection>();
  110.  
  111. //Server DB
  112. public int MapIndex, MapInstanceIndex, ItemIndex, MonsterIndex, NPCIndex, QuestIndex, GameshopIndex, ConquestIndex, RespawnIndex, MobLevelSpawn;
  113. public List<MapInfo> MapInfoList = new List<MapInfo>();
  114. public List<MapInstanceInfo> MapInstanceInfoList = new List<MapInstanceInfo>();
  115. public List<ItemInfo> ItemInfoList = new List<ItemInfo>();
  116. public List<MonsterInfo> MonsterInfoList = new List<MonsterInfo>();
  117. public List<MagicInfo> MagicInfoList = new List<MagicInfo>();
  118. public List<NPCInfo> NPCInfoList = new List<NPCInfo>();
  119. public DragonInfo DragonInfo = new DragonInfo();
  120. public List<QuestInfo> QuestInfoList = new List<QuestInfo>();
  121. public List<ItemSetInfo> ItemSetInfoList = new List<ItemSetInfo>();
  122.  
  123. public List<GameShopItem> GameShopList = new List<GameShopItem>();
  124. public Dictionary<int, int> GameshopLog = new Dictionary<int, int>();
  125. //User DB
  126. public int NextAccountID, NextCharacterID;
  127. public ulong NextUserItemID, NextAuctionID, NextMailID;
  128. public List<AccountInfo> AccountList = new List<AccountInfo>();
  129. public List<CharacterInfo> CharacterList = new List<CharacterInfo>();
  130. public LinkedList<AuctionInfo> Auctions = new LinkedList<AuctionInfo>();
  131. public int GuildCount, ParagonInfoCount, NextGuildID;
  132. public List<GuildObject> GuildList = new List<GuildObject>();
  133.  
  134. public List<ParagonInfo> ParagonInfoList = new List<ParagonInfo>();
  135.  
  136. //Live Info
  137. public List<Map> MapList = new List<Map>();
  138. public MapInstanceManager InstancesManager = new MapInstanceManager();
  139. public List<SafeZoneInfo> StartPoints = new List<SafeZoneInfo>();
  140. public List<ItemInfo> StartItems = new List<ItemInfo>();
  141. public List<MailInfo> Mail = new List<MailInfo>();
  142. public List<PlayerObject> Players = new List<PlayerObject>();
  143. public bool Saving = false;
  144. public LightSetting Lights;
  145. public LinkedList<MapObject> Objects = new LinkedList<MapObject>();
  146. public GroupLootManager GroupLootManager = new GroupLootManager();
  147.  
  148. public List<ConquestInfo> ConquestInfos = new List<ConquestInfo>();
  149. public List<ConquestObject> Conquests = new List<ConquestObject>();
  150. //multithread vars
  151. readonly object _locker = new object();
  152. public MobThread[] MobThreads = new MobThread[Settings.ThreadLimit];
  153. private Thread[] MobThreading = new Thread[Settings.ThreadLimit];
  154. public int spawnmultiplyer = 1;//set this to 2 if you want double spawns (warning this can easely lag your server far beyond what you imagine)
  155.  
  156. public List<string> CustomCommands = new List<string>();
  157. public Dragon DragonSystem;
  158. public NPCObject DefaultNPC;
  159. public NPCObject MonsterNPC;
  160.  
  161. public List<DropInfo> FishingDrops = new List<DropInfo>();
  162. public List<DropInfo> AwakeningDrops = new List<DropInfo>();
  163.  
  164. public List<DropInfo> StrongboxDrops = new List<DropInfo>();
  165. public List<DropInfo> BlackstoneDrops = new List<DropInfo>();
  166.  
  167. public List<DropInfo> NormalInstanceDrops = new List<DropInfo>();
  168. public List<DropInfo> HeroicInstanceDrops = new List<DropInfo>();
  169. public List<DropInfo> InsaneInstanceDrops = new List<DropInfo>();
  170.  
  171. public List<GuildAtWar> GuildsAtWar = new List<GuildAtWar>();
  172. public List<MapRespawn> SavedSpawns = new List<MapRespawn>();
  173.  
  174. public List<Rank_Character_Info> RankTop20 = new List<Rank_Character_Info>();
  175. public List<Rank_Character_Info>[] RankClass20 = new List<Rank_Character_Info>[5];
  176. public int[] RankBottomLevel = new int[6];
  177. public List<RobotInfo> RobotCommandList = new List<RobotInfo>();
  178. public List<CraftingInfo> CraftingInfoList = new List<CraftingInfo>();
  179. public int CurrentWeekOfTheYear = 0;
  180. static Envir()
  181. {
  182. AccountIDReg =
  183. new Regex(@"^[A-Za-z0-9]{" + Globals.MinAccountIDLength + "," + Globals.MaxAccountIDLength + "}$");
  184. PasswordReg =
  185. new Regex(@"^[A-Za-z0-9]{" + Globals.MinPasswordLength + "," + Globals.MaxPasswordLength + "}$");
  186. EMailReg = new Regex(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
  187. CharacterReg =
  188. new Regex(@"^[A-Za-z0-9]{" + Globals.MinCharacterNameLength + "," + Globals.MaxCharacterNameLength +
  189. "}$");
  190. }
  191.  
  192. public static int LastCount = 0, LastRealCount = 0;
  193. public static long LastRunTime = 0;
  194. public int MonsterCount;
  195.  
  196. private long dayTime, warTime, mailTime, guildTime, conquestTime, robotTime, craftime, viptime, grpLootTime, ProcessCurrencyCapTime;
  197.  
  198. private bool MagicExists(Spell spell)
  199. {
  200. for (int i = 0; i < MagicInfoList.Count; i++)
  201. {
  202. if (MagicInfoList[i].Spell == spell) return true;
  203. }
  204. return false;
  205. }
  206.  
  207. private void FillMagicInfoList()
  208. {
  209. //Warrior
  210. if (!MagicExists(Spell.Fencing)) MagicInfoList.Add(new MagicInfo { Name = "Fencing", Spell = Spell.Fencing, Icon = 2, Level1 = 7, Level2 = 9, Level3 = 12, Need1 = 270, Need2 = 600, Need3 = 1300, Range = 0 });
  211. if (!MagicExists(Spell.Slaying)) MagicInfoList.Add(new MagicInfo { Name = "Slaying", Spell = Spell.Slaying, Icon = 6, Level1 = 15, Level2 = 17, Level3 = 20, Need1 = 500, Need2 = 1100, Need3 = 1800, Range = 0 });
  212. if (!MagicExists(Spell.Thrusting)) MagicInfoList.Add(new MagicInfo { Name = "Thrusting", Spell = Spell.Thrusting, Icon = 11, Level1 = 22, Level2 = 24, Level3 = 27, Need1 = 2000, Need2 = 3500, Need3 = 6000, Range = 0 });
  213. if (!MagicExists(Spell.HalfMoon)) MagicInfoList.Add(new MagicInfo { Name = "HalfMoon", Spell = Spell.HalfMoon, Icon = 24, Level1 = 26, Level2 = 28, Level3 = 31, Need1 = 5000, Need2 = 8000, Need3 = 14000, BaseCost = 3, Range = 0 });
  214. if (!MagicExists(Spell.ShoulderDash)) MagicInfoList.Add(new MagicInfo { Name = "ShoulderDash", Spell = Spell.ShoulderDash, Icon = 26, Level1 = 30, Level2 = 32, Level3 = 34, Need1 = 3000, Need2 = 4000, Need3 = 6000, BaseCost = 4, LevelCost = 4, DelayBase = 2500, Range = 0 });
  215. if (!MagicExists(Spell.TwinDrakeBlade)) MagicInfoList.Add(new MagicInfo { Name = "TwinDrakeBlade", Spell = Spell.TwinDrakeBlade, Icon = 37, Level1 = 32, Level2 = 34, Level3 = 37, Need1 = 4000, Need2 = 6000, Need3 = 10000, BaseCost = 10, Range = 0 });
  216. if (!MagicExists(Spell.Entrapment)) MagicInfoList.Add(new MagicInfo { Name = "Entrapment", Spell = Spell.Entrapment, Icon = 46, Level1 = 32, Level2 = 35, Level3 = 37, Need1 = 2000, Need2 = 3500, Need3 = 5500, BaseCost = 15, LevelCost = 3, Range = 12 });
  217. if (!MagicExists(Spell.FlamingSword)) MagicInfoList.Add(new MagicInfo { Name = "FlamingSword", Spell = Spell.FlamingSword, Icon = 25, Level1 = 35, Level2 = 37, Level3 = 40, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 7, Range = 0 });
  218. if (!MagicExists(Spell.LionRoar)) MagicInfoList.Add(new MagicInfo { Name = "LionRoar", Spell = Spell.LionRoar, Icon = 42, Level1 = 36, Level2 = 39, Level3 = 41, Need1 = 5000, Need2 = 8000, Need3 = 12000, BaseCost = 14, LevelCost = 4, Range = 0 });
  219. if (!MagicExists(Spell.CrossHalfMoon)) MagicInfoList.Add(new MagicInfo { Name = "CrossHalfMoon", Spell = Spell.CrossHalfMoon, Icon = 33, Level1 = 38, Level2 = 40, Level3 = 42, Need1 = 7000, Need2 = 11000, Need3 = 16000, BaseCost = 6, Range = 0 });
  220. if (!MagicExists(Spell.BladeAvalanche)) MagicInfoList.Add(new MagicInfo { Name = "BladeAvalanche", Spell = Spell.BladeAvalanche, Icon = 43, Level1 = 38, Level2 = 41, Level3 = 43, Need1 = 5000, Need2 = 8000, Need3 = 12000, BaseCost = 14, LevelCost = 4, Range = 0 });
  221. if (!MagicExists(Spell.ProtectionField)) MagicInfoList.Add(new MagicInfo { Name = "ProtectionField", Spell = Spell.ProtectionField, Icon = 50, Level1 = 39, Level2 = 42, Level3 = 45, Need1 = 6000, Need2 = 12000, Need3 = 18000, BaseCost = 23, LevelCost = 6, Range = 0 });
  222. if (!MagicExists(Spell.Rage)) MagicInfoList.Add(new MagicInfo { Name = "Rage", Spell = Spell.Rage, Icon = 49, Level1 = 44, Level2 = 47, Level3 = 50, Need1 = 8000, Need2 = 14000, Need3 = 20000, BaseCost = 20, LevelCost = 5, Range = 0 });
  223. if (!MagicExists(Spell.CounterAttack)) MagicInfoList.Add(new MagicInfo { Name = "CounterAttack", Spell = Spell.CounterAttack, Icon = 72, Level1 = 47, Level2 = 51, Level3 = 55, Need1 = 7000, Need2 = 11000, Need3 = 15000, BaseCost = 12, LevelCost = 4, DelayBase = 24000, Range = 0 });
  224. if (!MagicExists(Spell.SlashingBurst)) MagicInfoList.Add(new MagicInfo { Name = "SlashingBurst", Spell = Spell.SlashingBurst, Icon = 55, Level1 = 50, Level2 = 53, Level3 = 56, Need1 = 10000, Need2 = 16000, Need3 = 24000, BaseCost = 25, LevelCost = 4, MPowerBase = 1, PowerBase = 3, DelayBase = 14000, DelayReduction = 4000, Range = 0 });
  225. if (!MagicExists(Spell.Fury)) MagicInfoList.Add(new MagicInfo { Name = "Fury", Spell = Spell.Fury, Icon = 76, Level1 = 45, Level2 = 48, Level3 = 51, Need1 = 8000, Need2 = 14000, Need3 = 20000, BaseCost = 10, LevelCost = 4, DelayBase = 600000, DelayReduction = 120000, Range = 0 });
  226. if (!MagicExists(Spell.ImmortalSkin)) MagicInfoList.Add(new MagicInfo { Name = "ImmortalSkin", Spell = Spell.ImmortalSkin, Icon = 80, Level1 = 60, Level2 = 61, Level3 = 62, Need1 = 1560, Need2 = 2200, Need3 = 3000, BaseCost = 10, LevelCost = 4, DelayBase = 600000, DelayReduction = 120000, Range = 0 });
  227. if (!MagicExists(Spell.DemonRush)) MagicInfoList.Add(new MagicInfo { Name = "DemonRush", Spell = Spell.DemonRush, Icon = 80, Level1 = 30, Level2 = 32, Level3 = 34, Need1 = 3000, Need2 = 4000, Need3 = 6000, BaseCost = 4, LevelCost = 4, DelayBase = 2500, Range = 0 });
  228. if (!MagicExists(Spell.WeaponJab)) MagicInfoList.Add(new MagicInfo { Name = "WeaponJab", Spell = Spell.WeaponJab, Icon = 25, Level1 = 35, Level2 = 37, Level3 = 40, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 7, Range = 0 });
  229. if (!MagicExists(Spell.SpinningThrust)) MagicInfoList.Add(new MagicInfo { Name = "SpinningThrust", Spell = Spell.SpinningThrust, Icon = 26, Level1 = 30, Level2 = 32, Level3 = 34, Need1 = 3000, Need2 = 4000, Need3 = 6000, BaseCost = 4, LevelCost = 4, DelayBase = 2500, Range = 0 });
  230. if (!MagicExists(Spell.TripleAttack)) MagicInfoList.Add(new MagicInfo { Name = "TripleAttack", Spell = Spell.TripleAttack, Icon = 43, Level1 = 38, Level2 = 41, Level3 = 43, Need1 = 5000, Need2 = 8000, Need3 = 12000, BaseCost = 14, LevelCost = 4, Range = 0 });
  231. if (!MagicExists(Spell.BladeStorm)) MagicInfoList.Add(new MagicInfo { Name = "BladeStorm", Spell = Spell.BladeStorm, Icon = 44, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 6000, Need2 = 11000, Need3 = 16000, BaseCost = 45, LevelCost = 8, MPowerBase = 100, PowerBase = 25, Range = 0 });
  232. if (!MagicExists(Spell.CrashDown)) MagicInfoList.Add(new MagicInfo { Name = "CrashDown", Spell = Spell.CrashDown, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  233. if (!MagicExists(Spell.Vengeance)) MagicInfoList.Add(new MagicInfo { Name = "Vengeance", Spell = Spell.Vengeance, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  234.  
  235.  
  236. //Wizard
  237. if (!MagicExists(Spell.FireBall)) MagicInfoList.Add(new MagicInfo { Name = "FireBall", Spell = Spell.FireBall, Icon = 0, Level1 = 7, Level2 = 9, Level3 = 11, Need1 = 200, Need2 = 350, Need3 = 700, BaseCost = 3, LevelCost = 2, MPowerBase = 8, PowerBase = 2, Range = 9 });
  238. if (!MagicExists(Spell.Repulsion)) MagicInfoList.Add(new MagicInfo { Name = "Repulsion", Spell = Spell.Repulsion, Icon = 7, Level1 = 12, Level2 = 15, Level3 = 19, Need1 = 500, Need2 = 1300, Need3 = 2200, BaseCost = 2, LevelCost = 2, Range = 0 });
  239. if (!MagicExists(Spell.ElectricShock)) MagicInfoList.Add(new MagicInfo { Name = "ElectricShock", Spell = Spell.ElectricShock, Icon = 19, Level1 = 13, Level2 = 18, Level3 = 24, Need1 = 530, Need2 = 1100, Need3 = 2200, BaseCost = 3, LevelCost = 1, Range = 9 });
  240. if (!MagicExists(Spell.GreatFireBall)) MagicInfoList.Add(new MagicInfo { Name = "GreatFireBall", Spell = Spell.GreatFireBall, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 9 });
  241. if (!MagicExists(Spell.HellFire)) MagicInfoList.Add(new MagicInfo { Name = "HellFire", Spell = Spell.HellFire, Icon = 8, Level1 = 16, Level2 = 20, Level3 = 24, Need1 = 700, Need2 = 2700, Need3 = 3500, BaseCost = 10, LevelCost = 3, MPowerBase = 14, PowerBase = 6, Range = 0 });
  242. if (!MagicExists(Spell.ThunderBolt)) MagicInfoList.Add(new MagicInfo { Name = "ThunderBolt", Spell = Spell.ThunderBolt, Icon = 10, Level1 = 17, Level2 = 20, Level3 = 23, Need1 = 500, Need2 = 2000, Need3 = 3500, BaseCost = 9, LevelCost = 2, MPowerBase = 8, MPowerBonus = 20, PowerBase = 9, Range = 9 });
  243. if (!MagicExists(Spell.Teleport)) MagicInfoList.Add(new MagicInfo { Name = "Teleport", Spell = Spell.Teleport, Icon = 20, Level1 = 19, Level2 = 22, Level3 = 25, Need1 = 350, Need2 = 1000, Need3 = 2000, BaseCost = 10, LevelCost = 3, Range = 0 });
  244. if (!MagicExists(Spell.FireBang)) MagicInfoList.Add(new MagicInfo { Name = "FireBang", Spell = Spell.FireBang, Icon = 22, Level1 = 22, Level2 = 25, Level3 = 28, Need1 = 3000, Need2 = 5000, Need3 = 10000, BaseCost = 14, LevelCost = 4, MPowerBase = 8, PowerBase = 8, Range = 9 });
  245. if (!MagicExists(Spell.FireWall)) MagicInfoList.Add(new MagicInfo { Name = "FireWall", Spell = Spell.FireWall, Icon = 21, Level1 = 24, Level2 = 28, Level3 = 33, Need1 = 4000, Need2 = 10000, Need3 = 20000, BaseCost = 30, LevelCost = 5, MPowerBase = 3, PowerBase = 3, Range = 9 });
  246. if (!MagicExists(Spell.Lightning)) MagicInfoList.Add(new MagicInfo { Name = "Lightning", Spell = Spell.Lightning, Icon = 9, Level1 = 26, Level2 = 29, Level3 = 32, Need1 = 3000, Need2 = 6000, Need3 = 12000, BaseCost = 38, LevelCost = 7, MPowerBase = 12, PowerBase = 12, Range = 0 });
  247. if (!MagicExists(Spell.FrostCrunch)) MagicInfoList.Add(new MagicInfo { Name = "FrostCrunch", Spell = Spell.FrostCrunch, Icon = 38, Level1 = 28, Level2 = 30, Level3 = 33, Need1 = 3000, Need2 = 5000, Need3 = 8000, BaseCost = 15, LevelCost = 3, MPowerBase = 12, PowerBase = 12, Range = 9 });
  248. if (!MagicExists(Spell.ThunderStorm)) MagicInfoList.Add(new MagicInfo { Name = "ThunderStorm", Spell = Spell.ThunderStorm, Icon = 23, Level1 = 30, Level2 = 32, Level3 = 34, Need1 = 4000, Need2 = 8000, Need3 = 12000, BaseCost = 29, LevelCost = 9, MPowerBase = 10, MPowerBonus = 20, PowerBase = 10, PowerBonus = 20, Range = 0 });
  249. if (!MagicExists(Spell.MagicShield)) MagicInfoList.Add(new MagicInfo { Name = "MagicShield", Spell = Spell.MagicShield, Icon = 30, Level1 = 31, Level2 = 34, Level3 = 38, Need1 = 3000, Need2 = 7000, Need3 = 10000, BaseCost = 35, LevelCost = 5, Range = 0 });
  250. if (!MagicExists(Spell.TurnUndead)) MagicInfoList.Add(new MagicInfo { Name = "TurnUndead", Spell = Spell.TurnUndead, Icon = 31, Level1 = 32, Level2 = 35, Level3 = 39, Need1 = 3000, Need2 = 7000, Need3 = 10000, BaseCost = 52, LevelCost = 13, Range = 9 });
  251. if (!MagicExists(Spell.Vampirism)) MagicInfoList.Add(new MagicInfo { Name = "Vampirism", Spell = Spell.Vampirism, Icon = 47, Level1 = 33, Level2 = 36, Level3 = 40, Need1 = 3000, Need2 = 5000, Need3 = 8000, BaseCost = 26, LevelCost = 13, MPowerBase = 12, PowerBase = 12, Range = 9 });
  252. if (!MagicExists(Spell.IceStorm)) MagicInfoList.Add(new MagicInfo { Name = "IceStorm", Spell = Spell.IceStorm, Icon = 32, Level1 = 35, Level2 = 37, Level3 = 40, Need1 = 4000, Need2 = 8000, Need3 = 12000, BaseCost = 33, LevelCost = 3, MPowerBase = 12, PowerBase = 14, Range = 9 });
  253. if (!MagicExists(Spell.FlameDisruptor)) MagicInfoList.Add(new MagicInfo { Name = "FlameDisruptor", Spell = Spell.FlameDisruptor, Icon = 34, Level1 = 38, Level2 = 40, Level3 = 42, Need1 = 5000, Need2 = 9000, Need3 = 14000, BaseCost = 28, LevelCost = 3, MPowerBase = 15, MPowerBonus = 20, PowerBase = 9, Range = 9 });
  254. if (!MagicExists(Spell.Mirroring)) MagicInfoList.Add(new MagicInfo { Name = "Mirroring", Spell = Spell.Mirroring, Icon = 41, Level1 = 41, Level2 = 43, Level3 = 45, Need1 = 6000, Need2 = 11000, Need3 = 16000, BaseCost = 21, Range = 0 });
  255. if (!MagicExists(Spell.FlameField)) MagicInfoList.Add(new MagicInfo { Name = "FlameField", Spell = Spell.FlameField, Icon = 44, Level1 = 42, Level2 = 43, Level3 = 45, Need1 = 6000, Need2 = 11000, Need3 = 16000, BaseCost = 45, LevelCost = 8, MPowerBase = 100, PowerBase = 25, Range = 0 });
  256. if (!MagicExists(Spell.Blizzard)) MagicInfoList.Add(new MagicInfo { Name = "Blizzard", Spell = Spell.Blizzard, Icon = 51, Level1 = 44, Level2 = 47, Level3 = 50, Need1 = 8000, Need2 = 16000, Need3 = 24000, BaseCost = 65, LevelCost = 10, MPowerBase = 30, MPowerBonus = 10, PowerBase = 20, PowerBonus = 5, Range = 9 });
  257. if (!MagicExists(Spell.MagicBooster)) MagicInfoList.Add(new MagicInfo { Name = "MagicBooster", Spell = Spell.MagicBooster, Icon = 73, Level1 = 47, Level2 = 49, Level3 = 52, Need1 = 12000, Need2 = 18000, Need3 = 24000, BaseCost = 150, LevelCost = 15, Range = 0 });
  258. if (!MagicExists(Spell.MeteorStrike)) MagicInfoList.Add(new MagicInfo { Name = "MeteorStrike", Spell = Spell.MeteorStrike, Icon = 52, Level1 = 49, Level2 = 52, Level3 = 55, Need1 = 15000, Need2 = 20000, Need3 = 25000, BaseCost = 115, LevelCost = 17, MPowerBase = 40, MPowerBonus = 10, PowerBase = 20, PowerBonus = 15, Range = 9 });
  259. if (!MagicExists(Spell.IceThrust)) MagicInfoList.Add(new MagicInfo { Name = "IceThrust", Spell = Spell.IceThrust, Icon = 56, Level1 = 53, Level2 = 56, Level3 = 59, Need1 = 17000, Need2 = 22000, Need3 = 27000, BaseCost = 100, LevelCost = 20, MPowerBase = 100, PowerBase = 50, Range = 0 });
  260. if (!MagicExists(Spell.Blink)) MagicInfoList.Add(new MagicInfo { Name = "Blink", Spell = Spell.Blink, Icon = 20, Level1 = 19, Level2 = 22, Level3 = 25, Need1 = 350, Need2 = 1000, Need3 = 2000, BaseCost = 10, LevelCost = 3, Range = 12 });
  261. //if (!MagicExists(Spell.FastMove)) MagicInfoList.Add(new MagicInfo { Name = "FastMove", Spell = Spell.ImmortalSkin, Icon = ?, Level1 = ?, Level2 = ?, Level3 = ?, Need1 = ?, Need2 = ?, Need3 = ?, BaseCost = ?, LevelCost = ?, DelayBase = ?, DelayReduction = ? });
  262. if (!MagicExists(Spell.StormEscape)) MagicInfoList.Add(new MagicInfo { Name = "StormEscape", Spell = Spell.StormEscape, Icon = 23, Level1 = 60, Level2 = 61, Level3 = 62, Need1 = 2200, Need2 = 3300, Need3 = 4400, BaseCost = 65, LevelCost = 8, MPowerBase = 12, PowerBase = 4, Range = 12 });
  263. if (!MagicExists(Spell.IceField)) MagicInfoList.Add(new MagicInfo { Name = "IceField", Spell = Spell.IceField, Icon = 23, Level1 = 60, Level2 = 61, Level3 = 62, Need1 = 2200, Need2 = 3300, Need3 = 4400, BaseCost = 65, LevelCost = 8, MPowerBase = 12, PowerBase = 4, Range = 12 });
  264. if (!MagicExists(Spell.FrostQuake)) MagicInfoList.Add(new MagicInfo { Name = "FrostQuake", Spell = Spell.FrostQuake, Icon = 56, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 17000, Need2 = 22000, Need3 = 27000, BaseCost = 100, LevelCost = 20, MPowerBase = 100, PowerBase = 50, Range = 0 });
  265. if (!MagicExists(Spell.DoubleFireBall)) MagicInfoList.Add(new MagicInfo { Name = "DoubleFireBall", Spell = Spell.DoubleFireBall, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 9 });
  266. if (!MagicExists(Spell.FireBird)) MagicInfoList.Add(new MagicInfo { Name = "FireBird", Spell = Spell.FireBird, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 9 });
  267. if (!MagicExists(Spell.BurningBall)) MagicInfoList.Add(new MagicInfo { Name = "BurningBall", Spell = Spell.BurningBall, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 9 });
  268. if (!MagicExists(Spell.SwordStorm)) MagicInfoList.Add(new MagicInfo { Name = "SwordStorm", Spell = Spell.SwordStorm, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 9 });
  269. if (!MagicExists(Spell.AlmightyPush)) MagicInfoList.Add(new MagicInfo { Name = "AlmightyPush", Spell = Spell.AlmightyPush, Icon = 4, Level1 = 15, Level2 = 18, Level3 = 21, Need1 = 2000, Need2 = 2700, Need3 = 3500, BaseCost = 5, LevelCost = 1, MPowerBase = 6, PowerBase = 10, Range = 0 });
  270. if (!MagicExists(Spell.DarkChains)) MagicInfoList.Add(new MagicInfo { Name = "DarkChains", Spell = Spell.DarkChains, Icon = 88, Level1 = 150, Level2 = 155, Level3 = 160, Need1 = 100, Need2 = 200, Need3 = 300, BaseCost = 115, LevelCost = 17, MPowerBase = 40, MPowerBonus = 10, PowerBase = 20, PowerBonus = 15, Range = 9 });
  271.  
  272.  
  273. //Taoist
  274. if (!MagicExists(Spell.Healing)) MagicInfoList.Add(new MagicInfo { Name = "Healing", Spell = Spell.Healing, Icon = 1, Level1 = 7, Level2 = 11, Level3 = 14, Need1 = 150, Need2 = 350, Need3 = 700, BaseCost = 3, LevelCost = 2, MPowerBase = 14, Range = 12 });
  275. if (!MagicExists(Spell.SpiritSword)) MagicInfoList.Add(new MagicInfo { Name = "SpiritSword", Spell = Spell.SpiritSword, Icon = 3, Level1 = 9, Level2 = 12, Level3 = 15, Need1 = 350, Need2 = 1300, Need3 = 2700, Range = 0 });
  276. if (!MagicExists(Spell.Poisoning)) MagicInfoList.Add(new MagicInfo { Name = "Poisoning", Spell = Spell.Poisoning, Icon = 5, Level1 = 14, Level2 = 17, Level3 = 20, Need1 = 700, Need2 = 1300, Need3 = 2700, BaseCost = 2, LevelCost = 1, MPowerBase = 6, Range = 9 });
  277. if (!MagicExists(Spell.SoulFireBall)) MagicInfoList.Add(new MagicInfo { Name = "SoulFireBall", Spell = Spell.SoulFireBall, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  278. if (!MagicExists(Spell.SummonSkeleton)) MagicInfoList.Add(new MagicInfo { Name = "SummonSkeleton", Spell = Spell.SummonSkeleton, Icon = 16, Level1 = 19, Level2 = 22, Level3 = 26, Need1 = 1000, Need2 = 2000, Need3 = 3500, BaseCost = 12, LevelCost = 4, Range = 0 });
  279. if (!MagicExists(Spell.Hiding)) MagicInfoList.Add(new MagicInfo { Name = "Hiding", Spell = Spell.Hiding, Icon = 17, Level1 = 20, Level2 = 23, Level3 = 26, Need1 = 1300, Need2 = 2700, Need3 = 5300, BaseCost = 1, LevelCost = 1, Range = 0 });
  280. if (!MagicExists(Spell.MassHiding)) MagicInfoList.Add(new MagicInfo { Name = "MassHiding", Spell = Spell.MassHiding, Icon = 18, Level1 = 21, Level2 = 25, Level3 = 29, Need1 = 1300, Need2 = 2700, Need3 = 5300, BaseCost = 2, LevelCost = 2, Range = 9 });
  281. if (!MagicExists(Spell.SoulShield)) MagicInfoList.Add(new MagicInfo { Name = "SoulShield", Spell = Spell.SoulShield, Icon = 13, Level1 = 22, Level2 = 24, Level3 = 26, Need1 = 2000, Need2 = 3500, Need3 = 7000, BaseCost = 2, LevelCost = 2, Range = 9 });
  282. if (!MagicExists(Spell.Revelation)) MagicInfoList.Add(new MagicInfo { Name = "Revelation", Spell = Spell.Revelation, Icon = 27, Level1 = 23, Level2 = 25, Level3 = 28, Need1 = 1500, Need2 = 2500, Need3 = 4000, BaseCost = 4, LevelCost = 4, Range = 9 });
  283. if (!MagicExists(Spell.BlessedArmour)) MagicInfoList.Add(new MagicInfo { Name = "BlessedArmour", Spell = Spell.BlessedArmour, Icon = 14, Level1 = 25, Level2 = 27, Level3 = 29, Need1 = 4000, Need2 = 6000, Need3 = 10000, BaseCost = 2, LevelCost = 2, Range = 9 });
  284. if (!MagicExists(Spell.EnergyRepulsor)) MagicInfoList.Add(new MagicInfo { Name = "EnergyRepulsor", Spell = Spell.EnergyRepulsor, Icon = 36, Level1 = 27, Level2 = 29, Level3 = 31, Need1 = 1800, Need2 = 2400, Need3 = 3200, BaseCost = 2, LevelCost = 2, Range = 0 });
  285. if (!MagicExists(Spell.TrapHexagon)) MagicInfoList.Add(new MagicInfo { Name = "TrapHexagon", Spell = Spell.TrapHexagon, Icon = 15, Level1 = 28, Level2 = 30, Level3 = 32, Need1 = 2500, Need2 = 5000, Need3 = 10000, BaseCost = 7, LevelCost = 3, Range = 9 });
  286. if (!MagicExists(Spell.Purification)) MagicInfoList.Add(new MagicInfo { Name = "Purification", Spell = Spell.Purification, Icon = 39, Level1 = 30, Level2 = 32, Level3 = 35, Need1 = 3000, Need2 = 5000, Need3 = 8000, BaseCost = 14, LevelCost = 2, Range = 9 });
  287. if (!MagicExists(Spell.MassHealing)) MagicInfoList.Add(new MagicInfo { Name = "MassHealing", Spell = Spell.MassHealing, Icon = 28, Level1 = 31, Level2 = 33, Level3 = 36, Need1 = 2000, Need2 = 4000, Need3 = 8000, BaseCost = 28, LevelCost = 3, MPowerBase = 10, PowerBase = 4, Range = 9 });
  288. if (!MagicExists(Spell.Hallucination)) MagicInfoList.Add(new MagicInfo { Name = "Hallucination", Spell = Spell.Hallucination, Icon = 48, Level1 = 31, Level2 = 34, Level3 = 36, Need1 = 4000, Need2 = 6000, Need3 = 9000, BaseCost = 22, LevelCost = 10, Range = 9 });
  289. if (!MagicExists(Spell.UltimateEnhancer)) MagicInfoList.Add(new MagicInfo { Name = "UltimateEnchancer", Spell = Spell.UltimateEnhancer, Icon = 35, Level1 = 33, Level2 = 35, Level3 = 38, Need1 = 5000, Need2 = 7000, Need3 = 10000, BaseCost = 28, LevelCost = 4, Range = 9 });
  290. if (!MagicExists(Spell.SummonShinsu)) MagicInfoList.Add(new MagicInfo { Name = "SummonShinsu", Spell = Spell.SummonShinsu, Icon = 29, Level1 = 35, Level2 = 37, Level3 = 40, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 28, LevelCost = 4, Range = 0 });
  291. if (!MagicExists(Spell.Reincarnation)) MagicInfoList.Add(new MagicInfo { Name = "Reincarnation", Spell = Spell.Reincarnation, Icon = 53, Level1 = 37, Level2 = 39, Level3 = 41, Need1 = 2000, Need2 = 6000, Need3 = 10000, BaseCost = 125, LevelCost = 17, Range = 9 });
  292. if (!MagicExists(Spell.SummonHolyDeva)) MagicInfoList.Add(new MagicInfo { Name = "SummonHolyDeva", Spell = Spell.SummonHolyDeva, Icon = 40, Level1 = 38, Level2 = 41, Level3 = 43, Need1 = 4000, Need2 = 6000, Need3 = 9000, BaseCost = 28, LevelCost = 4, Range = 0 });
  293. if (!MagicExists(Spell.Curse)) MagicInfoList.Add(new MagicInfo { Name = "Curse", Spell = Spell.Curse, Icon = 45, Level1 = 40, Level2 = 42, Level3 = 44, Need1 = 4000, Need2 = 6000, Need3 = 9000, BaseCost = 17, LevelCost = 3, Range = 9 });
  294. if (!MagicExists(Spell.Plague)) MagicInfoList.Add(new MagicInfo { Name = "Plague", Spell = Spell.Plague, Icon = 74, Level1 = 42, Level2 = 44, Level3 = 47, Need1 = 5000, Need2 = 9000, Need3 = 13000, BaseCost = 20, LevelCost = 5, MPowerBase = 10, PowerBase = 8, Range = 9 });
  295. if (!MagicExists(Spell.PoisonCloud)) MagicInfoList.Add(new MagicInfo { Name = "PoisonCloud", Spell = Spell.PoisonCloud, Icon = 54, Level1 = 43, Level2 = 45, Level3 = 48, Need1 = 4000, Need2 = 8000, Need3 = 12000, BaseCost = 30, LevelCost = 5, MPowerBase = 40, PowerBase = 20, DelayBase = 18000, DelayReduction = 2000, Range = 9 });
  296. if (!MagicExists(Spell.EnergyShield)) MagicInfoList.Add(new MagicInfo { Name = "EnergyShield", Spell = Spell.EnergyShield, Icon = 57, Level1 = 48, Level2 = 51, Level3 = 54, Need1 = 5000, Need2 = 9000, Need3 = 13000, BaseCost = 50, LevelCost = 20, Range = 9 });
  297. if (!MagicExists(Spell.PetEnhancer)) MagicInfoList.Add(new MagicInfo { Name = "PetEnhancer", Spell = Spell.PetEnhancer, Icon = 78, Level1 = 45, Level2 = 48, Level3 = 51, Need1 = 4000, Need2 = 8000, Need3 = 12000, BaseCost = 30, LevelCost = 40, Range = 0 });
  298. if (!MagicExists(Spell.SpiritTigerAssault)) MagicInfoList.Add(new MagicInfo { Name = "SpiritTigerAssault", Spell = Spell.SpiritTigerAssault, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  299. if (!MagicExists(Spell.DoubleSoulFireBall)) MagicInfoList.Add(new MagicInfo { Name = "DoubleSoulFireBall", Spell = Spell.DoubleSoulFireBall, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  300. if (!MagicExists(Spell.SwordsOfLight)) MagicInfoList.Add(new MagicInfo { Name = "SwordsOfLight", Spell = Spell.SwordsOfLight, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  301. if (!MagicExists(Spell.SpiritualFistBurst)) MagicInfoList.Add(new MagicInfo { Name = "SpiritualFistBurst ", Spell = Spell.SpiritualFistBurst, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  302. if (!MagicExists(Spell.SpiritFire)) MagicInfoList.Add(new MagicInfo { Name = "SpiritFire", Spell = Spell.SpiritFire, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  303. if (!MagicExists(Spell.YinYangBurst)) MagicInfoList.Add(new MagicInfo { Name = "YinYangBurst", Spell = Spell.YinYangBurst, Icon = 12, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  304. if (!MagicExists(Spell.MassRevelation)) MagicInfoList.Add(new MagicInfo { Name = "MassRevelation", Spell = Spell.MassRevelation, Icon = 27, Level1 = 23, Level2 = 25, Level3 = 28, Need1 = 1500, Need2 = 2500, Need3 = 4000, BaseCost = 4, LevelCost = 4, Range = 9 });
  305.  
  306. //#Totem
  307. if (!MagicExists(Spell.SummonHolyTotem)) MagicInfoList.Add(new MagicInfo { Name = "SummonHolyTotem", Spell = Spell.SummonHolyTotem, Icon = 29, Level1 = 50, Level2 = 37, Level3 = 40, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 28, LevelCost = 4, Range = 0 });
  308. if (!MagicExists(Spell.SummonGuardianTotem)) MagicInfoList.Add(new MagicInfo { Name = "SummonGuardianTotem", Spell = Spell.SummonGuardianTotem, Icon = 29, Level1 = 50, Level2 = 37, Level3 = 40, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 28, LevelCost = 4, Range = 0 });
  309. if (!MagicExists(Spell.HealingCircle)) MagicInfoList.Add(new MagicInfo { Name = "HealingCircle", Spell = Spell.HealingCircle, Icon = 12, Level1 = 18, Level2 = 21, Level3 = 24, Need1 = 1300, Need2 = 2700, Need3 = 4000, BaseCost = 3, LevelCost = 1, MPowerBase = 8, PowerBase = 3, Range = 9 });
  310.  
  311. //Assassin
  312. if (!MagicExists(Spell.FatalSword)) MagicInfoList.Add(new MagicInfo { Name = "FatalSword", Spell = Spell.FatalSword, Icon = 58, Level1 = 7, Level2 = 9, Level3 = 12, Need1 = 500, Need2 = 1000, Need3 = 2300, Range = 0 });
  313. if (!MagicExists(Spell.DoubleSlash)) MagicInfoList.Add(new MagicInfo { Name = "DoubleSlash", Spell = Spell.DoubleSlash, Icon = 59, Level1 = 15, Level2 = 17, Level3 = 19, Need1 = 700, Need2 = 1500, Need3 = 2200, BaseCost = 2, LevelCost = 1 });
  314. if (!MagicExists(Spell.Haste)) MagicInfoList.Add(new MagicInfo { Name = "Haste", Spell = Spell.Haste, Icon = 60, Level1 = 20, Level2 = 22, Level3 = 25, Need1 = 2000, Need2 = 3000, Need3 = 6000, BaseCost = 3, LevelCost = 2, Range = 0 });
  315. if (!MagicExists(Spell.FlashDash)) MagicInfoList.Add(new MagicInfo { Name = "FlashDash", Spell = Spell.FlashDash, Icon = 61, Level1 = 25, Level2 = 27, Level3 = 30, Need1 = 4000, Need2 = 7000, Need3 = 9000, BaseCost = 12, LevelCost = 2, DelayBase = 200, Range = 0 });
  316. if (!MagicExists(Spell.LightBody)) MagicInfoList.Add(new MagicInfo { Name = "LightBody", Spell = Spell.LightBody, Icon = 68, Level1 = 27, Level2 = 29, Level3 = 32, Need1 = 5000, Need2 = 7000, Need3 = 10000, BaseCost = 11, LevelCost = 2, Range = 0 });
  317. if (!MagicExists(Spell.HeavenlySword)) MagicInfoList.Add(new MagicInfo { Name = "HeavenlySword", Spell = Spell.HeavenlySword, Icon = 62, Level1 = 30, Level2 = 32, Level3 = 35, Need1 = 4000, Need2 = 8000, Need3 = 10000, BaseCost = 13, LevelCost = 2, MPowerBase = 8, Range = 0 });
  318. if (!MagicExists(Spell.FireBurst)) MagicInfoList.Add(new MagicInfo { Name = "FireBurst", Spell = Spell.FireBurst, Icon = 63, Level1 = 33, Level2 = 35, Level3 = 38, Need1 = 4000, Need2 = 6000, Need3 = 8000, BaseCost = 10, LevelCost = 1, Range = 0 });
  319. if (!MagicExists(Spell.Trap)) MagicInfoList.Add(new MagicInfo { Name = "Trap", Spell = Spell.Trap, Icon = 64, Level1 = 33, Level2 = 35, Level3 = 38, Need1 = 2000, Need2 = 4000, Need3 = 6000, BaseCost = 14, LevelCost = 2, DelayBase = 60000, DelayReduction = 15000, Range = 9 });
  320. if (!MagicExists(Spell.PoisonSword)) MagicInfoList.Add(new MagicInfo { Name = "PoisonSword", Spell = Spell.PoisonSword, Icon = 69, Level1 = 34, Level2 = 36, Level3 = 39, Need1 = 5000, Need2 = 8000, Need3 = 11000, BaseCost = 14, LevelCost = 3, Range = 0 });
  321. if (!MagicExists(Spell.MoonLight)) MagicInfoList.Add(new MagicInfo { Name = "MoonLight", Spell = Spell.MoonLight, Icon = 65, Level1 = 36, Level2 = 39, Level3 = 42, Need1 = 3000, Need2 = 5000, Need3 = 8000, BaseCost = 36, LevelCost = 3, Range = 0 });
  322. if (!MagicExists(Spell.MPEater)) MagicInfoList.Add(new MagicInfo { Name = "MPEater", Spell = Spell.MPEater, Icon = 66, Level1 = 38, Level2 = 41, Level3 = 44, Need1 = 5000, Need2 = 8000, Need3 = 11000, Range = 0 });
  323. if (!MagicExists(Spell.SwiftFeet)) MagicInfoList.Add(new MagicInfo { Name = "SwiftFeet", Spell = Spell.SwiftFeet, Icon = 67, Level1 = 40, Level2 = 43, Level3 = 46, Need1 = 4000, Need2 = 6000, Need3 = 9000, BaseCost = 17, LevelCost = 5, DelayBase = 210000, DelayReduction = 40000, Range = 0 });
  324. if (!MagicExists(Spell.DarkBody)) MagicInfoList.Add(new MagicInfo { Name = "DarkBody", Spell = Spell.DarkBody, Icon = 70, Level1 = 46, Level2 = 49, Level3 = 52, Need1 = 6000, Need2 = 10000, Need3 = 14000, BaseCost = 40, LevelCost = 7, Range = 0 });
  325. if (!MagicExists(Spell.Hemorrhage)) MagicInfoList.Add(new MagicInfo { Name = "Hemorrhage", Spell = Spell.Hemorrhage, Icon = 75, Level1 = 47, Level2 = 51, Level3 = 55, Need1 = 9000, Need2 = 15000, Need3 = 21000, Range = 0 });
  326. if (!MagicExists(Spell.CrescentSlash)) MagicInfoList.Add(new MagicInfo { Name = "CrescentSlash", Spell = Spell.CrescentSlash, Icon = 71, Level1 = 50, Level2 = 53, Level3 = 56, Need1 = 12000, Need2 = 16000, Need3 = 24000, BaseCost = 19, LevelCost = 5, Range = 0 });
  327. //if (!MagicExists(Spell.MoonMist)) MagicInfoList.Add(new MagicInfo { Name = "MoonMist", Spell = Spell.ImmortalSkin, Icon = ?, Level1 = ?, Level2 = ?, Level3 = ?, Need1 = ?, Need2 = ?, Need3 = ?, BaseCost = ?, LevelCost = ?, DelayBase = ?, DelayReduction = ? });
  328. if (!MagicExists(Spell.FanOfKnives)) MagicInfoList.Add(new MagicInfo { Name = "FanOfKnives", Spell = Spell.FanOfKnives, Icon = 71, Level1 = 50, Level2 = 53, Level3 = 56, Need1 = 12000, Need2 = 16000, Need3 = 24000, BaseCost = 19, LevelCost = 5, Range = 0 });
  329. if (!MagicExists(Spell.Backstab)) MagicInfoList.Add(new MagicInfo { Name = "Backstab", Spell = Spell.Backstab, Icon = 6, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 500, Need2 = 1100, Need3 = 1800, BaseCost = 25, LevelCost = 15, Range = 0 });
  330.  
  331. //Archer
  332. if (!MagicExists(Spell.Focus)) MagicInfoList.Add(new MagicInfo { Name = "Focus", Spell = Spell.Focus, Icon = 88, Level1 = 7, Level2 = 13, Level3 = 17, Need1 = 270, Need2 = 600, Need3 = 1300, Range = 0 });
  333. if (!MagicExists(Spell.StraightShot)) MagicInfoList.Add(new MagicInfo { Name = "StraightShot", Spell = Spell.StraightShot, Icon = 89, Level1 = 9, Level2 = 12, Level3 = 16, Need1 = 350, Need2 = 750, Need3 = 1400, BaseCost = 3, LevelCost = 2, MPowerBase = 8, PowerBase = 3, Range = 9 });
  334. if (!MagicExists(Spell.DoubleShot)) MagicInfoList.Add(new MagicInfo { Name = "DoubleShot", Spell = Spell.DoubleShot, Icon = 90, Level1 = 14, Level2 = 18, Level3 = 21, Need1 = 700, Need2 = 1500, Need3 = 2100, BaseCost = 3, LevelCost = 2, MPowerBase = 6, PowerBase = 2, Range = 9 });
  335. if (!MagicExists(Spell.ExplosiveTrap)) MagicInfoList.Add(new MagicInfo { Name = "ExplosiveTrap", Spell = Spell.ExplosiveTrap, Icon = 91, Level1 = 22, Level2 = 25, Level3 = 30, Need1 = 2000, Need2 = 3500, Need3 = 5000, BaseCost = 10, LevelCost = 3, MPowerBase = 15, PowerBase = 15, Range = 0 });
  336. if (!MagicExists(Spell.DelayedExplosion)) MagicInfoList.Add(new MagicInfo { Name = "DelayedExplosion", Spell = Spell.DelayedExplosion, Icon = 92, Level1 = 31, Level2 = 34, Level3 = 39, Need1 = 3000, Need2 = 7000, Need3 = 10000, BaseCost = 8, LevelCost = 2, MPowerBase = 30, PowerBase = 15, Range = 9 });
  337. if (!MagicExists(Spell.Meditation)) MagicInfoList.Add(new MagicInfo { Name = "Meditation", Spell = Spell.Meditation, Icon = 93, Level1 = 19, Level2 = 24, Level3 = 29, Need1 = 1800, Need2 = 2600, Need3 = 5600, BaseCost = 8, LevelCost = 2, Range = 0 });
  338. if (!MagicExists(Spell.ElementalShot)) MagicInfoList.Add(new MagicInfo { Name = "ElementalShot", Spell = Spell.ElementalShot, Icon = 94, Level1 = 20, Level2 = 25, Level3 = 31, Need1 = 1800, Need2 = 2700, Need3 = 6000, BaseCost = 8, LevelCost = 2, MPowerBase = 6, PowerBase = 3, Range = 9 });
  339. if (!MagicExists(Spell.Concentration)) MagicInfoList.Add(new MagicInfo { Name = "Concentration", Spell = Spell.Concentration, Icon = 96, Level1 = 23, Level2 = 27, Level3 = 32, Need1 = 2100, Need2 = 3800, Need3 = 6500, BaseCost = 8, LevelCost = 2, Range = 0 });
  340. if (!MagicExists(Spell.ElementalBarrier)) MagicInfoList.Add(new MagicInfo { Name = "ElementalBarrier", Spell = Spell.ElementalBarrier, Icon = 98, Level1 = 33, Level2 = 38, Level3 = 44, Need1 = 3000, Need2 = 7000, Need3 = 10000, BaseCost = 10, LevelCost = 2, MPowerBase = 15, PowerBase = 5, Range = 0 });
  341. if (!MagicExists(Spell.BackStep)) MagicInfoList.Add(new MagicInfo { Name = "BackStep", Spell = Spell.BackStep, Icon = 95, Level1 = 30, Level2 = 34, Level3 = 38, Need1 = 2400, Need2 = 3000, Need3 = 6000, BaseCost = 12, LevelCost = 2, DelayBase = 2500, Range = 0 });
  342. if (!MagicExists(Spell.BindingShot)) MagicInfoList.Add(new MagicInfo { Name = "BindingShot", Spell = Spell.BindingShot, Icon = 97, Level1 = 35, Level2 = 39, Level3 = 42, Need1 = 400, Need2 = 7000, Need3 = 9500, BaseCost = 7, LevelCost = 3, Range = 9 });
  343. if (!MagicExists(Spell.SummonVampire)) MagicInfoList.Add(new MagicInfo { Name = "SummonVampire", Spell = Spell.SummonVampire, Icon = 99, Level1 = 28, Level2 = 33, Level3 = 41, Need1 = 2000, Need2 = 2700, Need3 = 7500, BaseCost = 10, LevelCost = 5, Range = 9 });
  344. if (!MagicExists(Spell.VampireShot)) MagicInfoList.Add(new MagicInfo { Name = "VampireShot", Spell = Spell.VampireShot, Icon = 100, Level1 = 26, Level2 = 32, Level3 = 36, Need1 = 3000, Need2 = 6000, Need3 = 12000, BaseCost = 12, LevelCost = 3, MPowerBase = 10, PowerBase = 7, Range = 9 });
  345. if (!MagicExists(Spell.SummonToad)) MagicInfoList.Add(new MagicInfo { Name = "SummonToad", Spell = Spell.SummonToad, Icon = 101, Level1 = 37, Level2 = 43, Level3 = 47, Need1 = 5800, Need2 = 10000, Need3 = 13000, BaseCost = 10, LevelCost = 5, Range = 9 });
  346. if (!MagicExists(Spell.PoisonShot)) MagicInfoList.Add(new MagicInfo { Name = "PoisonShot", Spell = Spell.PoisonShot, Icon = 102, Level1 = 40, Level2 = 45, Level3 = 49, Need1 = 6000, Need2 = 14000, Need3 = 16000, BaseCost = 10, LevelCost = 4, MPowerBase = 10, PowerBase = 10, Range = 9 });
  347. if (!MagicExists(Spell.CrippleShot)) MagicInfoList.Add(new MagicInfo { Name = "CrippleShot", Spell = Spell.CrippleShot, Icon = 103, Level1 = 43, Level2 = 47, Level3 = 50, Need1 = 12000, Need2 = 15000, Need3 = 18000, BaseCost = 15, LevelCost = 3, MPowerBase = 10, MPowerBonus = 20, PowerBase = 10, Range = 9 });
  348. if (!MagicExists(Spell.SummonSnakes)) MagicInfoList.Add(new MagicInfo { Name = "SummonSnakes", Spell = Spell.SummonSnakes, Icon = 104, Level1 = 46, Level2 = 51, Level3 = 54, Need1 = 14000, Need2 = 17000, Need3 = 20000, BaseCost = 10, LevelCost = 5, Range = 9 });
  349. if (!MagicExists(Spell.NapalmShot)) MagicInfoList.Add(new MagicInfo { Name = "NapalmShot", Spell = Spell.NapalmShot, Icon = 105, Level1 = 48, Level2 = 52, Level3 = 55, Need1 = 15000, Need2 = 18000, Need3 = 21000, BaseCost = 40, LevelCost = 10, MPowerBase = 25, MPowerBonus = 25, PowerBase = 25, Range = 9 });
  350. if (!MagicExists(Spell.OneWithNature)) MagicInfoList.Add(new MagicInfo { Name = "OneWithNature", Spell = Spell.OneWithNature, Icon = 106, Level1 = 50, Level2 = 53, Level3 = 56, Need1 = 17000, Need2 = 19000, Need3 = 24000, BaseCost = 80, LevelCost = 15, MPowerBase = 75, MPowerBonus = 35, PowerBase = 30, PowerBonus = 20, Range = 0 });
  351. if (!MagicExists(Spell.MentalState)) MagicInfoList.Add(new MagicInfo { Name = "MentalState", Spell = Spell.MentalState, Icon = 81, Level1 = 11, Level2 = 15, Level3 = 22, Need1 = 500, Need2 = 900, Need3 = 1800, BaseCost = 1, LevelCost = 1, Range = 0 });
  352. if (!MagicExists(Spell.CursedArrow)) MagicInfoList.Add(new MagicInfo { Name = "CursedArrow", Spell = Spell.CursedArrow, Icon = 38, Level1 = 48, Level2 = 55, Level3 = 60, Need1 = 3000, Need2 = 5000, Need3 = 8000, BaseCost = 15, LevelCost = 3, MPowerBase = 12, PowerBase = 12, Range = 9 });
  353. if (!MagicExists(Spell.Frenzy)) MagicInfoList.Add(new MagicInfo { Name = "Frenzy", Spell = Spell.Frenzy, Icon = 50, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 6000, Need2 = 12000, Need3 = 18000, BaseCost = 23, LevelCost = 6, Range = 0 });
  354. if (!MagicExists(Spell.ElectricEye)) MagicInfoList.Add(new MagicInfo { Name = "ElectricEye", Spell = Spell.ElectricEye, Icon = 50, Level1 = 140, Level2 = 145, Level3 = 150, Need1 = 6000, Need2 = 12000, Need3 = 18000, BaseCost = 23, LevelCost = 6, Range = 0 });
  355.  
  356. //Custom
  357. if (!MagicExists(Spell.Portal)) MagicInfoList.Add(new MagicInfo { Name = "Portal", Spell = Spell.Portal, Icon = 1, Level1 = 7, Level2 = 11, Level3 = 14, Need1 = 150, Need2 = 350, Need3 = 700, BaseCost = 3, LevelCost = 2, Range = 9 });
  358. }
  359.  
  360. private string CanStartEnvir()
  361. {
  362. if (Settings.EnforceDBChecks)
  363. {
  364. if (StartPoints.Count == 0) return "Cannot start server without start points";
  365.  
  366. if (GetMonsterInfo(Settings.SkeletonName, true) == null) return "Cannot start server without mob: " + Settings.SkeletonName;
  367. if (GetMonsterInfo(Settings.ShinsuName, true) == null) return "Cannot start server without mob: " + Settings.ShinsuName;
  368. if (GetMonsterInfo(Settings.BugBatName, true) == null) return "Cannot start server without mob: " + Settings.BugBatName;
  369. if (GetMonsterInfo(Settings.SnowWolf1, true) == null) return "Cannot start server without mob: " + Settings.SnowWolf1;
  370. if (GetMonsterInfo(Settings.SnowWolf2, true) == null) return "Cannot start server without mob: " + Settings.SnowWolf2;
  371. if (GetMonsterInfo(Settings.SnowWolf3, true) == null) return "Cannot start server without mob: " + Settings.SnowWolf3;
  372. if (GetMonsterInfo(Settings.SnowWolf4, true) == null) return "Cannot start server without mob: " + Settings.SnowWolf4;
  373. if (GetMonsterInfo(Settings.OrcMob1, true) == null) return "Cannot start server without mob: " + Settings.OrcMob1;
  374. if (GetMonsterInfo(Settings.OrcMob2, true) == null) return "Cannot start server without mob: " + Settings.OrcMob2;
  375. if (GetMonsterInfo(Settings.OrcMob3, true) == null) return "Cannot start server without mob: " + Settings.OrcMob3;
  376. if (GetMonsterInfo(Settings.OrcMob4, true) == null) return "Cannot start server without mob: " + Settings.OrcMob4;
  377. if (GetMonsterInfo(Settings.Zuma1, true) == null) return "Cannot start server without mob: " + Settings.Zuma1;
  378. if (GetMonsterInfo(Settings.Zuma2, true) == null) return "Cannot start server without mob: " + Settings.Zuma2;
  379. if (GetMonsterInfo(Settings.Zuma3, true) == null) return "Cannot start server without mob: " + Settings.Zuma3;
  380. if (GetMonsterInfo(Settings.Zuma4, true) == null) return "Cannot start server without mob: " + Settings.Zuma4;
  381. if (GetMonsterInfo(Settings.Zuma5, true) == null) return "Cannot start server without mob: " + Settings.Zuma5;
  382. if (GetMonsterInfo(Settings.Zuma6, true) == null) return "Cannot start server without mob: " + Settings.Zuma6;
  383. if (GetMonsterInfo(Settings.Zuma7, true) == null) return "Cannot start server without mob: " + Settings.Zuma7;
  384. if (GetMonsterInfo(Settings.Turtle1, true) == null) return "Cannot start server without mob: " + Settings.Turtle1;
  385. if (GetMonsterInfo(Settings.Turtle2, true) == null) return "Cannot start server without mob: " + Settings.Turtle2;
  386. if (GetMonsterInfo(Settings.Turtle3, true) == null) return "Cannot start server without mob: " + Settings.Turtle3;
  387. if (GetMonsterInfo(Settings.Turtle4, true) == null) return "Cannot start server without mob: " + Settings.Turtle4;
  388. if (GetMonsterInfo(Settings.Turtle5, true) == null) return "Cannot start server without mob: " + Settings.Turtle5;
  389. if (GetMonsterInfo(Settings.BoneMonster1, true) == null) return "Cannot start server without mob: " + Settings.BoneMonster1;
  390. if (GetMonsterInfo(Settings.BoneMonster2, true) == null) return "Cannot start server without mob: " + Settings.BoneMonster2;
  391. if (GetMonsterInfo(Settings.BoneMonster3, true) == null) return "Cannot start server without mob: " + Settings.BoneMonster3;
  392. if (GetMonsterInfo(Settings.BoneMonster4, true) == null) return "Cannot start server without mob: " + Settings.BoneMonster4;
  393. if (GetMonsterInfo(Settings.WhiteSnake, true) == null) return "Cannot start server without mob: " + Settings.WhiteSnake;
  394. if (GetMonsterInfo(Settings.AngelName, true) == null) return "Cannot start server without mob: " + Settings.AngelName;
  395. if (GetMonsterInfo(Settings.BombSpiderName, true) == null) return "Cannot start server without mob: " + Settings.BombSpiderName;
  396. if (GetMonsterInfo(Settings.CloneName, true) == null) return "Cannot start server without mob: " + Settings.CloneName;
  397. if (GetMonsterInfo(Settings.AssassinCloneName, true) == null) return "Cannot start server without mob: " + Settings.AssassinCloneName;
  398. if (GetMonsterInfo(Settings.VampireName, true) == null) return "Cannot start server without mob: " + Settings.VampireName;
  399. if (GetMonsterInfo(Settings.ToadName, true) == null) return "Cannot start server without mob: " + Settings.ToadName;
  400. if (GetMonsterInfo(Settings.SnakeTotemName, true) == null) return "Cannot start server without mob: " + Settings.SnakeTotemName;
  401. if (GetMonsterInfo(Settings.FishingMonster, true) == null) return "Cannot start server without mob: " + Settings.FishingMonster;
  402. if (GetMonsterInfo(Settings.HolyTotemName, true) == null) return "Cannot start server without mob: " + Settings.HolyTotemName;
  403. if (GetMonsterInfo(Settings.GuardianTotemName, true) == null) return "Cannot start server without mob: " + Settings.GuardianTotemName;
  404.  
  405. if (GetItemInfo(Settings.RefineOreName) == null) return "Cannot start server without item: " + Settings.RefineOreName;
  406. }
  407.  
  408. //add intelligent creature checks?
  409.  
  410. return "true";
  411. }
  412.  
  413. private void WorkLoop()
  414. {
  415. try
  416. {
  417. #region Start up
  418. Time = Stopwatch.ElapsedMilliseconds;
  419.  
  420. long conTime = Time;
  421. long saveTime = Time + Settings.SaveDelay * Settings.Minute;
  422. long userTime = Time + Settings.Minute * 5;
  423. long SpawnTime = Time;
  424. long processTime = Time + 1000;
  425. long StartTime = Time;
  426.  
  427. int processCount = 0;
  428. int processRealCount = 0;
  429.  
  430. LinkedListNode<MapObject> current = null;
  431.  
  432. if (Settings.Multithreaded)
  433. {
  434. for (int j = 0; j < MobThreads.Length; j++)
  435. {
  436. MobThreads[j] = new MobThread();
  437. MobThreads[j].Id = j;
  438. }
  439. }
  440.  
  441. StartEnvir();
  442. string canstartserver = CanStartEnvir();
  443. if (canstartserver != "true")
  444. {
  445. SMain.Enqueue(canstartserver);
  446. StopEnvir();
  447. _thread = null;
  448. Stop();
  449. return;
  450. }
  451.  
  452. if (Settings.Multithreaded)
  453. {
  454. for (int j = 0; j < MobThreads.Length; j++)
  455. {
  456. MobThread Info = MobThreads[j];
  457. if (j > 0) //dont start up 0
  458. {
  459. MobThreading[j] = new Thread(() => ThreadLoop(Info));
  460. MobThreading[j].IsBackground = true;
  461. MobThreading[j].Start();
  462. }
  463. }
  464. }
  465.  
  466. StartNetwork();
  467. #endregion
  468.  
  469. try
  470. {
  471.  
  472. while (Running)
  473. {
  474. #region Timing
  475.  
  476. Time = Stopwatch.ElapsedMilliseconds;
  477.  
  478. if (Time >= processTime)
  479. {
  480. LastCount = processCount;
  481. LastRealCount = processRealCount;
  482. processCount = 0;
  483. processRealCount = 0;
  484. processTime = Time + 1000;
  485. }
  486.  
  487. #endregion
  488.  
  489. #region Connection
  490. if (conTime != Time)
  491. {
  492. conTime = Time;
  493.  
  494. AdjustLights();
  495.  
  496.  
  497. lock (Connections)
  498. {
  499. MirConnection currentConnection = null;
  500. try
  501. {
  502. for (int i = Connections.Count - 1; i >= 0; i--)
  503. {
  504. currentConnection = Connections[i];
  505. currentConnection.Process(); //line 581
  506. }
  507. }
  508. catch (Exception ex)
  509. {
  510. //currentConnection Should never be Null unless someone made a **** up by adding a null to ConnectionList
  511. string crashMessage = string.Format("IPAddress: {0} crashed the server and was disconnected| Account: {1}| Character: {2}|Exception:{3}| StackTrace:{4}| InnerException:{5} | Source:{6}",
  512. currentConnection.IPAddress,
  513. currentConnection.Account == null ? "<No Account>" : currentConnection.Account.AccountID,
  514. currentConnection.Player == null || currentConnection.Player.Info == null ? "<No Character>" : currentConnection.Player.Name
  515. , ex.Message, ex.StackTrace, ex.InnerException, ex.Source);
  516.  
  517. SMain.Enqueue(crashMessage);
  518.  
  519. currentConnection.SendDisconnect(2);
  520.  
  521.  
  522.  
  523. }
  524. }
  525.  
  526. lock (StatusConnections)
  527. {
  528. for (int i = StatusConnections.Count - 1; i >= 0; i--)
  529. {
  530. StatusConnections[i].Process();
  531. }
  532. }
  533. }
  534.  
  535. #endregion
  536.  
  537. #region Processing
  538.  
  539. if (current == null)
  540. current = Objects.First;
  541.  
  542. if (current == Objects.First)
  543. {
  544. LastRunTime = Time - StartTime;
  545. StartTime = Time;
  546. }
  547.  
  548. if (Settings.Multithreaded)
  549. {
  550. for (int j = 1; j < MobThreads.Length; j++)
  551. {
  552. MobThread Info = MobThreads[j];
  553.  
  554. if (Info.Stop == true)
  555. {
  556. Info.EndTime = Time + 10;
  557. Info.Stop = false;
  558. }
  559. }
  560. lock (_locker)
  561. {
  562. Monitor.PulseAll(_locker); // changing a blocking condition. (this makes the threads wake up!)
  563. }
  564. //run the first loop in the main thread so the main thread automaticaly 'halts' untill the other threads are finished
  565. ThreadLoop(MobThreads[0]);
  566. }
  567.  
  568. Boolean TheEnd = false;
  569. long Start = Stopwatch.ElapsedMilliseconds;
  570. while ((!TheEnd) && (Stopwatch.ElapsedMilliseconds - Start < 20))
  571. {
  572. if (current == null)
  573. {
  574. TheEnd = true;
  575. break;
  576. }
  577. else
  578. {
  579. LinkedListNode<MapObject> next = current.Next;
  580. if (!Settings.Multithreaded || ((current.Value.Race != ObjectType.Monster) || (current.Value.Master != null)))
  581. {
  582. if (Time > current.Value.OperateTime)
  583. {
  584. current.Value.Process();
  585. current.Value.SetOperateTime();
  586. }
  587. processCount++;
  588. }
  589. current = next;
  590. }
  591. }
  592.  
  593. for (int i = 0; i < MapList.Count; i++)
  594. MapList[i].Process();
  595.  
  596.  
  597. if (DragonSystem != null) DragonSystem.Process();
  598.  
  599. Process();
  600. try
  601. {
  602. InstancesManager.Process();
  603.  
  604. }
  605. catch (Exception e)
  606. {
  607. SMain.Enqueue(e);
  608. }
  609.  
  610. if (Time >= saveTime)
  611. {
  612. saveTime = Time + Settings.SaveDelay * Settings.Minute;
  613. BeginSaveAccounts();
  614. SaveGuilds();
  615. SaveGoods();
  616. SaveConquests();
  617. }
  618.  
  619. if (Time >= userTime)
  620. {
  621. userTime = Time + Settings.Minute * 5;
  622. Broadcast(new S.Chat
  623. {
  624. Message = string.Format("Online Players: {0}", Math.Round(PlayerCount * 1.25F)),
  625. Type = ChatType.Hint
  626. });
  627. }
  628.  
  629. if (Time >= SpawnTime)
  630. {
  631. SpawnTime = Time + (Settings.Second * 10);//technicaly this limits the respawn tick code to a minimum of 10 second each but lets assume it's not meant to be this accurate
  632. SMain.Envir.RespawnTick.Process();
  633. }
  634.  
  635. // if (Players.Count == 0) Thread.Sleep(1);
  636. // GC.Collect();
  637.  
  638. #endregion
  639. }
  640. }
  641. catch (Exception ex)
  642. {
  643. SMain.Enqueue(ex);
  644.  
  645. // Get stack trace for the exception with source file information
  646. var st = new StackTrace(ex, true);
  647. // Get the top stack frame
  648. var frame = st.GetFrame(0);
  649. // Get the line number from the stack frame
  650. var line = frame.GetFileLineNumber();
  651.  
  652. File.AppendAllText(@".\Error.txt",
  653. string.Format("[Force close error - {0}] {1} at line {2}{3}", Now, ex, line, Environment.NewLine));
  654.  
  655. lock (Connections)
  656. {
  657. for (int i = Connections.Count - 1; i >= 0; i--)
  658. Connections[i].SendDisconnect(3);
  659. }
  660. }
  661.  
  662. StopNetwork();
  663. StopEnvir();
  664. SaveAccounts();
  665. SaveGuilds(true);
  666. SaveConquests(true);
  667. // SaveParagonInfo();
  668. }
  669. catch (Exception ex)
  670. {
  671. // Get stack trace for the exception with source file information
  672. var st = new StackTrace(ex, true);
  673. // Get the top stack frame
  674. var frame = st.GetFrame(0);
  675. // Get the line number from the stack frame
  676. var line = frame.GetFileLineNumber();
  677.  
  678. SMain.Enqueue("[outer workloop error]" + ex);
  679. File.AppendAllText(@".\Error.txt",
  680. string.Format("[{0}] {1} at line {2}{3}", Now, ex, line, Environment.NewLine));
  681. }
  682. _thread = null;
  683.  
  684. }
  685.  
  686. private void ThreadLoop(MobThread Info)
  687. {
  688. Info.Stop = false;
  689. long starttime = Time;
  690. try
  691. {
  692.  
  693. bool stopping = false;
  694. if (Info.current == null)
  695. Info.current = Info.ObjectsList.First;
  696. stopping = Info.current == null;
  697. //while (stopping == false)
  698. while (Running)
  699. {
  700. if (Info.current == null)
  701. Info.current = Info.ObjectsList.First;
  702. else
  703. {
  704. LinkedListNode<MapObject> next = Info.current.Next;
  705.  
  706. //if we reach the end of our list > go back to the top (since we are running threaded, we dont want the system to sit there for xxms doing nothing)
  707. if (Info.current == Info.ObjectsList.Last)
  708. {
  709. next = Info.ObjectsList.First;
  710. Info.LastRunTime = (Info.LastRunTime + (Time - Info.StartTime)) / 2;
  711. //Info.LastRunTime = (Time - Info.StartTime) /*> 0 ? (Time - Info.StartTime) : Info.LastRunTime */;
  712. Info.StartTime = Time;
  713. }
  714. if (Time > Info.current.Value.OperateTime)
  715. {
  716. if (Info.current.Value.Master == null)//since we are running multithreaded, dont allow pets to be processed (unless you constantly move pets into their map appropriate thead)
  717. {
  718. var playerProcess = Info.current.Value as PlayerObject;
  719.  
  720. if (playerProcess != null && (playerProcess.Connection == null || playerProcess.Info == null))
  721. {
  722. SMain.EnqueueDebugging(string.Format("Tried to process player that isn't set."));
  723. Info.current.Value.Despawn();
  724. }
  725. else
  726. Info.current.Value.Process();
  727.  
  728. Info.current.Value.SetOperateTime();
  729. }
  730. }
  731. Info.current = next;
  732.  
  733. /* if (Time > Info.current.Value.OperateTime)
  734. {
  735. if (Info.current.Value.Master == null)//since we are running multithreaded, dont allow pets to be processed (unless you constantly move pets into their map appropriate thead)
  736. {
  737. Info.current.Value.Process();
  738.  
  739. Info.current.Value.SetOperateTime();
  740. }
  741. }
  742. Info.current = next;*/
  743. }
  744. //if it's the main thread > make it loop till the subthreads are done, else make it stop after 'endtime'
  745. if (Info.Id == 0)
  746. {
  747. stopping = true;
  748. for (int x = 1; x < MobThreads.Length; x++)
  749. if (MobThreads[x].Stop == false)
  750. stopping = false;
  751. if (stopping)
  752. {
  753. Info.Stop = stopping;
  754. return;
  755. }
  756. }
  757. else
  758. {
  759. if ((Stopwatch.ElapsedMilliseconds > Info.EndTime) && Running)
  760. {
  761. Info.Stop = true;
  762. lock (_locker)
  763. {
  764. while (Info.Stop) Monitor.Wait(_locker);
  765. }
  766. }
  767.  
  768. }
  769. }
  770. }
  771. catch (Exception ex)
  772. {
  773. if (ex is ThreadInterruptedException) return;
  774. SMain.Enqueue(ex);
  775.  
  776. File.AppendAllText(@".\Error.txt",
  777. string.Format("[{0}] {1}{2}", Now, ex, Environment.NewLine));
  778. }
  779. //Info.Stop = true;
  780. }
  781.  
  782. private void AdjustLights()
  783. {
  784. LightSetting oldLights = Lights;
  785.  
  786. int hours = (Now.Hour * 2) % 24;
  787. if (hours == 6 || hours == 7)
  788. Lights = LightSetting.Dawn;
  789. else if (hours >= 8 && hours <= 15)
  790. Lights = LightSetting.Day;
  791. else if (hours == 16 || hours == 17)
  792. Lights = LightSetting.Evening;
  793. else
  794. Lights = LightSetting.Night;
  795.  
  796. if (oldLights == Lights) return;
  797.  
  798. Broadcast(new S.TimeOfDay { Lights = Lights });
  799. }
  800.  
  801. public void Process()
  802. {
  803. if (Time >= robotTime)
  804. {
  805. robotTime = Time + Settings.Minute;
  806. ProcessRobot();
  807.  
  808. }
  809. //#Rework [Needs revamping poor performance code]
  810. if (Time >= craftime)
  811. {
  812. craftime = Time + Settings.Minute;
  813. var players = Players.Where(h => h.CraftingItem != null).ToList();
  814. for (int i = 0; i < players.Count; i++) players[i].ProcessCraft();
  815.  
  816. }
  817.  
  818. if (Time >= dayTime)
  819. {
  820. dayTime = Time + Settings.Day;
  821. ProcessNewDay();
  822. }
  823.  
  824. if (Time >= warTime)
  825. {
  826. for (int i = GuildsAtWar.Count - 1; i >= 0; i--)
  827. {
  828. GuildsAtWar[i].TimeRemaining -= Settings.Minute;
  829.  
  830. if (GuildsAtWar[i].TimeRemaining < 0)
  831. {
  832. GuildsAtWar[i].EndWar();
  833. GuildsAtWar.RemoveAt(i);
  834. }
  835. }
  836.  
  837. warTime = Time + Settings.Minute;
  838. }
  839.  
  840. if (Time >= mailTime)
  841. {
  842. for (int i = Mail.Count - 1; i >= 0; i--)
  843. {
  844. MailInfo mail = Mail[i];
  845.  
  846. if (mail.Receive())
  847. {
  848. //collected mail ok
  849. }
  850. }
  851.  
  852. mailTime = Time + (Settings.Minute * 1);
  853. }
  854.  
  855. if (Time >= guildTime)
  856. {
  857. guildTime = Time + (Settings.Minute);
  858. for (int i = 0; i < GuildList.Count; i++)
  859. {
  860. GuildList[i].Process();
  861. }
  862. }
  863.  
  864. if (Time >= conquestTime)
  865. {
  866. conquestTime = Time + (Settings.Second * 10);
  867. for (int i = 0; i < Conquests.Count; i++)
  868. Conquests[i].Process();
  869. }
  870. if (Time >= grpLootTime)
  871. {
  872. grpLootTime = Time + (Settings.Second * 3);
  873. GroupLootManager.ProcessGroupLoot();
  874. }
  875. if (Time >= ProcessCurrencyCapTime)
  876. {
  877. ProcessCurrencyCapTime = Time + (Settings.Hour);
  878. ProcessCurrencyCap();
  879. }
  880. }
  881. public void ProcessCurrencyCap()
  882. {
  883. var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
  884. int weekYear = cal.GetWeekOfYear(DateTime.Now, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Friday);
  885. if (weekYear != CurrentWeekOfTheYear)
  886. {
  887. CleanCharactersCurrencyWeeklyValue();
  888. CurrentWeekOfTheYear = weekYear;
  889. SaveDBFlag = true;
  890. }
  891. }
  892. public void CleanCharactersCurrencyWeeklyValue()
  893. {
  894. SMain.Enqueue(string.Format("{0}: Removing Players Currency Cap", DateTime.Now));
  895. foreach (var charInfo in CharacterList)
  896. {
  897. charInfo.ConquestPointsWeeklyValue = 0;
  898. charInfo.HonorPointsWeeklyValue = 0;
  899. charInfo.JusticePointsWeeklyValue = 0;
  900. charInfo.ValorPointsWeeklyValue = 0;
  901.  
  902. }
  903. }
  904. public void LoadRobot()
  905. {
  906. RobotCommandList.Clear();
  907.  
  908. string path = Path.Combine(Settings.EnvirPath, "Robot" + ".txt");
  909.  
  910. if (!File.Exists(path))
  911. {
  912. FileStream newfile = File.Create(path);
  913. newfile.Close();
  914. }
  915.  
  916. string[] lines = File.ReadAllLines(path);
  917.  
  918. for (int i = 0; i < lines.Length; i++)
  919. {
  920. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  921.  
  922. RobotInfo RobotCommand = RobotInfo.FromLine(lines[i]);
  923.  
  924. if (RobotCommand == null)
  925. {
  926. SMain.Enqueue(string.Format("Could not load Robot Line: {0}", lines[i]));
  927. continue;
  928. }
  929.  
  930. RobotCommandList.Add(RobotCommand);
  931.  
  932. }
  933.  
  934.  
  935.  
  936. }
  937. public void ProcessRobot()
  938. {
  939. foreach (RobotInfo R in RobotCommandList)
  940. {
  941.  
  942. if (R._Day != (byte)Now.DayOfWeek && R._Day != -1) continue;
  943. if (R._Hour != Now.Hour && R._Hour != -1) continue;
  944. if (R._Min != Now.Minute && R._Min != -1) continue;
  945.  
  946. SMain.Enqueue(string.Format("Script: {0} - Day : {1} - Hour : {2} - Min : {3}", R.Command, R._Day, R._Hour, R._Min));
  947.  
  948.  
  949. CallRobotCommand(R.Command);
  950.  
  951. }
  952. }
  953. private void CallRobotCommand(string command)
  954. {
  955. char[] delimiters = new[] { ',', '(', ')' }; // Get Params
  956. var parts = command.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
  957. // Packet p;
  958. Map map;
  959. System.Drawing.Point P;
  960. string[] read;
  961.  
  962. int i;
  963. string fileName;
  964.  
  965. if (!parts.Any()) return;
  966. if (parts[0] == "") return;
  967.  
  968. var randomNPC = this.MapList.First(h => h.Info.FileName.ToLower() == "r001").NPCs.First().NPCPages.First().SegmentList.First();
  969.  
  970.  
  971. switch (parts[0])
  972. {
  973. case "LEVEL":
  974. if (parts.Length < 3 && randomNPC != null) return;
  975. randomNPC.CheckList.Add(new NPCChecks(CheckType.Level, parts[1], parts[2]));
  976. break;
  977.  
  978. #region RecallNameList
  979. case "RecallRandomList":
  980. if (parts.Length < 3) return;
  981.  
  982. fileName = Path.Combine(Settings.NameListPath, parts[1] + ".txt");
  983. if (!File.Exists(fileName)) return;
  984.  
  985. read = File.ReadAllLines(fileName);
  986.  
  987. map = SMain.Envir.GetMapByNameAndInstance(parts[2], Convert.ToInt32(parts[3]));
  988.  
  989. if (map == null) return;
  990.  
  991.  
  992. foreach (var v in read)
  993. {
  994. PlayerObject ob = GetPlayer(v);
  995. if (ob == null) continue;
  996.  
  997. ob.TeleportRandom(200, 0, map);
  998.  
  999. }
  1000.  
  1001. break;
  1002.  
  1003. case "RecallNameList":
  1004. if (parts.Length < 5) return;
  1005.  
  1006. fileName = Path.Combine(Settings.NameListPath, parts[1] + ".txt");
  1007. if (!File.Exists(fileName)) return;
  1008.  
  1009. read = File.ReadAllLines(fileName);
  1010.  
  1011. map = SMain.Envir.GetMapByNameAndInstance(parts[2], Convert.ToInt32(parts[3]));
  1012.  
  1013. if (map == null) return;
  1014.  
  1015. P = new Point(Convert.ToInt32(parts[4]), Convert.ToInt32(parts[5]));
  1016.  
  1017. if (P == null) return;
  1018.  
  1019. foreach (var v in read)
  1020. {
  1021. PlayerObject ob = GetPlayer(v);
  1022. if (ob == null) continue;
  1023.  
  1024. ob.Teleport(map, P);
  1025.  
  1026. }
  1027. break;
  1028. #endregion
  1029. #region ClearNameList
  1030.  
  1031.  
  1032. case "ClearNameList":
  1033. if (parts.Length < 2) return;
  1034.  
  1035. fileName = Path.Combine(Settings.NameListPath, parts[1] + ".txt");
  1036. if (File.Exists(fileName))
  1037. File.WriteAllLines(fileName, new string[] { });
  1038. break;
  1039. #endregion
  1040. #region Announcement
  1041.  
  1042. case "Announcement":
  1043. if (parts.Length < 3) return;
  1044.  
  1045. byte tempChatType;
  1046.  
  1047. tempChatType = Convert.ToByte(parts[2]);
  1048.  
  1049. if (!Enum.IsDefined(typeof(ChatType), tempChatType)) return;
  1050.  
  1051.  
  1052.  
  1053. for (i = 0; i < Players.Count; i++)
  1054. Players[i].ReceiveChat(parts[1], (ChatType)tempChatType);
  1055.  
  1056. break;
  1057. #endregion
  1058. #region Spawn
  1059. case "Spawn":
  1060. int count = 0;
  1061. byte MobLevel = 0;
  1062. if (parts.Length < 7) return;
  1063.  
  1064. P = new Point(Convert.ToInt32(parts[3]), Convert.ToInt32(parts[4]));
  1065. if (P == null)
  1066. return;
  1067.  
  1068. map = SMain.Envir.GetMapByNameAndInstance(parts[2]);
  1069. if (map == null)
  1070. return;
  1071.  
  1072. MonsterInfo mInfo = GetMonsterInfo(parts[1]);
  1073. if (mInfo == null)
  1074. return;
  1075.  
  1076. if (parts.Length > 7)
  1077. if (!byte.TryParse(parts[7], out MobLevel) || MobLevel > 10) MobLevel = 0;
  1078.  
  1079. if (parts[6] == "true")
  1080. {
  1081. foreach (MapObject M in Objects)
  1082. {
  1083. if (M.CurrentMap != map || M.Race != ObjectType.Monster || M.Dead) continue;
  1084. if (!mInfo.Name.Contains(M.Name)) continue;
  1085.  
  1086. count++;
  1087. }
  1088.  
  1089. if (count >= Convert.ToInt32(parts[5])) return;
  1090. }
  1091.  
  1092. for (i = 0; i < (Convert.ToInt32(parts[5]) - count); i++)
  1093. {
  1094. MonsterObject monster = MonsterObject.GetMonster(mInfo);
  1095. if (monster == null) return;
  1096. monster.MobLevel = MobLevel;
  1097. monster.MaxMobLevel = 10;
  1098. monster.Spawn(map, P);
  1099. }
  1100.  
  1101. break;
  1102. #endregion
  1103. #region MapFlag
  1104. case "MapFlag":
  1105. if (parts.Length < 5) return;
  1106. map = SMain.Envir.GetMapByNameAndInstance(parts[1], Convert.ToInt32(parts[2]));
  1107. if (map == null)
  1108. return;
  1109. switch (parts[3])
  1110. {
  1111. case "NoFight":
  1112. if (parts[4] == "true")
  1113. map.Info.NoFight = true;
  1114. else
  1115. map.Info.NoFight = false;
  1116. break;
  1117.  
  1118. case "Fight":
  1119. if (parts[4] == "true")
  1120. map.Info.Fight = true;
  1121. else
  1122. map.Info.Fight = false;
  1123. break;
  1124.  
  1125. case "NoDropMonster":
  1126. if (parts[4] == "true")
  1127. map.Info.NoDropMonster = true;
  1128. else
  1129. map.Info.NoDropMonster = false;
  1130. break;
  1131.  
  1132. case "NoDropPlayer":
  1133. if (parts[4] == "true")
  1134. map.Info.NoDropPlayer = true;
  1135. else
  1136. map.Info.NoDropPlayer = false;
  1137. break;
  1138.  
  1139. case "NoRecall":
  1140. if (parts[4] == "true")
  1141. map.Info.NoRecall = true;
  1142. else
  1143. map.Info.NoRecall = false;
  1144. break;
  1145.  
  1146. case "NoDrug":
  1147. if (parts[4] == "true")
  1148. map.Info.NoDrug = true;
  1149. else
  1150. map.Info.NoDrug = false;
  1151. break;
  1152. }
  1153. break;
  1154. #endregion
  1155.  
  1156. }
  1157. }
  1158.  
  1159. public void Broadcast(Packet p)
  1160. {
  1161. for (int i = 0; i < Players.Count; i++) Players[i].Enqueue(p);
  1162. }
  1163.  
  1164. public void RequiresBaseStatUpdate()
  1165. {
  1166. for (int i = 0; i < Players.Count; i++) Players[i].HasUpdatedBaseStats = false;
  1167. }
  1168.  
  1169. public void SaveDB()
  1170. {
  1171. using (FileStream stream = File.Create(DatabasePath))
  1172. using (BinaryWriter writer = new BinaryWriter(stream))
  1173. {
  1174. writer.Write(Version);
  1175. writer.Write(CustomVersion);
  1176. writer.Write(MapIndex);
  1177. writer.Write(ItemIndex);
  1178. writer.Write(MonsterIndex);
  1179. writer.Write(NPCIndex);
  1180. writer.Write(QuestIndex);
  1181. writer.Write(GameshopIndex);
  1182. writer.Write(ConquestIndex);
  1183. writer.Write(RespawnIndex);
  1184. writer.Write(MobLevelSpawn);
  1185.  
  1186. writer.Write(MapInfoList.Count);
  1187. for (int i = 0; i < MapInfoList.Count; i++)
  1188. MapInfoList[i].Save(writer);
  1189.  
  1190. writer.Write(ItemInfoList.Count);
  1191. for (int i = 0; i < ItemInfoList.Count; i++)
  1192. ItemInfoList[i].Save(writer);
  1193.  
  1194. writer.Write(MonsterInfoList.Count);
  1195. for (int i = 0; i < MonsterInfoList.Count; i++)
  1196. MonsterInfoList[i].Save(writer);
  1197.  
  1198. writer.Write(NPCInfoList.Count);
  1199. for (int i = 0; i < NPCInfoList.Count; i++)
  1200. NPCInfoList[i].Save(writer);
  1201.  
  1202. writer.Write(QuestInfoList.Count);
  1203. for (int i = 0; i < QuestInfoList.Count; i++)
  1204. QuestInfoList[i].Save(writer);
  1205.  
  1206. DragonInfo.Save(writer);
  1207. writer.Write(MagicInfoList.Count);
  1208. for (int i = 0; i < MagicInfoList.Count; i++)
  1209. MagicInfoList[i].Save(writer);
  1210.  
  1211. writer.Write(GameShopList.Count);
  1212. for (int i = 0; i < GameShopList.Count; i++)
  1213. GameShopList[i].Save(writer);
  1214.  
  1215. writer.Write(ConquestInfos.Count);
  1216. for (int i = 0; i < ConquestInfos.Count; i++)
  1217. ConquestInfos[i].Save(writer);
  1218.  
  1219.  
  1220. RespawnTick.Save(writer);
  1221.  
  1222. writer.Write(MapInstanceInfoList.Count);
  1223. for (int i = 0; i < MapInstanceInfoList.Count; i++)
  1224. MapInstanceInfoList[i].Save(writer);
  1225.  
  1226. writer.Write(MapInstanceIndex);
  1227.  
  1228. writer.Write(CurrentWeekOfTheYear);
  1229.  
  1230.  
  1231. }
  1232. }
  1233. public void SaveAccounts()
  1234. {
  1235. while (Saving)
  1236. Thread.Sleep(1);
  1237.  
  1238. try
  1239. {
  1240. using (FileStream stream = File.Create(AccountPath + "n"))
  1241. SaveAccounts(stream);
  1242. if (File.Exists(AccountPath))
  1243. File.Move(AccountPath, AccountPath + "o");
  1244. File.Move(AccountPath + "n", AccountPath);
  1245. if (File.Exists(AccountPath + "o"))
  1246. File.Delete(AccountPath + "o");
  1247.  
  1248. }
  1249. catch (Exception ex)
  1250. {
  1251. SMain.Enqueue(ex);
  1252. }
  1253. }
  1254. public void SaveParagonInfo()
  1255. {
  1256. if (!Directory.Exists(Settings.ParagonInfoPath)) Directory.CreateDirectory(Settings.ParagonInfoPath);
  1257. for (int i = 0; i < ParagonInfoList.Count; i++)
  1258. {
  1259. MemoryStream mStream = new MemoryStream();
  1260. BinaryWriter writer = new BinaryWriter(mStream);
  1261. ParagonInfoList[i].Save(writer);
  1262.  
  1263. FileStream fStream = new FileStream(Settings.ParagonInfoPath + i.ToString() + ".mgdn", FileMode.Create);
  1264. byte[] data = mStream.ToArray();
  1265. fStream.BeginWrite(data, 0, data.Length, EndSaveGuildsAsync, fStream);
  1266. }
  1267. //using (FileStream stream = File.Create(ParagonInfo))
  1268. //using (BinaryWriter writer = new BinaryWriter(stream))
  1269. //{
  1270. // writer.Write(ParagonInfoList.Count);
  1271. // for (int i = 0; i < ParagonInfoList.Count; i++)
  1272. // ParagonInfoList[i].Save(writer);
  1273. //}
  1274. }
  1275. public void SavePlayerRecipes()
  1276. {
  1277. if (!Directory.Exists(Settings.RecipesInfoPath)) Directory.CreateDirectory(Settings.RecipesInfoPath);
  1278.  
  1279. for (int i = 0; i < CharacterList.Count; i++)
  1280. {
  1281. var character = CharacterList[i];
  1282.  
  1283. MemoryStream mStream = new MemoryStream();
  1284. BinaryWriter writer = new BinaryWriter(mStream);
  1285.  
  1286. writer.Write(character.Recipes.Count);
  1287. for (int j = 0; j < character.Recipes.Count; j++)
  1288. {
  1289. var recipe = character.Recipes[j];
  1290. recipe.Save(writer);
  1291. }
  1292.  
  1293. FileStream fStream = new FileStream(Settings.RecipesInfoPath + character.Name + ".mgdn", FileMode.Create);
  1294. byte[] data = mStream.ToArray();
  1295. fStream.BeginWrite(data, 0, data.Length, EndSaveGuildsAsync, fStream);
  1296. }
  1297.  
  1298. }
  1299.  
  1300.  
  1301.  
  1302. private void SaveAccounts(Stream stream)
  1303. {
  1304. using (BinaryWriter writer = new BinaryWriter(stream))
  1305. {
  1306. writer.Write(Version);
  1307. writer.Write(CustomVersion);
  1308. writer.Write(NextAccountID);
  1309. writer.Write(NextCharacterID);
  1310. writer.Write(NextUserItemID);
  1311. writer.Write(GuildList.Count);
  1312. writer.Write(NextGuildID);
  1313. writer.Write(AccountList.Count);
  1314.  
  1315. for (int i = 0; i < AccountList.Count; i++)
  1316. AccountList[i].Save(writer);
  1317.  
  1318. writer.Write(NextAuctionID);
  1319. writer.Write(Auctions.Count);
  1320. foreach (AuctionInfo auction in Auctions)
  1321. auction.Save(writer);
  1322.  
  1323. writer.Write(NextMailID);
  1324. writer.Write(Mail.Count);
  1325. foreach (MailInfo mail in Mail)
  1326. mail.Save(writer);
  1327.  
  1328. writer.Write(GameshopLog.Count);
  1329. foreach (var item in GameshopLog)
  1330. {
  1331. writer.Write(item.Key);
  1332. writer.Write(item.Value);
  1333. }
  1334.  
  1335. writer.Write(SavedSpawns.Count);
  1336. foreach (MapRespawn Spawn in SavedSpawns)
  1337. {
  1338. RespawnSave Save = new RespawnSave { RespawnIndex = Spawn.Info.RespawnIndex, NextSpawnTick = Spawn.NextSpawnTick, Spawned = (Spawn.Count >= (Spawn.Info.Count * spawnmultiplyer)) };
  1339. Save.save(writer);
  1340. }
  1341.  
  1342. writer.Write(ParagonInfoList.Count);
  1343. }
  1344. }
  1345.  
  1346. private void SaveGuilds(bool forced = false)
  1347. {
  1348. if (!Directory.Exists(Settings.GuildPath)) Directory.CreateDirectory(Settings.GuildPath);
  1349. for (int i = 0; i < GuildList.Count; i++)
  1350. {
  1351. if (GuildList[i].NeedSave || forced)
  1352. {
  1353. GuildList[i].NeedSave = false;
  1354. MemoryStream mStream = new MemoryStream();
  1355. BinaryWriter writer = new BinaryWriter(mStream);
  1356. GuildList[i].Save(writer);
  1357. FileStream fStream = new FileStream(Settings.GuildPath + i.ToString() + ".mgdn", FileMode.Create);
  1358. byte[] data = mStream.ToArray();
  1359. fStream.BeginWrite(data, 0, data.Length, EndSaveGuildsAsync, fStream);
  1360. }
  1361. }
  1362. }
  1363. private void EndSaveGuildsAsync(IAsyncResult result)
  1364. {
  1365. FileStream fStream = result.AsyncState as FileStream;
  1366. try
  1367. {
  1368. if (fStream != null)
  1369. {
  1370. string oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  1371. string newfilename = fStream.Name;
  1372. fStream.EndWrite(result);
  1373. fStream.Dispose();
  1374. if (File.Exists(oldfilename))
  1375. File.Move(oldfilename, oldfilename + "o");
  1376. File.Move(newfilename, oldfilename);
  1377. if (File.Exists(oldfilename + "o"))
  1378. File.Delete(oldfilename + "o");
  1379. }
  1380. }
  1381. catch (Exception e)
  1382. {
  1383. SMain.Enqueue(e);
  1384. }
  1385. }
  1386.  
  1387. private void SaveGoods(bool forced = false)
  1388. {
  1389. if (!Directory.Exists(Settings.GoodsPath)) Directory.CreateDirectory(Settings.GoodsPath);
  1390.  
  1391. for (int i = 0; i < MapList.Count; i++)
  1392. {
  1393. Map map = MapList[i];
  1394.  
  1395. if (map.NPCs.Count < 1) continue;
  1396.  
  1397. for (int j = 0; j < map.NPCs.Count; j++)
  1398. {
  1399. NPCObject npc = map.NPCs[j];
  1400.  
  1401. if (forced)
  1402. {
  1403. npc.ProcessGoods(forced);
  1404. }
  1405.  
  1406. if (!npc.NeedSave) continue;
  1407.  
  1408. string path = Settings.GoodsPath + npc.Info.Index.ToString() + ".msdn";
  1409.  
  1410. MemoryStream mStream = new MemoryStream();
  1411. BinaryWriter writer = new BinaryWriter(mStream);
  1412. int Temp = 9999;
  1413. writer.Write(Temp);
  1414. writer.Write(Version);
  1415. writer.Write(CustomVersion);
  1416. writer.Write(npc.UsedGoods.Count);
  1417.  
  1418. for (int k = 0; k < npc.UsedGoods.Count; k++)
  1419. {
  1420. npc.UsedGoods[k].Save(writer);
  1421. }
  1422.  
  1423. FileStream fStream = new FileStream(path, FileMode.Create);
  1424. byte[] data = mStream.ToArray();
  1425. fStream.BeginWrite(data, 0, data.Length, EndSaveGoodsAsync, fStream);
  1426. }
  1427. }
  1428. }
  1429. private void EndSaveGoodsAsync(IAsyncResult result)
  1430. {
  1431. try
  1432. {
  1433. FileStream fStream = result.AsyncState as FileStream;
  1434. if (fStream != null)
  1435. {
  1436. string oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  1437. string newfilename = fStream.Name;
  1438. fStream.EndWrite(result);
  1439. fStream.Dispose();
  1440. if (File.Exists(oldfilename))
  1441. File.Move(oldfilename, oldfilename + "o");
  1442. File.Move(newfilename, oldfilename);
  1443. if (File.Exists(oldfilename + "o"))
  1444. File.Delete(oldfilename + "o");
  1445. }
  1446. }
  1447. catch (Exception e)
  1448. {
  1449. SMain.Enqueue(e);
  1450.  
  1451. }
  1452.  
  1453. }
  1454.  
  1455. private void SaveConquests(bool forced = false)
  1456. {
  1457. if (!Directory.Exists(Settings.ConquestsPath)) Directory.CreateDirectory(Settings.ConquestsPath);
  1458. for (int i = 0; i < Conquests.Count; i++)
  1459. {
  1460. if (Conquests[i].NeedSave || forced)
  1461. {
  1462. Conquests[i].NeedSave = false;
  1463. MemoryStream mStream = new MemoryStream();
  1464. BinaryWriter writer = new BinaryWriter(mStream);
  1465. Conquests[i].Save(writer);
  1466. FileStream fStream = new FileStream(Settings.ConquestsPath + Conquests[i].Info.Index.ToString() + ".mcdn", FileMode.Create);
  1467. byte[] data = mStream.ToArray();
  1468. fStream.BeginWrite(data, 0, data.Length, EndSaveConquestsAsync, fStream);
  1469. }
  1470. }
  1471. }
  1472. private void EndSaveConquestsAsync(IAsyncResult result)
  1473. {
  1474. FileStream fStream = result.AsyncState as FileStream;
  1475. try
  1476. {
  1477. if (fStream != null)
  1478. {
  1479. string oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  1480. string newfilename = fStream.Name;
  1481. fStream.EndWrite(result);
  1482. fStream.Dispose();
  1483. if (File.Exists(oldfilename))
  1484. File.Move(oldfilename, oldfilename + "o");
  1485. File.Move(newfilename, oldfilename);
  1486. if (File.Exists(oldfilename + "o"))
  1487. File.Delete(oldfilename + "o");
  1488. }
  1489. }
  1490. catch (Exception e)
  1491. {
  1492. SMain.Enqueue(e);
  1493. }
  1494. }
  1495.  
  1496. public void BeginSaveAccounts()
  1497. {
  1498. if (Saving) return;
  1499.  
  1500. Saving = true;
  1501.  
  1502.  
  1503. using (MemoryStream mStream = new MemoryStream())
  1504. {
  1505. if (File.Exists(AccountPath))
  1506. {
  1507. if (!Directory.Exists(BackUpPath)) Directory.CreateDirectory(BackUpPath);
  1508. string fileName = string.Format("Accounts {0:0000}-{1:00}-{2:00} {3:00}-{4:00}-{5:00}.bak", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, Now.Second);
  1509. if (File.Exists(Path.Combine(BackUpPath, fileName))) File.Delete(Path.Combine(BackUpPath, fileName));
  1510. File.Move(AccountPath, Path.Combine(BackUpPath, fileName));
  1511. }
  1512.  
  1513. SaveAccounts(mStream);
  1514. FileStream fStream = new FileStream(AccountPath + "n", FileMode.Create);
  1515.  
  1516. byte[] data = mStream.ToArray();
  1517. fStream.BeginWrite(data, 0, data.Length, EndSaveAccounts, fStream);
  1518. }
  1519.  
  1520. }
  1521. private void EndSaveAccounts(IAsyncResult result)
  1522. {
  1523. FileStream fStream = result.AsyncState as FileStream;
  1524. try
  1525. {
  1526. if (fStream != null)
  1527. {
  1528. string oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  1529. string newfilename = fStream.Name;
  1530. fStream.EndWrite(result);
  1531. fStream.Dispose();
  1532. if (File.Exists(oldfilename))
  1533. File.Move(oldfilename, oldfilename + "o");
  1534. File.Move(newfilename, oldfilename);
  1535. if (File.Exists(oldfilename + "o"))
  1536. File.Delete(oldfilename + "o");
  1537. }
  1538. }
  1539. catch (Exception e)
  1540. {
  1541. SMain.Enqueue(e);
  1542.  
  1543. }
  1544.  
  1545. Saving = false;
  1546. }
  1547. public void ClearUsersItems()
  1548. {
  1549. using (FileStream stream = File.OpenRead(DatabasePath))
  1550. using (BinaryReader reader = new BinaryReader(stream))
  1551. {
  1552. LoadVersion = reader.ReadInt32();
  1553. if (LoadVersion > 57)
  1554. LoadCustomVersion = reader.ReadInt32();
  1555. MapIndex = reader.ReadInt32();
  1556. ItemIndex = reader.ReadInt32();
  1557. MonsterIndex = reader.ReadInt32();
  1558.  
  1559. if (LoadVersion > 33)
  1560. {
  1561. NPCIndex = reader.ReadInt32();
  1562. QuestIndex = reader.ReadInt32();
  1563. }
  1564. if (LoadVersion >= 63)
  1565. {
  1566. GameshopIndex = reader.ReadInt32();
  1567. }
  1568.  
  1569. if (LoadVersion >= 66)
  1570. {
  1571. ConquestIndex = reader.ReadInt32();
  1572. }
  1573.  
  1574. if (LoadVersion >= 68)
  1575. RespawnIndex = reader.ReadInt32();
  1576.  
  1577. if (LoadVersion >= 75)
  1578. MobLevelSpawn = reader.ReadInt32();
  1579.  
  1580.  
  1581. int count = 0;
  1582. count = reader.ReadInt32();
  1583. ItemInfoList.Clear();
  1584. for (int i = 0; i < count; i++)
  1585. {
  1586. ItemInfoList.Add(new ItemInfo(reader, LoadVersion, LoadCustomVersion));
  1587. if ((ItemInfoList[i] != null) && (ItemInfoList[i].RandomStatsId < Settings.RandomItemStatsList.Count))
  1588. {
  1589. ItemInfoList[i].RandomStats = Settings.RandomItemStatsList[ItemInfoList[i].RandomStatsId];
  1590. }
  1591. }
  1592.  
  1593. if (LoadVersion >= 80)
  1594. MapIndex = reader.ReadInt32();
  1595.  
  1596. }
  1597.  
  1598. }
  1599. public void LoadDB()
  1600. {
  1601. lock (LoadLock)
  1602. {
  1603. if (!File.Exists(DatabasePath))
  1604. SaveDB();
  1605.  
  1606. using (FileStream stream = File.OpenRead(DatabasePath))
  1607. using (BinaryReader reader = new BinaryReader(stream))
  1608. {
  1609. LoadVersion = reader.ReadInt32();
  1610. if (LoadVersion > 57)
  1611. LoadCustomVersion = reader.ReadInt32();
  1612. MapIndex = reader.ReadInt32();
  1613. ItemIndex = reader.ReadInt32();
  1614. MonsterIndex = reader.ReadInt32();
  1615.  
  1616. if (LoadVersion > 33)
  1617. {
  1618. NPCIndex = reader.ReadInt32();
  1619. QuestIndex = reader.ReadInt32();
  1620. }
  1621. if (LoadVersion >= 63)
  1622. {
  1623. GameshopIndex = reader.ReadInt32();
  1624. }
  1625.  
  1626. if (LoadVersion >= 66)
  1627. {
  1628. ConquestIndex = reader.ReadInt32();
  1629. }
  1630.  
  1631. if (LoadVersion >= 68)
  1632. RespawnIndex = reader.ReadInt32();
  1633.  
  1634. if (LoadVersion >= 75)
  1635. MobLevelSpawn = reader.ReadInt32();
  1636.  
  1637.  
  1638. int count = reader.ReadInt32();
  1639. MapInfoList.Clear();
  1640. for (int i = 0; i < count; i++)
  1641. MapInfoList.Add(new MapInfo(reader));
  1642.  
  1643. count = reader.ReadInt32();
  1644. ItemInfoList.Clear();
  1645. for (int i = 0; i < count; i++)
  1646. {
  1647. ItemInfoList.Add(new ItemInfo(reader, LoadVersion, LoadCustomVersion));
  1648. if ((ItemInfoList[i] != null) && (ItemInfoList[i].RandomStatsId < Settings.RandomItemStatsList.Count))
  1649. {
  1650. ItemInfoList[i].RandomStats = Settings.RandomItemStatsList[ItemInfoList[i].RandomStatsId];
  1651. }
  1652. }
  1653. count = reader.ReadInt32();
  1654. MonsterInfoList.Clear();
  1655. for (int i = 0; i < count; i++)
  1656. MonsterInfoList.Add(new MonsterInfo(reader));
  1657.  
  1658. if (LoadVersion > 33)
  1659. {
  1660. count = reader.ReadInt32();
  1661. NPCInfoList.Clear();
  1662. for (int i = 0; i < count; i++)
  1663. NPCInfoList.Add(new NPCInfo(reader));
  1664.  
  1665. count = reader.ReadInt32();
  1666. QuestInfoList.Clear();
  1667. for (int i = 0; i < count; i++)
  1668. QuestInfoList.Add(new QuestInfo(reader));
  1669. }
  1670.  
  1671. if (LoadVersion >= 11) DragonInfo = new DragonInfo(reader);
  1672. else DragonInfo = new DragonInfo();
  1673. if (LoadVersion >= 58)
  1674. {
  1675. count = reader.ReadInt32();
  1676. for (int i = 0; i < count; i++)
  1677. MagicInfoList.Add(new MagicInfo(reader, LoadVersion, LoadCustomVersion));
  1678. }
  1679. FillMagicInfoList();
  1680.  
  1681. if (LoadVersion >= 63)
  1682. {
  1683. count = reader.ReadInt32();
  1684. GameShopList.Clear();
  1685. for (int i = 0; i < count; i++)
  1686. {
  1687. GameShopItem item = new GameShopItem(reader, LoadVersion, LoadCustomVersion);
  1688. if (SMain.Envir.BindGameShop(item))
  1689. {
  1690. GameShopList.Add(item);
  1691. }
  1692. }
  1693. }
  1694.  
  1695. if (LoadVersion >= 66)
  1696. {
  1697. ConquestInfos.Clear();
  1698. count = reader.ReadInt32();
  1699. for (int i = 0; i < count; i++)
  1700. {
  1701. ConquestInfos.Add(new ConquestInfo(reader));
  1702. }
  1703. }
  1704.  
  1705. if (LoadVersion > 67)
  1706. RespawnTick = new RespawnTimer(reader);
  1707.  
  1708. if (LoadCustomVersion > 81)
  1709. {
  1710. int mapInstanceInfoCount = reader.ReadInt32();
  1711. MapInstanceInfoList.Clear();
  1712. for (int i = 0; i < mapInstanceInfoCount; i++)
  1713. MapInstanceInfoList.Add(new MapInstanceInfo(reader));
  1714.  
  1715. MapInstanceIndex = reader.ReadInt32();
  1716.  
  1717. }
  1718.  
  1719. if (LoadCustomVersion > 93)
  1720. CurrentWeekOfTheYear = reader.ReadInt32();
  1721. }
  1722.  
  1723. Settings.LinkGuildCreationItems(ItemInfoList);
  1724. }
  1725.  
  1726. }
  1727. public void LoadParagonInfo()
  1728. {
  1729. lock (LoadLock)
  1730. {
  1731. int count = 0;
  1732.  
  1733. ParagonInfoList.Clear();
  1734.  
  1735. for (int i = 0; i < ParagonInfoCount; i++)
  1736. {
  1737. ParagonInfo info;
  1738. if (File.Exists(Settings.ParagonInfoPath + i.ToString() + ".mgd"))
  1739. {
  1740. using (FileStream stream = File.OpenRead(Settings.ParagonInfoPath + i.ToString() + ".mgd"))
  1741. using (BinaryReader reader = new BinaryReader(stream))
  1742. info = new ParagonInfo(reader);
  1743.  
  1744. //if (!newGuild.Ranks.Any(a => (byte)a.Options == 255)) continue;
  1745. //if (GuildList.Any(e => e.Name == newGuild.Name)) continue;
  1746. ParagonInfoList.Add(info);
  1747.  
  1748. count++;
  1749. }
  1750. }
  1751.  
  1752. if (count != ParagonInfoCount) ParagonInfoCount = count;
  1753.  
  1754.  
  1755. }
  1756. }
  1757. public void LoadPlayerRecipes()
  1758. {
  1759. for (int i = 0; i < CharacterList.Count; i++)
  1760. {
  1761. var character = CharacterList[i];
  1762. if (!File.Exists(Settings.RecipesInfoPath + character.Name + ".mgd"))
  1763. continue;
  1764.  
  1765. using (FileStream stream = File.OpenRead(Settings.RecipesInfoPath + character.Name + ".mgd"))
  1766. using (BinaryReader reader = new BinaryReader(stream))
  1767. {
  1768. int count = reader.ReadInt32();
  1769. for (int j = 0; j < count; j++)
  1770. {
  1771. var recipe = new RecipeInfo(reader);
  1772. character.Recipes.Add(recipe);
  1773. }
  1774. }
  1775.  
  1776.  
  1777. }
  1778. }
  1779. public void LoadAccounts()
  1780. {
  1781. //reset ranking
  1782. for (int i = 0; i < RankClass20.Count(); i++)
  1783. {
  1784. if (RankClass20[i] != null)
  1785. RankClass20[i].Clear();
  1786. else
  1787. RankClass20[i] = new List<Rank_Character_Info>();
  1788. }
  1789. RankTop20.Clear();
  1790. for (int i = 0; i < RankBottomLevel.Count(); i++)
  1791. {
  1792. RankBottomLevel[i] = 0;
  1793. }
  1794.  
  1795.  
  1796. lock (LoadLock)
  1797. {
  1798. if (!File.Exists(AccountPath))
  1799. SaveAccounts();
  1800.  
  1801. using (FileStream stream = File.OpenRead(AccountPath))
  1802. using (BinaryReader reader = new BinaryReader(stream))
  1803. {
  1804. LoadVersion = reader.ReadInt32();
  1805. if (LoadVersion > 57) LoadCustomVersion = reader.ReadInt32();
  1806. NextAccountID = reader.ReadInt32();
  1807. NextCharacterID = reader.ReadInt32();
  1808. NextUserItemID = reader.ReadUInt64();
  1809.  
  1810. if (LoadVersion > 27)
  1811. {
  1812. GuildCount = reader.ReadInt32();
  1813. NextGuildID = reader.ReadInt32();
  1814. }
  1815.  
  1816. int count = reader.ReadInt32();
  1817. AccountList.Clear();
  1818. CharacterList.Clear();
  1819. for (int i = 0; i < count; i++)
  1820. {
  1821. AccountList.Add(new AccountInfo(reader));
  1822. CharacterList.AddRange(AccountList[i].Characters);
  1823. }
  1824.  
  1825. if (LoadVersion < 7) return;
  1826.  
  1827. foreach (AuctionInfo auction in Auctions)
  1828. auction.CharacterInfo.AccountInfo.Auctions.Remove(auction);
  1829. Auctions.Clear();
  1830.  
  1831. if (LoadVersion >= 8)
  1832. NextAuctionID = reader.ReadUInt64();
  1833.  
  1834. count = reader.ReadInt32();
  1835. for (int i = 0; i < count; i++)
  1836. {
  1837. AuctionInfo auction = new AuctionInfo(reader, LoadVersion, LoadCustomVersion);
  1838.  
  1839. if (!BindItem(auction.Item) || !BindCharacter(auction)) continue;
  1840.  
  1841. Auctions.AddLast(auction);
  1842. auction.CharacterInfo.AccountInfo.Auctions.AddLast(auction);
  1843. }
  1844.  
  1845. if (LoadVersion == 7)
  1846. {
  1847. foreach (AuctionInfo auction in Auctions)
  1848. {
  1849. if (auction.Sold && auction.Expired) auction.Expired = false;
  1850.  
  1851. auction.AuctionID = ++NextAuctionID;
  1852. }
  1853. }
  1854.  
  1855. if (LoadVersion > 43)
  1856. {
  1857. NextMailID = reader.ReadUInt64();
  1858.  
  1859. Mail.Clear();
  1860.  
  1861. count = reader.ReadInt32();
  1862. for (int i = 0; i < count; i++)
  1863. {
  1864. Mail.Add(new MailInfo(reader, LoadVersion, LoadCustomVersion));
  1865. }
  1866. }
  1867.  
  1868. if (LoadVersion >= 63)
  1869. {
  1870. int logCount = reader.ReadInt32();
  1871. for (int i = 0; i < logCount; i++)
  1872. {
  1873. GameshopLog.Add(reader.ReadInt32(), reader.ReadInt32());
  1874. }
  1875.  
  1876. if (ResetGS) ClearGameshopLog();
  1877. }
  1878.  
  1879. if (LoadVersion >= 68)
  1880. {
  1881. int SaveCount = reader.ReadInt32();
  1882. for (int i = 0; i < SaveCount; i++)
  1883. {
  1884. RespawnSave Saved = new RespawnSave(reader);
  1885. foreach (MapRespawn Respawn in SavedSpawns)
  1886. {
  1887. if (Respawn.Info.RespawnIndex == Saved.RespawnIndex)
  1888. {
  1889. Respawn.NextSpawnTick = Saved.NextSpawnTick;
  1890. if ((Saved.Spawned) && ((Respawn.Info.Count * spawnmultiplyer) > Respawn.Count))
  1891. {
  1892. int mobcount = (Respawn.Info.Count * spawnmultiplyer) - Respawn.Count;
  1893. for (int j = 0; j < mobcount; j++)
  1894. {
  1895. Respawn.Spawn();
  1896. }
  1897. }
  1898. }
  1899. }
  1900.  
  1901. }
  1902. }
  1903.  
  1904. if (LoadCustomVersion >= 89)
  1905. {
  1906. ParagonInfoCount = reader.ReadInt32();
  1907. }
  1908.  
  1909. }
  1910. }
  1911. }
  1912.  
  1913. public void LoadGuilds()
  1914. {
  1915. lock (LoadLock)
  1916. {
  1917. int count = 0;
  1918.  
  1919. GuildList.Clear();
  1920.  
  1921. for (int i = 0; i < GuildCount; i++)
  1922. {
  1923. GuildObject newGuild;
  1924. if (File.Exists(Settings.GuildPath + i.ToString() + ".mgd"))
  1925. {
  1926. using (FileStream stream = File.OpenRead(Settings.GuildPath + i.ToString() + ".mgd"))
  1927. using (BinaryReader reader = new BinaryReader(stream))
  1928. newGuild = new GuildObject(reader);
  1929.  
  1930. //if (!newGuild.Ranks.Any(a => (byte)a.Options == 255)) continue;
  1931. //if (GuildList.Any(e => e.Name == newGuild.Name)) continue;
  1932. GuildList.Add(newGuild);
  1933.  
  1934. count++;
  1935. }
  1936. }
  1937.  
  1938. if (count != GuildCount) GuildCount = count;
  1939.  
  1940.  
  1941. }
  1942. }
  1943.  
  1944. public void LoadFishingDrops()
  1945. {
  1946. FishingDrops.Clear();
  1947.  
  1948. for (byte i = 0; i <= 19; i++)
  1949. {
  1950. string path = Path.Combine(Settings.DropPath, Settings.FishingDropFilename + ".txt");
  1951.  
  1952. path = path.Replace("00", i.ToString("D2"));
  1953.  
  1954. if (!File.Exists(path) && i < 2)
  1955. {
  1956. FileStream newfile = File.Create(path);
  1957. newfile.Close();
  1958. }
  1959.  
  1960. if (!File.Exists(path)) continue;
  1961.  
  1962. string[] lines = File.ReadAllLines(path);
  1963.  
  1964. for (int j = 0; j < lines.Length; j++)
  1965. {
  1966. if (lines[j].StartsWith(";") || string.IsNullOrWhiteSpace(lines[j])) continue;
  1967.  
  1968. DropInfo drop = DropInfo.FromLine(lines[j]);
  1969. if (drop == null)
  1970. {
  1971. SMain.Enqueue(string.Format("Could not load fishing drop: {0}", lines[j]));
  1972. continue;
  1973. }
  1974.  
  1975. drop.Type = i;
  1976.  
  1977. FishingDrops.Add(drop);
  1978. }
  1979.  
  1980. FishingDrops.Sort((drop1, drop2) =>
  1981. {
  1982. if (drop1.Chance > 0 && drop2.Chance == 0)
  1983. return 1;
  1984. if (drop1.Chance == 0 && drop2.Chance > 0)
  1985. return -1;
  1986.  
  1987. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  1988. });
  1989. }
  1990. }
  1991.  
  1992. public void LoadAwakeningMaterials()
  1993. {
  1994. AwakeningDrops.Clear();
  1995.  
  1996. string path = Path.Combine(Settings.DropPath, Settings.AwakeningDropFilename + ".txt");
  1997.  
  1998. if (!File.Exists(path))
  1999. {
  2000. FileStream newfile = File.Create(path);
  2001. newfile.Close();
  2002.  
  2003. }
  2004.  
  2005. string[] lines = File.ReadAllLines(path);
  2006.  
  2007. for (int i = 0; i < lines.Length; i++)
  2008. {
  2009. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2010.  
  2011. DropInfo drop = DropInfo.FromLine(lines[i]);
  2012. if (drop == null)
  2013. {
  2014. SMain.Enqueue(string.Format("Could not load Awakening drop: {0}", lines[i]));
  2015. continue;
  2016. }
  2017.  
  2018. AwakeningDrops.Add(drop);
  2019. }
  2020.  
  2021. AwakeningDrops.Sort((drop1, drop2) =>
  2022. {
  2023. if (drop1.Chance > 0 && drop2.Chance == 0)
  2024. return 1;
  2025. if (drop1.Chance == 0 && drop2.Chance > 0)
  2026. return -1;
  2027.  
  2028. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2029. });
  2030. }
  2031.  
  2032. public void LoadStrongBoxDrops()
  2033. {
  2034. StrongboxDrops.Clear();
  2035.  
  2036. string path = Path.Combine(Settings.DropPath, Settings.StrongboxDropFilename + ".txt");
  2037.  
  2038. if (!File.Exists(path))
  2039. {
  2040. FileStream newfile = File.Create(path);
  2041. newfile.Close();
  2042. }
  2043.  
  2044. string[] lines = File.ReadAllLines(path);
  2045.  
  2046. for (int i = 0; i < lines.Length; i++)
  2047. {
  2048. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2049.  
  2050. DropInfo drop = DropInfo.FromLine(lines[i]);
  2051. if (drop == null)
  2052. {
  2053. SMain.Enqueue(string.Format("Could not load strongbox drop: {0}", lines[i]));
  2054. continue;
  2055. }
  2056.  
  2057. StrongboxDrops.Add(drop);
  2058. }
  2059.  
  2060. StrongboxDrops.Sort((drop1, drop2) =>
  2061. {
  2062. if (drop1.Chance > 0 && drop2.Chance == 0)
  2063. return 1;
  2064. if (drop1.Chance == 0 && drop2.Chance > 0)
  2065. return -1;
  2066.  
  2067. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2068. });
  2069. }
  2070.  
  2071. public void LoadBlackStoneDrops()
  2072. {
  2073. BlackstoneDrops.Clear();
  2074.  
  2075. string path = Path.Combine(Settings.DropPath, Settings.BlackstoneDropFilename + ".txt");
  2076.  
  2077. if (!File.Exists(path))
  2078. {
  2079. FileStream newfile = File.Create(path);
  2080. newfile.Close();
  2081.  
  2082. }
  2083.  
  2084. string[] lines = File.ReadAllLines(path);
  2085.  
  2086. for (int i = 0; i < lines.Length; i++)
  2087. {
  2088. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2089.  
  2090. DropInfo drop = DropInfo.FromLine(lines[i]);
  2091. if (drop == null)
  2092. {
  2093. SMain.Enqueue(string.Format("Could not load blackstone drop: {0}", lines[i]));
  2094. continue;
  2095. }
  2096.  
  2097. BlackstoneDrops.Add(drop);
  2098. }
  2099.  
  2100. BlackstoneDrops.Sort((drop1, drop2) =>
  2101. {
  2102. if (drop1.Chance > 0 && drop2.Chance == 0)
  2103. return 1;
  2104. if (drop1.Chance == 0 && drop2.Chance > 0)
  2105. return -1;
  2106.  
  2107. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2108. });
  2109. }
  2110.  
  2111. public void LoadNormalInstanceDrops()
  2112. {
  2113. NormalInstanceDrops.Clear();
  2114.  
  2115. string path = Path.Combine(Settings.DropPath, Settings.NormalInstanceDropFilename + ".txt");
  2116.  
  2117. if (!File.Exists(path))
  2118. {
  2119. FileStream newfile = File.Create(path);
  2120. newfile.Close();
  2121.  
  2122. }
  2123.  
  2124. string[] lines = File.ReadAllLines(path);
  2125.  
  2126. for (int i = 0; i < lines.Length; i++)
  2127. {
  2128. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2129.  
  2130. DropInfo drop = DropInfo.FromLine(lines[i]);
  2131. if (drop == null)
  2132. {
  2133. SMain.Enqueue(string.Format("Could not load NormalInstance drop: {0}", lines[i]));
  2134. continue;
  2135. }
  2136.  
  2137. NormalInstanceDrops.Add(drop);
  2138. }
  2139.  
  2140. NormalInstanceDrops.Sort((drop1, drop2) =>
  2141. {
  2142. if (drop1.Chance > 0 && drop2.Chance == 0)
  2143. return 1;
  2144. if (drop1.Chance == 0 && drop2.Chance > 0)
  2145. return -1;
  2146.  
  2147. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2148. });
  2149. }
  2150.  
  2151. public void LoadHeroicInstanceDrops()
  2152. {
  2153. HeroicInstanceDrops.Clear();
  2154.  
  2155. string path = Path.Combine(Settings.DropPath, Settings.HeroicInstanceDropFilename + ".txt");
  2156.  
  2157. if (!File.Exists(path))
  2158. {
  2159. FileStream newfile = File.Create(path);
  2160. newfile.Close();
  2161.  
  2162. }
  2163.  
  2164. string[] lines = File.ReadAllLines(path);
  2165.  
  2166. for (int i = 0; i < lines.Length; i++)
  2167. {
  2168. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2169.  
  2170. DropInfo drop = DropInfo.FromLine(lines[i]);
  2171. if (drop == null)
  2172. {
  2173. SMain.Enqueue(string.Format("Could not load HeroicInstance drop: {0}", lines[i]));
  2174. continue;
  2175. }
  2176.  
  2177. HeroicInstanceDrops.Add(drop);
  2178. }
  2179.  
  2180. HeroicInstanceDrops.Sort((drop1, drop2) =>
  2181. {
  2182. if (drop1.Chance > 0 && drop2.Chance == 0)
  2183. return 1;
  2184. if (drop1.Chance == 0 && drop2.Chance > 0)
  2185. return -1;
  2186.  
  2187. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2188. });
  2189. }
  2190.  
  2191. public void LoadInsaneInstanceDrops()
  2192. {
  2193. InsaneInstanceDrops.Clear();
  2194.  
  2195. string path = Path.Combine(Settings.DropPath, Settings.InsaneInstanceDropFilename + ".txt");
  2196.  
  2197. if (!File.Exists(path))
  2198. {
  2199. FileStream newfile = File.Create(path);
  2200. newfile.Close();
  2201.  
  2202. }
  2203.  
  2204. string[] lines = File.ReadAllLines(path);
  2205.  
  2206. for (int i = 0; i < lines.Length; i++)
  2207. {
  2208. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2209.  
  2210. DropInfo drop = DropInfo.FromLine(lines[i]);
  2211. if (drop == null)
  2212. {
  2213. SMain.Enqueue(string.Format("Could not load InsaneInstance drop: {0}", lines[i]));
  2214. continue;
  2215. }
  2216.  
  2217. InsaneInstanceDrops.Add(drop);
  2218. }
  2219.  
  2220. InsaneInstanceDrops.Sort((drop1, drop2) =>
  2221. {
  2222. if (drop1.Chance > 0 && drop2.Chance == 0)
  2223. return 1;
  2224. if (drop1.Chance == 0 && drop2.Chance > 0)
  2225. return -1;
  2226.  
  2227. return drop1.Item.Type.CompareTo(drop2.Item.Type);
  2228. });
  2229. }
  2230.  
  2231. public void LoadConquests()
  2232. {
  2233. lock (LoadLock)
  2234. {
  2235. int count = 0;
  2236.  
  2237. Conquests.Clear();
  2238.  
  2239. ConquestObject newConquest;
  2240. Map tempMap;
  2241. ConquestArcherObject tempArcher;
  2242. ConquestGateObject tempGate;
  2243. ConquestWallObject tempWall;
  2244. ConquestSiegeObject tempSiege;
  2245.  
  2246. for (int i = 0; i < ConquestInfos.Count; i++)
  2247. {
  2248. newConquest = null;
  2249. tempMap = GetMap(ConquestInfos[i].MapIndex);
  2250.  
  2251. if (tempMap == null) continue;
  2252.  
  2253. if (File.Exists(Settings.ConquestsPath + ConquestInfos[i].Index.ToString() + ".mcd"))
  2254. {
  2255. using (FileStream stream = File.OpenRead(Settings.ConquestsPath + ConquestInfos[i].Index.ToString() + ".mcd"))
  2256. using (BinaryReader reader = new BinaryReader(stream))
  2257. newConquest = new ConquestObject(reader) { Info = ConquestInfos[i], ConquestMap = tempMap };
  2258.  
  2259. for (int k = 0; k < GuildList.Count; k++)
  2260. {
  2261. if (newConquest.Owner == GuildList[k].Guildindex)
  2262. {
  2263. newConquest.Guild = GuildList[k];
  2264. GuildList[k].Conquest = newConquest;
  2265. }
  2266. }
  2267.  
  2268. Conquests.Add(newConquest);
  2269. tempMap.Conquest.Add(newConquest);
  2270. count++;
  2271. }
  2272. else
  2273. {
  2274. newConquest = new ConquestObject { Info = ConquestInfos[i], NeedSave = true, ConquestMap = tempMap };
  2275.  
  2276. Conquests.Add(newConquest);
  2277. tempMap.Conquest.Add(newConquest);
  2278. }
  2279.  
  2280. //Bind Info to Saved Archer objects or create new objects
  2281. for (int j = 0; j < ConquestInfos[i].ConquestGuards.Count; j++)
  2282. {
  2283. tempArcher = newConquest.ArcherList.FirstOrDefault(x => x.Index == ConquestInfos[i].ConquestGuards[j].Index);
  2284.  
  2285. if (tempArcher != null)
  2286. {
  2287. tempArcher.Info = ConquestInfos[i].ConquestGuards[j];
  2288. tempArcher.Conquest = newConquest;
  2289. }
  2290. else
  2291. {
  2292. newConquest.ArcherList.Add(new ConquestArcherObject { Info = ConquestInfos[i].ConquestGuards[j], Alive = true, Index = ConquestInfos[i].ConquestGuards[j].Index, Conquest = newConquest });
  2293. }
  2294. }
  2295.  
  2296. //Remove archers that have been removed from DB
  2297. for (int j = 0; j < newConquest.ArcherList.Count; j++)
  2298. {
  2299. if (newConquest.ArcherList[j].Info == null)
  2300. newConquest.ArcherList.Remove(newConquest.ArcherList[j]);
  2301. }
  2302.  
  2303. //Bind Info to Saved Gate objects or create new objects
  2304. for (int j = 0; j < ConquestInfos[i].ConquestGates.Count; j++)
  2305. {
  2306. tempGate = newConquest.GateList.FirstOrDefault(x => x.Index == ConquestInfos[i].ConquestGates[j].Index);
  2307.  
  2308. if (tempGate != null)
  2309. {
  2310. tempGate.Info = ConquestInfos[i].ConquestGates[j];
  2311. tempGate.Conquest = newConquest;
  2312. }
  2313. else
  2314. {
  2315. newConquest.GateList.Add(new ConquestGateObject { Info = ConquestInfos[i].ConquestGates[j], Health = uint.MaxValue, Index = ConquestInfos[i].ConquestGates[j].Index, Conquest = newConquest });
  2316. }
  2317. }
  2318.  
  2319. //Remove Gates that have been removed from DB
  2320. for (int j = 0; j < newConquest.GateList.Count; j++)
  2321. {
  2322. if (newConquest.GateList[j].Info == null)
  2323. newConquest.GateList.Remove(newConquest.GateList[j]);
  2324. }
  2325.  
  2326. //Bind Info to Saved Wall objects or create new objects
  2327. for (int j = 0; j < ConquestInfos[i].ConquestWalls.Count; j++)
  2328. {
  2329. tempWall = newConquest.WallList.FirstOrDefault(x => x.Index == ConquestInfos[i].ConquestWalls[j].Index);
  2330.  
  2331. if (tempWall != null)
  2332. {
  2333. tempWall.Info = ConquestInfos[i].ConquestWalls[j];
  2334. tempWall.Conquest = newConquest;
  2335. }
  2336. else
  2337. {
  2338. newConquest.WallList.Add(new ConquestWallObject { Info = ConquestInfos[i].ConquestWalls[j], Index = ConquestInfos[i].ConquestWalls[j].Index, Health = uint.MaxValue, Conquest = newConquest });
  2339. }
  2340. }
  2341.  
  2342. //Remove Walls that have been removed from DB
  2343. for (int j = 0; j < newConquest.WallList.Count; j++)
  2344. {
  2345. if (newConquest.WallList[j].Info == null)
  2346. newConquest.WallList.Remove(newConquest.WallList[j]);
  2347. }
  2348.  
  2349.  
  2350. //Bind Info to Saved Siege objects or create new objects
  2351. for (int j = 0; j < ConquestInfos[i].ConquestSieges.Count; j++)
  2352. {
  2353. tempSiege = newConquest.SiegeList.FirstOrDefault(x => x.Index == ConquestInfos[i].ConquestSieges[j].Index);
  2354.  
  2355. if (tempSiege != null)
  2356. {
  2357. tempSiege.Info = ConquestInfos[i].ConquestSieges[j];
  2358. tempSiege.Conquest = newConquest;
  2359. }
  2360. else
  2361. {
  2362. newConquest.SiegeList.Add(new ConquestSiegeObject { Info = ConquestInfos[i].ConquestSieges[j], Index = ConquestInfos[i].ConquestSieges[j].Index, Health = uint.MaxValue, Conquest = newConquest });
  2363. }
  2364. }
  2365.  
  2366. //Remove Siege that have been removed from DB
  2367. for (int j = 0; j < newConquest.SiegeList.Count; j++)
  2368. {
  2369. if (newConquest.SiegeList[j].Info == null)
  2370. newConquest.SiegeList.Remove(newConquest.SiegeList[j]);
  2371. }
  2372.  
  2373.  
  2374. newConquest.LoadArchers();
  2375. newConquest.LoadGates();
  2376. newConquest.LoadWalls();
  2377. newConquest.LoadSieges();
  2378. newConquest.LoadNPCs();
  2379. }
  2380. }
  2381. }
  2382.  
  2383. public void LoadItemSets()
  2384. {
  2385. ItemSetInfoList.Clear();
  2386. if (Directory.Exists(Settings.EnvirPath))
  2387. {
  2388. string[] ItemSets;
  2389.  
  2390. ItemSets = Directory.GetFiles(Settings.ItemSetsPath);
  2391.  
  2392. foreach (var s in ItemSets)
  2393. {
  2394. if (File.Exists(s))
  2395. {
  2396. ItemSetInfo info = new ItemSetInfo();
  2397. InIReader reader = new InIReader(s);
  2398. info.SetName = reader.ReadString("Config", "SetName", string.Empty);
  2399. var type = reader.ReadByte("Config", "Type", 0);
  2400. info.SetType = ((ItemSet)type);
  2401.  
  2402. info.AcInc1 = reader.ReadByte("SetBonus1", "Ac", 0);
  2403. info.AcInc2 = reader.ReadByte("SetBonus2", "Ac", 0);
  2404. info.AcInc3 = reader.ReadByte("SetBonus3", "Ac", 0);
  2405.  
  2406. info.MacInc1 = reader.ReadByte("SetBonus1", "Mac", 0);
  2407. info.MacInc2 = reader.ReadByte("SetBonus2", "Mac", 0);
  2408. info.MacInc3 = reader.ReadByte("SetBonus3", "Mac", 0);
  2409.  
  2410. info.DCInc1 = reader.ReadByte("SetBonus1", "DC", 0);
  2411. info.DCInc2 = reader.ReadByte("SetBonus2", "DC", 0);
  2412. info.DCInc3 = reader.ReadByte("SetBonus3", "DC", 0);
  2413.  
  2414. info.MCInc1 = reader.ReadByte("SetBonus1", "MC", 0);
  2415. info.MCInc2 = reader.ReadByte("SetBonus2", "MC", 0);
  2416. info.MCInc3 = reader.ReadByte("SetBonus3", "MC", 0);
  2417.  
  2418. info.SCInc1 = reader.ReadByte("SetBonus1", "SC", 0);
  2419. info.SCInc2 = reader.ReadByte("SetBonus2", "SC", 0);
  2420. info.SCInc3 = reader.ReadByte("SetBonus3", "SC", 0);
  2421.  
  2422. info.AccInc1 = reader.ReadByte("SetBonus1", "Acc", 0);
  2423. info.AccInc2 = reader.ReadByte("SetBonus2", "Acc", 0);
  2424. info.AccInc3 = reader.ReadByte("SetBonus3", "Acc", 0);
  2425.  
  2426. info.AgilInc1 = reader.ReadByte("SetBonus1", "Agil", 0);
  2427. info.AgilInc2 = reader.ReadByte("SetBonus2", "Agil", 0);
  2428. info.AgilInc3 = reader.ReadByte("SetBonus3", "Agil", 0);
  2429.  
  2430. info.AspeedInc1 = reader.ReadByte("SetBonus1", "Aspeed", 0);
  2431. info.AspeedInc2 = reader.ReadByte("SetBonus2", "Aspeed", 0);
  2432. info.AspeedInc3 = reader.ReadByte("SetBonus3", "Aspeed", 0);
  2433.  
  2434. ItemSetInfoList.Add(info);
  2435. }
  2436.  
  2437. }
  2438.  
  2439.  
  2440. }
  2441.  
  2442. }
  2443. public void LoadCrafting()
  2444. {
  2445. CraftingInfoList.Clear();
  2446. string[] CraftingList;
  2447.  
  2448. if (Directory.Exists(Settings.CraftingPath))
  2449. {
  2450. CraftingList = Directory.GetFiles(Settings.CraftingPath);
  2451.  
  2452. foreach (var s in CraftingList)
  2453. {
  2454. if (File.Exists(s))
  2455. {
  2456. List<string> lines = File.ReadAllLines(s).ToList();
  2457.  
  2458. if (!ParseCraftingLine(lines))
  2459. SMain.Enqueue(s + " failed to load");
  2460. }
  2461.  
  2462. }
  2463.  
  2464.  
  2465. }
  2466.  
  2467. CraftingInfoList.Sort((c1, c2) => c1.LevelReq.CompareTo(c2.LevelReq));
  2468.  
  2469. }
  2470. public bool ParseCraftingLine(List<string> lines)
  2471. {
  2472. CraftingInfo info = new CraftingInfo();
  2473.  
  2474. const string
  2475. IDKey = "[@ID]",
  2476. NameKey = "[@NAME]",
  2477. LevelRequiredKey = "[@LEVELREQUIRED]",
  2478. ClassRequiredKey = "[@CLASSREQUIRED]",
  2479. GoldRequiredKey = "[@GOLDREQUIRED]",
  2480. JusticeRequiredKey = "[@JUSTICEREQUIRED]",
  2481. ValorRequiredKey = "[@VALORREQUIRED]",
  2482. HonorRequiredKey = "[@HONORREQUIRED]",
  2483. ConquestRequiredKey = "[@CONQUESTREQUIRED]",
  2484. ChanceKey = "[@CHANCE]",
  2485. ItemRequiredKey = "[@ITEMREQUIRED]",
  2486. TimeRequiredKey = "[@TIMEREQUIRED]",
  2487. RequireRecipeKey = "[@REQUIRERECIPE]",
  2488. AmountKey = "[@AMOUNT]";
  2489.  
  2490.  
  2491.  
  2492. List<string> headers = new List<string>
  2493. {
  2494. NameKey, LevelRequiredKey, ClassRequiredKey,
  2495. GoldRequiredKey, ChanceKey, ItemRequiredKey,
  2496. TimeRequiredKey,AmountKey,IDKey,JusticeRequiredKey,ValorRequiredKey ,HonorRequiredKey,ConquestRequiredKey,RequireRecipeKey
  2497. };
  2498.  
  2499. int currentHeader = 0;
  2500.  
  2501. while (currentHeader < headers.Count)
  2502. {
  2503. for (int i = 0; i < lines.Count; i++)
  2504. {
  2505. string line = lines[i].ToUpper();
  2506.  
  2507. if (line != headers[currentHeader].ToUpper()) continue;
  2508.  
  2509. for (int j = i + 1; j < lines.Count; j++)
  2510. {
  2511. string innerLine = lines[j];
  2512.  
  2513. if (innerLine.StartsWith("[")) break;
  2514. if (string.IsNullOrEmpty(lines[j])) continue;
  2515.  
  2516. switch (line)
  2517. {
  2518. case NameKey:
  2519. info.Item = GetItemInfo(innerLine);
  2520. if (info.Item == null) return false;
  2521. break;
  2522. case LevelRequiredKey:
  2523. if (!ushort.TryParse(innerLine, out info.LevelReq)) return false; // Required Level
  2524. break;
  2525. case ClassRequiredKey:
  2526. if (!byte.TryParse(innerLine, out info.ClassReq)) return false; // Required Class
  2527. break;
  2528. case JusticeRequiredKey:
  2529. if (!uint.TryParse(innerLine, out info.JusticeReq)) return false; // Required Gold
  2530. break;
  2531. case ValorRequiredKey:
  2532. if (!uint.TryParse(innerLine, out info.ValorReq)) return false; // Required Gold
  2533. break;
  2534. case HonorRequiredKey:
  2535. if (!uint.TryParse(innerLine, out info.HonorReq)) return false; // Required Gold
  2536. break;
  2537. case ConquestRequiredKey:
  2538. if (!uint.TryParse(innerLine, out info.ConquestReq)) return false; // Required Gold
  2539. break;
  2540.  
  2541. case ChanceKey:
  2542. if (!byte.TryParse(innerLine, out info.Chance)) return false; // Required Class
  2543. break;
  2544. case TimeRequiredKey:
  2545. if (!ushort.TryParse(innerLine, out info.Time)) return false; // Required Time
  2546. break;
  2547. case AmountKey:
  2548. if (!ushort.TryParse(innerLine, out info.Amount)) return false; // Required Time
  2549. break;
  2550. case IDKey:
  2551. if (!int.TryParse(innerLine, out info.UniqueIndex)) return false; // Index
  2552. break;
  2553. case RequireRecipeKey:
  2554. if (!bool.TryParse(innerLine, out info.RequireRecipe)) return false; // Index
  2555. break;
  2556.  
  2557. case ItemRequiredKey:
  2558. CraftRequiering temp = new CraftRequiering();
  2559.  
  2560. string[] split = innerLine.Split(' ');
  2561.  
  2562. if (split.Length < 2) return false;
  2563.  
  2564. temp.ItemReq = GetItemInfo(split[0]);
  2565. if (temp.ItemReq == null) return false;
  2566.  
  2567. if (!ushort.TryParse(split[1], out temp.Amount)) return false; // Required Amount
  2568.  
  2569. info.ItemList.Add(temp);
  2570.  
  2571. break;
  2572.  
  2573. }
  2574. }
  2575. }
  2576.  
  2577. currentHeader++;
  2578. }
  2579. if (info.Item == null || info.UniqueIndex == -1 || CraftingInfoList.Any(x => x.UniqueIndex == info.UniqueIndex)) return false;
  2580. CraftingInfoList.Add(info);
  2581. return true;
  2582. }
  2583. private bool BindCharacter(AuctionInfo auction)
  2584. {
  2585. for (int i = 0; i < CharacterList.Count; i++)
  2586. {
  2587. if (CharacterList[i].Index != auction.CharacterIndex) continue;
  2588.  
  2589. auction.CharacterInfo = CharacterList[i];
  2590. return true;
  2591. }
  2592. return false;
  2593.  
  2594. }
  2595.  
  2596. public void Start()
  2597. {
  2598. if (Running || _thread != null) return;
  2599.  
  2600. Running = true;
  2601.  
  2602. _thread = new Thread(WorkLoop) { IsBackground = true };
  2603. _thread.Start();
  2604.  
  2605. }
  2606. public void Stop()
  2607. {
  2608. Running = false;
  2609.  
  2610. lock (_locker)
  2611. {
  2612. Monitor.PulseAll(_locker); // changing a blocking condition. (this makes the threads wake up!)
  2613. }
  2614.  
  2615. //simply intterupt all the mob threads if they are running (will give an invisible error on them but fastest way of getting rid of them on shutdowns)
  2616. for (int i = 1; i < MobThreading.Length; i++)
  2617. {
  2618. if (MobThreads[i] != null)
  2619. MobThreads[i].EndTime = Time + 9999;
  2620. if ((MobThreading[i] != null) &&
  2621. (MobThreading[i].ThreadState != System.Threading.ThreadState.Stopped) && (MobThreading[i].ThreadState != System.Threading.ThreadState.Unstarted))
  2622. {
  2623. MobThreading[i].Interrupt();
  2624. }
  2625. }
  2626.  
  2627.  
  2628. while (_thread != null)
  2629. Thread.Sleep(1);
  2630. }
  2631.  
  2632. public void Reboot()
  2633. {
  2634. (new Thread(() =>
  2635. {
  2636. SMain.Enqueue("Server rebooting...");
  2637. Stop();
  2638. Start();
  2639. })).Start();
  2640. }
  2641.  
  2642. private void StartEnvir()
  2643. {
  2644. Players.Clear();
  2645. StartPoints.Clear();
  2646. StartItems.Clear();
  2647. MapList.Clear();
  2648. //MapInstanceList.Clear();
  2649.  
  2650. GameshopLog.Clear();
  2651. CustomCommands.Clear();
  2652. MonsterCount = 0;
  2653.  
  2654. LoadDB();
  2655.  
  2656. for (int i = 0; i < MapInfoList.Count; i++)
  2657. MapInfoList[i].CreateMap();
  2658. SMain.Enqueue(string.Format("{0} Maps Loaded.", MapInfoList.Count));
  2659.  
  2660. for (int i = 0; i < ItemInfoList.Count; i++)
  2661. {
  2662. if (ItemInfoList[i].StartItem)
  2663. StartItems.Add(ItemInfoList[i]);
  2664. }
  2665.  
  2666. for (int i = 0; i < MonsterInfoList.Count; i++)
  2667. MonsterInfoList[i].LoadDrops();
  2668.  
  2669.  
  2670. LoadFishingDrops();
  2671. LoadAwakeningMaterials();
  2672. LoadStrongBoxDrops();
  2673. LoadBlackStoneDrops();
  2674. SMain.Enqueue("Drops Loaded.");
  2675.  
  2676. LoadCrafting();
  2677. SMain.Enqueue("Crafting Loaded.");
  2678.  
  2679. LoadItemSets();
  2680. SMain.Enqueue(ItemSetInfoList.Count.ToString() + " Item Sets Loaded");
  2681.  
  2682. LoadRobot();
  2683. SMain.Enqueue("Robot Loaded");
  2684.  
  2685. if (ParagonManager.Enabled)
  2686. {
  2687. SMain.Enqueue("Loading Paragon system");
  2688. ParagonManager.Load();
  2689. SMain.Enqueue("Paragon system loaded - Enabled: " + ParagonManager.Enabled + " : Level cap: " + ParagonManager.LevelCap);
  2690. }
  2691.  
  2692. if (DragonInfo.Enabled)
  2693. {
  2694. DragonSystem = new Dragon(DragonInfo);
  2695. if (DragonSystem != null)
  2696. {
  2697. if (DragonSystem.Load()) DragonSystem.Info.LoadDrops();
  2698. }
  2699.  
  2700. SMain.Enqueue("Dragon Loaded.");
  2701. }
  2702.  
  2703. DefaultNPC = new NPCObject(new NPCInfo() { Name = "DefaultNPC", FileName = Settings.DefaultNPCFilename, IsDefault = true });
  2704. MonsterNPC = new NPCObject(new NPCInfo() { Name = "MonsterNPC", FileName = Settings.MonsterNPCFilename, IsDefault = true });
  2705.  
  2706. SMain.Enqueue("Envir Started.");
  2707. }
  2708. private void StartNetwork()
  2709. {
  2710. Connections.Clear();
  2711.  
  2712. LoadAccounts();
  2713.  
  2714. LoadGuilds();
  2715.  
  2716. LoadConquests();
  2717.  
  2718. LoadParagonInfo();
  2719. LoadPlayerRecipes();
  2720.  
  2721. _listener = new TcpListener(IPAddress.Parse(Settings.IPAddress), Settings.Port);
  2722. _listener.Start();
  2723. _listener.BeginAcceptTcpClient(Connection, null);
  2724.  
  2725. if (StatusPortEnabled)
  2726. {
  2727. _StatusPort = new TcpListener(IPAddress.Parse(Settings.IPAddress), 3000);
  2728. _StatusPort.Start();
  2729. _StatusPort.BeginAcceptTcpClient(StatusConnection, null);
  2730. }
  2731. SMain.Enqueue("Network Started.");
  2732.  
  2733. //FixGuilds();
  2734. }
  2735.  
  2736. private void StopEnvir()
  2737. {
  2738. SaveGoods(true);
  2739. SaveParagonInfo();
  2740. SavePlayerRecipes();
  2741. if (SaveDBFlag)
  2742. {
  2743. SaveDB();
  2744. SaveDBFlag = false;
  2745. }
  2746.  
  2747. MapList.Clear();
  2748. InstancesManager.Instances.Clear();
  2749. StartPoints.Clear();
  2750. StartItems.Clear();
  2751. Objects.Clear();
  2752. Players.Clear();
  2753. CleanUp();
  2754.  
  2755. GC.Collect();
  2756.  
  2757. SMain.Enqueue("Envir Stopped.");
  2758. }
  2759. private void StopNetwork()
  2760. {
  2761. _listener.Stop();
  2762. lock (Connections)
  2763. {
  2764. for (int i = Connections.Count - 1; i >= 0; i--)
  2765. Connections[i].SendDisconnect(0);
  2766. }
  2767.  
  2768. if (StatusPortEnabled)
  2769. {
  2770. _StatusPort.Stop();
  2771. for (int i = StatusConnections.Count - 1; i >= 0; i--)
  2772. StatusConnections[i].SendDisconnect();
  2773. }
  2774.  
  2775. long expire = Time + 5000;
  2776.  
  2777. while (Connections.Count != 0 && Stopwatch.ElapsedMilliseconds < expire)
  2778. {
  2779. Time = Stopwatch.ElapsedMilliseconds;
  2780.  
  2781. for (int i = Connections.Count - 1; i >= 0; i--)
  2782. Connections[i].Process();
  2783.  
  2784. Thread.Sleep(1);
  2785. }
  2786.  
  2787.  
  2788. Connections.Clear();
  2789.  
  2790. expire = Time + 10000;
  2791. while (StatusConnections.Count != 0 && Stopwatch.ElapsedMilliseconds < expire)
  2792. {
  2793. Time = Stopwatch.ElapsedMilliseconds;
  2794.  
  2795. for (int i = StatusConnections.Count - 1; i >= 0; i--)
  2796. StatusConnections[i].Process();
  2797.  
  2798. Thread.Sleep(1);
  2799. }
  2800.  
  2801.  
  2802. StatusConnections.Clear();
  2803. SMain.Enqueue("Network Stopped.");
  2804. }
  2805.  
  2806. private void CleanUp()
  2807. {
  2808. for (int i = 0; i < CharacterList.Count; i++)
  2809. {
  2810. CharacterInfo info = CharacterList[i];
  2811.  
  2812. if (info.Deleted)
  2813. {
  2814. #region Mentor Cleanup
  2815. if (info.Mentor > 0)
  2816. {
  2817. CharacterInfo Mentor = GetCharacterInfo(info.Mentor);
  2818.  
  2819. if (Mentor != null)
  2820. {
  2821. Mentor.Mentor = 0;
  2822. Mentor.MentorExp = 0;
  2823. Mentor.isMentor = false;
  2824. }
  2825.  
  2826. info.Mentor = 0;
  2827. info.MentorExp = 0;
  2828. info.isMentor = false;
  2829. }
  2830. #endregion
  2831.  
  2832. #region Marriage Cleanup
  2833. if (info.Married > 0)
  2834. {
  2835. CharacterInfo Lover = GetCharacterInfo(info.Married);
  2836.  
  2837. info.Married = 0;
  2838. info.MarriedDate = DateTime.Now;
  2839.  
  2840. Lover.Married = 0;
  2841. Lover.MarriedDate = DateTime.Now;
  2842. if (Lover.Equipment[(int)EquipmentSlot.RingL] != null)
  2843. Lover.Equipment[(int)EquipmentSlot.RingL].WeddingRing = -1;
  2844. }
  2845. #endregion
  2846.  
  2847. if (info.DeleteDate < DateTime.Now.AddDays(-7))
  2848. {
  2849. //delete char from db
  2850. }
  2851. }
  2852. if (info.Mail.Count > Settings.MailCapacity)
  2853. {
  2854. for (int j = (info.Mail.Count - 1 - (int)Settings.MailCapacity); j >= 0; j--)
  2855. {
  2856. if (info.Mail[j].DateOpened > DateTime.Now && info.Mail[j].Collected && info.Mail[j].Items.Count == 0 && info.Mail[j].Gold == 0)
  2857. {
  2858. info.Mail.Remove(info.Mail[j]);
  2859. }
  2860. }
  2861. }
  2862. }
  2863. }
  2864.  
  2865. private void Connection(IAsyncResult result)
  2866. {
  2867. if (!Running || !_listener.Server.IsBound) return;
  2868.  
  2869. try
  2870. {
  2871. TcpClient tempTcpClient = _listener.EndAcceptTcpClient(result);
  2872. lock (Connections)
  2873. Connections.Add(new MirConnection(++_sessionID, tempTcpClient));
  2874. }
  2875. catch (Exception ex)
  2876. {
  2877. SMain.Enqueue(ex);
  2878. }
  2879. finally
  2880. {
  2881. while (Connections.Count >= Settings.MaxUser)
  2882. Thread.Sleep(1);
  2883.  
  2884. if (Running && _listener.Server.IsBound)
  2885. _listener.BeginAcceptTcpClient(Connection, null);
  2886. }
  2887. }
  2888.  
  2889. private void StatusConnection(IAsyncResult result)
  2890. {
  2891. if (!Running || !_StatusPort.Server.IsBound) return;
  2892.  
  2893. try
  2894. {
  2895. TcpClient tempTcpClient = _StatusPort.EndAcceptTcpClient(result);
  2896. lock (StatusConnections)
  2897. StatusConnections.Add(new MirStatusConnection(tempTcpClient));
  2898. }
  2899. catch (Exception ex)
  2900. {
  2901. SMain.Enqueue(ex);
  2902. }
  2903. finally
  2904. {
  2905. while (StatusConnections.Count >= 5) //dont allow to many status port connections it's just an abuse thing
  2906. Thread.Sleep(1);
  2907.  
  2908. if (Running && _StatusPort.Server.IsBound)
  2909. _StatusPort.BeginAcceptTcpClient(StatusConnection, null);
  2910. }
  2911. }
  2912.  
  2913. public void NewAccount(ClientPackets.NewAccount p, MirConnection c)
  2914. {
  2915. if (!Settings.AllowNewAccount)
  2916. {
  2917. c.Enqueue(new ServerPackets.NewAccount { Result = 0 });
  2918. return;
  2919. }
  2920.  
  2921. if (!AccountIDReg.IsMatch(p.AccountID))
  2922. {
  2923. c.Enqueue(new ServerPackets.NewAccount { Result = 1 });
  2924. return;
  2925. }
  2926.  
  2927. if (!PasswordReg.IsMatch(p.Password))
  2928. {
  2929. c.Enqueue(new ServerPackets.NewAccount { Result = 2 });
  2930. return;
  2931. }
  2932. if (!string.IsNullOrWhiteSpace(p.EMailAddress) && !EMailReg.IsMatch(p.EMailAddress) ||
  2933. p.EMailAddress.Length > 50)
  2934. {
  2935. c.Enqueue(new ServerPackets.NewAccount { Result = 3 });
  2936. return;
  2937. }
  2938.  
  2939. if (!string.IsNullOrWhiteSpace(p.UserName) && p.UserName.Length > 20)
  2940. {
  2941. c.Enqueue(new ServerPackets.NewAccount { Result = 4 });
  2942. return;
  2943. }
  2944.  
  2945. if (!string.IsNullOrWhiteSpace(p.SecretQuestion) && p.SecretQuestion.Length > 30)
  2946. {
  2947. c.Enqueue(new ServerPackets.NewAccount { Result = 5 });
  2948. return;
  2949. }
  2950.  
  2951. if (!string.IsNullOrWhiteSpace(p.SecretAnswer) && p.SecretAnswer.Length > 30)
  2952. {
  2953. c.Enqueue(new ServerPackets.NewAccount { Result = 6 });
  2954. return;
  2955. }
  2956.  
  2957. lock (AccountLock)
  2958. {
  2959. if (AccountExists(p.AccountID))
  2960. {
  2961. c.Enqueue(new ServerPackets.NewAccount { Result = 7 });
  2962. return;
  2963. }
  2964.  
  2965. AccountList.Add(new AccountInfo(p) { Index = ++NextAccountID, CreationIP = c.IPAddress });
  2966.  
  2967.  
  2968. c.Enqueue(new ServerPackets.NewAccount { Result = 8 });
  2969. }
  2970. }
  2971. public void ChangePassword(ClientPackets.ChangePassword p, MirConnection c)
  2972. {
  2973. if (!Settings.AllowChangePassword)
  2974. {
  2975. c.Enqueue(new ServerPackets.ChangePassword { Result = 0 });
  2976. return;
  2977. }
  2978.  
  2979. if (!AccountIDReg.IsMatch(p.AccountID))
  2980. {
  2981. c.Enqueue(new ServerPackets.ChangePassword { Result = 1 });
  2982. return;
  2983. }
  2984.  
  2985. if (!PasswordReg.IsMatch(p.CurrentPassword))
  2986. {
  2987. c.Enqueue(new ServerPackets.ChangePassword { Result = 2 });
  2988. return;
  2989. }
  2990.  
  2991. if (!PasswordReg.IsMatch(p.NewPassword))
  2992. {
  2993. c.Enqueue(new ServerPackets.ChangePassword { Result = 3 });
  2994. return;
  2995. }
  2996.  
  2997. AccountInfo account = GetAccount(p.AccountID);
  2998.  
  2999. if (account == null)
  3000. {
  3001. c.Enqueue(new ServerPackets.ChangePassword { Result = 4 });
  3002. return;
  3003. }
  3004.  
  3005. if (account.Banned)
  3006. {
  3007. if (account.ExpiryDate > Now)
  3008. {
  3009. c.Enqueue(new ServerPackets.ChangePasswordBanned { Reason = account.BanReason, ExpiryDate = account.ExpiryDate });
  3010. return;
  3011. }
  3012. account.Banned = false;
  3013. }
  3014. account.BanReason = string.Empty;
  3015. account.ExpiryDate = DateTime.MinValue;
  3016.  
  3017. if (String.CompareOrdinal(account.Password, p.CurrentPassword) != 0)
  3018. {
  3019. c.Enqueue(new ServerPackets.ChangePassword { Result = 5 });
  3020. return;
  3021. }
  3022.  
  3023. account.Password = p.NewPassword;
  3024. c.Enqueue(new ServerPackets.ChangePassword { Result = 6 });
  3025. }
  3026. public void Login(ClientPackets.Login p, MirConnection c)
  3027. {
  3028. if (!Settings.AllowLogin)
  3029. {
  3030. c.Enqueue(new ServerPackets.Login { Result = 0 });
  3031. return;
  3032. }
  3033.  
  3034. if (!AccountIDReg.IsMatch(p.AccountID))
  3035. {
  3036. c.Enqueue(new ServerPackets.Login { Result = 1 });
  3037. return;
  3038. }
  3039.  
  3040.  
  3041. AccountInfo account = GetAccount(p.AccountID);
  3042.  
  3043. if (account == null)
  3044. {
  3045. c.Enqueue(new ServerPackets.Login { Result = 3 });
  3046. return;
  3047. }
  3048.  
  3049. if (account.Banned)
  3050. {
  3051. if (account.ExpiryDate > DateTime.Now)
  3052. {
  3053. c.Enqueue(new ServerPackets.LoginBanned
  3054. {
  3055. Reason = account.BanReason,
  3056. ExpiryDate = account.ExpiryDate
  3057. });
  3058. return;
  3059. }
  3060. account.Banned = false;
  3061. }
  3062. account.BanReason = string.Empty;
  3063. account.ExpiryDate = DateTime.MinValue;
  3064.  
  3065.  
  3066. if (String.CompareOrdinal(account.Password, p.Password) != 0)
  3067. {
  3068. if (account.WrongPasswordCount++ >= 5)
  3069. {
  3070. account.Banned = true;
  3071. account.BanReason = "Too many Wrong Login Attempts.";
  3072. account.ExpiryDate = DateTime.Now.AddMinutes(2);
  3073.  
  3074. c.Enqueue(new ServerPackets.LoginBanned
  3075. {
  3076. Reason = account.BanReason,
  3077. ExpiryDate = account.ExpiryDate
  3078. });
  3079. return;
  3080. }
  3081.  
  3082. c.Enqueue(new ServerPackets.Login { Result = 4 });
  3083. return;
  3084. }
  3085. account.WrongPasswordCount = 0;
  3086.  
  3087. lock (AccountLock)
  3088. {
  3089. if (account.Connection != null)
  3090. account.Connection.SendDisconnect(1);
  3091.  
  3092. account.Connection = c;
  3093. }
  3094.  
  3095. c.Account = account;
  3096. c.Stage = GameStage.Select;
  3097.  
  3098. account.LastDate = Now;
  3099. account.LastIP = c.IPAddress;
  3100.  
  3101. // SMain.Enqueue(account.Connection.SessionID + ", " + account.Connection.IPAddress + ", User logged in.");
  3102. c.Enqueue(new ServerPackets.LoginSuccess { Characters = account.GetSelectInfo() });
  3103. }
  3104. public string GetMd5Sum(string str)
  3105. {
  3106. //vBulletin uses UTF8 as strings, so you need to pass the user input string as UTF8 also
  3107. Encoder enc = System.Text.Encoding.UTF8.GetEncoder();
  3108.  
  3109. //Create a byte[] array to store the new UTF8 string
  3110. byte[] utf8text = new byte[str.Length];
  3111.  
  3112. //Pass the string to the byte[] array
  3113. enc.GetBytes(str.ToCharArray(), 0, str.Length, utf8text, 0, true);
  3114.  
  3115. //Hash the byte[] array with our UTF8 string inside
  3116. MD5 md5 = new MD5CryptoServiceProvider();
  3117. byte[] result = md5.ComputeHash(utf8text);
  3118.  
  3119. //Build the final string by converting each byte
  3120. //into hex and appending it to a StringBuilder
  3121. StringBuilder sb = new StringBuilder();
  3122. for (int i = 0; i < result.Length; i++)
  3123. {
  3124. sb.Append(result[i].ToString("x2")); //x2 here so the outcome result is all in lowercase, couse vbulleting also stores all in lowercase
  3125. }
  3126.  
  3127. //And return it
  3128. return sb.ToString();
  3129. }
  3130.  
  3131. public void LoginForums(ClientPackets.Login p, MirConnection c)
  3132. {
  3133. if (!Settings.AllowLogin)
  3134. {
  3135. c.Enqueue(new ServerPackets.Login { Result = 0 });
  3136. return;
  3137. }
  3138.  
  3139. MySql.Data.MySqlClient.MySqlConnection conn;
  3140. string myConnectionString = Settings.ForumsConnectionString;//
  3141.  
  3142. try
  3143. {
  3144. conn = new MySql.Data.MySqlClient.MySqlConnection();
  3145. conn.ConnectionString = myConnectionString;
  3146. conn.Open();
  3147.  
  3148. string pass = p.Password;
  3149. string query = string.Format("SELECT user.userid,user.password,user.email,user.salt FROM `user` WHERE `username` = '{0}'", p.AccountID);
  3150.  
  3151.  
  3152. var cmd = new MySqlCommand(query, conn);
  3153. DataTable mysqlResult = new DataTable();
  3154. using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
  3155. {
  3156. da.Fill(mysqlResult);
  3157. }
  3158. conn.Close();
  3159.  
  3160. if (mysqlResult.Rows.Count > 0)
  3161. {
  3162. var result = mysqlResult.Rows[0];
  3163. var password = result.ItemArray[1];
  3164. var email = result.ItemArray[2];
  3165. var salt = result.ItemArray[3];
  3166.  
  3167. string p1 = GetMd5Sum(pass);
  3168. string p2 = p1 + salt;
  3169. string finalPass = GetMd5Sum(p2);
  3170.  
  3171. if (finalPass == password.ToString())
  3172. {
  3173. AccountInfo account = GetOrCreateAccount(p.AccountID, p.Password, email.ToString());
  3174.  
  3175. lock (AccountLock)
  3176. {
  3177. if (account.Connection != null)
  3178. account.Connection.SendDisconnect(1);
  3179.  
  3180. account.Connection = c;
  3181. }
  3182.  
  3183. c.Account = account;
  3184. c.Stage = GameStage.Select;
  3185.  
  3186. account.LastDate = Now;
  3187. account.LastIP = c.IPAddress;
  3188. c.Enqueue(new ServerPackets.LoginSuccess { Characters = account.GetSelectInfo() });
  3189. }
  3190. else
  3191. {
  3192. //Wrong Pass
  3193. c.Enqueue(new ServerPackets.Login { Result = 4 });
  3194. return;
  3195.  
  3196. }
  3197. }
  3198. else
  3199. {
  3200. c.Enqueue(new ServerPackets.Login { Result = 3 });
  3201. return;
  3202. }
  3203.  
  3204.  
  3205. }
  3206. catch (MySql.Data.MySqlClient.MySqlException ex)
  3207. {
  3208. c.Enqueue(new ServerPackets.Login { Result = 3 });
  3209. }
  3210. catch (Exception e)
  3211. {
  3212. c.Enqueue(new ServerPackets.Login { Result = 3 });
  3213. }
  3214. }
  3215.  
  3216. public void NewCharacter(ClientPackets.NewCharacter p, MirConnection c)
  3217. {
  3218. if (!Settings.AllowNewCharacter)
  3219. {
  3220. c.Enqueue(new ServerPackets.NewCharacter { Result = 0 });
  3221. return;
  3222. }
  3223.  
  3224. if (!CharacterReg.IsMatch(p.Name))
  3225. {
  3226. c.Enqueue(new ServerPackets.NewCharacter { Result = 1 });
  3227. return;
  3228. }
  3229.  
  3230. if (p.Gender != MirGender.Male && p.Gender != MirGender.Female)
  3231. {
  3232. c.Enqueue(new ServerPackets.NewCharacter { Result = 2 });
  3233. return;
  3234. }
  3235.  
  3236. if (p.Class != MirClass.Warrior && p.Class != MirClass.Wizard && p.Class != MirClass.Taoist &&
  3237. p.Class != MirClass.Assassin && p.Class != MirClass.Archer)
  3238. {
  3239. c.Enqueue(new ServerPackets.NewCharacter { Result = 3 });
  3240. return;
  3241. }
  3242.  
  3243. if ((p.Class == MirClass.Assassin && !Settings.AllowCreateAssassin) ||
  3244. (p.Class == MirClass.Archer && !Settings.AllowCreateArcher))
  3245. {
  3246. c.Enqueue(new ServerPackets.NewCharacter { Result = 3 });
  3247. return;
  3248. }
  3249.  
  3250. int count = 0;
  3251.  
  3252. for (int i = 0; i < c.Account.Characters.Count; i++)
  3253. {
  3254. if (c.Account.Characters[i].Deleted) continue;
  3255.  
  3256. if (++count >= Globals.MaxCharacterCount)
  3257. {
  3258. c.Enqueue(new ServerPackets.NewCharacter { Result = 4 });
  3259. return;
  3260. }
  3261. }
  3262.  
  3263. lock (AccountLock)
  3264. {
  3265. if (CharacterExists(p.Name))
  3266. {
  3267. c.Enqueue(new ServerPackets.NewCharacter { Result = 5 });
  3268. return;
  3269. }
  3270.  
  3271. CharacterInfo info = new CharacterInfo(p, c) { Index = ++NextCharacterID, AccountInfo = c.Account };
  3272.  
  3273. c.Account.Characters.Add(info);
  3274. CharacterList.Add(info);
  3275.  
  3276. c.Enqueue(new ServerPackets.NewCharacterSuccess { CharInfo = info.ToSelectInfo() });
  3277. }
  3278. }
  3279.  
  3280. public bool AccountExists(string accountID)
  3281. {
  3282. for (int i = 0; i < AccountList.Count; i++)
  3283. if (String.Compare(AccountList[i].AccountID, accountID, StringComparison.OrdinalIgnoreCase) == 0)
  3284. return true;
  3285.  
  3286. return false;
  3287. }
  3288. public bool CharacterExists(string name)
  3289. {
  3290. for (int i = 0; i < CharacterList.Count; i++)
  3291. if (String.Compare(CharacterList[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  3292. return true;
  3293.  
  3294. return false;
  3295. }
  3296.  
  3297. public List<CharacterInfo> MatchPlayer(string PlayerID, bool match = false)
  3298. {
  3299. if (string.IsNullOrEmpty(PlayerID)) return new List<CharacterInfo>(CharacterList);
  3300.  
  3301. List<CharacterInfo> list = new List<CharacterInfo>();
  3302.  
  3303. for (int i = 0; i < CharacterList.Count; i++)
  3304. {
  3305. if (match)
  3306. {
  3307. if (CharacterList[i].Name.Equals(PlayerID, StringComparison.OrdinalIgnoreCase))
  3308. list.Add(CharacterList[i]);
  3309. }
  3310. else
  3311. {
  3312. if (CharacterList[i].Name.IndexOf(PlayerID, StringComparison.OrdinalIgnoreCase) >= 0)
  3313. list.Add(CharacterList[i]);
  3314. }
  3315. }
  3316.  
  3317. return list;
  3318. }
  3319.  
  3320.  
  3321. public List<CharacterInfo> MatchPlayerbyItem(string ItemID, bool match = false)
  3322. {
  3323. if (string.IsNullOrEmpty(ItemID)) return new List<CharacterInfo>(CharacterList);
  3324.  
  3325. List<CharacterInfo> list = new List<CharacterInfo>();
  3326.  
  3327. for (int i = 0; i < CharacterList.Count; i++)
  3328. {
  3329. if (match)
  3330. {
  3331. foreach (var item in CharacterList[i].Inventory)
  3332. if (item != null && item.Name.Equals(ItemID, StringComparison.OrdinalIgnoreCase) && !list.Contains(CharacterList[i]))
  3333. list.Add(CharacterList[i]);
  3334.  
  3335. foreach (var item in CharacterList[i].AccountInfo.Storage)
  3336. if (item != null && item.Name.Equals(ItemID, StringComparison.OrdinalIgnoreCase) && !list.Contains(CharacterList[i]))
  3337. list.Add(CharacterList[i]);
  3338.  
  3339. foreach (var item in CharacterList[i].QuestInventory)
  3340. if (item != null && item.Name.Equals(ItemID, StringComparison.OrdinalIgnoreCase) && !list.Contains(CharacterList[i]))
  3341. list.Add(CharacterList[i]);
  3342.  
  3343. foreach (var item in CharacterList[i].Equipment)
  3344. if (item != null && item.Name.Equals(ItemID, StringComparison.OrdinalIgnoreCase) && !list.Contains(CharacterList[i]))
  3345. list.Add(CharacterList[i]);
  3346.  
  3347. foreach (var mail in CharacterList[i].Mail)
  3348. foreach (var item in mail.Items)
  3349. if (item != null && item.Name.Equals(ItemID, StringComparison.OrdinalIgnoreCase) && !list.Contains(CharacterList[i]))
  3350. list.Add(CharacterList[i]);
  3351. }
  3352. else
  3353. {
  3354. foreach (var item in CharacterList[i].Inventory)
  3355. if (item != null && item.Name.IndexOf(ItemID, StringComparison.OrdinalIgnoreCase) >= 0 && !list.Contains(CharacterList[i]))
  3356. list.Add(CharacterList[i]);
  3357.  
  3358. foreach (var item in CharacterList[i].QuestInventory)
  3359. if (item != null && item.Name.IndexOf(ItemID, StringComparison.OrdinalIgnoreCase) >= 0 && !list.Contains(CharacterList[i]))
  3360. list.Add(CharacterList[i]);
  3361.  
  3362. foreach (var item in CharacterList[i].Equipment)
  3363. if (item != null && item.Name.IndexOf(ItemID, StringComparison.OrdinalIgnoreCase) >= 0 && !list.Contains(CharacterList[i]))
  3364. list.Add(CharacterList[i]);
  3365.  
  3366. foreach (var item in CharacterList[i].AccountInfo.Storage)
  3367. if (item != null && item.Name.IndexOf(ItemID, StringComparison.OrdinalIgnoreCase) >= 0 && !list.Contains(CharacterList[i]))
  3368. list.Add(CharacterList[i]);
  3369. }
  3370.  
  3371. }
  3372.  
  3373. return list;
  3374. }
  3375.  
  3376. private AccountInfo GetAccount(string accountID)
  3377. {
  3378. for (int i = 0; i < AccountList.Count; i++)
  3379. if (String.Compare(AccountList[i].AccountID, accountID, StringComparison.OrdinalIgnoreCase) == 0)
  3380. return AccountList[i];
  3381.  
  3382. return null;
  3383. }
  3384. private AccountInfo GetOrCreateAccount(string accountID, string password, string email)
  3385. {
  3386. var account = AccountList.FirstOrDefault(o => o.AccountID.ToLower() == accountID.ToLower());
  3387. if (account == null)
  3388. {
  3389. ClientPackets.NewAccount p = new ClientPackets.NewAccount()
  3390. {
  3391. AccountID = accountID.ToLower(),
  3392. BirthDate = new DateTime(2018, 1, 1),
  3393. EMailAddress = email,
  3394. Password = password,
  3395. SecretAnswer = "Auto Generated",
  3396. SecretQuestion = "AutoGenerated",
  3397. UserName = accountID.ToLower(),
  3398. };
  3399.  
  3400. AccountInfo info = new AccountInfo(p) { Index = ++NextAccountID };
  3401. AccountList.Add(info);
  3402. return info;
  3403. }
  3404. account.Password = password;
  3405. return account;
  3406.  
  3407. }
  3408. public List<AccountInfo> MatchAccounts(string accountID, bool match = false)
  3409. {
  3410. if (string.IsNullOrEmpty(accountID)) return new List<AccountInfo>(AccountList);
  3411.  
  3412. List<AccountInfo> list = new List<AccountInfo>();
  3413.  
  3414. for (int i = 0; i < AccountList.Count; i++)
  3415. {
  3416. if (match)
  3417. {
  3418. if (AccountList[i].AccountID.Equals(accountID, StringComparison.OrdinalIgnoreCase))
  3419. list.Add(AccountList[i]);
  3420. }
  3421. else
  3422. {
  3423. if (AccountList[i].AccountID.IndexOf(accountID, StringComparison.OrdinalIgnoreCase) >= 0)
  3424. list.Add(AccountList[i]);
  3425. }
  3426. }
  3427.  
  3428. return list;
  3429. }
  3430.  
  3431. public List<AccountInfo> MatchAccountsByPlayer(string playerName, bool match = false)
  3432. {
  3433. if (string.IsNullOrEmpty(playerName)) return new List<AccountInfo>(AccountList);
  3434.  
  3435. List<AccountInfo> list = new List<AccountInfo>();
  3436.  
  3437. for (int i = 0; i < AccountList.Count; i++)
  3438. {
  3439. for (int j = 0; j < AccountList[i].Characters.Count; j++)
  3440. {
  3441. if (match)
  3442. {
  3443. if (AccountList[i].Characters[j].Name.Equals(playerName, StringComparison.OrdinalIgnoreCase))
  3444. list.Add(AccountList[i]);
  3445. }
  3446. else
  3447. {
  3448. if (AccountList[i].Characters[j].Name.IndexOf(playerName, StringComparison.OrdinalIgnoreCase) >= 0)
  3449. list.Add(AccountList[i]);
  3450. }
  3451. }
  3452. }
  3453.  
  3454. return list;
  3455. }
  3456.  
  3457. public void CreateAccountInfo()
  3458. {
  3459. AccountList.Add(new AccountInfo { Index = ++NextAccountID });
  3460. }
  3461. public void CreateMapInfo()
  3462. {
  3463. MapInfoList.Add(new MapInfo { Index = ++MapIndex });
  3464. }
  3465.  
  3466. public void CreateMapInstanceInfo()
  3467. {
  3468. MapInstanceInfoList.Add(new MapInstanceInfo { Index = ++MapInstanceIndex });
  3469. }
  3470. public void CreateItemInfo(ItemType type = ItemType.Nothing)
  3471. {
  3472. ItemInfoList.Add(new ItemInfo { Index = ++ItemIndex, Type = type, RandomStatsId = 255 });
  3473. }
  3474. public void CreateMonsterInfo()
  3475. {
  3476. MonsterInfoList.Add(new MonsterInfo { Index = ++MonsterIndex });
  3477. }
  3478. public void CreateNPCInfo()
  3479. {
  3480. NPCInfoList.Add(new NPCInfo { Index = ++NPCIndex });
  3481. }
  3482. public void CreateQuestInfo()
  3483. {
  3484. QuestInfoList.Add(new QuestInfo { Index = ++QuestIndex });
  3485. }
  3486.  
  3487. public void AddToGameShop(ItemInfo Info)
  3488. {
  3489. GameShopList.Add(new GameShopItem { GIndex = ++GameshopIndex, GoldPrice = (uint)(1000 * Settings.CredxGold), CreditPrice = 1000, ItemIndex = Info.Index, Info = Info, Date = DateTime.Now, Class = "All", Category = Info.Type.ToString() });
  3490. }
  3491.  
  3492. public void Remove(MapInfo info)
  3493. {
  3494. MapInfoList.Remove(info);
  3495. //Desync all objects\
  3496. }
  3497. public void Remove(MapInstanceInfo info)
  3498. {
  3499. MapInstanceInfoList.Remove(info);
  3500. //Desync all objects\
  3501. }
  3502. public void Remove(ItemInfo info)
  3503. {
  3504. ItemInfoList.Remove(info);
  3505. }
  3506. public void Remove(MonsterInfo info)
  3507. {
  3508. MonsterInfoList.Remove(info);
  3509. //Desync all objects\
  3510. }
  3511. public void Remove(NPCInfo info)
  3512. {
  3513. NPCInfoList.Remove(info);
  3514. //Desync all objects\
  3515. }
  3516. public void Remove(QuestInfo info)
  3517. {
  3518. QuestInfoList.Remove(info);
  3519. //Desync all objects\
  3520. }
  3521.  
  3522. public void Remove(GameShopItem info)
  3523. {
  3524. GameShopList.Remove(info);
  3525.  
  3526. if (GameShopList.Count == 0)
  3527. {
  3528. GameshopIndex = 0;
  3529. }
  3530.  
  3531. //Desync all objects\
  3532. }
  3533.  
  3534. public UserItem CreateFreshItem(ItemInfo info)
  3535. {
  3536. UserItem item = new UserItem(info)
  3537. {
  3538. UniqueID = ++NextUserItemID,
  3539. CurrentDura = info.Durability,
  3540. MaxDura = info.Durability
  3541. };
  3542.  
  3543. UpdateItemExpiry(item);
  3544.  
  3545. return item;
  3546. }
  3547.  
  3548. public UserItem CreateDropItem(ItemInfo info)
  3549. {
  3550. if (info == null) return null;
  3551.  
  3552. UserItem item = new UserItem(info)
  3553. {
  3554. UniqueID = ++NextUserItemID,
  3555. MaxDura = info.Durability,
  3556. CurrentDura = (ushort)Math.Min(info.Durability, Random.Next(info.Durability) + 1000),
  3557. Grade = info.Grade
  3558. };
  3559.  
  3560. UpgradeItem(item);
  3561.  
  3562.  
  3563. UpdateItemExpiry(item);
  3564.  
  3565. if (!info.NeedIdentify) item.Identified = true;
  3566. return item;
  3567. }
  3568.  
  3569. public UserItem CreateDropItem(ItemInfo info, MapObject owner)
  3570. {
  3571. if (info == null) return null;
  3572.  
  3573. UserItem item = new UserItem(info)
  3574. {
  3575. UniqueID = ++NextUserItemID,
  3576. MaxDura = info.Durability,
  3577. CurrentDura = (ushort)Math.Min(info.Durability, Random.Next(info.Durability) + 1000),
  3578. Grade = info.Grade
  3579. };
  3580.  
  3581. UpgradeItem(item);
  3582.  
  3583. UpgradeGrade(item, owner);
  3584.  
  3585. UpdateItemExpiry(item);
  3586.  
  3587. if (!info.NeedIdentify) item.Identified = true;
  3588. return item;
  3589. }
  3590.  
  3591. public UserItem CreateGMtem(ItemInfo info)
  3592. {
  3593. if (info == null) return null;
  3594.  
  3595. UserItem item = new UserItem(info)
  3596. {
  3597. UniqueID = ++NextUserItemID,
  3598. MaxDura = info.Durability,
  3599. CurrentDura = (ushort)Math.Min(info.Durability, Random.Next(info.Durability) + 1000),
  3600. GMItem = true
  3601.  
  3602. };
  3603.  
  3604. //UpgradeItem(item);
  3605.  
  3606. //UpdateItemExpiry(item);
  3607.  
  3608. if (!info.NeedIdentify) item.Identified = true;
  3609. return item;
  3610. }
  3611. public void UpdateItemExpiry(UserItem item)
  3612. {
  3613. //can't have expiry on usable items
  3614. if (item.Info.Type == ItemType.Scroll || item.Info.Type == ItemType.Potion ||
  3615. item.Info.Type == ItemType.Scroll || item.Info.Type == ItemType.Transform) return;
  3616.  
  3617. ExpireInfo expiryInfo = new ExpireInfo();
  3618.  
  3619. Regex r = new Regex(@"\[(.*?)\]");
  3620. Match expiryMatch = r.Match(item.Info.Name);
  3621.  
  3622. if (expiryMatch.Success)
  3623. {
  3624. string parameter = expiryMatch.Groups[1].Captures[0].Value;
  3625.  
  3626. var numAlpha = new Regex("(?<Numeric>[0-9]*)(?<Alpha>[a-zA-Z]*)");
  3627. var match = numAlpha.Match(parameter);
  3628.  
  3629. string alpha = match.Groups["Alpha"].Value;
  3630. int num = 0;
  3631.  
  3632. int.TryParse(match.Groups["Numeric"].Value, out num);
  3633.  
  3634. switch (alpha)
  3635. {
  3636. case "m":
  3637. expiryInfo.ExpiryDate = DateTime.Now.AddMinutes(num);
  3638. break;
  3639. case "h":
  3640. expiryInfo.ExpiryDate = DateTime.Now.AddHours(num);
  3641. break;
  3642. case "d":
  3643. expiryInfo.ExpiryDate = DateTime.Now.AddDays(num);
  3644. break;
  3645. case "M":
  3646. expiryInfo.ExpiryDate = DateTime.Now.AddMonths(num);
  3647. break;
  3648. case "y":
  3649. expiryInfo.ExpiryDate = DateTime.Now.AddYears(num);
  3650. break;
  3651. default:
  3652. expiryInfo.ExpiryDate = DateTime.MaxValue;
  3653. break;
  3654. }
  3655.  
  3656. item.ExpireInfo = expiryInfo;
  3657. }
  3658. }
  3659. public void UpgradeGrade(UserItem item, MapObject owner)
  3660. {
  3661. if (item.Info.Type == 0 || (byte)item.Info.Type > 10)
  3662. return;
  3663.  
  3664. if (item.Info.Grade != ItemGrade.None)
  3665. return;
  3666.  
  3667. float droprateDecrease = 0;
  3668. if (owner != null)
  3669. droprateDecrease = owner.ItemDropRateOffset > 0 ? owner.ItemDropRateOffset / 5 : 0;
  3670.  
  3671.  
  3672. int chance = Random.Next((Settings.IncreaseForLessRareItemDrop - (int)(droprateDecrease * Settings.ItemRareDropIncreaseRate)));
  3673. if (chance == 0)
  3674. {
  3675. Upgrade(item, ItemGrade.Godly);
  3676. }
  3677. else if (chance >= 1 && chance <= 5)
  3678. {
  3679. // legendary
  3680. Upgrade(item, ItemGrade.Mythical);
  3681. }
  3682. else if (chance >= 6 && chance <= 20)
  3683. {
  3684. // legendary
  3685. Upgrade(item, ItemGrade.Legendary);
  3686. }
  3687. else if (chance >= 21 && chance <= 50)
  3688. {// rare
  3689. Upgrade(item, ItemGrade.Rare);
  3690. }
  3691. else if (chance >= 51 && chance <= 100)
  3692. {
  3693. // common
  3694. Upgrade(item, ItemGrade.Common);
  3695. }
  3696. else if (chance >= 101)
  3697. { // do nothing
  3698. }
  3699. else return;
  3700.  
  3701.  
  3702. }
  3703. public void DowngradeGrade(PlayerObject player, UserItem item)
  3704. {
  3705. switch (item.Grade)
  3706. {
  3707. case ItemGrade.Common:
  3708. Downgrade(item, ItemGrade.None);
  3709. break;
  3710. case ItemGrade.Rare:
  3711. Downgrade(item, ItemGrade.Common);
  3712. break;
  3713. case ItemGrade.Legendary:
  3714. Downgrade(item, ItemGrade.Rare);
  3715. break;
  3716. case ItemGrade.Mythical:
  3717. Downgrade(item, ItemGrade.Legendary);
  3718. break;
  3719. default:
  3720. break;
  3721. }
  3722. }
  3723.  
  3724. public void CheckGradeItems(UserItem item, PlayerObject player)
  3725. {
  3726. if (item.Info.Type == 0 || (byte)item.Info.Type > 10)
  3727. return;
  3728.  
  3729. item.MinAc = 0; item.MaxAC = 0;
  3730. item.MinMAC = 0; item.MaxMAC = 0;
  3731. item.MinDC = 0; item.MaxDC = 0;
  3732. item.MinSC = 0; item.MaxSC = 0;
  3733. item.MinMC = 0; item.MaxMC = 0;
  3734.  
  3735. if (!item.IsGradeUpgraded || item.Grade == ItemGrade.None)
  3736. return;
  3737.  
  3738. switch (item.Grade)
  3739. {
  3740. case ItemGrade.Common:
  3741. Upgrade(item, ItemGrade.Common);
  3742. break;
  3743. case ItemGrade.Rare:
  3744. Upgrade(item, ItemGrade.Rare);
  3745. break;
  3746. case ItemGrade.Legendary:
  3747. Upgrade(item, ItemGrade.Legendary);
  3748. break;
  3749. case ItemGrade.Mythical:
  3750. Upgrade(item, ItemGrade.Mythical);
  3751. break;
  3752. case ItemGrade.Godly:
  3753. Upgrade(item, ItemGrade.Godly);
  3754. break;
  3755.  
  3756. default:
  3757. break;
  3758. }
  3759. }
  3760. public void UpgradeGrade(PlayerObject player, UserItem item)
  3761. {
  3762. switch (item.Grade)
  3763. {
  3764. case ItemGrade.None:
  3765. Upgrade(item, ItemGrade.Common);
  3766. break;
  3767. case ItemGrade.Common:
  3768. Upgrade(item, ItemGrade.Rare);
  3769. break;
  3770. case ItemGrade.Rare:
  3771. Upgrade(item, ItemGrade.Legendary);
  3772. break;
  3773. case ItemGrade.Legendary:
  3774. Upgrade(item, ItemGrade.Mythical);
  3775. break;
  3776. case ItemGrade.Mythical:
  3777. Upgrade(item, ItemGrade.Godly);
  3778. break;
  3779. default:
  3780. break;
  3781. }
  3782. }
  3783. public void UpgradeGrade(PlayerObject player, UserItem item, ItemGrade grade)
  3784. {
  3785. Upgrade(item, grade);
  3786. }
  3787.  
  3788. private static void Upgrade(UserItem item, ItemGrade grade)
  3789. {
  3790. int buffStatsPercentage = 0;
  3791. int buffStatsBase = 0;
  3792. switch (grade)
  3793. {
  3794.  
  3795. case ItemGrade.Common:
  3796. buffStatsPercentage = Settings.CommonStatPercentage;
  3797. buffStatsBase = Settings.CommonStatBase;
  3798. break;
  3799. case ItemGrade.Rare:
  3800. buffStatsPercentage = Settings.RareStatPercentage;
  3801. buffStatsBase = Settings.RareStatBase;
  3802. break;
  3803. case ItemGrade.Legendary:
  3804. buffStatsPercentage = Settings.LegendaryStatPercentage;
  3805. buffStatsBase = Settings.LegendaryStatBase;
  3806. break;
  3807. case ItemGrade.Mythical:
  3808. buffStatsPercentage = Settings.MythicStatPercentage;
  3809. buffStatsBase = Settings.MythicStatBase;
  3810. break;
  3811. case ItemGrade.Godly:
  3812. buffStatsPercentage = Settings.GodlyStatPercentage;
  3813. buffStatsBase = Settings.GodlyStatBase;
  3814. break;
  3815.  
  3816. }
  3817. if (buffStatsPercentage == 0 && buffStatsBase == 0)
  3818. return;
  3819.  
  3820. var maxValue = 0;
  3821.  
  3822. if (item.Info.MaxAC > 0)
  3823. maxValue = item.Info.MaxAC > maxValue ? item.Info.MaxAC : maxValue;
  3824.  
  3825. if (item.Info.MaxMAC > 0)
  3826. maxValue = item.Info.MaxMAC > maxValue ? item.Info.MaxMAC : maxValue;
  3827.  
  3828. if (item.Info.MaxDC > 0)
  3829. maxValue = item.Info.MaxDC > maxValue ? item.Info.MaxDC : maxValue;
  3830.  
  3831. if (item.Info.MaxMC > 0)
  3832. maxValue = item.Info.MaxMC > maxValue ? item.Info.MaxMC : maxValue;
  3833.  
  3834. if (item.Info.MaxSC > 0)
  3835. maxValue = item.Info.MaxSC > maxValue ? item.Info.MaxSC : maxValue;
  3836.  
  3837. var valueToAdd = (ushort)Math.Min(ushort.MaxValue, buffStatsBase + Math.Round((decimal)maxValue * buffStatsPercentage / 100, 0, MidpointRounding.AwayFromZero));
  3838. var halfedVal = (ushort)Math.Round((decimal)valueToAdd / 2, 0, MidpointRounding.AwayFromZero);
  3839.  
  3840. if (item.Info.MaxAC > 0)
  3841. {
  3842. item.MaxAC = halfedVal;
  3843. item.MinAc = halfedVal;
  3844. }
  3845.  
  3846. if (item.Info.MaxMAC > 0)
  3847. {
  3848. item.MaxMAC = halfedVal;
  3849. item.MinMAC = halfedVal;
  3850. }
  3851.  
  3852. if (item.Info.MaxDC > 0)
  3853. {
  3854. item.MaxDC = valueToAdd;
  3855. item.MinDC = valueToAdd;
  3856. }
  3857.  
  3858. if (item.Info.MaxMC > 0)
  3859. {
  3860. item.MinMC = valueToAdd;
  3861. item.MaxMC = valueToAdd;
  3862. }
  3863. if (item.Info.MaxSC > 0)
  3864. {
  3865. item.MinSC = valueToAdd;
  3866. item.MaxSC = valueToAdd;
  3867. }
  3868. item.IsGradeUpgraded = true;
  3869. item.Grade = grade;
  3870.  
  3871. }
  3872. private static void Downgrade(UserItem item, ItemGrade grade)
  3873. {
  3874. if (grade == ItemGrade.None)
  3875. {
  3876. item.IsGradeUpgraded = false;
  3877. item.MinAc = 0; item.MaxAC = 0;
  3878. item.MinMAC = 0; item.MaxMAC = 0;
  3879. item.MinDC = 0; item.MaxDC = 0;
  3880. item.MinSC = 0; item.MaxSC = 0;
  3881. item.MinMC = 0; item.MaxMC = 0;
  3882. item.Grade = ItemGrade.None;
  3883. return;
  3884. }
  3885.  
  3886. int buffStatsPercentage = 0;
  3887. int buffStatsBase = 0;
  3888. switch (grade)
  3889. {
  3890. case ItemGrade.Common:
  3891. buffStatsPercentage = Settings.CommonStatPercentage;
  3892. buffStatsBase = Settings.CommonStatBase;
  3893. break;
  3894. case ItemGrade.Rare:
  3895. buffStatsPercentage = Settings.RareStatPercentage;
  3896. buffStatsBase = Settings.RareStatBase;
  3897. break;
  3898. case ItemGrade.Legendary:
  3899. buffStatsPercentage = Settings.LegendaryStatPercentage;
  3900. buffStatsBase = Settings.LegendaryStatBase;
  3901. break;
  3902. case ItemGrade.Mythical:
  3903. buffStatsPercentage = Settings.MythicStatPercentage;
  3904. buffStatsBase = Settings.MythicStatBase;
  3905. break;
  3906. case ItemGrade.Godly:
  3907. buffStatsPercentage = Settings.GodlyStatPercentage;
  3908. buffStatsBase = Settings.GodlyStatBase;
  3909. break;
  3910.  
  3911. }
  3912. item.Grade = grade;
  3913. if (buffStatsPercentage == 0 && buffStatsBase == 0)
  3914. return;
  3915.  
  3916. var maxValue = 0;
  3917.  
  3918. if (item.Info.MaxAC > 0)
  3919. maxValue = item.Info.MaxAC > maxValue ? item.Info.MaxAC : maxValue;
  3920.  
  3921. if (item.Info.MaxMAC > 0)
  3922. maxValue = item.Info.MaxMAC > maxValue ? item.Info.MaxMAC : maxValue;
  3923.  
  3924. if (item.Info.MaxDC > 0)
  3925. maxValue = item.Info.MaxDC > maxValue ? item.Info.MaxDC : maxValue;
  3926.  
  3927. if (item.Info.MaxMC > 0)
  3928. maxValue = item.Info.MaxMC > maxValue ? item.Info.MaxMC : maxValue;
  3929.  
  3930. if (item.Info.MaxSC > 0)
  3931. maxValue = item.Info.MaxSC > maxValue ? item.Info.MaxSC : maxValue;
  3932.  
  3933. var valueToAdd = (ushort)Math.Min(ushort.MaxValue, buffStatsBase + Math.Round((decimal)maxValue * buffStatsPercentage / 100, 0, MidpointRounding.AwayFromZero));
  3934. var halfedValue = (ushort)Math.Round((decimal)valueToAdd / 2, 0, MidpointRounding.AwayFromZero);
  3935.  
  3936.  
  3937. if (item.Info.MaxAC > 0)
  3938. {
  3939. item.MaxAC = halfedValue;
  3940. item.MinAc = halfedValue;
  3941. }
  3942.  
  3943. if (item.Info.MaxMAC > 0)
  3944. {
  3945.  
  3946. item.MaxMAC = halfedValue;
  3947. item.MinMAC = halfedValue;
  3948. }
  3949.  
  3950. if (item.Info.MaxDC > 0)
  3951. {
  3952. item.MaxDC = valueToAdd;
  3953. item.MinDC = valueToAdd;
  3954. }
  3955.  
  3956. if (item.Info.MaxMC > 0)
  3957. {
  3958. item.MinMC = valueToAdd;
  3959. item.MaxMC = valueToAdd;
  3960.  
  3961. }
  3962. if (item.Info.MaxSC > 0)
  3963. {
  3964. item.MinSC = valueToAdd;
  3965. item.MaxSC = valueToAdd;
  3966.  
  3967. }
  3968. }
  3969.  
  3970. public void UpgradeItem(UserItem item)
  3971. {
  3972. if (item.Info.RandomStats == null) return;
  3973. RandomItemStat stat = item.Info.RandomStats;
  3974. if ((stat.MaxDuraChance > 0) && (Random.Next(stat.MaxDuraChance) == 0))
  3975. {
  3976. int dura = RandomRange(stat.MaxDuraMaxStat, stat.MaxDuraStatChance);
  3977. item.MaxDura = (ushort)Math.Min(ushort.MaxValue, item.MaxDura + dura * 1000);
  3978. item.CurrentDura = (ushort)Math.Min(ushort.MaxValue, item.CurrentDura + dura * 1000);
  3979. }
  3980.  
  3981. if ((stat.MaxAcChance > 0) && (Random.Next(stat.MaxAcChance) == 0)) item.AC = (byte)(RandomRange(stat.MaxAcMaxStat - 1, stat.MaxAcStatChance) + 1);
  3982. if ((stat.MaxMacChance > 0) && (Random.Next(stat.MaxMacChance) == 0)) item.MAC = (byte)(RandomRange(stat.MaxMacMaxStat - 1, stat.MaxMacStatChance) + 1);
  3983. if ((stat.MaxDcChance > 0) && (Random.Next(stat.MaxDcChance) == 0)) item.DC = (byte)(RandomRange(stat.MaxDcMaxStat - 1, stat.MaxDcStatChance) + 1);
  3984. if ((stat.MaxMcChance > 0) && (Random.Next(stat.MaxScChance) == 0)) item.MC = (byte)(RandomRange(stat.MaxMcMaxStat - 1, stat.MaxMcStatChance) + 1);
  3985. if ((stat.MaxScChance > 0) && (Random.Next(stat.MaxMcChance) == 0)) item.SC = (byte)(RandomRange(stat.MaxScMaxStat - 1, stat.MaxScStatChance) + 1);
  3986. if ((stat.AccuracyChance > 0) && (Random.Next(stat.AccuracyChance) == 0)) item.Accuracy = (byte)(RandomRange(stat.AccuracyMaxStat - 1, stat.AccuracyStatChance) + 1);
  3987. if ((stat.AgilityChance > 0) && (Random.Next(stat.AgilityChance) == 0)) item.Agility = (byte)(RandomRange(stat.AgilityMaxStat - 1, stat.AgilityStatChance) + 1);
  3988.  
  3989. if ((stat.HpChance > 0) && (Random.Next(stat.HpChance) == 0))
  3990. {
  3991. int hp = RandomRange(stat.HpMaxStat, stat.HpChance);
  3992. item.HP = (ushort)Math.Min(ushort.MaxValue, item.HP + hp * 10);
  3993. }
  3994.  
  3995. if ((stat.MpChance > 0) && (Random.Next(stat.MpChance) == 0))
  3996. {
  3997. int mp = RandomRange(stat.MpMaxStat, stat.MpChance);
  3998. item.MP = (ushort)Math.Min(ushort.MaxValue, item.MP + mp * 10);
  3999. }
  4000.  
  4001. // if ((stat.HpChance > 0) && (Random.Next(stat.HpChance) == 0)) item.HP = (byte)(RandomRange(stat.HpMaxStat - 10, stat.HpStatChance) + 10);
  4002. // if ((stat.MpChance > 0) && (Random.Next(stat.MpChance) == 0)) item.MP = (byte)(RandomRange(stat.MpMaxStat - 10, stat.MpStatChance) + 10);
  4003.  
  4004. if ((stat.StrongChance > 0) && (Random.Next(stat.StrongChance) == 0)) item.Strong = (byte)(RandomRange(stat.StrongMaxStat - 1, stat.StrongStatChance) + 1);
  4005. if ((stat.MagicResistChance > 0) && (Random.Next(stat.MagicResistChance) == 0)) item.MagicResist = (byte)(RandomRange(stat.MagicResistMaxStat - 1, stat.MagicResistStatChance) + 1);
  4006. if ((stat.PoisonResistChance > 0) && (Random.Next(stat.PoisonResistChance) == 0)) item.PoisonResist = (byte)(RandomRange(stat.PoisonResistMaxStat - 1, stat.PoisonResistStatChance) + 1);
  4007. if ((stat.HpRecovChance > 0) && (Random.Next(stat.HpRecovChance) == 0)) item.HealthRecovery = (byte)(RandomRange(stat.HpRecovMaxStat - 1, stat.HpRecovStatChance) + 1);
  4008. if ((stat.MpRecovChance > 0) && (Random.Next(stat.MpRecovChance) == 0)) item.ManaRecovery = (byte)(RandomRange(stat.MpRecovMaxStat - 1, stat.MpRecovStatChance) + 1);
  4009. if ((stat.PoisonRecovChance > 0) && (Random.Next(stat.PoisonRecovChance) == 0)) item.PoisonRecovery = (byte)(RandomRange(stat.PoisonRecovMaxStat - 1, stat.PoisonRecovStatChance) + 1);
  4010. if ((stat.CriticalRateChance > 0) && (Random.Next(stat.CriticalRateChance) == 0)) item.CriticalRate = (byte)(RandomRange(stat.CriticalRateMaxStat - 1, stat.CriticalRateStatChance) + 1);
  4011. if ((stat.CriticalDamageChance > 0) && (Random.Next(stat.CriticalDamageChance) == 0)) item.CriticalDamage = (byte)(RandomRange(stat.CriticalDamageMaxStat - 1, stat.CriticalDamageStatChance) + 1);
  4012. if ((stat.FreezeChance > 0) && (Random.Next(stat.FreezeChance) == 0)) item.Freezing = (byte)(RandomRange(stat.FreezeMaxStat - 1, stat.FreezeStatChance) + 1);
  4013. if ((stat.PoisonAttackChance > 0) && (Random.Next(stat.PoisonAttackChance) == 0)) item.PoisonAttack = (byte)(RandomRange(stat.PoisonAttackMaxStat - 1, stat.PoisonAttackStatChance) + 1);
  4014. if ((stat.AttackSpeedChance > 0) && (Random.Next(stat.AttackSpeedChance) == 0)) item.AttackSpeed = (sbyte)(RandomRange(stat.AttackSpeedMaxStat - 1, stat.AttackSpeedStatChance) + 1);
  4015. if ((stat.LuckChance > 0) && (Random.Next(stat.LuckChance) == 0)) item.Luck = (sbyte)(RandomRange(stat.LuckMaxStat - 1, stat.LuckStatChance) + 1);
  4016. if ((stat.CurseChance > 0) && (Random.Next(100) <= stat.CurseChance)) item.Cursed = true;
  4017. }
  4018.  
  4019. public int RandomRange(int count, int rate)
  4020. {
  4021. int x = 0;
  4022. for (int i = 0; i < count; i++) if (Random.Next(rate) == 0) x++;
  4023. return x;
  4024. }
  4025. public bool BindItem(UserItem item)
  4026. {
  4027. for (int i = 0; i < ItemInfoList.Count; i++)
  4028. {
  4029. ItemInfo info = ItemInfoList[i];
  4030. if (info.Index != item.ItemIndex) continue;
  4031. item.Info = info;
  4032.  
  4033. return BindSlotItems(item);
  4034. }
  4035. return false;
  4036. }
  4037.  
  4038. public bool BindGameShop(GameShopItem item, bool EditEnvir = true)
  4039. {
  4040. for (int i = 0; i < SMain.EditEnvir.ItemInfoList.Count; i++)
  4041. {
  4042. ItemInfo info = SMain.EditEnvir.ItemInfoList[i];
  4043. if (info.Index != item.ItemIndex) continue;
  4044. item.Info = info;
  4045.  
  4046. return true;
  4047. }
  4048. return false;
  4049. }
  4050.  
  4051. public bool BindSlotItems(UserItem item)
  4052. {
  4053. for (int i = 0; i < item.Slots.Length; i++)
  4054. {
  4055. if (item.Slots[i] == null) continue;
  4056.  
  4057. if (!BindItem(item.Slots[i])) return false;
  4058. }
  4059.  
  4060. item.SetSlotSize();
  4061.  
  4062. return true;
  4063. }
  4064.  
  4065. public bool BindQuest(QuestProgressInfo quest)
  4066. {
  4067. for (int i = 0; i < QuestInfoList.Count; i++)
  4068. {
  4069. QuestInfo info = QuestInfoList[i];
  4070. if (info.Index != quest.Index) continue;
  4071. quest.Info = info;
  4072. return true;
  4073. }
  4074. return false;
  4075. }
  4076.  
  4077. public Map GetMap(int index)
  4078. {
  4079. return MapList.FirstOrDefault(t => t.Info.Index == index);
  4080. }
  4081. public Map GetMapByName(string name)
  4082. {
  4083. return MapList.FirstOrDefault(t => String.Equals(t.Info.FileName, name, StringComparison.CurrentCultureIgnoreCase));
  4084. }
  4085. public Map GetMapByNameAndInstance(string name, int instanceValue = 0)
  4086. {
  4087. if (instanceValue < 0) instanceValue = 0;
  4088. if (instanceValue > 0) instanceValue--;
  4089.  
  4090. var instanceMapList = MapList.Where(t => String.Equals(t.Info.FileName, name, StringComparison.CurrentCultureIgnoreCase)).ToList();
  4091. return instanceValue < instanceMapList.Count() ? instanceMapList[instanceValue] : null;
  4092. }
  4093.  
  4094. public MapObject GetObject(uint objectID)
  4095. {
  4096. return Objects.FirstOrDefault(e => e.ObjectID == objectID);
  4097. }
  4098.  
  4099. public MonsterInfo GetMonsterInfo(int index)
  4100. {
  4101. for (int i = 0; i < MonsterInfoList.Count; i++)
  4102. if (MonsterInfoList[i].Index == index) return MonsterInfoList[i];
  4103.  
  4104. return null;
  4105. }
  4106.  
  4107. public NPCObject GetNPC(string name)
  4108. {
  4109. return MapList.SelectMany(t1 => t1.NPCs.Where(t => t.Info.Name == name)).FirstOrDefault();
  4110. }
  4111. /*
  4112. public MonsterInfo GetMonsterInfo(string name)
  4113. {
  4114. for (int i = 0; i < MonsterInfoList.Count; i++)
  4115. {
  4116. MonsterInfo info = MonsterInfoList[i];
  4117. //if (info.Name != name && !info.Name.Replace(" ", "").StartsWith(name, StringComparison.OrdinalIgnoreCase)) continue;
  4118. if (String.Compare(info.Name, name, StringComparison.OrdinalIgnoreCase) != 0 && String.Compare(info.Name.Replace(" ", ""), name.Replace(" ", ""), StringComparison.OrdinalIgnoreCase) != 0) continue;
  4119. return info;
  4120. }
  4121. return null;
  4122. }
  4123. */
  4124. public MonsterInfo GetMonsterInfo(string name, bool Strict = false)
  4125. {
  4126. for (int i = 0; i < MonsterInfoList.Count; i++)
  4127. {
  4128. MonsterInfo info = MonsterInfoList[i];
  4129. if (Strict)
  4130. {
  4131. if (info.Name != name) continue;
  4132. return info;
  4133. }
  4134. else
  4135. {
  4136. //if (info.Name != name && !info.Name.Replace(" ", "").StartsWith(name, StringComparison.OrdinalIgnoreCase)) continue;
  4137. if (String.Compare(info.Name, name, StringComparison.OrdinalIgnoreCase) != 0 && String.Compare(info.Name.Replace(" ", ""), name.Replace(" ", ""), StringComparison.OrdinalIgnoreCase) != 0) continue;
  4138. return info;
  4139. }
  4140. }
  4141. return null;
  4142. }
  4143. public PlayerObject GetPlayer(string name)
  4144. {
  4145. for (int i = 0; i < Players.Count; i++)
  4146. if (String.Compare(Players[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  4147. return Players[i];
  4148.  
  4149. return null;
  4150. }
  4151. public PlayerObject GetPlayer(uint PlayerId)
  4152. {
  4153. var player = Players.FirstOrDefault(p => p.Info.Index == PlayerId);
  4154. return player;
  4155. //for (int i = 0; i < Players.Count; i++)
  4156. // if (Players[i].Info.Index == PlayerId)
  4157. // return Players[i];
  4158.  
  4159. //return null;
  4160. }
  4161. public CharacterInfo GetCharacterInfo(string name)
  4162. {
  4163. for (int i = 0; i < CharacterList.Count; i++)
  4164. if (String.Compare(CharacterList[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  4165. return CharacterList[i];
  4166.  
  4167. return null;
  4168. }
  4169.  
  4170. public CharacterInfo GetCharacterInfo(int index)
  4171. {
  4172. for (int i = 0; i < CharacterList.Count; i++)
  4173. if (CharacterList[i].Index == index)
  4174. return CharacterList[i];
  4175.  
  4176. return null;
  4177. }
  4178.  
  4179. public ItemInfo GetItemInfo(int index)
  4180. {
  4181. for (int i = 0; i < ItemInfoList.Count; i++)
  4182. {
  4183. ItemInfo info = ItemInfoList[i];
  4184. if (info.Index != index) continue;
  4185. return info;
  4186. }
  4187. return null;
  4188. }
  4189. public ItemInfo GetItemInfo(string name)
  4190. {
  4191. for (int i = 0; i < ItemInfoList.Count; i++)
  4192. {
  4193. ItemInfo info = ItemInfoList[i];
  4194. if (String.Compare(info.Name.Replace(" ", ""), name, StringComparison.OrdinalIgnoreCase) != 0) continue;
  4195. return info;
  4196. }
  4197. return null;
  4198. }
  4199. public QuestInfo GetQuestInfo(int index)
  4200. {
  4201. return QuestInfoList.FirstOrDefault(info => info.Index == index);
  4202. }
  4203.  
  4204. public ItemInfo GetBook(short Skill)
  4205. {
  4206. for (int i = 0; i < ItemInfoList.Count; i++)
  4207. {
  4208. ItemInfo info = ItemInfoList[i];
  4209. if ((info.Type != ItemType.Book) || (info.Shape != Skill)) continue;
  4210. return info;
  4211. }
  4212. return null;
  4213. }
  4214.  
  4215. public void MessageAccount(AccountInfo account, string message, ChatType type)
  4216. {
  4217. if (account == null) return;
  4218. if (account.Characters == null) return;
  4219.  
  4220. for (int i = 0; i < account.Characters.Count; i++)
  4221. {
  4222. if (account.Characters[i].Player == null) continue;
  4223. account.Characters[i].Player.ReceiveChat(message, type);
  4224. return;
  4225. }
  4226. }
  4227. public GuildObject GetGuild(string name)
  4228. {
  4229. for (int i = 0; i < GuildList.Count; i++)
  4230. {
  4231. if (String.Compare(GuildList[i].Name.Replace(" ", ""), name, StringComparison.OrdinalIgnoreCase) != 0) continue;
  4232. return GuildList[i];
  4233. }
  4234. return null;
  4235. }
  4236. public GuildObject GetGuild(int index)
  4237. {
  4238. for (int i = 0; i < GuildList.Count; i++)
  4239. if (GuildList[i].Guildindex == index)
  4240. return GuildList[i];
  4241. return null;
  4242. }
  4243.  
  4244. public void ProcessNewDay()
  4245. {
  4246. foreach (CharacterInfo c in CharacterList)
  4247. {
  4248. ClearDailyQuests(c);
  4249.  
  4250. c.NewDay = true;
  4251.  
  4252. if (c.Player != null)
  4253. {
  4254. c.Player.CallDefaultNPC(DefaultNPCType.Daily);
  4255. }
  4256. }
  4257. }
  4258.  
  4259. private void ClearDailyQuests(CharacterInfo info)
  4260. {
  4261. foreach (var quest in QuestInfoList)
  4262. {
  4263. if (quest.Type != QuestType.Daily) continue;
  4264.  
  4265. for (int i = 0; i < info.CompletedQuests.Count; i++)
  4266. {
  4267. if (info.CompletedQuests[i] != quest.Index) continue;
  4268.  
  4269. info.CompletedQuests.RemoveAt(i);
  4270. }
  4271. }
  4272.  
  4273. if (info.Player != null)
  4274. {
  4275. info.Player.GetCompletedQuests();
  4276. }
  4277. }
  4278.  
  4279. public GuildBuffInfo FindGuildBuffInfo(int Id)
  4280. {
  4281. for (int i = 0; i < Settings.Guild_BuffList.Count; i++)
  4282. if (Settings.Guild_BuffList[i].Id == Id)
  4283. return Settings.Guild_BuffList[i];
  4284. return null;
  4285. }
  4286.  
  4287. public void ClearGameshopLog()
  4288. {
  4289. SMain.Envir.GameshopLog.Clear();
  4290.  
  4291. for (int i = 0; i < AccountList.Count; i++)
  4292. {
  4293. for (int f = 0; f < AccountList[i].Characters.Count; f++)
  4294. {
  4295. AccountList[i].Characters[f].GSpurchases.Clear();
  4296. }
  4297. }
  4298.  
  4299. ResetGS = false;
  4300. SMain.Enqueue("Gameshop Purchase Logs Cleared.");
  4301.  
  4302. }
  4303.  
  4304. public bool InsertRank(List<Rank_Character_Info> Ranking, Rank_Character_Info NewRank)
  4305. {
  4306. bool output = false;
  4307. if (Ranking.Count == 0)
  4308. {
  4309. Ranking.Add(NewRank);
  4310. return true;
  4311. }
  4312. for (int i = 0; i < Ranking.Count; i++)
  4313. {
  4314. if (Ranking[i] == null)
  4315. {
  4316. Ranking.Insert(i, NewRank);
  4317. output = true;
  4318. break;
  4319. }
  4320. //if level is lower
  4321. if (Ranking[i].level < NewRank.level)
  4322. {
  4323. Ranking.Insert(i, NewRank);
  4324. output = true;
  4325. break;
  4326. }
  4327. //if exp is lower but level = same
  4328. if ((Ranking[i].level == NewRank.level) && (Ranking[i].Experience < NewRank.Experience))
  4329. {
  4330. Ranking.Insert(i, NewRank);
  4331. output = true;
  4332. break;
  4333. }
  4334. }
  4335. if ((Ranking.Count < 20) && (!output))
  4336. {
  4337. Ranking.Add(NewRank);
  4338. return true;
  4339. }
  4340. return output;
  4341. }
  4342.  
  4343. public bool UpdateRank(List<Rank_Character_Info> Ranking, CharacterInfo info)
  4344. {
  4345. for (int i = 0; i < Ranking.Count; i++)
  4346. {
  4347. if (Ranking[i] == null) break;//safety first
  4348. if (Ranking[i].Name == info.Name)
  4349. {
  4350. Ranking[i].level = info.Level;
  4351. Ranking[i].Experience = info.Experience;
  4352. int NewRank = -1;
  4353. for (int j = i - 1; j >= 0; j--)
  4354. {
  4355. if (Ranking[j] == null) break;//safety first
  4356. if ((Ranking[j].level > Ranking[i].level) || (Ranking[j].Experience > Ranking[i].Experience)) break;
  4357. NewRank = j;
  4358. }
  4359. if (NewRank > -1)
  4360. {
  4361. Ranking.Insert(NewRank, Ranking[i]);
  4362. Ranking.RemoveAt(i + 1);
  4363. }
  4364.  
  4365. return true;
  4366. }
  4367. }
  4368. return false;
  4369. }
  4370.  
  4371. public void CheckRankUpdate(CharacterInfo info)
  4372. {
  4373. List<Rank_Character_Info> Ranking;
  4374. //first check overall top 20
  4375. Rank_Character_Info NewRank;
  4376. if (info.Level >= RankBottomLevel[0])
  4377. {
  4378. Ranking = RankTop20;
  4379. if (!UpdateRank(Ranking, info))
  4380. {
  4381. NewRank = new Rank_Character_Info() { Name = info.Name, Class = info.Class, Experience = info.Experience, level = info.Level/*, rank = 1*/, PlayerId = info.Index };
  4382. if (InsertRank(Ranking, NewRank))
  4383. {
  4384. if (Ranking.Count > 20)
  4385. Ranking.RemoveAt(20);
  4386. }
  4387. }
  4388. if (Ranking.Count >= 20)
  4389. {
  4390. NewRank = Ranking.Last();
  4391. if (NewRank != null)
  4392. RankBottomLevel[0] = NewRank.level;
  4393. }
  4394. }
  4395. //now check class top 20
  4396. if (info.Level >= RankBottomLevel[(byte)info.Class + 1])
  4397. {
  4398. Ranking = RankClass20[(byte)info.Class];
  4399. if (!UpdateRank(Ranking, info))
  4400. {
  4401. NewRank = new Rank_Character_Info() { Name = info.Name, Class = info.Class, Experience = info.Experience, level = info.Level/*, rank = 1*/, PlayerId = info.Index };
  4402. if (InsertRank(Ranking, NewRank))
  4403. {
  4404. if (Ranking.Count > 20)
  4405. Ranking.RemoveAt(20);
  4406. }
  4407. }
  4408. if (Ranking.Count >= 20)
  4409. {
  4410. NewRank = Ranking.Last();
  4411. if (NewRank != null)
  4412. RankBottomLevel[(byte)info.Class + 1] = NewRank.level;
  4413. }
  4414. }
  4415. }
  4416. }
  4417.  
  4418.  
  4419. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement