Envir.cs 204 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487
  1. using ClientPackets;
  2. using Server.Library.MirDatabase;
  3. using Server.Library.Utils;
  4. using Server.MirDatabase;
  5. using Server.MirNetwork;
  6. using Server.MirObjects;
  7. using Server.MirObjects.Monsters;
  8. using System.Collections.Concurrent;
  9. using System.Diagnostics;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Numerics;
  13. using System.Text.RegularExpressions;
  14. using S = ServerPackets;
  15. namespace Server.MirEnvir
  16. {
  17. public class MobThread
  18. {
  19. public int Id = 0;
  20. public long LastRunTime = 0;
  21. public long StartTime = 0;
  22. public long EndTime = 0;
  23. public LinkedList<MapObject> ObjectsList = new LinkedList<MapObject>();
  24. public LinkedListNode<MapObject> _current = null;
  25. public bool Stop = false;
  26. }
  27. public class RandomProvider
  28. {
  29. private static int seed = Environment.TickCount;
  30. private static readonly ThreadLocal<Random> RandomWrapper = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));
  31. public static Random GetThreadRandom() =>
  32. RandomWrapper.Value;
  33. public int Next() =>
  34. RandomWrapper.Value.Next();
  35. public int Next(int maxValue) =>
  36. RandomWrapper.Value.Next(maxValue);
  37. public int Next(int minValue, int maxValue) =>
  38. RandomWrapper.Value.Next(minValue, maxValue);
  39. }
  40. public class Envir
  41. {
  42. public static Envir Main { get; } = new Envir();
  43. public static Envir Edit { get; } = new Envir();
  44. protected static MessageQueue MessageQueue => MessageQueue.Instance;
  45. public static object AccountLock = new object();
  46. public static object LoadLock = new object();
  47. public const int MinVersion = 60;
  48. public const int Version = 117;
  49. public const int CustomVersion = 0;
  50. public static readonly string DatabasePath = Path.Combine(".", "Server.MirDB");
  51. public static readonly string AccountPath = Path.Combine(".", "Server.MirADB");
  52. public static readonly string BackUpPath = Path.Combine(".", "Back Up");
  53. public static readonly string AccountsBackUpPath = Path.Combine(".", "Back Up", "Accounts");
  54. public static readonly string DatabaseBackUpPath = Path.Combine(".", "Back Up", "Database");
  55. public static readonly string ArchivePath = Path.Combine(".", "Archive");
  56. public bool ResetGS = false;
  57. public bool GuildRefreshNeeded;
  58. private static readonly Regex AccountIDReg, PasswordReg, EMailReg, CharacterReg;
  59. public static int LoadVersion;
  60. public static int LoadCustomVersion;
  61. private readonly DateTime _startTime = DateTime.UtcNow;
  62. public readonly Stopwatch Stopwatch = Stopwatch.StartNew();
  63. public long Time { get; private set; }
  64. public RespawnTimer RespawnTick = new RespawnTimer();
  65. private static List<string> DisabledCharNames = new List<string>();
  66. private static List<string> LineMessages = new List<string>();
  67. public static ConcurrentDictionary<string, DateTime> IPBlocks = new ConcurrentDictionary<string, DateTime>();
  68. public static ConcurrentDictionary<string, MirConnectionLog> ConnectionLogs = new ConcurrentDictionary<string, MirConnectionLog>();
  69. public DateTime Now =>
  70. _startTime.AddMilliseconds(Time);
  71. public bool Running { get; private set; }
  72. private static uint _objectID;
  73. public uint ObjectID => ++_objectID;
  74. public static int _playerCount;
  75. public int PlayerCount => Players.Count;
  76. public int[] OnlineRankingCount = new int[6];
  77. public int HeroCount => Heroes.Count;
  78. public RandomProvider Random = new RandomProvider();
  79. private Thread _thread;
  80. private TcpListener _listener;
  81. private bool StatusPortEnabled = true;
  82. public List<MirStatusConnection> StatusConnections = new List<MirStatusConnection>();
  83. private TcpListener _StatusPort;
  84. private int _sessionID;
  85. public List<MirConnection> Connections = new List<MirConnection>();
  86. //Server DB
  87. public int MapIndex, ItemIndex, MonsterIndex, NPCIndex, QuestIndex, GameshopIndex, ConquestIndex, RespawnIndex, ScriptIndex;
  88. public List<MapInfo> MapInfoList = new List<MapInfo>();
  89. public List<ItemInfo> ItemInfoList = new List<ItemInfo>();
  90. public List<MonsterInfo> MonsterInfoList = new List<MonsterInfo>();
  91. public List<MagicInfo> MagicInfoList = new List<MagicInfo>();
  92. public List<NPCInfo> NPCInfoList = new List<NPCInfo>();
  93. public DragonInfo DragonInfo = new DragonInfo();
  94. public List<QuestInfo> QuestInfoList = new List<QuestInfo>();
  95. public List<GameShopItem> GameShopList = new List<GameShopItem>();
  96. public List<RecipeInfo> RecipeInfoList = new List<RecipeInfo>();
  97. public List<BuffInfo> BuffInfoList = new List<BuffInfo>();
  98. public List<ConquestInfo> ConquestInfoList = new List<ConquestInfo>();
  99. public List<GTMap> GTMapList = new List<GTMap>();
  100. //User DB
  101. public int NextAccountID, NextCharacterID, NextGuildID, NextHeroID;
  102. public ulong NextUserItemID, NextAuctionID, NextMailID, NextRecipeID;
  103. public List<AccountInfo> AccountList = new List<AccountInfo>();
  104. public List<CharacterInfo> CharacterList = new List<CharacterInfo>();
  105. public List<GuildInfo> GuildList = new List<GuildInfo>();
  106. public LinkedList<AuctionInfo> Auctions = new LinkedList<AuctionInfo>();
  107. public List<ConquestGuildInfo> ConquestList = new List<ConquestGuildInfo>();
  108. public Dictionary<int, int> GameshopLog = new Dictionary<int, int>();
  109. public List<HeroInfo> HeroList = new List<HeroInfo>();
  110. public int GuildCount; //This shouldn't be needed?? -> remove in the future
  111. //Live Info
  112. public bool Saving = false;
  113. public List<Map> MapList = new List<Map>();
  114. public List<SafeZoneInfo> StartPoints = new List<SafeZoneInfo>();
  115. public List<ItemInfo> StartItems = new List<ItemInfo>();
  116. public List<PlayerObject> Players = new List<PlayerObject>();
  117. public List<SpellObject> Spells = new List<SpellObject>();
  118. public List<NPCObject> NPCs = new List<NPCObject>();
  119. public List<GuildObject> Guilds = new List<GuildObject>();
  120. public List<ConquestObject> Conquests = new List<ConquestObject>();
  121. public List<HeroObject> Heroes = new List<HeroObject>();
  122. public LightSetting Lights;
  123. public LinkedList<MapObject> Objects = new LinkedList<MapObject>();
  124. public Dictionary<int, NPCScript> Scripts = new Dictionary<int, NPCScript>();
  125. public Dictionary<string, Timer> Timers = new Dictionary<string, Timer>();
  126. //multithread vars
  127. readonly object _locker = new object();
  128. public MobThread[] MobThreads = new MobThread[Settings.ThreadLimit];
  129. private readonly Thread[] MobThreading = new Thread[Settings.ThreadLimit];
  130. public int SpawnMultiplier = 1;//set this to 2 if you want double spawns (warning this can easily lag your server far beyond what you imagine)
  131. public List<string> CustomCommands = new List<string>();
  132. public Dragon DragonSystem;
  133. public NPCScript DefaultNPC, MonsterNPC, RobotNPC;
  134. public List<DropInfo> FishingDrops = new List<DropInfo>();
  135. public List<DropInfo> AwakeningDrops = new List<DropInfo>();
  136. public List<DropInfo> StrongboxDrops = new List<DropInfo>();
  137. public List<DropInfo> BlackstoneDrops = new List<DropInfo>();
  138. public List<GuildAtWar> GuildsAtWar = new List<GuildAtWar>();
  139. public List<MapRespawn> SavedSpawns = new List<MapRespawn>();
  140. public List<RankCharacterInfo> RankTop = new List<RankCharacterInfo>();
  141. public List<RankCharacterInfo>[] RankClass = new List<RankCharacterInfo>[5];
  142. static HttpServer http;
  143. static Envir()
  144. {
  145. AccountIDReg = new Regex(@"^[A-Za-z0-9]{" + Globals.MinAccountIDLength + "," + Globals.MaxAccountIDLength + "}$");
  146. PasswordReg = new Regex(@"^[A-Za-z0-9]{" + Globals.MinPasswordLength + "," + Globals.MaxPasswordLength + "}$");
  147. EMailReg = new Regex(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
  148. CharacterReg = new Regex(@"^[\u4e00-\u9fa5_A-Za-z0-9]{" + Globals.MinCharacterNameLength + "," + Globals.MaxCharacterNameLength + "}$");
  149. }
  150. public static bool IsPasswordValid(string password)
  151. {
  152. if (string.IsNullOrEmpty(password)) return false;
  153. return PasswordReg.IsMatch(password);
  154. }
  155. public static int LastCount = 0, LastRealCount = 0;
  156. public static long LastRunTime = 0;
  157. public int MonsterCount;
  158. private long warTime, guildTime, conquestTime, rentalItemsTime, auctionTime, spawnTime, robotTime, timerTime;
  159. private int dailyTime = DateTime.UtcNow.Day;
  160. private bool MagicExists(Spell spell)
  161. {
  162. for (var i = 0; i < MagicInfoList.Count; i++)
  163. {
  164. if (MagicInfoList[i].Spell == spell) return true;
  165. }
  166. return false;
  167. }
  168. private void UpdateMagicInfo()
  169. {
  170. for (var i = 0; i < MagicInfoList.Count; i++)
  171. {
  172. switch (MagicInfoList[i].Spell)
  173. {
  174. //warrior
  175. case Spell.Thrusting:
  176. MagicInfoList[i].MultiplierBase = 0.25f;
  177. MagicInfoList[i].MultiplierBonus = 0.25f;
  178. break;
  179. case Spell.HalfMoon:
  180. MagicInfoList[i].MultiplierBase = 0.3f;
  181. MagicInfoList[i].MultiplierBonus = 0.1f;
  182. break;
  183. case Spell.ShoulderDash:
  184. MagicInfoList[i].MPowerBase = 4;
  185. break;
  186. case Spell.TwinDrakeBlade:
  187. MagicInfoList[i].MultiplierBase = 0.8f;
  188. MagicInfoList[i].MultiplierBonus = 0.1f;
  189. break;
  190. case Spell.FlamingSword:
  191. MagicInfoList[i].MultiplierBase = 1.4f;
  192. MagicInfoList[i].MultiplierBonus = 0.4f;
  193. break;
  194. case Spell.CrossHalfMoon:
  195. MagicInfoList[i].MultiplierBase = 0.4f;
  196. MagicInfoList[i].MultiplierBonus = 0.1f;
  197. break;
  198. case Spell.BladeAvalanche:
  199. MagicInfoList[i].MultiplierBase = 1f;
  200. MagicInfoList[i].MultiplierBonus = 0.4f;
  201. break;
  202. case Spell.SlashingBurst:
  203. MagicInfoList[i].MultiplierBase = 3.25f;
  204. MagicInfoList[i].MultiplierBonus = 0.25f;
  205. break;
  206. //wiz
  207. case Spell.Repulsion:
  208. MagicInfoList[i].MPowerBase = 4;
  209. break;
  210. //tao
  211. case Spell.Poisoning:
  212. MagicInfoList[i].MPowerBase = 0;
  213. break;
  214. case Spell.Curse:
  215. MagicInfoList[i].MPowerBase = 20;
  216. break;
  217. case Spell.Plague:
  218. MagicInfoList[i].MPowerBase = 0;
  219. MagicInfoList[i].PowerBase = 0;
  220. break;
  221. //sin
  222. case Spell.FatalSword:
  223. MagicInfoList[i].MPowerBase = 20;
  224. break;
  225. case Spell.DoubleSlash:
  226. MagicInfoList[i].MultiplierBase = 0.8f;
  227. MagicInfoList[i].MultiplierBonus = 0.1f;
  228. break;
  229. case Spell.FireBurst:
  230. MagicInfoList[i].MPowerBase = 4;
  231. break;
  232. case Spell.MoonLight:
  233. MagicInfoList[i].MPowerBase = 20;
  234. break;
  235. case Spell.DarkBody:
  236. MagicInfoList[i].MPowerBase = 20;
  237. break;
  238. case Spell.Hemorrhage:
  239. MagicInfoList[i].MultiplierBase = 0.2f;
  240. MagicInfoList[i].MultiplierBonus = 0.05f;
  241. break;
  242. case Spell.CrescentSlash:
  243. MagicInfoList[i].MultiplierBase = 1f;
  244. MagicInfoList[i].MultiplierBonus = 0.4f;
  245. break;
  246. }
  247. }
  248. }
  249. private void FillMagicInfoList()
  250. {
  251. //Warrior
  252. if (!MagicExists(Spell.Fencing))
  253. 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 });
  254. if (!MagicExists(Spell.Slaying))
  255. 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 });
  256. if (!MagicExists(Spell.Thrusting))
  257. MagicInfoList.Add(new MagicInfo
  258. {
  259. Name = "Thrusting",
  260. Spell = Spell.Thrusting,
  261. Icon = 11,
  262. Level1 = 22,
  263. Level2 = 24,
  264. Level3 = 27,
  265. Need1 = 2000,
  266. Need2 = 3500,
  267. Need3 = 6000,
  268. Range = 0,
  269. MultiplierBase = 0.25f,
  270. MultiplierBonus = 0.25f
  271. });
  272. if (!MagicExists(Spell.HalfMoon))
  273. MagicInfoList.Add(new MagicInfo
  274. {
  275. Name = "HalfMoon",
  276. Spell = Spell.HalfMoon,
  277. Icon = 24,
  278. Level1 = 26,
  279. Level2 = 28,
  280. Level3 = 31,
  281. Need1 = 5000,
  282. Need2 = 8000,
  283. Need3 = 14000,
  284. BaseCost = 3,
  285. Range = 0,
  286. MultiplierBase = 0.3f,
  287. MultiplierBonus = 0.1f
  288. });
  289. if (!MagicExists(Spell.ShoulderDash))
  290. MagicInfoList.Add(new MagicInfo
  291. {
  292. Name = "ShoulderDash",
  293. Spell = Spell.ShoulderDash,
  294. Icon = 26,
  295. Level1 = 30,
  296. Level2 = 32,
  297. Level3 = 34,
  298. Need1 = 3000,
  299. Need2 = 4000,
  300. Need3 = 6000,
  301. BaseCost = 4,
  302. LevelCost = 4,
  303. DelayBase = 2500,
  304. Range = 0,
  305. MPowerBase = 4
  306. });
  307. if (!MagicExists(Spell.TwinDrakeBlade))
  308. MagicInfoList.Add(new MagicInfo
  309. {
  310. Name = "TwinDrakeBlade",
  311. Spell = Spell.TwinDrakeBlade,
  312. Icon = 37,
  313. Level1 = 32,
  314. Level2 = 34,
  315. Level3 = 37,
  316. Need1 = 4000,
  317. Need2 = 6000,
  318. Need3 = 10000,
  319. BaseCost = 10,
  320. Range = 0,
  321. MultiplierBase = 0.8f,
  322. MultiplierBonus = 0.1f
  323. });
  324. if (!MagicExists(Spell.Entrapment))
  325. MagicInfoList.Add(new MagicInfo
  326. {
  327. Name = "Entrapment",
  328. Spell = Spell.Entrapment,
  329. Icon = 46,
  330. Level1 = 32,
  331. Level2 = 35,
  332. Level3 = 37,
  333. Need1 = 2000,
  334. Need2 = 3500,
  335. Need3 = 5500,
  336. BaseCost = 15,
  337. LevelCost = 3,
  338. Range = 9
  339. });
  340. if (!MagicExists(Spell.FlamingSword))
  341. MagicInfoList.Add(new MagicInfo
  342. {
  343. Name = "FlamingSword",
  344. Spell = Spell.FlamingSword,
  345. Icon = 25,
  346. Level1 = 35,
  347. Level2 = 37,
  348. Level3 = 40,
  349. Need1 = 2000,
  350. Need2 = 4000,
  351. Need3 = 6000,
  352. BaseCost = 7,
  353. Range = 0,
  354. MultiplierBase = 1.4f,
  355. MultiplierBonus = 0.4f
  356. });
  357. if (!MagicExists(Spell.LionRoar))
  358. MagicInfoList.Add(new MagicInfo
  359. {
  360. Name = "LionRoar",
  361. Spell = Spell.LionRoar,
  362. Icon = 42,
  363. Level1 = 36,
  364. Level2 = 39,
  365. Level3 = 41,
  366. Need1 = 5000,
  367. Need2 = 8000,
  368. Need3 = 12000,
  369. BaseCost = 14,
  370. LevelCost = 4,
  371. Range = 0
  372. });
  373. if (!MagicExists(Spell.CrossHalfMoon))
  374. MagicInfoList.Add(new MagicInfo
  375. {
  376. Name = "CrossHalfMoon",
  377. Spell = Spell.CrossHalfMoon,
  378. Icon = 33,
  379. Level1 = 38,
  380. Level2 = 40,
  381. Level3 = 42,
  382. Need1 = 7000,
  383. Need2 = 11000,
  384. Need3 = 16000,
  385. BaseCost = 6,
  386. Range = 0,
  387. MultiplierBase = 0.4f,
  388. MultiplierBonus = 0.1f
  389. });
  390. if (!MagicExists(Spell.BladeAvalanche))
  391. MagicInfoList.Add(new MagicInfo
  392. {
  393. Name = "BladeAvalanche",
  394. Spell = Spell.BladeAvalanche,
  395. Icon = 43,
  396. Level1 = 38,
  397. Level2 = 41,
  398. Level3 = 43,
  399. Need1 = 5000,
  400. Need2 = 8000,
  401. Need3 = 12000,
  402. BaseCost = 14,
  403. LevelCost = 4,
  404. Range = 0,
  405. MultiplierBonus = 0.3f
  406. });
  407. if (!MagicExists(Spell.ProtectionField))
  408. MagicInfoList.Add(new MagicInfo
  409. {
  410. Name = "ProtectionField",
  411. Spell = Spell.ProtectionField,
  412. Icon = 50,
  413. Level1 = 39,
  414. Level2 = 42,
  415. Level3 = 45,
  416. Need1 = 6000,
  417. Need2 = 12000,
  418. Need3 = 18000,
  419. BaseCost = 23,
  420. LevelCost = 6,
  421. Range = 0
  422. });
  423. if (!MagicExists(Spell.Rage))
  424. MagicInfoList.Add(new MagicInfo
  425. { 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 });
  426. if (!MagicExists(Spell.CounterAttack))
  427. MagicInfoList.Add(new MagicInfo
  428. {
  429. Name = "CounterAttack",
  430. Spell = Spell.CounterAttack,
  431. Icon = 72,
  432. Level1 = 47,
  433. Level2 = 51,
  434. Level3 = 55,
  435. Need1 = 7000,
  436. Need2 = 11000,
  437. Need3 = 15000,
  438. BaseCost = 12,
  439. LevelCost = 4,
  440. DelayBase = 24000,
  441. Range = 0,
  442. MultiplierBonus = 0.4f
  443. });
  444. if (!MagicExists(Spell.SlashingBurst))
  445. MagicInfoList.Add(new MagicInfo
  446. {
  447. Name = "SlashingBurst",
  448. Spell = Spell.SlashingBurst,
  449. Icon = 55,
  450. Level1 = 50,
  451. Level2 = 53,
  452. Level3 = 56,
  453. Need1 = 10000,
  454. Need2 = 16000,
  455. Need3 = 24000,
  456. BaseCost = 25,
  457. LevelCost = 4,
  458. MPowerBase = 1,
  459. PowerBase = 3,
  460. DelayBase = 14000,
  461. DelayReduction = 4000,
  462. Range = 0,
  463. MultiplierBase = 3.25f,
  464. MultiplierBonus = 0.25f
  465. });
  466. if (!MagicExists(Spell.Fury))
  467. MagicInfoList.Add(new MagicInfo
  468. {
  469. Name = "Fury",
  470. Spell = Spell.Fury,
  471. Icon = 76,
  472. Level1 = 45,
  473. Level2 = 48,
  474. Level3 = 51,
  475. Need1 = 8000,
  476. Need2 = 14000,
  477. Need3 = 20000,
  478. BaseCost = 10,
  479. LevelCost = 4,
  480. DelayBase = 600000,
  481. DelayReduction = 120000,
  482. Range = 0
  483. });
  484. if (!MagicExists(Spell.ImmortalSkin))
  485. MagicInfoList.Add(new MagicInfo
  486. {
  487. Name = "ImmortalSkin",
  488. Spell = Spell.ImmortalSkin,
  489. Icon = 80,
  490. Level1 = 60,
  491. Level2 = 61,
  492. Level3 = 62,
  493. Need1 = 1560,
  494. Need2 = 2200,
  495. Need3 = 3000,
  496. BaseCost = 10,
  497. LevelCost = 4,
  498. DelayBase = 600000,
  499. DelayReduction = 120000,
  500. Range = 0
  501. });
  502. //Wizard
  503. if (!MagicExists(Spell.FireBall))
  504. MagicInfoList.Add(new MagicInfo
  505. {
  506. Name = "FireBall",
  507. Spell = Spell.FireBall,
  508. Icon = 0,
  509. Level1 = 7,
  510. Level2 = 9,
  511. Level3 = 11,
  512. Need1 = 200,
  513. Need2 = 350,
  514. Need3 = 700,
  515. BaseCost = 3,
  516. LevelCost = 2,
  517. MPowerBase = 8,
  518. PowerBase = 2,
  519. Range = 9
  520. });
  521. if (!MagicExists(Spell.Repulsion))
  522. MagicInfoList.Add(new MagicInfo
  523. {
  524. Name = "Repulsion",
  525. Spell = Spell.Repulsion,
  526. Icon = 7,
  527. Level1 = 12,
  528. Level2 = 15,
  529. Level3 = 19,
  530. Need1 = 500,
  531. Need2 = 1300,
  532. Need3 = 2200,
  533. BaseCost = 2,
  534. LevelCost = 2,
  535. Range = 0,
  536. MPowerBase = 4
  537. });
  538. if (!MagicExists(Spell.ElectricShock))
  539. MagicInfoList.Add(new MagicInfo
  540. {
  541. Name = "ElectricShock",
  542. Spell = Spell.ElectricShock,
  543. Icon = 19,
  544. Level1 = 13,
  545. Level2 = 18,
  546. Level3 = 24,
  547. Need1 = 530,
  548. Need2 = 1100,
  549. Need3 = 2200,
  550. BaseCost = 3,
  551. LevelCost = 1,
  552. Range = 9
  553. });
  554. if (!MagicExists(Spell.GreatFireBall))
  555. MagicInfoList.Add(new MagicInfo
  556. {
  557. Name = "GreatFireBall",
  558. Spell = Spell.GreatFireBall,
  559. Icon = 4,
  560. Level1 = 15,
  561. Level2 = 18,
  562. Level3 = 21,
  563. Need1 = 2000,
  564. Need2 = 2700,
  565. Need3 = 3500,
  566. BaseCost = 5,
  567. LevelCost = 1,
  568. MPowerBase = 6,
  569. PowerBase = 10,
  570. Range = 9
  571. });
  572. if (!MagicExists(Spell.HellFire))
  573. MagicInfoList.Add(new MagicInfo
  574. {
  575. Name = "HellFire",
  576. Spell = Spell.HellFire,
  577. Icon = 8,
  578. Level1 = 16,
  579. Level2 = 20,
  580. Level3 = 24,
  581. Need1 = 700,
  582. Need2 = 2700,
  583. Need3 = 3500,
  584. BaseCost = 10,
  585. LevelCost = 3,
  586. MPowerBase = 14,
  587. PowerBase = 6,
  588. Range = 0
  589. });
  590. if (!MagicExists(Spell.ThunderBolt))
  591. MagicInfoList.Add(new MagicInfo
  592. {
  593. Name = "ThunderBolt",
  594. Spell = Spell.ThunderBolt,
  595. Icon = 10,
  596. Level1 = 17,
  597. Level2 = 20,
  598. Level3 = 23,
  599. Need1 = 500,
  600. Need2 = 2000,
  601. Need3 = 3500,
  602. BaseCost = 9,
  603. LevelCost = 2,
  604. MPowerBase = 8,
  605. MPowerBonus = 20,
  606. PowerBase = 9,
  607. Range = 9
  608. });
  609. if (!MagicExists(Spell.Teleport))
  610. MagicInfoList.Add(new MagicInfo
  611. { 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 });
  612. if (!MagicExists(Spell.FireBang))
  613. MagicInfoList.Add(new MagicInfo
  614. {
  615. Name = "FireBang",
  616. Spell = Spell.FireBang,
  617. Icon = 22,
  618. Level1 = 22,
  619. Level2 = 25,
  620. Level3 = 28,
  621. Need1 = 3000,
  622. Need2 = 5000,
  623. Need3 = 10000,
  624. BaseCost = 14,
  625. LevelCost = 4,
  626. MPowerBase = 8,
  627. PowerBase = 8,
  628. Range = 9
  629. });
  630. if (!MagicExists(Spell.FireWall))
  631. MagicInfoList.Add(new MagicInfo
  632. {
  633. Name = "FireWall",
  634. Spell = Spell.FireWall,
  635. Icon = 21,
  636. Level1 = 24,
  637. Level2 = 28,
  638. Level3 = 33,
  639. Need1 = 4000,
  640. Need2 = 10000,
  641. Need3 = 20000,
  642. BaseCost = 30,
  643. LevelCost = 5,
  644. MPowerBase = 3,
  645. PowerBase = 3,
  646. Range = 9
  647. });
  648. if (!MagicExists(Spell.Lightning))
  649. MagicInfoList.Add(new MagicInfo
  650. {
  651. Name = "Lightning",
  652. Spell = Spell.Lightning,
  653. Icon = 9,
  654. Level1 = 26,
  655. Level2 = 29,
  656. Level3 = 32,
  657. Need1 = 3000,
  658. Need2 = 6000,
  659. Need3 = 12000,
  660. BaseCost = 38,
  661. LevelCost = 7,
  662. MPowerBase = 12,
  663. PowerBase = 12,
  664. Range = 0
  665. });
  666. if (!MagicExists(Spell.FrostCrunch))
  667. MagicInfoList.Add(new MagicInfo
  668. {
  669. Name = "FrostCrunch",
  670. Spell = Spell.FrostCrunch,
  671. Icon = 38,
  672. Level1 = 28,
  673. Level2 = 30,
  674. Level3 = 33,
  675. Need1 = 3000,
  676. Need2 = 5000,
  677. Need3 = 8000,
  678. BaseCost = 15,
  679. LevelCost = 3,
  680. MPowerBase = 12,
  681. PowerBase = 12,
  682. Range = 9
  683. });
  684. if (!MagicExists(Spell.ThunderStorm))
  685. MagicInfoList.Add(new MagicInfo
  686. {
  687. Name = "ThunderStorm",
  688. Spell = Spell.ThunderStorm,
  689. Icon = 23,
  690. Level1 = 30,
  691. Level2 = 32,
  692. Level3 = 34,
  693. Need1 = 4000,
  694. Need2 = 8000,
  695. Need3 = 12000,
  696. BaseCost = 29,
  697. LevelCost = 9,
  698. MPowerBase = 10,
  699. MPowerBonus = 20,
  700. PowerBase = 10,
  701. PowerBonus = 20,
  702. Range = 0
  703. });
  704. if (!MagicExists(Spell.MagicShield))
  705. MagicInfoList.Add(new MagicInfo
  706. {
  707. Name = "MagicShield",
  708. Spell = Spell.MagicShield,
  709. Icon = 30,
  710. Level1 = 31,
  711. Level2 = 34,
  712. Level3 = 38,
  713. Need1 = 3000,
  714. Need2 = 7000,
  715. Need3 = 10000,
  716. BaseCost = 35,
  717. LevelCost = 5,
  718. Range = 0
  719. });
  720. if (!MagicExists(Spell.TurnUndead))
  721. MagicInfoList.Add(new MagicInfo
  722. {
  723. Name = "TurnUndead",
  724. Spell = Spell.TurnUndead,
  725. Icon = 31,
  726. Level1 = 32,
  727. Level2 = 35,
  728. Level3 = 39,
  729. Need1 = 3000,
  730. Need2 = 7000,
  731. Need3 = 10000,
  732. BaseCost = 52,
  733. LevelCost = 13,
  734. Range = 9
  735. });
  736. if (!MagicExists(Spell.Vampirism))
  737. MagicInfoList.Add(new MagicInfo
  738. {
  739. Name = "Vampirism",
  740. Spell = Spell.Vampirism,
  741. Icon = 47,
  742. Level1 = 33,
  743. Level2 = 36,
  744. Level3 = 40,
  745. Need1 = 3000,
  746. Need2 = 5000,
  747. Need3 = 8000,
  748. BaseCost = 26,
  749. LevelCost = 13,
  750. MPowerBase = 12,
  751. PowerBase = 12,
  752. Range = 9
  753. });
  754. if (!MagicExists(Spell.IceStorm))
  755. MagicInfoList.Add(new MagicInfo
  756. {
  757. Name = "IceStorm",
  758. Spell = Spell.IceStorm,
  759. Icon = 32,
  760. Level1 = 35,
  761. Level2 = 37,
  762. Level3 = 40,
  763. Need1 = 4000,
  764. Need2 = 8000,
  765. Need3 = 12000,
  766. BaseCost = 33,
  767. LevelCost = 3,
  768. MPowerBase = 12,
  769. PowerBase = 14,
  770. Range = 9
  771. });
  772. if (!MagicExists(Spell.FlameDisruptor))
  773. MagicInfoList.Add(new MagicInfo
  774. {
  775. Name = "FlameDisruptor",
  776. Spell = Spell.FlameDisruptor,
  777. Icon = 34,
  778. Level1 = 38,
  779. Level2 = 40,
  780. Level3 = 42,
  781. Need1 = 5000,
  782. Need2 = 9000,
  783. Need3 = 14000,
  784. BaseCost = 28,
  785. LevelCost = 3,
  786. MPowerBase = 15,
  787. MPowerBonus = 20,
  788. PowerBase = 9,
  789. Range = 9
  790. });
  791. if (!MagicExists(Spell.Mirroring))
  792. MagicInfoList.Add(new MagicInfo
  793. { Name = "Mirroring", Spell = Spell.Mirroring, Icon = 41, Level1 = 41, Level2 = 43, Level3 = 45, Need1 = 6000, Need2 = 11000, Need3 = 16000, BaseCost = 21, Range = 0 });
  794. if (!MagicExists(Spell.FlameField))
  795. MagicInfoList.Add(new MagicInfo
  796. {
  797. Name = "FlameField",
  798. Spell = Spell.FlameField,
  799. Icon = 44,
  800. Level1 = 42,
  801. Level2 = 43,
  802. Level3 = 45,
  803. Need1 = 6000,
  804. Need2 = 11000,
  805. Need3 = 16000,
  806. BaseCost = 45,
  807. LevelCost = 8,
  808. MPowerBase = 100,
  809. PowerBase = 25,
  810. Range = 9
  811. });
  812. if (!MagicExists(Spell.Blizzard))
  813. MagicInfoList.Add(new MagicInfo
  814. {
  815. Name = "Blizzard",
  816. Spell = Spell.Blizzard,
  817. Icon = 51,
  818. Level1 = 44,
  819. Level2 = 47,
  820. Level3 = 50,
  821. Need1 = 8000,
  822. Need2 = 16000,
  823. Need3 = 24000,
  824. BaseCost = 65,
  825. LevelCost = 10,
  826. MPowerBase = 30,
  827. MPowerBonus = 10,
  828. PowerBase = 20,
  829. PowerBonus = 5,
  830. Range = 9
  831. });
  832. if (!MagicExists(Spell.MagicBooster))
  833. MagicInfoList.Add(new MagicInfo
  834. {
  835. Name = "MagicBooster",
  836. Spell = Spell.MagicBooster,
  837. Icon = 73,
  838. Level1 = 47,
  839. Level2 = 49,
  840. Level3 = 52,
  841. Need1 = 12000,
  842. Need2 = 18000,
  843. Need3 = 24000,
  844. BaseCost = 150,
  845. LevelCost = 15,
  846. Range = 0
  847. });
  848. if (!MagicExists(Spell.MeteorStrike))
  849. MagicInfoList.Add(new MagicInfo
  850. {
  851. Name = "MeteorStrike",
  852. Spell = Spell.MeteorStrike,
  853. Icon = 52,
  854. Level1 = 49,
  855. Level2 = 52,
  856. Level3 = 55,
  857. Need1 = 15000,
  858. Need2 = 20000,
  859. Need3 = 25000,
  860. BaseCost = 115,
  861. LevelCost = 17,
  862. MPowerBase = 40,
  863. MPowerBonus = 10,
  864. PowerBase = 20,
  865. PowerBonus = 15,
  866. Range = 9
  867. });
  868. if (!MagicExists(Spell.IceThrust))
  869. MagicInfoList.Add(new MagicInfo
  870. {
  871. Name = "IceThrust",
  872. Spell = Spell.IceThrust,
  873. Icon = 56,
  874. Level1 = 53,
  875. Level2 = 56,
  876. Level3 = 59,
  877. Need1 = 17000,
  878. Need2 = 22000,
  879. Need3 = 27000,
  880. BaseCost = 100,
  881. LevelCost = 20,
  882. MPowerBase = 100,
  883. PowerBase = 50,
  884. Range = 0
  885. });
  886. if (!MagicExists(Spell.Blink))
  887. MagicInfoList.Add(new MagicInfo
  888. { Name = "Blink", Spell = Spell.Blink, Icon = 20, Level1 = 19, Level2 = 22, Level3 = 25, Need1 = 350, Need2 = 1000, Need3 = 2000, BaseCost = 10, LevelCost = 3, Range = 9 });
  889. //if (!MagicExists(Spell.FastMove)) MagicInfoList.Add(new MagicInfo { Name = "FastMove", Spell = Spell.ImmortalSkin, Icon = ?, Level1 = ?, Level2 = ?, Level3 = ?, Need1 = ?, Need2 = ?, Need3 = ?, BaseCost = ?, LevelCost = ?, DelayBase = ?, DelayReduction = ? });
  890. if (!MagicExists(Spell.StormEscape))
  891. MagicInfoList.Add(new MagicInfo
  892. {
  893. Name = "StormEscape",
  894. Spell = Spell.StormEscape,
  895. Icon = 23,
  896. Level1 = 60,
  897. Level2 = 61,
  898. Level3 = 62,
  899. Need1 = 2200,
  900. Need2 = 3300,
  901. Need3 = 4400,
  902. BaseCost = 65,
  903. LevelCost = 8,
  904. MPowerBase = 12,
  905. PowerBase = 4,
  906. Range = 9
  907. });
  908. //Taoist
  909. if (!MagicExists(Spell.Healing))
  910. MagicInfoList.Add(new MagicInfo
  911. {
  912. Name = "Healing",
  913. Spell = Spell.Healing,
  914. Icon = 1,
  915. Level1 = 7,
  916. Level2 = 11,
  917. Level3 = 14,
  918. Need1 = 150,
  919. Need2 = 350,
  920. Need3 = 700,
  921. BaseCost = 3,
  922. LevelCost = 2,
  923. MPowerBase = 14,
  924. Range = 9
  925. });
  926. if (!MagicExists(Spell.SpiritSword))
  927. MagicInfoList.Add(new MagicInfo
  928. { Name = "SpiritSword", Spell = Spell.SpiritSword, Icon = 3, Level1 = 9, Level2 = 12, Level3 = 15, Need1 = 350, Need2 = 1300, Need3 = 2700, Range = 0 });
  929. if (!MagicExists(Spell.Poisoning))
  930. MagicInfoList.Add(new MagicInfo
  931. { Name = "Poisoning", Spell = Spell.Poisoning, Icon = 5, Level1 = 14, Level2 = 17, Level3 = 20, Need1 = 700, Need2 = 1300, Need3 = 2700, BaseCost = 2, LevelCost = 1, Range = 9 });
  932. if (!MagicExists(Spell.SoulFireBall))
  933. MagicInfoList.Add(new MagicInfo
  934. {
  935. Name = "SoulFireBall",
  936. Spell = Spell.SoulFireBall,
  937. Icon = 12,
  938. Level1 = 18,
  939. Level2 = 21,
  940. Level3 = 24,
  941. Need1 = 1300,
  942. Need2 = 2700,
  943. Need3 = 4000,
  944. BaseCost = 3,
  945. LevelCost = 1,
  946. MPowerBase = 8,
  947. PowerBase = 3,
  948. Range = 9
  949. });
  950. if (!MagicExists(Spell.SummonSkeleton))
  951. MagicInfoList.Add(new MagicInfo
  952. {
  953. Name = "SummonSkeleton",
  954. Spell = Spell.SummonSkeleton,
  955. Icon = 16,
  956. Level1 = 19,
  957. Level2 = 22,
  958. Level3 = 26,
  959. Need1 = 1000,
  960. Need2 = 2000,
  961. Need3 = 3500,
  962. BaseCost = 12,
  963. LevelCost = 4,
  964. Range = 0
  965. });
  966. if (!MagicExists(Spell.Hiding))
  967. MagicInfoList.Add(new MagicInfo
  968. { 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 });
  969. if (!MagicExists(Spell.MassHiding))
  970. MagicInfoList.Add(new MagicInfo
  971. {
  972. Name = "MassHiding",
  973. Spell = Spell.MassHiding,
  974. Icon = 18,
  975. Level1 = 21,
  976. Level2 = 25,
  977. Level3 = 29,
  978. Need1 = 1300,
  979. Need2 = 2700,
  980. Need3 = 5300,
  981. BaseCost = 2,
  982. LevelCost = 2,
  983. Range = 9
  984. });
  985. if (!MagicExists(Spell.SoulShield))
  986. MagicInfoList.Add(new MagicInfo
  987. {
  988. Name = "SoulShield",
  989. Spell = Spell.SoulShield,
  990. Icon = 13,
  991. Level1 = 22,
  992. Level2 = 24,
  993. Level3 = 26,
  994. Need1 = 2000,
  995. Need2 = 3500,
  996. Need3 = 7000,
  997. BaseCost = 2,
  998. LevelCost = 2,
  999. Range = 9
  1000. });
  1001. if (!MagicExists(Spell.Revelation))
  1002. MagicInfoList.Add(new MagicInfo
  1003. {
  1004. Name = "Revelation",
  1005. Spell = Spell.Revelation,
  1006. Icon = 27,
  1007. Level1 = 23,
  1008. Level2 = 25,
  1009. Level3 = 28,
  1010. Need1 = 1500,
  1011. Need2 = 2500,
  1012. Need3 = 4000,
  1013. BaseCost = 4,
  1014. LevelCost = 4,
  1015. Range = 9
  1016. });
  1017. if (!MagicExists(Spell.BlessedArmour))
  1018. MagicInfoList.Add(new MagicInfo
  1019. {
  1020. Name = "BlessedArmour",
  1021. Spell = Spell.BlessedArmour,
  1022. Icon = 14,
  1023. Level1 = 25,
  1024. Level2 = 27,
  1025. Level3 = 29,
  1026. Need1 = 4000,
  1027. Need2 = 6000,
  1028. Need3 = 10000,
  1029. BaseCost = 2,
  1030. LevelCost = 2,
  1031. Range = 9
  1032. });
  1033. if (!MagicExists(Spell.EnergyRepulsor))
  1034. MagicInfoList.Add(new MagicInfo
  1035. {
  1036. Name = "EnergyRepulsor",
  1037. Spell = Spell.EnergyRepulsor,
  1038. Icon = 36,
  1039. Level1 = 27,
  1040. Level2 = 29,
  1041. Level3 = 31,
  1042. Need1 = 1800,
  1043. Need2 = 2400,
  1044. Need3 = 3200,
  1045. BaseCost = 2,
  1046. LevelCost = 2,
  1047. Range = 0,
  1048. MPowerBase = 4
  1049. });
  1050. if (!MagicExists(Spell.TrapHexagon))
  1051. MagicInfoList.Add(new MagicInfo
  1052. {
  1053. Name = "TrapHexagon",
  1054. Spell = Spell.TrapHexagon,
  1055. Icon = 15,
  1056. Level1 = 28,
  1057. Level2 = 30,
  1058. Level3 = 32,
  1059. Need1 = 2500,
  1060. Need2 = 5000,
  1061. Need3 = 10000,
  1062. BaseCost = 7,
  1063. LevelCost = 3,
  1064. Range = 9
  1065. });
  1066. if (!MagicExists(Spell.Purification))
  1067. MagicInfoList.Add(new MagicInfo
  1068. {
  1069. Name = "Purification",
  1070. Spell = Spell.Purification,
  1071. Icon = 39,
  1072. Level1 = 30,
  1073. Level2 = 32,
  1074. Level3 = 35,
  1075. Need1 = 3000,
  1076. Need2 = 5000,
  1077. Need3 = 8000,
  1078. BaseCost = 14,
  1079. LevelCost = 2,
  1080. Range = 9
  1081. });
  1082. if (!MagicExists(Spell.MassHealing))
  1083. MagicInfoList.Add(new MagicInfo
  1084. {
  1085. Name = "MassHealing",
  1086. Spell = Spell.MassHealing,
  1087. Icon = 28,
  1088. Level1 = 31,
  1089. Level2 = 33,
  1090. Level3 = 36,
  1091. Need1 = 2000,
  1092. Need2 = 4000,
  1093. Need3 = 8000,
  1094. BaseCost = 28,
  1095. LevelCost = 3,
  1096. MPowerBase = 10,
  1097. PowerBase = 4,
  1098. Range = 9
  1099. });
  1100. if (!MagicExists(Spell.Hallucination))
  1101. MagicInfoList.Add(new MagicInfo
  1102. {
  1103. Name = "Hallucination",
  1104. Spell = Spell.Hallucination,
  1105. Icon = 48,
  1106. Level1 = 31,
  1107. Level2 = 34,
  1108. Level3 = 36,
  1109. Need1 = 4000,
  1110. Need2 = 6000,
  1111. Need3 = 9000,
  1112. BaseCost = 22,
  1113. LevelCost = 10,
  1114. Range = 9
  1115. });
  1116. if (!MagicExists(Spell.UltimateEnhancer))
  1117. MagicInfoList.Add(new MagicInfo
  1118. {
  1119. Name = "UltimateEnchancer",
  1120. Spell = Spell.UltimateEnhancer,
  1121. Icon = 35,
  1122. Level1 = 33,
  1123. Level2 = 35,
  1124. Level3 = 38,
  1125. Need1 = 5000,
  1126. Need2 = 7000,
  1127. Need3 = 10000,
  1128. BaseCost = 28,
  1129. LevelCost = 4,
  1130. Range = 9
  1131. });
  1132. if (!MagicExists(Spell.SummonShinsu))
  1133. MagicInfoList.Add(new MagicInfo
  1134. {
  1135. Name = "SummonShinsu",
  1136. Spell = Spell.SummonShinsu,
  1137. Icon = 29,
  1138. Level1 = 35,
  1139. Level2 = 37,
  1140. Level3 = 40,
  1141. Need1 = 2000,
  1142. Need2 = 4000,
  1143. Need3 = 6000,
  1144. BaseCost = 28,
  1145. LevelCost = 4,
  1146. Range = 0
  1147. });
  1148. if (!MagicExists(Spell.Reincarnation))
  1149. MagicInfoList.Add(new MagicInfo
  1150. {
  1151. Name = "Reincarnation",
  1152. Spell = Spell.Reincarnation,
  1153. Icon = 53,
  1154. Level1 = 37,
  1155. Level2 = 39,
  1156. Level3 = 41,
  1157. Need1 = 2000,
  1158. Need2 = 6000,
  1159. Need3 = 10000,
  1160. BaseCost = 125,
  1161. LevelCost = 17,
  1162. Range = 9
  1163. });
  1164. if (!MagicExists(Spell.SummonHolyDeva))
  1165. MagicInfoList.Add(new MagicInfo
  1166. {
  1167. Name = "SummonHolyDeva",
  1168. Spell = Spell.SummonHolyDeva,
  1169. Icon = 40,
  1170. Level1 = 38,
  1171. Level2 = 41,
  1172. Level3 = 43,
  1173. Need1 = 4000,
  1174. Need2 = 6000,
  1175. Need3 = 9000,
  1176. BaseCost = 28,
  1177. LevelCost = 4,
  1178. Range = 0
  1179. });
  1180. if (!MagicExists(Spell.Curse))
  1181. MagicInfoList.Add(new MagicInfo
  1182. {
  1183. Name = "Curse",
  1184. Spell = Spell.Curse,
  1185. Icon = 45,
  1186. Level1 = 40,
  1187. Level2 = 42,
  1188. Level3 = 44,
  1189. Need1 = 4000,
  1190. Need2 = 6000,
  1191. Need3 = 9000,
  1192. BaseCost = 17,
  1193. LevelCost = 3,
  1194. Range = 9,
  1195. MPowerBase = 20
  1196. });
  1197. if (!MagicExists(Spell.Plague))
  1198. MagicInfoList.Add(new MagicInfo
  1199. { Name = "Plague", Spell = Spell.Plague, Icon = 74, Level1 = 42, Level2 = 44, Level3 = 47, Need1 = 5000, Need2 = 9000, Need3 = 13000, BaseCost = 20, LevelCost = 5, Range = 9 });
  1200. if (!MagicExists(Spell.PoisonCloud))
  1201. MagicInfoList.Add(new MagicInfo
  1202. {
  1203. Name = "PoisonCloud",
  1204. Spell = Spell.PoisonCloud,
  1205. Icon = 54,
  1206. Level1 = 43,
  1207. Level2 = 45,
  1208. Level3 = 48,
  1209. Need1 = 4000,
  1210. Need2 = 8000,
  1211. Need3 = 12000,
  1212. BaseCost = 30,
  1213. LevelCost = 5,
  1214. MPowerBase = 40,
  1215. PowerBase = 20,
  1216. DelayBase = 18000,
  1217. DelayReduction = 2000,
  1218. Range = 9
  1219. });
  1220. if (!MagicExists(Spell.EnergyShield))
  1221. MagicInfoList.Add(new MagicInfo
  1222. {
  1223. Name = "EnergyShield",
  1224. Spell = Spell.EnergyShield,
  1225. Icon = 57,
  1226. Level1 = 48,
  1227. Level2 = 51,
  1228. Level3 = 54,
  1229. Need1 = 5000,
  1230. Need2 = 9000,
  1231. Need3 = 13000,
  1232. BaseCost = 50,
  1233. LevelCost = 20,
  1234. Range = 9
  1235. });
  1236. if (!MagicExists(Spell.PetEnhancer))
  1237. MagicInfoList.Add(new MagicInfo
  1238. {
  1239. Name = "PetEnhancer",
  1240. Spell = Spell.PetEnhancer,
  1241. Icon = 78,
  1242. Level1 = 45,
  1243. Level2 = 48,
  1244. Level3 = 51,
  1245. Need1 = 4000,
  1246. Need2 = 8000,
  1247. Need3 = 12000,
  1248. BaseCost = 30,
  1249. LevelCost = 40,
  1250. Range = 0
  1251. });
  1252. if (!MagicExists(Spell.HealingCircle))
  1253. MagicInfoList.Add(new MagicInfo
  1254. {
  1255. Name = "HealingCircle",
  1256. Spell = Spell.HealingCircle,
  1257. Icon = 82,
  1258. Level1 = 39,
  1259. Level2 = 41,
  1260. Level3 = 43,
  1261. Need1 = 7000,
  1262. Need2 = 12000,
  1263. Need3 = 15000,
  1264. BaseCost = 10,
  1265. LevelCost = 100
  1266. });
  1267. //Assassin
  1268. if (!MagicExists(Spell.FatalSword))
  1269. 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 });
  1270. if (!MagicExists(Spell.DoubleSlash))
  1271. MagicInfoList.Add(new MagicInfo
  1272. { Name = "DoubleSlash", Spell = Spell.DoubleSlash, Icon = 59, Level1 = 15, Level2 = 17, Level3 = 19, Need1 = 700, Need2 = 1500, Need3 = 2200, BaseCost = 2, LevelCost = 1 });
  1273. if (!MagicExists(Spell.Haste))
  1274. MagicInfoList.Add(new MagicInfo
  1275. { 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 });
  1276. if (!MagicExists(Spell.FlashDash))
  1277. MagicInfoList.Add(new MagicInfo
  1278. {
  1279. Name = "FlashDash",
  1280. Spell = Spell.FlashDash,
  1281. Icon = 61,
  1282. Level1 = 25,
  1283. Level2 = 27,
  1284. Level3 = 30,
  1285. Need1 = 4000,
  1286. Need2 = 7000,
  1287. Need3 = 9000,
  1288. BaseCost = 12,
  1289. LevelCost = 2,
  1290. DelayBase = 200,
  1291. Range = 0
  1292. });
  1293. if (!MagicExists(Spell.LightBody))
  1294. MagicInfoList.Add(new MagicInfo
  1295. {
  1296. Name = "LightBody",
  1297. Spell = Spell.LightBody,
  1298. Icon = 68,
  1299. Level1 = 27,
  1300. Level2 = 29,
  1301. Level3 = 32,
  1302. Need1 = 5000,
  1303. Need2 = 7000,
  1304. Need3 = 10000,
  1305. BaseCost = 11,
  1306. LevelCost = 2,
  1307. Range = 0
  1308. });
  1309. if (!MagicExists(Spell.HeavenlySword))
  1310. MagicInfoList.Add(new MagicInfo
  1311. {
  1312. Name = "HeavenlySword",
  1313. Spell = Spell.HeavenlySword,
  1314. Icon = 62,
  1315. Level1 = 30,
  1316. Level2 = 32,
  1317. Level3 = 35,
  1318. Need1 = 4000,
  1319. Need2 = 8000,
  1320. Need3 = 10000,
  1321. BaseCost = 13,
  1322. LevelCost = 2,
  1323. MPowerBase = 8,
  1324. Range = 0
  1325. });
  1326. if (!MagicExists(Spell.FireBurst))
  1327. MagicInfoList.Add(new MagicInfo
  1328. {
  1329. Name = "FireBurst",
  1330. Spell = Spell.FireBurst,
  1331. Icon = 63,
  1332. Level1 = 33,
  1333. Level2 = 35,
  1334. Level3 = 38,
  1335. Need1 = 4000,
  1336. Need2 = 6000,
  1337. Need3 = 8000,
  1338. BaseCost = 10,
  1339. LevelCost = 1,
  1340. Range = 0
  1341. });
  1342. if (!MagicExists(Spell.Trap))
  1343. MagicInfoList.Add(new MagicInfo
  1344. {
  1345. Name = "Trap",
  1346. Spell = Spell.Trap,
  1347. Icon = 64,
  1348. Level1 = 33,
  1349. Level2 = 35,
  1350. Level3 = 38,
  1351. Need1 = 2000,
  1352. Need2 = 4000,
  1353. Need3 = 6000,
  1354. BaseCost = 14,
  1355. LevelCost = 2,
  1356. DelayBase = 60000,
  1357. DelayReduction = 15000,
  1358. Range = 9
  1359. });
  1360. if (!MagicExists(Spell.PoisonSword))
  1361. MagicInfoList.Add(new MagicInfo
  1362. {
  1363. Name = "PoisonSword",
  1364. Spell = Spell.PoisonSword,
  1365. Icon = 69,
  1366. Level1 = 34,
  1367. Level2 = 36,
  1368. Level3 = 39,
  1369. Need1 = 5000,
  1370. Need2 = 8000,
  1371. Need3 = 11000,
  1372. BaseCost = 14,
  1373. LevelCost = 3,
  1374. Range = 0
  1375. });
  1376. if (!MagicExists(Spell.MoonLight))
  1377. MagicInfoList.Add(new MagicInfo
  1378. {
  1379. Name = "MoonLight",
  1380. Spell = Spell.MoonLight,
  1381. Icon = 65,
  1382. Level1 = 36,
  1383. Level2 = 39,
  1384. Level3 = 42,
  1385. Need1 = 3000,
  1386. Need2 = 5000,
  1387. Need3 = 8000,
  1388. BaseCost = 36,
  1389. LevelCost = 3,
  1390. Range = 0
  1391. });
  1392. if (!MagicExists(Spell.MPEater))
  1393. 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 });
  1394. if (!MagicExists(Spell.SwiftFeet))
  1395. MagicInfoList.Add(new MagicInfo
  1396. {
  1397. Name = "SwiftFeet",
  1398. Spell = Spell.SwiftFeet,
  1399. Icon = 67,
  1400. Level1 = 40,
  1401. Level2 = 43,
  1402. Level3 = 46,
  1403. Need1 = 4000,
  1404. Need2 = 6000,
  1405. Need3 = 9000,
  1406. BaseCost = 17,
  1407. LevelCost = 5,
  1408. DelayBase = 210000,
  1409. DelayReduction = 40000,
  1410. Range = 0
  1411. });
  1412. if (!MagicExists(Spell.DarkBody))
  1413. MagicInfoList.Add(new MagicInfo
  1414. {
  1415. Name = "DarkBody",
  1416. Spell = Spell.DarkBody,
  1417. Icon = 70,
  1418. Level1 = 46,
  1419. Level2 = 49,
  1420. Level3 = 52,
  1421. Need1 = 6000,
  1422. Need2 = 10000,
  1423. Need3 = 14000,
  1424. BaseCost = 40,
  1425. LevelCost = 7,
  1426. Range = 0
  1427. });
  1428. if (!MagicExists(Spell.Hemorrhage))
  1429. MagicInfoList.Add(new MagicInfo
  1430. { Name = "Hemorrhage", Spell = Spell.Hemorrhage, Icon = 75, Level1 = 47, Level2 = 51, Level3 = 55, Need1 = 9000, Need2 = 15000, Need3 = 21000, Range = 0 });
  1431. if (!MagicExists(Spell.CrescentSlash))
  1432. MagicInfoList.Add(new MagicInfo
  1433. {
  1434. Name = "CresentSlash",
  1435. Spell = Spell.CrescentSlash,
  1436. Icon = 71,
  1437. Level1 = 50,
  1438. Level2 = 53,
  1439. Level3 = 56,
  1440. Need1 = 12000,
  1441. Need2 = 16000,
  1442. Need3 = 24000,
  1443. BaseCost = 19,
  1444. LevelCost = 5,
  1445. Range = 0
  1446. });
  1447. if (!MagicExists(Spell.MoonMist))
  1448. MagicInfoList.Add(new MagicInfo
  1449. {
  1450. Name = "MoonMist",
  1451. Spell = Spell.MoonMist,
  1452. Icon = 83,
  1453. Level1 = 48,
  1454. Level2 = 51,
  1455. Level3 = 56,
  1456. Need1 = 10,
  1457. Need2 = 20,
  1458. Need3 = 30,
  1459. BaseCost = 30,
  1460. LevelCost = 5,
  1461. DelayBase = 20000,
  1462. DelayReduction = 2000
  1463. });
  1464. if (!MagicExists(Spell.CatTongue))
  1465. MagicInfoList.Add(new MagicInfo
  1466. {
  1467. Name = "CatTongue",
  1468. Spell = Spell.CatTongue,
  1469. Icon = 79,
  1470. Level1 = 48,
  1471. Level2 = 51,
  1472. Level3 = 56,
  1473. Need1 = 10,
  1474. Need2 = 20,
  1475. Need3 = 30,
  1476. BaseCost = 30,
  1477. LevelCost = 5,
  1478. DelayBase = 20000,
  1479. DelayReduction = 2000
  1480. });
  1481. //Archer
  1482. if (!MagicExists(Spell.Focus))
  1483. 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 });
  1484. if (!MagicExists(Spell.StraightShot))
  1485. MagicInfoList.Add(new MagicInfo
  1486. {
  1487. Name = "StraightShot",
  1488. Spell = Spell.StraightShot,
  1489. Icon = 89,
  1490. Level1 = 9,
  1491. Level2 = 12,
  1492. Level3 = 16,
  1493. Need1 = 350,
  1494. Need2 = 750,
  1495. Need3 = 1400,
  1496. BaseCost = 3,
  1497. LevelCost = 2,
  1498. MPowerBase = 8,
  1499. PowerBase = 3,
  1500. Range = 9
  1501. });
  1502. if (!MagicExists(Spell.DoubleShot))
  1503. MagicInfoList.Add(new MagicInfo
  1504. {
  1505. Name = "DoubleShot",
  1506. Spell = Spell.DoubleShot,
  1507. Icon = 90,
  1508. Level1 = 14,
  1509. Level2 = 18,
  1510. Level3 = 21,
  1511. Need1 = 700,
  1512. Need2 = 1500,
  1513. Need3 = 2100,
  1514. BaseCost = 3,
  1515. LevelCost = 2,
  1516. MPowerBase = 6,
  1517. PowerBase = 2,
  1518. Range = 9
  1519. });
  1520. if (!MagicExists(Spell.ExplosiveTrap))
  1521. MagicInfoList.Add(new MagicInfo
  1522. {
  1523. Name = "ExplosiveTrap",
  1524. Spell = Spell.ExplosiveTrap,
  1525. Icon = 91,
  1526. Level1 = 22,
  1527. Level2 = 25,
  1528. Level3 = 30,
  1529. Need1 = 2000,
  1530. Need2 = 3500,
  1531. Need3 = 5000,
  1532. BaseCost = 10,
  1533. LevelCost = 3,
  1534. MPowerBase = 15,
  1535. PowerBase = 15,
  1536. Range = 0
  1537. });
  1538. if (!MagicExists(Spell.DelayedExplosion))
  1539. MagicInfoList.Add(new MagicInfo
  1540. {
  1541. Name = "DelayedExplosion",
  1542. Spell = Spell.DelayedExplosion,
  1543. Icon = 92,
  1544. Level1 = 31,
  1545. Level2 = 34,
  1546. Level3 = 39,
  1547. Need1 = 3000,
  1548. Need2 = 7000,
  1549. Need3 = 10000,
  1550. BaseCost = 8,
  1551. LevelCost = 2,
  1552. MPowerBase = 30,
  1553. PowerBase = 15,
  1554. Range = 9
  1555. });
  1556. if (!MagicExists(Spell.Meditation))
  1557. MagicInfoList.Add(new MagicInfo
  1558. {
  1559. Name = "Meditation",
  1560. Spell = Spell.Meditation,
  1561. Icon = 93,
  1562. Level1 = 19,
  1563. Level2 = 24,
  1564. Level3 = 29,
  1565. Need1 = 1800,
  1566. Need2 = 2600,
  1567. Need3 = 5600,
  1568. BaseCost = 8,
  1569. LevelCost = 2,
  1570. Range = 0
  1571. });
  1572. if (!MagicExists(Spell.ElementalShot))
  1573. MagicInfoList.Add(new MagicInfo
  1574. {
  1575. Name = "ElementalShot",
  1576. Spell = Spell.ElementalShot,
  1577. Icon = 94,
  1578. Level1 = 20,
  1579. Level2 = 25,
  1580. Level3 = 31,
  1581. Need1 = 1800,
  1582. Need2 = 2700,
  1583. Need3 = 6000,
  1584. BaseCost = 8,
  1585. LevelCost = 2,
  1586. MPowerBase = 6,
  1587. PowerBase = 3,
  1588. Range = 9
  1589. });
  1590. if (!MagicExists(Spell.Concentration))
  1591. MagicInfoList.Add(new MagicInfo
  1592. {
  1593. Name = "Concentration",
  1594. Spell = Spell.Concentration,
  1595. Icon = 96,
  1596. Level1 = 23,
  1597. Level2 = 27,
  1598. Level3 = 32,
  1599. Need1 = 2100,
  1600. Need2 = 3800,
  1601. Need3 = 6500,
  1602. BaseCost = 8,
  1603. LevelCost = 2,
  1604. Range = 0
  1605. });
  1606. if (!MagicExists(Spell.ElementalBarrier))
  1607. MagicInfoList.Add(new MagicInfo
  1608. {
  1609. Name = "ElementalBarrier",
  1610. Spell = Spell.ElementalBarrier,
  1611. Icon = 98,
  1612. Level1 = 33,
  1613. Level2 = 38,
  1614. Level3 = 44,
  1615. Need1 = 3000,
  1616. Need2 = 7000,
  1617. Need3 = 10000,
  1618. BaseCost = 10,
  1619. LevelCost = 2,
  1620. MPowerBase = 15,
  1621. PowerBase = 5,
  1622. Range = 0
  1623. });
  1624. if (!MagicExists(Spell.BackStep))
  1625. MagicInfoList.Add(new MagicInfo
  1626. {
  1627. Name = "BackStep",
  1628. Spell = Spell.BackStep,
  1629. Icon = 95,
  1630. Level1 = 30,
  1631. Level2 = 34,
  1632. Level3 = 38,
  1633. Need1 = 2400,
  1634. Need2 = 3000,
  1635. Need3 = 6000,
  1636. BaseCost = 12,
  1637. LevelCost = 2,
  1638. DelayBase = 2500,
  1639. Range = 0
  1640. });
  1641. if (!MagicExists(Spell.BindingShot))
  1642. MagicInfoList.Add(new MagicInfo
  1643. {
  1644. Name = "BindingShot",
  1645. Spell = Spell.BindingShot,
  1646. Icon = 97,
  1647. Level1 = 35,
  1648. Level2 = 39,
  1649. Level3 = 42,
  1650. Need1 = 400,
  1651. Need2 = 7000,
  1652. Need3 = 9500,
  1653. BaseCost = 7,
  1654. LevelCost = 3,
  1655. Range = 9
  1656. });
  1657. if (!MagicExists(Spell.Stonetrap))
  1658. MagicInfoList.Add(new MagicInfo
  1659. { Name = "Stonetrap", Spell = Spell.Stonetrap, Icon = 97, Level1 = 40, Level2 = 43, Level3 = 46, Need1 = 4900, Need2 = 9800, Need3 = 141, BaseCost = 7, LevelCost = 3, Range = 9 });
  1660. if (!MagicExists(Spell.SummonVampire))
  1661. MagicInfoList.Add(new MagicInfo
  1662. {
  1663. Name = "SummonVampire",
  1664. Spell = Spell.SummonVampire,
  1665. Icon = 99,
  1666. Level1 = 28,
  1667. Level2 = 33,
  1668. Level3 = 41,
  1669. Need1 = 2000,
  1670. Need2 = 2700,
  1671. Need3 = 7500,
  1672. BaseCost = 10,
  1673. LevelCost = 5,
  1674. Range = 9
  1675. });
  1676. if (!MagicExists(Spell.VampireShot))
  1677. MagicInfoList.Add(new MagicInfo
  1678. {
  1679. Name = "VampireShot",
  1680. Spell = Spell.VampireShot,
  1681. Icon = 100,
  1682. Level1 = 26,
  1683. Level2 = 32,
  1684. Level3 = 36,
  1685. Need1 = 3000,
  1686. Need2 = 6000,
  1687. Need3 = 12000,
  1688. BaseCost = 12,
  1689. LevelCost = 3,
  1690. MPowerBase = 10,
  1691. PowerBase = 7,
  1692. Range = 9
  1693. });
  1694. if (!MagicExists(Spell.SummonToad))
  1695. MagicInfoList.Add(new MagicInfo
  1696. {
  1697. Name = "SummonToad",
  1698. Spell = Spell.SummonToad,
  1699. Icon = 101,
  1700. Level1 = 37,
  1701. Level2 = 43,
  1702. Level3 = 47,
  1703. Need1 = 5800,
  1704. Need2 = 10000,
  1705. Need3 = 13000,
  1706. BaseCost = 10,
  1707. LevelCost = 5,
  1708. Range = 9
  1709. });
  1710. if (!MagicExists(Spell.PoisonShot))
  1711. MagicInfoList.Add(new MagicInfo
  1712. {
  1713. Name = "PoisonShot",
  1714. Spell = Spell.PoisonShot,
  1715. Icon = 102,
  1716. Level1 = 40,
  1717. Level2 = 45,
  1718. Level3 = 49,
  1719. Need1 = 6000,
  1720. Need2 = 14000,
  1721. Need3 = 16000,
  1722. BaseCost = 10,
  1723. LevelCost = 4,
  1724. MPowerBase = 10,
  1725. PowerBase = 10,
  1726. Range = 9
  1727. });
  1728. if (!MagicExists(Spell.CrippleShot))
  1729. MagicInfoList.Add(new MagicInfo
  1730. {
  1731. Name = "CrippleShot",
  1732. Spell = Spell.CrippleShot,
  1733. Icon = 103,
  1734. Level1 = 43,
  1735. Level2 = 47,
  1736. Level3 = 50,
  1737. Need1 = 12000,
  1738. Need2 = 15000,
  1739. Need3 = 18000,
  1740. BaseCost = 15,
  1741. LevelCost = 3,
  1742. MPowerBase = 10,
  1743. MPowerBonus = 20,
  1744. PowerBase = 10,
  1745. Range = 9
  1746. });
  1747. if (!MagicExists(Spell.SummonSnakes))
  1748. MagicInfoList.Add(new MagicInfo
  1749. {
  1750. Name = "SummonSnakes",
  1751. Spell = Spell.SummonSnakes,
  1752. Icon = 104,
  1753. Level1 = 46,
  1754. Level2 = 51,
  1755. Level3 = 54,
  1756. Need1 = 14000,
  1757. Need2 = 17000,
  1758. Need3 = 20000,
  1759. BaseCost = 10,
  1760. LevelCost = 5,
  1761. Range = 9
  1762. });
  1763. if (!MagicExists(Spell.NapalmShot))
  1764. MagicInfoList.Add(new MagicInfo
  1765. {
  1766. Name = "NapalmShot",
  1767. Spell = Spell.NapalmShot,
  1768. Icon = 105,
  1769. Level1 = 48,
  1770. Level2 = 52,
  1771. Level3 = 55,
  1772. Need1 = 15000,
  1773. Need2 = 18000,
  1774. Need3 = 21000,
  1775. BaseCost = 40,
  1776. LevelCost = 10,
  1777. MPowerBase = 25,
  1778. MPowerBonus = 25,
  1779. PowerBase = 25,
  1780. Range = 9
  1781. });
  1782. if (!MagicExists(Spell.OneWithNature))
  1783. MagicInfoList.Add(new MagicInfo
  1784. {
  1785. Name = "OneWithNature",
  1786. Spell = Spell.OneWithNature,
  1787. Icon = 106,
  1788. Level1 = 50,
  1789. Level2 = 53,
  1790. Level3 = 56,
  1791. Need1 = 17000,
  1792. Need2 = 19000,
  1793. Need3 = 24000,
  1794. BaseCost = 80,
  1795. LevelCost = 15,
  1796. MPowerBase = 75,
  1797. MPowerBonus = 35,
  1798. PowerBase = 30,
  1799. PowerBonus = 20,
  1800. Range = 9
  1801. });
  1802. if (!MagicExists(Spell.MentalState))
  1803. MagicInfoList.Add(new MagicInfo
  1804. {
  1805. Name = "MentalState",
  1806. Spell = Spell.MentalState,
  1807. Icon = 81,
  1808. Level1 = 11,
  1809. Level2 = 15,
  1810. Level3 = 22,
  1811. Need1 = 500,
  1812. Need2 = 900,
  1813. Need3 = 1800,
  1814. BaseCost = 1,
  1815. LevelCost = 1,
  1816. Range = 0
  1817. });
  1818. //Custom
  1819. if (!MagicExists(Spell.Portal))
  1820. MagicInfoList.Add(new MagicInfo
  1821. { 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 });
  1822. if (!MagicExists(Spell.BattleCry))
  1823. MagicInfoList.Add(new MagicInfo
  1824. {
  1825. Name = "BattleCry",
  1826. Spell = Spell.BattleCry,
  1827. Icon = 42,
  1828. Level1 = 48,
  1829. Level2 = 51,
  1830. Level3 = 55,
  1831. Need1 = 8000,
  1832. Need2 = 11000,
  1833. Need3 = 15000,
  1834. BaseCost = 22,
  1835. LevelCost = 10,
  1836. Range = 0
  1837. });
  1838. if (!MagicExists(Spell.FireBounce))
  1839. MagicInfoList.Add(new MagicInfo
  1840. {
  1841. Name = "FireBounce",
  1842. Spell = Spell.FireBounce,
  1843. Icon = 4,
  1844. Level1 = 15,
  1845. Level2 = 18,
  1846. Level3 = 21,
  1847. Need1 = 2000,
  1848. Need2 = 2700,
  1849. Need3 = 3500,
  1850. BaseCost = 5,
  1851. LevelCost = 1,
  1852. MPowerBase = 6,
  1853. PowerBase = 10,
  1854. Range = 9
  1855. });
  1856. if (!MagicExists(Spell.MeteorShower))
  1857. MagicInfoList.Add(new MagicInfo
  1858. {
  1859. Name = "MeteorShower",
  1860. Spell = Spell.MeteorShower,
  1861. Icon = 4,
  1862. Level1 = 15,
  1863. Level2 = 18,
  1864. Level3 = 21,
  1865. Need1 = 2000,
  1866. Need2 = 2700,
  1867. Need3 = 3500,
  1868. BaseCost = 5,
  1869. LevelCost = 1,
  1870. MPowerBase = 6,
  1871. PowerBase = 10,
  1872. Range = 9
  1873. });
  1874. }
  1875. private string CanStartEnvir()
  1876. {
  1877. if (StartPoints.Count == 0) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMapAndStartPoint);
  1878. if (Settings.EnforceDBChecks)
  1879. {
  1880. if (GetMonsterInfo(Settings.SkeletonName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.SkeletonName;
  1881. if (GetMonsterInfo(Settings.ShinsuName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ShinsuName;
  1882. if (GetMonsterInfo(Settings.BugBatName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BugBatName;
  1883. if (GetMonsterInfo(Settings.Zuma1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma1;
  1884. if (GetMonsterInfo(Settings.Zuma2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma2;
  1885. if (GetMonsterInfo(Settings.Zuma3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma3;
  1886. if (GetMonsterInfo(Settings.Zuma4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma4;
  1887. if (GetMonsterInfo(Settings.Zuma5, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma5;
  1888. if (GetMonsterInfo(Settings.Zuma6, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma6;
  1889. if (GetMonsterInfo(Settings.Zuma7, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Zuma7;
  1890. if (GetMonsterInfo(Settings.Turtle1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Turtle1;
  1891. if (GetMonsterInfo(Settings.Turtle2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Turtle2;
  1892. if (GetMonsterInfo(Settings.Turtle3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Turtle3;
  1893. if (GetMonsterInfo(Settings.Turtle4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Turtle4;
  1894. if (GetMonsterInfo(Settings.Turtle5, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.Turtle5;
  1895. if (GetMonsterInfo(Settings.BoneMonster1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BoneMonster1;
  1896. if (GetMonsterInfo(Settings.BoneMonster2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BoneMonster2;
  1897. if (GetMonsterInfo(Settings.BoneMonster3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BoneMonster3;
  1898. if (GetMonsterInfo(Settings.BoneMonster4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BoneMonster4;
  1899. if (GetMonsterInfo(Settings.BehemothMonster1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BehemothMonster1;
  1900. if (GetMonsterInfo(Settings.BehemothMonster2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BehemothMonster2;
  1901. if (GetMonsterInfo(Settings.BehemothMonster3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BehemothMonster3;
  1902. if (GetMonsterInfo(Settings.HellKnight1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellKnight1;
  1903. if (GetMonsterInfo(Settings.HellKnight2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellKnight2;
  1904. if (GetMonsterInfo(Settings.HellKnight3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellKnight3;
  1905. if (GetMonsterInfo(Settings.HellKnight4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellKnight4;
  1906. if (GetMonsterInfo(Settings.HellBomb1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellBomb1;
  1907. if (GetMonsterInfo(Settings.HellBomb2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellBomb2;
  1908. if (GetMonsterInfo(Settings.HellBomb3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HellBomb3;
  1909. if (GetMonsterInfo(Settings.WhiteSnake, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.WhiteSnake;
  1910. if (GetMonsterInfo(Settings.AngelName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.AngelName;
  1911. if (GetMonsterInfo(Settings.BombSpiderName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.BombSpiderName;
  1912. if (GetMonsterInfo(Settings.CloneName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.CloneName;
  1913. if (GetMonsterInfo(Settings.AssassinCloneName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.AssassinCloneName;
  1914. if (GetMonsterInfo(Settings.VampireName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.VampireName;
  1915. if (GetMonsterInfo(Settings.ToadName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ToadName;
  1916. if (GetMonsterInfo(Settings.SnakeTotemName, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.SnakeTotemName;
  1917. if (GetMonsterInfo(Settings.FishingMonster, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.FishingMonster;
  1918. if (GetMonsterInfo(Settings.GeneralMeowMeowMob1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.GeneralMeowMeowMob1;
  1919. if (GetMonsterInfo(Settings.GeneralMeowMeowMob2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.GeneralMeowMeowMob2;
  1920. if (GetMonsterInfo(Settings.GeneralMeowMeowMob3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.GeneralMeowMeowMob3;
  1921. if (GetMonsterInfo(Settings.GeneralMeowMeowMob4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.GeneralMeowMeowMob4;
  1922. if (GetMonsterInfo(Settings.KingHydraxMob, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.KingHydraxMob;
  1923. if (GetMonsterInfo(Settings.HornedCommanderMob, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HornedCommanderMob;
  1924. if (GetMonsterInfo(Settings.HornedCommanderBombMob, true) == null)
  1925. return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.HornedCommanderBombMob;
  1926. if (GetMonsterInfo(Settings.SnowWolfKingMob, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.SnowWolfKingMob;
  1927. if (GetMonsterInfo(Settings.ScrollMob1, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ScrollMob1;
  1928. if (GetMonsterInfo(Settings.ScrollMob2, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ScrollMob2;
  1929. if (GetMonsterInfo(Settings.ScrollMob3, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ScrollMob3;
  1930. if (GetMonsterInfo(Settings.ScrollMob4, true) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutMob) + Settings.ScrollMob4;
  1931. if (GetItemInfo(Settings.RefineOreName) == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.CannotStartServerWithoutItem) + Settings.RefineOreName;
  1932. }
  1933. WorldMapIcon wmi = ValidateWorldMap();
  1934. if (wmi != null)
  1935. return GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.InvalidWorldmapIndex), wmi.MapIndex, wmi.Title);
  1936. //add intelligent creature checks?
  1937. return "true";
  1938. }
  1939. private void WorkLoop()
  1940. {
  1941. try
  1942. {
  1943. Time = Stopwatch.ElapsedMilliseconds;
  1944. var conTime = Time;
  1945. var saveTime = Time + Settings.SaveDelay * Settings.Minute;
  1946. var userTime = Time + Settings.Minute * 5;
  1947. var lineMessageTime = Time + Settings.Minute * Settings.LineMessageTimer;
  1948. var processTime = Time + 1000;
  1949. var startTime = Time;
  1950. var processCount = 0;
  1951. var processRealCount = 0;
  1952. LinkedListNode<MapObject> current = null;
  1953. if (Settings.Multithreaded)
  1954. {
  1955. for (var j = 0; j < MobThreads.Length; j++)
  1956. {
  1957. MobThreads[j] = new MobThread();
  1958. MobThreads[j].Id = j;
  1959. }
  1960. }
  1961. StartEnvir();
  1962. var canstartserver = CanStartEnvir();
  1963. if (canstartserver != "true")
  1964. {
  1965. MessageQueue.Enqueue(canstartserver);
  1966. StopEnvir();
  1967. _thread = null;
  1968. Stop();
  1969. return;
  1970. }
  1971. if (Settings.Multithreaded)
  1972. {
  1973. for (var j = 0; j < MobThreads.Length; j++)
  1974. {
  1975. var Info = MobThreads[j];
  1976. if (j <= 0) continue;
  1977. MobThreading[j] = new Thread(() => ThreadLoop(Info)) { IsBackground = true };
  1978. MobThreading[j].Start();
  1979. }
  1980. }
  1981. StartNetwork();
  1982. if (Settings.StartHTTPService)
  1983. {
  1984. http = new HttpServer();
  1985. http.Start();
  1986. }
  1987. try
  1988. {
  1989. while (Running)
  1990. {
  1991. Time = Stopwatch.ElapsedMilliseconds;
  1992. if (Time >= processTime)
  1993. {
  1994. LastCount = processCount;
  1995. LastRealCount = processRealCount;
  1996. processCount = 0;
  1997. processRealCount = 0;
  1998. processTime = Time + 1000;
  1999. }
  2000. if (conTime != Time)
  2001. {
  2002. conTime = Time;
  2003. AdjustLights();
  2004. lock (Connections)
  2005. {
  2006. for (var i = Connections.Count - 1; i >= 0; i--)
  2007. {
  2008. Connections[i].Process();
  2009. }
  2010. }
  2011. lock (StatusConnections)
  2012. {
  2013. for (var i = StatusConnections.Count - 1; i >= 0; i--)
  2014. {
  2015. StatusConnections[i].Process();
  2016. }
  2017. }
  2018. }
  2019. if (current == null)
  2020. current = Objects.First;
  2021. if (current == Objects.First)
  2022. {
  2023. LastRunTime = Time - startTime;
  2024. startTime = Time;
  2025. }
  2026. if (Settings.Multithreaded)
  2027. {
  2028. for (var j = 1; j < MobThreads.Length; j++)
  2029. {
  2030. var Info = MobThreads[j];
  2031. if (!Info.Stop) continue;
  2032. Info.EndTime = Time + 10;
  2033. Info.Stop = false;
  2034. }
  2035. lock (_locker)
  2036. {
  2037. Monitor.PulseAll(_locker); //changing a blocking condition. (this makes the threads wake up!)
  2038. }
  2039. //run the first loop in the main thread so the main thread automaticaly 'halts' until the other threads are finished
  2040. ThreadLoop(MobThreads[0]);
  2041. }
  2042. var TheEnd = false;
  2043. var Start = Stopwatch.ElapsedMilliseconds;
  2044. while (!TheEnd && Stopwatch.ElapsedMilliseconds - Start < 20)
  2045. {
  2046. if (current == null)
  2047. {
  2048. TheEnd = true;
  2049. break;
  2050. }
  2051. var next = current.Next;
  2052. if (!Settings.Multithreaded || current.Value.Race != ObjectType.Monster || current.Value.Master != null)
  2053. {
  2054. if (Time > current.Value.OperateTime)
  2055. {
  2056. current.Value.Process();
  2057. current.Value.SetOperateTime();
  2058. }
  2059. processCount++;
  2060. }
  2061. current = next;
  2062. }
  2063. for (var i = 0; i < MapList.Count; i++)
  2064. MapList[i].Process();
  2065. DragonSystem?.Process();
  2066. Process();
  2067. if (Time >= saveTime)
  2068. {
  2069. saveTime = Time + Settings.SaveDelay * Settings.Minute;
  2070. BeginSaveAccounts();
  2071. SaveDB();
  2072. SaveGuilds();
  2073. SaveGoods();
  2074. SaveConquests();
  2075. }
  2076. if (Time >= userTime)
  2077. {
  2078. userTime = Time + Settings.Minute * 5;
  2079. Broadcast(new S.Chat
  2080. {
  2081. Message = GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.OnlinePlayers), Players.Count),
  2082. Type = ChatType.Hint
  2083. });
  2084. }
  2085. if (LineMessages.Count > 0 && Time >= lineMessageTime)
  2086. {
  2087. lineMessageTime = Time + Settings.Minute * Settings.LineMessageTimer;
  2088. Broadcast(new S.Chat
  2089. {
  2090. Message = LineMessages[Random.Next(LineMessages.Count)],
  2091. Type = ChatType.LineMessage
  2092. });
  2093. }
  2094. // if (Players.Count == 0) Thread.Sleep(1);
  2095. // GC.Collect();
  2096. }
  2097. }
  2098. catch (Exception ex)
  2099. {
  2100. lock (Connections)
  2101. {
  2102. for (var i = Connections.Count - 1; i >= 0; i--)
  2103. Connections[i].SendDisconnect(3);
  2104. }
  2105. // Get stack trace for the exception with source file information
  2106. var st = new StackTrace(ex, true);
  2107. // Get the top stack frame
  2108. var frame = st.GetFrame(0);
  2109. // Get the line number from the stack frame
  2110. var line = frame.GetFileLineNumber();
  2111. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.InnerWorkloopErrorLine), line, ex));
  2112. }
  2113. StopNetwork();
  2114. StopEnvir();
  2115. SaveAccounts();
  2116. SaveGuilds(true);
  2117. SaveConquests(true);
  2118. }
  2119. catch (Exception ex)
  2120. {
  2121. // Get stack trace for the exception with source file information
  2122. var st = new StackTrace(ex, true);
  2123. // Get the top stack frame
  2124. var frame = st.GetFrame(0);
  2125. // Get the line number from the stack frame
  2126. var line = frame.GetFileLineNumber();
  2127. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.OuterWorkloopErrorLine), line, ex));
  2128. }
  2129. _thread = null;
  2130. }
  2131. private void ThreadLoop(MobThread Info)
  2132. {
  2133. Info.Stop = false;
  2134. try
  2135. {
  2136. var stopping = false;
  2137. if (Info._current == null)
  2138. Info._current = Info.ObjectsList.First;
  2139. stopping = Info._current == null;
  2140. while (Running)
  2141. {
  2142. if (Info._current == null)
  2143. Info._current = Info.ObjectsList.First;
  2144. else
  2145. {
  2146. var next = Info._current.Next;
  2147. //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)
  2148. if (Info._current == Info.ObjectsList.Last)
  2149. {
  2150. next = Info.ObjectsList.First;
  2151. Info.LastRunTime = (Info.LastRunTime + (Time - Info.StartTime)) / 2;
  2152. //Info.LastRunTime = (Time - Info.StartTime) /*> 0 ? (Time - Info.StartTime) : Info.LastRunTime */;
  2153. Info.StartTime = Time;
  2154. }
  2155. if (Time > Info._current.Value.OperateTime)
  2156. {
  2157. 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)
  2158. {
  2159. Info._current.Value.Process();
  2160. Info._current.Value.SetOperateTime();
  2161. }
  2162. }
  2163. Info._current = next;
  2164. }
  2165. //if it's the main thread > make it loop till the subthreads are done, else make it stop after 'endtime'
  2166. if (Info.Id == 0)
  2167. {
  2168. stopping = true;
  2169. for (var x = 1; x < MobThreads.Length; x++)
  2170. {
  2171. if (MobThreads[x].Stop == false)
  2172. {
  2173. stopping = false;
  2174. }
  2175. }
  2176. if (!stopping) continue;
  2177. Info.Stop = stopping;
  2178. return;
  2179. }
  2180. if (Stopwatch.ElapsedMilliseconds <= Info.EndTime || !Running) continue;
  2181. Info.Stop = true;
  2182. lock (_locker)
  2183. {
  2184. while (Info.Stop) Monitor.Wait(_locker);
  2185. }
  2186. }
  2187. }
  2188. catch (Exception ex)
  2189. {
  2190. if (ex is ThreadInterruptedException) return;
  2191. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ThreadLoopError), ex));
  2192. }
  2193. }
  2194. private void AdjustLights()
  2195. {
  2196. var oldLights = Lights;
  2197. var hours = Now.Hour * 2 % 24;
  2198. if (hours == 6 || hours == 7)
  2199. Lights = LightSetting.Dawn;
  2200. else if (hours >= 8 && hours <= 15)
  2201. Lights = LightSetting.Day;
  2202. else if (hours == 16 || hours == 17)
  2203. Lights = LightSetting.Evening;
  2204. else
  2205. Lights = LightSetting.Night;
  2206. if (oldLights == Lights) return;
  2207. Broadcast(new S.TimeOfDay { Lights = Lights });
  2208. }
  2209. public void Process()
  2210. {
  2211. if (Now.Day != dailyTime)
  2212. {
  2213. dailyTime = Now.Day;
  2214. ProcessNewDay();
  2215. }
  2216. if (Time >= warTime)
  2217. {
  2218. warTime = Time + Settings.Minute;
  2219. for (var i = GuildsAtWar.Count - 1; i >= 0; i--)
  2220. {
  2221. GuildsAtWar[i].TimeRemaining -= Settings.Minute;
  2222. if (GuildsAtWar[i].TimeRemaining >= 0) continue;
  2223. GuildsAtWar[i].EndWar();
  2224. GuildsAtWar.RemoveAt(i);
  2225. }
  2226. }
  2227. if (Time >= guildTime)
  2228. {
  2229. guildTime = Time + Settings.Minute;
  2230. for (var i = 0; i < Guilds.Count; i++)
  2231. {
  2232. Guilds[i].Process();
  2233. }
  2234. }
  2235. if (Time >= conquestTime)
  2236. {
  2237. conquestTime = Time + Settings.Second * 10;
  2238. for (var i = 0; i < Conquests.Count; i++)
  2239. {
  2240. Conquests[i].Process();
  2241. }
  2242. }
  2243. if (Time >= rentalItemsTime)
  2244. {
  2245. rentalItemsTime = Time + Settings.Minute * 5;
  2246. ProcessRentedItems();
  2247. }
  2248. if (Time >= auctionTime)
  2249. {
  2250. auctionTime = Time + Settings.Minute * 10;
  2251. ProcessAuction();
  2252. }
  2253. if (Time >= spawnTime)
  2254. {
  2255. spawnTime = Time + Settings.Second * 10;
  2256. Main.RespawnTick.Process();
  2257. }
  2258. if (Time >= robotTime)
  2259. {
  2260. robotTime = Time + Settings.Minute;
  2261. Robot.Process(RobotNPC);
  2262. }
  2263. if (Time >= timerTime)
  2264. {
  2265. timerTime = Time + Settings.Second;
  2266. string[] keys = Timers.Keys.ToArray();
  2267. foreach (var key in keys)
  2268. {
  2269. if (Timers[key].RelativeTime <= Time)
  2270. {
  2271. Timers.Remove(key);
  2272. }
  2273. }
  2274. }
  2275. }
  2276. private void ProcessAuction()
  2277. {
  2278. LinkedListNode<AuctionInfo> current = Auctions.First;
  2279. while (current != null)
  2280. {
  2281. AuctionInfo info = current.Value;
  2282. if (!info.Expired && !info.Sold && Now >= info.ConsignmentDate.AddDays(Globals.ConsignmentLength))
  2283. {
  2284. if (info.ItemType == MarketItemType.Auction && info.CurrentBid > info.Price)
  2285. {
  2286. string message = GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.YouWonForGold), info.Item.FriendlyName, info.CurrentBid);
  2287. info.Sold = true;
  2288. MailCharacter(info.CurrentBuyerInfo, item: info.Item, customMessage: message);
  2289. MessageAccount(info.CurrentBuyerInfo.AccountInfo, GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.YouBoughtForGold), info.Item.FriendlyName, info.CurrentBid),
  2290. ChatType.Hint);
  2291. MessageAccount(info.SellerInfo.AccountInfo, GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.YouSoldForGold), info.Item.FriendlyName, info.CurrentBid),
  2292. ChatType.Hint);
  2293. }
  2294. else
  2295. {
  2296. info.Expired = true;
  2297. }
  2298. }
  2299. current = current.Next;
  2300. }
  2301. }
  2302. public void Broadcast(Packet p)
  2303. {
  2304. for (var i = 0; i < Players.Count; i++) Players[i].Enqueue(p);
  2305. }
  2306. public void RequiresBaseStatUpdate()
  2307. {
  2308. for (var i = 0; i < Players.Count; i++) Players[i].HasUpdatedBaseStats = false;
  2309. }
  2310. public void RequiresHeroBaseStatUpdate()
  2311. {
  2312. for (var i = 0; i < Heroes.Count; i++)
  2313. {
  2314. Heroes[i].HasUpdatedBaseStats = false;
  2315. Heroes[i].RefreshStats();
  2316. }
  2317. }
  2318. public void SaveDB()
  2319. {
  2320. if (File.Exists(DatabasePath))
  2321. {
  2322. if (!Directory.Exists(DatabaseBackUpPath)) Directory.CreateDirectory(DatabaseBackUpPath);
  2323. var fileName =
  2324. $"Database {Now.Year:0000}-{Now.Month:00}-{Now.Day:00} {Now.Hour:00}-{Now.Minute:00}-{Now.Second:00}.bak";
  2325. var backupFile = Path.Combine(DatabaseBackUpPath, fileName);
  2326. if (File.Exists(backupFile)) File.Delete(backupFile);
  2327. File.Copy(DatabasePath, backupFile);
  2328. }
  2329. using (var stream = File.Create(DatabasePath))
  2330. using (var writer = new BinaryWriter(stream))
  2331. {
  2332. writer.Write(Version);
  2333. writer.Write(CustomVersion);
  2334. writer.Write(MapIndex);
  2335. writer.Write(ItemIndex);
  2336. writer.Write(MonsterIndex);
  2337. writer.Write(NPCIndex);
  2338. writer.Write(QuestIndex);
  2339. writer.Write(GameshopIndex);
  2340. writer.Write(ConquestIndex);
  2341. writer.Write(RespawnIndex);
  2342. writer.Write(MapInfoList.Count);
  2343. for (var i = 0; i < MapInfoList.Count; i++)
  2344. MapInfoList[i].Save(writer);
  2345. writer.Write(ItemInfoList.Count);
  2346. for (var i = 0; i < ItemInfoList.Count; i++)
  2347. ItemInfoList[i].Save(writer);
  2348. writer.Write(MonsterInfoList.Count);
  2349. for (var i = 0; i < MonsterInfoList.Count; i++)
  2350. MonsterInfoList[i].Save(writer);
  2351. writer.Write(NPCInfoList.Count);
  2352. for (var i = 0; i < NPCInfoList.Count; i++)
  2353. NPCInfoList[i].Save(writer);
  2354. writer.Write(QuestInfoList.Count);
  2355. for (var i = 0; i < QuestInfoList.Count; i++)
  2356. QuestInfoList[i].Save(writer);
  2357. DragonInfo.Save(writer);
  2358. writer.Write(MagicInfoList.Count);
  2359. for (var i = 0; i < MagicInfoList.Count; i++)
  2360. MagicInfoList[i].Save(writer);
  2361. writer.Write(GameShopList.Count);
  2362. for (var i = 0; i < GameShopList.Count; i++)
  2363. GameShopList[i].Save(writer);
  2364. writer.Write(ConquestInfoList.Count);
  2365. for (var i = 0; i < ConquestInfoList.Count; i++)
  2366. ConquestInfoList[i].Save(writer);
  2367. RespawnTick.Save(writer);
  2368. writer.Write(GTMapList.Count);
  2369. for (var i = 0; i < GTMapList.Count; i++)
  2370. GTMapList[i].Save(writer);
  2371. }
  2372. }
  2373. public CharacterInfo GetArchivedCharacter(string name)
  2374. {
  2375. DirectoryInfo dir = new DirectoryInfo(ArchivePath);
  2376. FileInfo[] files = dir.GetFiles($"{name}*.MirCA");
  2377. if (files.Length != 1)
  2378. {
  2379. return null;
  2380. }
  2381. var fileInfo = files[0];
  2382. CharacterInfo info = null;
  2383. using (var stream = fileInfo.OpenRead())
  2384. {
  2385. using var reader = new BinaryReader(stream);
  2386. var version = reader.ReadInt32();
  2387. var customVersion = reader.ReadInt32();
  2388. info = new CharacterInfo(reader, version, customVersion);
  2389. }
  2390. return info;
  2391. }
  2392. public void SaveArchivedCharacter(CharacterInfo info)
  2393. {
  2394. if (!Directory.Exists(ArchivePath)) Directory.CreateDirectory(ArchivePath);
  2395. using var stream = File.Create(Path.Combine(ArchivePath, @$"{info.Name}{Now:_MMddyyyy_HHmmss}.MirCA"));
  2396. using var writer = new BinaryWriter(stream);
  2397. writer.Write(Version);
  2398. writer.Write(CustomVersion);
  2399. info.Save(writer);
  2400. }
  2401. public void SaveAccounts()
  2402. {
  2403. while (Saving)
  2404. Thread.Sleep(1);
  2405. try
  2406. {
  2407. using (var stream = File.Create(AccountPath + "n"))
  2408. SaveAccounts(stream);
  2409. if (File.Exists(AccountPath))
  2410. File.Move(AccountPath, AccountPath + "o");
  2411. File.Move(AccountPath + "n", AccountPath);
  2412. if (File.Exists(AccountPath + "o"))
  2413. File.Delete(AccountPath + "o");
  2414. }
  2415. catch (Exception ex)
  2416. {
  2417. MessageQueue.Enqueue(ex);
  2418. }
  2419. }
  2420. private void SaveAccounts(Stream stream)
  2421. {
  2422. using (var writer = new BinaryWriter(stream))
  2423. {
  2424. writer.Write(Version);
  2425. writer.Write(CustomVersion);
  2426. writer.Write(NextAccountID);
  2427. writer.Write(NextCharacterID);
  2428. writer.Write(NextUserItemID);
  2429. writer.Write(NextHeroID);
  2430. writer.Write(GuildList.Count);
  2431. writer.Write(NextGuildID);
  2432. writer.Write(HeroList.Count);
  2433. for (var i = 0; i < HeroList.Count; i++)
  2434. HeroList[i].Save(writer);
  2435. writer.Write(AccountList.Count);
  2436. for (var i = 0; i < AccountList.Count; i++)
  2437. AccountList[i].Save(writer);
  2438. writer.Write(NextAuctionID);
  2439. writer.Write(Auctions.Count);
  2440. foreach (var auction in Auctions)
  2441. auction.Save(writer);
  2442. writer.Write(NextMailID);
  2443. writer.Write(GameshopLog.Count);
  2444. foreach (var item in GameshopLog)
  2445. {
  2446. writer.Write(item.Key);
  2447. writer.Write(item.Value);
  2448. }
  2449. writer.Write(SavedSpawns.Count);
  2450. foreach (var Spawn in SavedSpawns)
  2451. {
  2452. var Save = new RespawnSave { RespawnIndex = Spawn.Info.RespawnIndex, NextSpawnTick = Spawn.NextSpawnTick, Spawned = Spawn.Count >= Spawn.Info.Count * SpawnMultiplier };
  2453. Save.Save(writer);
  2454. }
  2455. }
  2456. }
  2457. private void SaveGuilds(bool forced = false)
  2458. {
  2459. if (!Directory.Exists(Settings.GuildPath)) Directory.CreateDirectory(Settings.GuildPath);
  2460. if (GuildRefreshNeeded == true) //deletes guild files and resaves with new indexing if a guild is deleted.
  2461. {
  2462. foreach (var guildfile in Directory.GetFiles(Settings.GuildPath, "*.mgd"))
  2463. {
  2464. File.Delete(guildfile);
  2465. }
  2466. GuildRefreshNeeded = false;
  2467. forced = true; //triggers a full resave of all guilds
  2468. }
  2469. for (var i = 0; i < GuildList.Count; i++)
  2470. {
  2471. if (GuildList[i].NeedSave || forced)
  2472. {
  2473. GuildList[i].NeedSave = false;
  2474. GuildObject liveGuild = Guilds.Find(g => g.Guildindex == GuildList[i].GuildIndex);
  2475. if (liveGuild != null)
  2476. {
  2477. GuildList[i] = liveGuild.Info;
  2478. }
  2479. var mStream = new MemoryStream();
  2480. var writer = new BinaryWriter(mStream);
  2481. GuildList[i].Save(writer);
  2482. var fStream = new FileStream(Path.Combine(Settings.GuildPath, i + ".mgdn"), FileMode.Create);
  2483. var data = mStream.ToArray();
  2484. fStream.BeginWrite(data, 0, data.Length, EndSaveGuildsAsync, fStream);
  2485. }
  2486. }
  2487. }
  2488. private void EndSaveGuildsAsync(IAsyncResult result)
  2489. {
  2490. var fStream = result.AsyncState as FileStream;
  2491. try
  2492. {
  2493. if (fStream == null) return;
  2494. var oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  2495. var newfilename = fStream.Name;
  2496. fStream.EndWrite(result);
  2497. fStream.Dispose();
  2498. if (File.Exists(oldfilename))
  2499. File.Move(oldfilename, oldfilename + "o");
  2500. File.Move(newfilename, oldfilename);
  2501. if (File.Exists(oldfilename + "o"))
  2502. File.Delete(oldfilename + "o");
  2503. }
  2504. catch (Exception)
  2505. {
  2506. }
  2507. }
  2508. private void SaveGoods(bool forced = false)
  2509. {
  2510. if (!Directory.Exists(Settings.GoodsPath)) Directory.CreateDirectory(Settings.GoodsPath);
  2511. for (var i = 0; i < MapList.Count; i++)
  2512. {
  2513. var map = MapList[i];
  2514. if (map.NPCs.Count == 0) continue;
  2515. for (var j = 0; j < map.NPCs.Count; j++)
  2516. {
  2517. var npc = map.NPCs[j];
  2518. if (forced)
  2519. {
  2520. npc.ProcessGoods(forced);
  2521. }
  2522. if (!npc.NeedSave) continue;
  2523. var path = Path.Combine(Settings.GoodsPath, npc.Info.Index + ".msdn");
  2524. var mStream = new MemoryStream();
  2525. var writer = new BinaryWriter(mStream);
  2526. var Temp = 9999;
  2527. writer.Write(Temp);
  2528. writer.Write(Version);
  2529. writer.Write(CustomVersion);
  2530. writer.Write(npc.UsedGoods.Count);
  2531. for (var k = 0; k < npc.UsedGoods.Count; k++)
  2532. {
  2533. npc.UsedGoods[k].Save(writer);
  2534. }
  2535. var fStream = new FileStream(path, FileMode.Create);
  2536. var data = mStream.ToArray();
  2537. fStream.BeginWrite(data, 0, data.Length, EndSaveGoodsAsync, fStream);
  2538. }
  2539. }
  2540. }
  2541. private void EndSaveGoodsAsync(IAsyncResult result)
  2542. {
  2543. try
  2544. {
  2545. var fStream = result.AsyncState as FileStream;
  2546. if (fStream == null) return;
  2547. var oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  2548. var newfilename = fStream.Name;
  2549. fStream.EndWrite(result);
  2550. fStream.Dispose();
  2551. if (File.Exists(oldfilename))
  2552. File.Move(oldfilename, oldfilename + "o");
  2553. File.Move(newfilename, oldfilename);
  2554. if (File.Exists(oldfilename + "o"))
  2555. File.Delete(oldfilename + "o");
  2556. }
  2557. catch (Exception)
  2558. {
  2559. }
  2560. }
  2561. private void SaveConquests(bool forced = false)
  2562. {
  2563. if (!Directory.Exists(Settings.ConquestsPath)) Directory.CreateDirectory(Settings.ConquestsPath);
  2564. for (var i = 0; i < ConquestList.Count; i++)
  2565. {
  2566. if (!ConquestList[i].NeedSave && !forced) continue;
  2567. ConquestList[i].NeedSave = false;
  2568. var mStream = new MemoryStream();
  2569. var writer = new BinaryWriter(mStream);
  2570. ConquestList[i].Save(writer);
  2571. var fStream = new FileStream(Path.Combine(Settings.ConquestsPath, ConquestList[i].Info.Index + ".mcdn"), FileMode.Create);
  2572. var data = mStream.ToArray();
  2573. fStream.BeginWrite(data, 0, data.Length, EndSaveConquestsAsync, fStream);
  2574. }
  2575. }
  2576. private void EndSaveConquestsAsync(IAsyncResult result)
  2577. {
  2578. var fStream = result.AsyncState as FileStream;
  2579. try
  2580. {
  2581. if (fStream == null) return;
  2582. var oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  2583. var newfilename = fStream.Name;
  2584. fStream.EndWrite(result);
  2585. fStream.Dispose();
  2586. if (File.Exists(oldfilename))
  2587. File.Move(oldfilename, oldfilename + "o");
  2588. File.Move(newfilename, oldfilename);
  2589. if (File.Exists(oldfilename + "o"))
  2590. File.Delete(oldfilename + "o");
  2591. }
  2592. catch (Exception)
  2593. {
  2594. }
  2595. }
  2596. public void BeginSaveAccounts()
  2597. {
  2598. if (Saving) return;
  2599. Saving = true;
  2600. using (var mStream = new MemoryStream())
  2601. {
  2602. if (File.Exists(AccountPath))
  2603. {
  2604. if (!Directory.Exists(AccountsBackUpPath)) Directory.CreateDirectory(AccountsBackUpPath);
  2605. var fileName =
  2606. $"Accounts {Now.Year:0000}-{Now.Month:00}-{Now.Day:00} {Now.Hour:00}-{Now.Minute:00}-{Now.Second:00}.bak";
  2607. if (File.Exists(Path.Combine(AccountsBackUpPath, fileName))) File.Delete(Path.Combine(AccountsBackUpPath, fileName));
  2608. File.Move(AccountPath, Path.Combine(AccountsBackUpPath, fileName));
  2609. }
  2610. SaveAccounts(mStream);
  2611. var fStream = new FileStream(AccountPath + "n", FileMode.Create);
  2612. var data = mStream.ToArray();
  2613. fStream.BeginWrite(data, 0, data.Length, EndSaveAccounts, fStream);
  2614. }
  2615. }
  2616. private void EndSaveAccounts(IAsyncResult result)
  2617. {
  2618. var fStream = result.AsyncState as FileStream;
  2619. try
  2620. {
  2621. if (fStream != null)
  2622. {
  2623. var oldfilename = fStream.Name.Substring(0, fStream.Name.Length - 1);
  2624. var newfilename = fStream.Name;
  2625. fStream.EndWrite(result);
  2626. fStream.Dispose();
  2627. if (File.Exists(oldfilename))
  2628. File.Move(oldfilename, oldfilename + "o");
  2629. File.Move(newfilename, oldfilename);
  2630. if (File.Exists(oldfilename + "o"))
  2631. File.Delete(oldfilename + "o");
  2632. }
  2633. }
  2634. catch (Exception)
  2635. {
  2636. }
  2637. Saving = false;
  2638. }
  2639. public bool LoadDB()
  2640. {
  2641. lock (LoadLock)
  2642. {
  2643. if (!File.Exists(DatabasePath))
  2644. {
  2645. SaveDB();
  2646. }
  2647. using (var stream = File.OpenRead(DatabasePath))
  2648. using (var reader = new BinaryReader(stream))
  2649. {
  2650. LoadVersion = reader.ReadInt32();
  2651. LoadCustomVersion = reader.ReadInt32();
  2652. if (LoadVersion < MinVersion)
  2653. {
  2654. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.CannotLoadDatabaseMinSupported), LoadVersion, MinVersion));
  2655. return false;
  2656. }
  2657. else if (LoadVersion > Version)
  2658. {
  2659. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.CannotLoadDatabaseMaxSupported), LoadVersion, Version));
  2660. return false;
  2661. }
  2662. MapIndex = reader.ReadInt32();
  2663. ItemIndex = reader.ReadInt32();
  2664. MonsterIndex = reader.ReadInt32();
  2665. NPCIndex = reader.ReadInt32();
  2666. QuestIndex = reader.ReadInt32();
  2667. if (LoadVersion >= 63)
  2668. {
  2669. GameshopIndex = reader.ReadInt32();
  2670. }
  2671. if (LoadVersion >= 66)
  2672. {
  2673. ConquestIndex = reader.ReadInt32();
  2674. }
  2675. if (LoadVersion >= 68)
  2676. RespawnIndex = reader.ReadInt32();
  2677. var count = reader.ReadInt32();
  2678. MapInfoList.Clear();
  2679. for (var i = 0; i < count; i++)
  2680. MapInfoList.Add(new MapInfo(reader));
  2681. count = reader.ReadInt32();
  2682. ItemInfoList.Clear();
  2683. for (var i = 0; i < count; i++)
  2684. {
  2685. ItemInfoList.Add(new ItemInfo(reader, LoadVersion, LoadCustomVersion));
  2686. if (ItemInfoList[i] != null && ItemInfoList[i].RandomStatsId < Settings.RandomItemStatsList.Count)
  2687. {
  2688. ItemInfoList[i].RandomStats = Settings.RandomItemStatsList[ItemInfoList[i].RandomStatsId];
  2689. }
  2690. }
  2691. count = reader.ReadInt32();
  2692. MonsterInfoList.Clear();
  2693. for (var i = 0; i < count; i++)
  2694. MonsterInfoList.Add(new MonsterInfo(reader));
  2695. count = reader.ReadInt32();
  2696. NPCInfoList.Clear();
  2697. for (var i = 0; i < count; i++)
  2698. NPCInfoList.Add(new NPCInfo(reader));
  2699. count = reader.ReadInt32();
  2700. QuestInfoList.Clear();
  2701. for (var i = 0; i < count; i++)
  2702. QuestInfoList.Add(new QuestInfo(reader));
  2703. DragonInfo = new DragonInfo(reader);
  2704. count = reader.ReadInt32();
  2705. for (var i = 0; i < count; i++)
  2706. {
  2707. var m = new MagicInfo(reader, LoadVersion, LoadCustomVersion);
  2708. if (!MagicExists(m.Spell))
  2709. MagicInfoList.Add(m);
  2710. }
  2711. FillMagicInfoList();
  2712. if (LoadVersion <= 70)
  2713. UpdateMagicInfo();
  2714. if (LoadVersion >= 63)
  2715. {
  2716. count = reader.ReadInt32();
  2717. GameShopList.Clear();
  2718. for (var i = 0; i < count; i++)
  2719. {
  2720. var item = new GameShopItem(reader, LoadVersion, LoadCustomVersion);
  2721. if (Main.BindGameShop(item))
  2722. {
  2723. GameShopList.Add(item);
  2724. }
  2725. }
  2726. }
  2727. if (LoadVersion >= 66)
  2728. {
  2729. ConquestInfoList.Clear();
  2730. count = reader.ReadInt32();
  2731. for (var i = 0; i < count; i++)
  2732. {
  2733. ConquestInfoList.Add(new ConquestInfo(reader));
  2734. }
  2735. }
  2736. if (LoadVersion > 67)
  2737. RespawnTick = new RespawnTimer(reader);
  2738. }
  2739. Settings.LinkGuildCreationItems(ItemInfoList);
  2740. }
  2741. return true;
  2742. }
  2743. public void LoadAccounts()
  2744. {
  2745. //reset ranking
  2746. for (var i = 0; i < RankClass.Count(); i++)
  2747. {
  2748. if (RankClass[i] != null)
  2749. {
  2750. RankClass[i].Clear();
  2751. }
  2752. else
  2753. {
  2754. RankClass[i] = new List<RankCharacterInfo>();
  2755. }
  2756. }
  2757. RankTop.Clear();
  2758. lock (LoadLock)
  2759. {
  2760. if (!File.Exists(AccountPath))
  2761. {
  2762. SaveAccounts();
  2763. }
  2764. using (var stream = File.OpenRead(AccountPath))
  2765. using (var reader = new BinaryReader(stream))
  2766. {
  2767. LoadVersion = reader.ReadInt32();
  2768. LoadCustomVersion = reader.ReadInt32();
  2769. NextAccountID = reader.ReadInt32();
  2770. NextCharacterID = reader.ReadInt32();
  2771. NextUserItemID = reader.ReadUInt64();
  2772. if (LoadVersion > 98)
  2773. NextHeroID = reader.ReadInt32();
  2774. GuildCount = reader.ReadInt32();
  2775. NextGuildID = reader.ReadInt32();
  2776. int count;
  2777. if (LoadVersion > 102)
  2778. {
  2779. count = reader.ReadInt32();
  2780. HeroList.Clear();
  2781. for (var i = 0; i < count; i++)
  2782. HeroList.Add(new HeroInfo(reader, LoadVersion, LoadCustomVersion));
  2783. }
  2784. count = reader.ReadInt32();
  2785. AccountList.Clear();
  2786. CharacterList.Clear();
  2787. int TrueAccount = 0;
  2788. for (var i = 0; i < count; i++)
  2789. {
  2790. AccountInfo NextAccount = new AccountInfo(reader);
  2791. if (i > 0 && NextAccount.Characters.Count == 0)
  2792. continue;
  2793. AccountList.Add(NextAccount);
  2794. CharacterList.AddRange(AccountList[TrueAccount].Characters);
  2795. if (LoadVersion > 98 && LoadVersion < 103)
  2796. AccountList[TrueAccount].Characters.ForEach(character => HeroList.AddRange(character.Heroes));
  2797. TrueAccount++;
  2798. }
  2799. foreach (var auction in Auctions)
  2800. {
  2801. auction.SellerInfo.AccountInfo.Auctions.Remove(auction);
  2802. }
  2803. Auctions.Clear();
  2804. NextAuctionID = reader.ReadUInt64();
  2805. count = reader.ReadInt32();
  2806. for (var i = 0; i < count; i++)
  2807. {
  2808. var auction = new AuctionInfo(reader, LoadVersion, LoadCustomVersion);
  2809. if (!BindItem(auction.Item) || !BindCharacter(auction)) continue;
  2810. Auctions.AddLast(auction);
  2811. auction.SellerInfo.AccountInfo.Auctions.AddLast(auction);
  2812. }
  2813. NextMailID = reader.ReadUInt64();
  2814. if (LoadVersion <= 80)
  2815. {
  2816. count = reader.ReadInt32();
  2817. for (var i = 0; i < count; i++)
  2818. {
  2819. var mail = new MailInfo(reader, LoadVersion, LoadCustomVersion);
  2820. mail.RecipientInfo = GetCharacterInfo(mail.RecipientIndex);
  2821. if (mail.RecipientInfo != null)
  2822. {
  2823. mail.RecipientInfo.Mail.Add(mail); //add to players inbox
  2824. }
  2825. }
  2826. }
  2827. if (LoadVersion >= 63)
  2828. {
  2829. var logCount = reader.ReadInt32();
  2830. for (var i = 0; i < logCount; i++)
  2831. {
  2832. GameshopLog.Add(reader.ReadInt32(), reader.ReadInt32());
  2833. }
  2834. if (ResetGS) ClearGameshopLog();
  2835. }
  2836. if (LoadVersion >= 68)
  2837. {
  2838. var saveCount = reader.ReadInt32();
  2839. for (var i = 0; i < saveCount; i++)
  2840. {
  2841. var saved = new RespawnSave(reader);
  2842. foreach (var respawn in SavedSpawns)
  2843. {
  2844. if (respawn.Info.RespawnIndex != saved.RespawnIndex) continue;
  2845. respawn.NextSpawnTick = saved.NextSpawnTick;
  2846. if (!saved.Spawned || respawn.Info.Count * SpawnMultiplier <= respawn.Count)
  2847. {
  2848. continue;
  2849. }
  2850. var mobcount = respawn.Info.Count * SpawnMultiplier - respawn.Count;
  2851. for (var j = 0; j < mobcount; j++)
  2852. {
  2853. respawn.Spawn();
  2854. }
  2855. }
  2856. }
  2857. }
  2858. }
  2859. }
  2860. }
  2861. public void LoadGuilds()
  2862. {
  2863. lock (LoadLock)
  2864. {
  2865. var count = 0;
  2866. GuildList.Clear();
  2867. for (var i = 0; i < GuildCount; i++)
  2868. {
  2869. GuildInfo guildInfo;
  2870. if (!File.Exists(Path.Combine(Settings.GuildPath, i + ".mgd"))) continue;
  2871. using (var stream = File.OpenRead(Path.Combine(Settings.GuildPath, i + ".mgd")))
  2872. {
  2873. using var reader = new BinaryReader(stream);
  2874. guildInfo = new GuildInfo(reader);
  2875. }
  2876. GuildList.Add(guildInfo);
  2877. new GuildObject(guildInfo);
  2878. count++;
  2879. }
  2880. if (count != GuildCount) GuildCount = count;
  2881. }
  2882. }
  2883. public void LoadConquests()
  2884. {
  2885. lock (LoadLock)
  2886. {
  2887. Conquests.Clear();
  2888. ConquestList.Clear();
  2889. for (var i = 0; i < ConquestInfoList.Count; i++)
  2890. {
  2891. ConquestObject newConquest;
  2892. ConquestGuildInfo conquestGuildInfo;
  2893. var tempMap = GetMap(ConquestInfoList[i].MapIndex);
  2894. if (tempMap == null) continue;
  2895. if (File.Exists(Path.Combine(Settings.ConquestsPath, ConquestInfoList[i].Index + ".mcd")))
  2896. {
  2897. using (var stream = File.OpenRead(Path.Combine(Settings.ConquestsPath, ConquestInfoList[i].Index + ".mcd")))
  2898. {
  2899. using var reader = new BinaryReader(stream);
  2900. conquestGuildInfo = new ConquestGuildInfo(reader) { Info = ConquestInfoList[i] };
  2901. }
  2902. newConquest = new ConquestObject(conquestGuildInfo)
  2903. {
  2904. ConquestMap = tempMap
  2905. };
  2906. for (var k = 0; k < Guilds.Count; k++)
  2907. {
  2908. if (conquestGuildInfo.Owner != Guilds[k].Guildindex) continue;
  2909. newConquest.Guild = Guilds[k];
  2910. Guilds[k].Conquest = newConquest;
  2911. }
  2912. }
  2913. else
  2914. {
  2915. conquestGuildInfo = new ConquestGuildInfo { Info = ConquestInfoList[i], NeedSave = true };
  2916. newConquest = new ConquestObject(conquestGuildInfo)
  2917. {
  2918. ConquestMap = tempMap
  2919. };
  2920. }
  2921. ConquestList.Add(conquestGuildInfo);
  2922. Conquests.Add(newConquest);
  2923. tempMap.Conquest.Add(newConquest);
  2924. newConquest.Bind();
  2925. }
  2926. }
  2927. }
  2928. private void LoadGTInfo()
  2929. {
  2930. foreach (var gt in GTMapList)
  2931. {
  2932. var Guild = GuildList.FirstOrDefault(x => x.GTIndex == gt.Index);
  2933. if (Guild != null)
  2934. {
  2935. gt.Owner = Guild.Name;
  2936. if (Guild.Ranks.Count > 0 && Guild.Ranks[0] != null && Guild.Ranks[0].Members.Count > 0 && Guild.Ranks[0].Members[0] != null)
  2937. gt.Leader = Guild.Ranks[0].Members[0].Name;
  2938. gt.Price = 0;
  2939. gt.Days = (Now - Guild.GTRent).Days;
  2940. }
  2941. }
  2942. }
  2943. public void LoadDisabledChars()
  2944. {
  2945. DisabledCharNames.Clear();
  2946. var path = Path.Combine(Settings.EnvirPath, "DisabledChars.txt");
  2947. if (!File.Exists(path))
  2948. {
  2949. File.WriteAllText(path, "");
  2950. }
  2951. else
  2952. {
  2953. var lines = File.ReadAllLines(path);
  2954. for (var i = 0; i < lines.Length; i++)
  2955. {
  2956. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2957. DisabledCharNames.Add(lines[i].ToUpper());
  2958. }
  2959. }
  2960. }
  2961. public void LoadLineMessages()
  2962. {
  2963. LineMessages.Clear();
  2964. var path = Path.Combine(Settings.EnvirPath, "LineMessage.txt");
  2965. if (!File.Exists(path))
  2966. {
  2967. File.WriteAllText(path, "");
  2968. }
  2969. else
  2970. {
  2971. var lines = File.ReadAllLines(path);
  2972. for (var i = 0; i < lines.Length; i++)
  2973. {
  2974. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  2975. LineMessages.Add(lines[i]);
  2976. }
  2977. }
  2978. }
  2979. private bool BindCharacter(AuctionInfo auction)
  2980. {
  2981. bool bound = false;
  2982. for (int i = 0; i < CharacterList.Count; i++)
  2983. {
  2984. if (CharacterList[i].Index == auction.SellerIndex)
  2985. {
  2986. auction.SellerInfo = CharacterList[i];
  2987. bound = true;
  2988. }
  2989. else if (CharacterList[i].Index == auction.CurrentBuyerIndex)
  2990. {
  2991. auction.CurrentBuyerInfo = CharacterList[i];
  2992. bound = true;
  2993. }
  2994. }
  2995. return bound;
  2996. }
  2997. public void Start()
  2998. {
  2999. if (Running || _thread != null) return;
  3000. Running = true;
  3001. _thread = new Thread(WorkLoop) { IsBackground = true };
  3002. _thread.Start();
  3003. }
  3004. public void Stop()
  3005. {
  3006. Running = false;
  3007. lock (_locker)
  3008. {
  3009. // changing a blocking condition. (this makes the threads wake up!)
  3010. Monitor.PulseAll(_locker);
  3011. }
  3012. //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)
  3013. for (var i = 1; i < MobThreading.Length; i++)
  3014. {
  3015. if (MobThreads[i] != null)
  3016. {
  3017. MobThreads[i].EndTime = Time + 9999;
  3018. }
  3019. if (MobThreading[i] != null &&
  3020. MobThreading[i].ThreadState != System.Threading.ThreadState.Stopped && MobThreading[i].ThreadState != System.Threading.ThreadState.Unstarted)
  3021. {
  3022. MobThreading[i].Interrupt();
  3023. }
  3024. }
  3025. http?.Stop();
  3026. while (_thread != null)
  3027. Thread.Sleep(1);
  3028. }
  3029. public void Reboot()
  3030. {
  3031. new Thread(() =>
  3032. {
  3033. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ServerRebooting));
  3034. Stop();
  3035. Start();
  3036. }).Start();
  3037. }
  3038. public void UpdateIPBlock(string ipAddress, TimeSpan value)
  3039. {
  3040. IPBlocks[ipAddress] = Now.Add(value);
  3041. }
  3042. private void StartEnvir()
  3043. {
  3044. Players.Clear();
  3045. StartPoints.Clear();
  3046. StartItems.Clear();
  3047. MapList.Clear();
  3048. GTMapList.Clear();
  3049. GameshopLog.Clear();
  3050. CustomCommands.Clear();
  3051. Heroes.Clear();
  3052. MonsterCount = 0;
  3053. LoadDB();
  3054. BuffInfoList.Clear();
  3055. foreach (var buff in BuffInfo.Load())
  3056. {
  3057. BuffInfoList.Add(buff);
  3058. }
  3059. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.BuffsLoaded), BuffInfoList.Count));
  3060. RecipeInfoList.Clear();
  3061. foreach (var recipe in Directory.GetFiles(Settings.RecipePath, "*.txt")
  3062. .Select(path => Path.GetFileNameWithoutExtension(path))
  3063. .ToArray())
  3064. {
  3065. RecipeInfoList.Add(new RecipeInfo(recipe));
  3066. }
  3067. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.RecipesLoaded), RecipeInfoList.Count));
  3068. for (var i = 0; i < MapInfoList.Count; i++)
  3069. {
  3070. // Call CreateMap(), which adds the map to Envir.MapList
  3071. MapInfoList[i].CreateMap();
  3072. // Fetch the created map from Envir.MapList
  3073. Map map = MapList.FirstOrDefault(m => m.Info == MapInfoList[i]);
  3074. if (map != null)
  3075. {
  3076. if (MapInfoList[i].GT)
  3077. {
  3078. GTMap gt = GTMapList.FirstOrDefault(x => x.Index == MapInfoList[i].GTIndex);
  3079. if (gt != null)
  3080. {
  3081. gt.Maps.Add(map);
  3082. }
  3083. else
  3084. {
  3085. var GT = new GTMap()
  3086. {
  3087. Index = MapInfoList[i].GTIndex,
  3088. Name = MapInfoList[i].Title,
  3089. Price = Settings.BuyGTGold,
  3090. Days = 0,
  3091. Begin = 0,
  3092. Leader = "None",
  3093. Owner = "None",
  3094. };
  3095. GT.Maps.Add(map);
  3096. GTMapList.Add(GT);
  3097. }
  3098. }
  3099. }
  3100. }
  3101. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.MapsLoaded), MapInfoList.Count));
  3102. for (var i = 0; i < ItemInfoList.Count; i++)
  3103. {
  3104. if (ItemInfoList[i].StartItem)
  3105. {
  3106. StartItems.Add(ItemInfoList[i]);
  3107. }
  3108. }
  3109. ReloadDrops();
  3110. LoadDisabledChars();
  3111. LoadLineMessages();
  3112. if (DragonInfo.Enabled)
  3113. {
  3114. DragonSystem = new Dragon(DragonInfo);
  3115. if (DragonSystem != null)
  3116. {
  3117. if (DragonSystem.Load()) DragonSystem.Info.LoadDrops();
  3118. }
  3119. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.DragonLoaded));
  3120. }
  3121. DefaultNPC = NPCScript.GetOrAdd((uint)Random.Next(1000000, 1999999), Settings.DefaultNPCFilename, NPCScriptType.AutoPlayer);
  3122. MonsterNPC = NPCScript.GetOrAdd((uint)Random.Next(2000000, 2999999), Settings.MonsterNPCFilename, NPCScriptType.AutoMonster);
  3123. RobotNPC = NPCScript.GetOrAdd((uint)Random.Next(3000000, 3999999), Settings.RobotNPCFilename, NPCScriptType.Robot);
  3124. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.EnvirStarted));
  3125. }
  3126. private void StartNetwork()
  3127. {
  3128. Connections.Clear();
  3129. LoadAccounts();
  3130. LoadGuilds();
  3131. LoadConquests();
  3132. LoadGTInfo();
  3133. _listener = new TcpListener(IPAddress.Parse(Settings.IPAddress), Settings.Port);
  3134. _listener.Start();
  3135. _listener.BeginAcceptTcpClient(Connection, null);
  3136. if (StatusPortEnabled)
  3137. {
  3138. _StatusPort = new TcpListener(IPAddress.Parse(Settings.IPAddress), 3000);
  3139. _StatusPort.Start();
  3140. _StatusPort.BeginAcceptTcpClient(StatusConnection, null);
  3141. }
  3142. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NetworkStarted));
  3143. }
  3144. private void StopEnvir()
  3145. {
  3146. SaveGoods(true);
  3147. MapList.Clear();
  3148. StartPoints.Clear();
  3149. StartItems.Clear();
  3150. Objects.Clear();
  3151. Players.Clear();
  3152. Heroes.Clear();
  3153. GTMapList.Clear();
  3154. CleanUp();
  3155. GC.Collect();
  3156. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.EnvirStopped));
  3157. }
  3158. private void StopNetwork()
  3159. {
  3160. _listener.Stop();
  3161. lock (Connections)
  3162. {
  3163. for (var i = Connections.Count - 1; i >= 0; i--)
  3164. Connections[i].SendDisconnect(0);
  3165. }
  3166. if (StatusPortEnabled)
  3167. {
  3168. _StatusPort.Stop();
  3169. for (var i = StatusConnections.Count - 1; i >= 0; i--)
  3170. StatusConnections[i].SendDisconnect();
  3171. }
  3172. var expire = Time + 5000;
  3173. while (Connections.Count != 0 && Stopwatch.ElapsedMilliseconds < expire)
  3174. {
  3175. Time = Stopwatch.ElapsedMilliseconds;
  3176. for (var i = Connections.Count - 1; i >= 0; i--)
  3177. Connections[i].Process();
  3178. Thread.Sleep(1);
  3179. }
  3180. Connections.Clear();
  3181. expire = Time + 10000;
  3182. while (StatusConnections.Count != 0 && Stopwatch.ElapsedMilliseconds < expire)
  3183. {
  3184. Time = Stopwatch.ElapsedMilliseconds;
  3185. for (var i = StatusConnections.Count - 1; i >= 0; i--)
  3186. StatusConnections[i].Process();
  3187. Thread.Sleep(1);
  3188. }
  3189. StatusConnections.Clear();
  3190. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NetworkStopped));
  3191. }
  3192. private void CleanUp()
  3193. {
  3194. for (var i = 0; i < CharacterList.Count; i++)
  3195. {
  3196. var info = CharacterList[i];
  3197. if (info.Deleted)
  3198. {
  3199. #region Mentor Cleanup
  3200. if (info.Mentor > 0)
  3201. {
  3202. var mentor = GetCharacterInfo(info.Mentor);
  3203. if (mentor != null)
  3204. {
  3205. mentor.Mentor = 0;
  3206. mentor.MentorExp = 0;
  3207. mentor.IsMentor = false;
  3208. }
  3209. info.Mentor = 0;
  3210. info.MentorExp = 0;
  3211. info.IsMentor = false;
  3212. }
  3213. #endregion
  3214. #region Marriage Cleanup
  3215. if (info.Married > 0)
  3216. {
  3217. var Lover = GetCharacterInfo(info.Married);
  3218. info.Married = 0;
  3219. info.MarriedDate = Now;
  3220. Lover.Married = 0;
  3221. Lover.MarriedDate = Now;
  3222. if (Lover.Equipment[(int)EquipmentSlot.RingL] != null)
  3223. Lover.Equipment[(int)EquipmentSlot.RingL].WeddingRing = -1;
  3224. }
  3225. #endregion
  3226. }
  3227. if (info.Mail.Count > Settings.MailCapacity)
  3228. {
  3229. for (var j = info.Mail.Count - 1 - (int)Settings.MailCapacity; j >= 0; j--)
  3230. {
  3231. if (info.Mail[j].DateOpened > Now && info.Mail[j].Collected && info.Mail[j].Items.Count == 0 && info.Mail[j].Gold == 0)
  3232. {
  3233. info.Mail.Remove(info.Mail[j]);
  3234. }
  3235. }
  3236. }
  3237. }
  3238. }
  3239. private void Connection(IAsyncResult result)
  3240. {
  3241. try
  3242. {
  3243. if (!Running || !_listener.Server.IsBound) return;
  3244. }
  3245. catch (Exception e)
  3246. {
  3247. MessageQueue.Enqueue(e.ToString());
  3248. }
  3249. try
  3250. {
  3251. var tempTcpClient = _listener.EndAcceptTcpClient(result);
  3252. bool connected = false;
  3253. var ipAddress = tempTcpClient.Client.RemoteEndPoint.ToString().Split(':')[0];
  3254. if (!IPBlocks.TryGetValue(ipAddress, out DateTime banDate) || banDate < Now)
  3255. {
  3256. int count = 0;
  3257. for (int i = 0; i < Connections.Count; i++)
  3258. {
  3259. var connection = Connections[i];
  3260. if (!connection.Connected || connection.IPAddress != ipAddress)
  3261. continue;
  3262. count++;
  3263. }
  3264. if (count >= Settings.MaxIP)
  3265. {
  3266. UpdateIPBlock(ipAddress, TimeSpan.FromSeconds(Settings.IPBlockSeconds));
  3267. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IpAddressDisconnectedTooManyConnections), ipAddress));
  3268. }
  3269. else
  3270. {
  3271. var tempConnection = new MirConnection(++_sessionID, tempTcpClient);
  3272. if (tempConnection.Connected)
  3273. {
  3274. connected = true;
  3275. lock (Connections)
  3276. Connections.Add(tempConnection);
  3277. }
  3278. }
  3279. }
  3280. if (!connected)
  3281. tempTcpClient.Close();
  3282. }
  3283. catch (Exception ex)
  3284. {
  3285. MessageQueue.Enqueue(ex);
  3286. }
  3287. finally
  3288. {
  3289. while (Connections.Count >= Settings.MaxUser)
  3290. Thread.Sleep(1);
  3291. if (Running && _listener.Server.IsBound)
  3292. _listener.BeginAcceptTcpClient(Connection, null);
  3293. }
  3294. }
  3295. private void StatusConnection(IAsyncResult result)
  3296. {
  3297. if (!Running || !_StatusPort.Server.IsBound) return;
  3298. try
  3299. {
  3300. var tempTcpClient = _StatusPort.EndAcceptTcpClient(result);
  3301. lock (StatusConnections)
  3302. StatusConnections.Add(new MirStatusConnection(tempTcpClient));
  3303. }
  3304. catch (Exception ex)
  3305. {
  3306. MessageQueue.Enqueue(ex);
  3307. }
  3308. finally
  3309. {
  3310. while (StatusConnections.Count >= 5) //dont allow to many status port connections it's just an abuse thing
  3311. Thread.Sleep(1);
  3312. if (Running && _StatusPort.Server.IsBound)
  3313. _StatusPort.BeginAcceptTcpClient(StatusConnection, null);
  3314. }
  3315. }
  3316. public void NewAccount(ClientPackets.NewAccount p, MirConnection c)
  3317. {
  3318. if (!Settings.AllowNewAccount)
  3319. {
  3320. c.Enqueue(new ServerPackets.NewAccount { Result = 0 });
  3321. return;
  3322. }
  3323. if (ConnectionLogs.TryGetValue(c.IPAddress, out MirConnectionLog currentlog))
  3324. {
  3325. if (currentlog.AccountsMade.Count > 2)
  3326. {
  3327. IPBlocks[c.IPAddress] = Now.AddHours(24);
  3328. c.Enqueue(new ServerPackets.NewAccount { Result = 0 });
  3329. return;
  3330. }
  3331. currentlog.AccountsMade.Add(Time);
  3332. for (int i = 0; i < currentlog.AccountsMade.Count; i++)
  3333. {
  3334. if ((currentlog.AccountsMade[i] + 60 * 60 * 1000) < Time)
  3335. {
  3336. currentlog.AccountsMade.RemoveAt(i);
  3337. break;
  3338. }
  3339. }
  3340. }
  3341. else
  3342. {
  3343. ConnectionLogs[c.IPAddress] = new MirConnectionLog() { IPAddress = c.IPAddress };
  3344. }
  3345. if (!AccountIDReg.IsMatch(p.AccountID))
  3346. {
  3347. c.Enqueue(new ServerPackets.NewAccount { Result = 1 });
  3348. return;
  3349. }
  3350. if (!PasswordReg.IsMatch(p.Password))
  3351. {
  3352. c.Enqueue(new ServerPackets.NewAccount { Result = 2 });
  3353. return;
  3354. }
  3355. if (!string.IsNullOrWhiteSpace(p.EMailAddress) && !EMailReg.IsMatch(p.EMailAddress) ||
  3356. p.EMailAddress.Length > 50)
  3357. {
  3358. c.Enqueue(new ServerPackets.NewAccount { Result = 3 });
  3359. return;
  3360. }
  3361. if (!string.IsNullOrWhiteSpace(p.UserName) && p.UserName.Length > 20)
  3362. {
  3363. c.Enqueue(new ServerPackets.NewAccount { Result = 4 });
  3364. return;
  3365. }
  3366. if (!string.IsNullOrWhiteSpace(p.SecretQuestion) && p.SecretQuestion.Length > 30)
  3367. {
  3368. c.Enqueue(new ServerPackets.NewAccount { Result = 5 });
  3369. return;
  3370. }
  3371. if (!string.IsNullOrWhiteSpace(p.SecretAnswer) && p.SecretAnswer.Length > 30)
  3372. {
  3373. c.Enqueue(new ServerPackets.NewAccount { Result = 6 });
  3374. return;
  3375. }
  3376. lock (AccountLock)
  3377. {
  3378. if (AccountExists(p.AccountID))
  3379. {
  3380. c.Enqueue(new ServerPackets.NewAccount { Result = 7 });
  3381. return;
  3382. }
  3383. AccountList.Add(new AccountInfo(p) { Index = ++NextAccountID, CreationIP = c.IPAddress });
  3384. c.Enqueue(new ServerPackets.NewAccount { Result = 8 });
  3385. }
  3386. }
  3387. public int HTTPNewAccount(ClientPackets.NewAccount p, string ip)
  3388. {
  3389. if (!Settings.AllowNewAccount)
  3390. {
  3391. return 0;
  3392. }
  3393. if (!AccountIDReg.IsMatch(p.AccountID))
  3394. {
  3395. return 1;
  3396. }
  3397. if (!PasswordReg.IsMatch(p.Password))
  3398. {
  3399. return 2;
  3400. }
  3401. if (!string.IsNullOrWhiteSpace(p.EMailAddress) && !EMailReg.IsMatch(p.EMailAddress) ||
  3402. p.EMailAddress.Length > 50)
  3403. {
  3404. return 3;
  3405. }
  3406. if (!string.IsNullOrWhiteSpace(p.UserName) && p.UserName.Length > 20)
  3407. {
  3408. return 4;
  3409. }
  3410. if (!string.IsNullOrWhiteSpace(p.SecretQuestion) && p.SecretQuestion.Length > 30)
  3411. {
  3412. return 5;
  3413. }
  3414. if (!string.IsNullOrWhiteSpace(p.SecretAnswer) && p.SecretAnswer.Length > 30)
  3415. {
  3416. return 6;
  3417. }
  3418. lock (AccountLock)
  3419. {
  3420. if (AccountExists(p.AccountID))
  3421. {
  3422. return 7;
  3423. }
  3424. AccountList.Add(new AccountInfo(p) { Index = ++NextAccountID, CreationIP = ip });
  3425. return 8;
  3426. }
  3427. }
  3428. public void ChangePassword(ClientPackets.ChangePassword p, MirConnection c)
  3429. {
  3430. if (!Settings.AllowChangePassword)
  3431. {
  3432. c.Enqueue(new ServerPackets.ChangePassword { Result = 0 });
  3433. return;
  3434. }
  3435. if (!AccountIDReg.IsMatch(p.AccountID))
  3436. {
  3437. c.Enqueue(new ServerPackets.ChangePassword { Result = 1 });
  3438. return;
  3439. }
  3440. if (!PasswordReg.IsMatch(p.CurrentPassword))
  3441. {
  3442. c.Enqueue(new ServerPackets.ChangePassword { Result = 2 });
  3443. return;
  3444. }
  3445. if (!PasswordReg.IsMatch(p.NewPassword))
  3446. {
  3447. c.Enqueue(new ServerPackets.ChangePassword { Result = 3 });
  3448. return;
  3449. }
  3450. var account = GetAccount(p.AccountID);
  3451. if (account == null)
  3452. {
  3453. c.Enqueue(new ServerPackets.ChangePassword { Result = 4 });
  3454. return;
  3455. }
  3456. if (account.Banned)
  3457. {
  3458. if (account.ExpiryDate > Now)
  3459. {
  3460. c.Enqueue(new ServerPackets.ChangePasswordBanned { Reason = account.BanReason, ExpiryDate = account.ExpiryDate });
  3461. return;
  3462. }
  3463. account.Banned = false;
  3464. }
  3465. account.BanReason = string.Empty;
  3466. account.ExpiryDate = DateTime.MinValue;
  3467. p.CurrentPassword = Utils.Crypto.HashPassword(p.CurrentPassword, account.Salt);
  3468. if (string.CompareOrdinal(account.Password, p.CurrentPassword) != 0)
  3469. {
  3470. c.Enqueue(new ServerPackets.ChangePassword { Result = 5 });
  3471. return;
  3472. }
  3473. account.Password = p.NewPassword;
  3474. account.RequirePasswordChange = false;
  3475. c.Enqueue(new ServerPackets.ChangePassword { Result = 6 });
  3476. }
  3477. public void Login(ClientPackets.Login p, MirConnection c)
  3478. {
  3479. if (!Settings.AllowLogin)
  3480. {
  3481. c.Enqueue(new ServerPackets.Login { Result = 0 });
  3482. return;
  3483. }
  3484. if (!AccountIDReg.IsMatch(p.AccountID))
  3485. {
  3486. c.Enqueue(new ServerPackets.Login { Result = 1 });
  3487. return;
  3488. }
  3489. if (!PasswordReg.IsMatch(p.Password))
  3490. {
  3491. c.Enqueue(new ServerPackets.Login { Result = 2 });
  3492. return;
  3493. }
  3494. var account = GetAccount(p.AccountID);
  3495. if (account == null)
  3496. {
  3497. c.Enqueue(new ServerPackets.Login { Result = 3 });
  3498. return;
  3499. }
  3500. if (account.Banned)
  3501. {
  3502. if (account.ExpiryDate > Now)
  3503. {
  3504. c.Enqueue(new ServerPackets.LoginBanned
  3505. {
  3506. Reason = account.BanReason,
  3507. ExpiryDate = account.ExpiryDate
  3508. });
  3509. return;
  3510. }
  3511. account.Banned = false;
  3512. }
  3513. account.BanReason = string.Empty;
  3514. account.ExpiryDate = DateTime.MinValue;
  3515. p.Password = Utils.Crypto.HashPassword(p.Password, account.Salt);
  3516. if (string.CompareOrdinal(account.Password, p.Password) != 0)
  3517. {
  3518. if (account.WrongPasswordCount++ >= 5)
  3519. {
  3520. account.Banned = true;
  3521. account.BanReason = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.TooManyWrongLoginAttempts);
  3522. account.ExpiryDate = Now.AddMinutes(2);
  3523. c.Enqueue(new ServerPackets.LoginBanned
  3524. {
  3525. Reason = account.BanReason,
  3526. ExpiryDate = account.ExpiryDate
  3527. });
  3528. return;
  3529. }
  3530. c.Enqueue(new ServerPackets.Login { Result = 4 });
  3531. return;
  3532. }
  3533. account.WrongPasswordCount = 0;
  3534. if (account.RequirePasswordChange)
  3535. {
  3536. c.Enqueue(new ServerPackets.Login { Result = 5 });
  3537. return;
  3538. }
  3539. lock (AccountLock)
  3540. {
  3541. account.Connection?.SendDisconnect(1);
  3542. account.Connection = c;
  3543. }
  3544. c.Account = account;
  3545. c.Stage = GameStage.Select;
  3546. account.LastDate = Now;
  3547. account.LastIP = c.IPAddress;
  3548. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.UserLoggedIn), account.Connection.SessionID, account.Connection.IPAddress));
  3549. c.Enqueue(new ServerPackets.LoginSuccess { Characters = account.GetSelectInfo() });
  3550. }
  3551. public int HTTPLogin(string AccountID, string Password)
  3552. {
  3553. if (!Settings.AllowLogin)
  3554. {
  3555. return 0;
  3556. }
  3557. if (!AccountIDReg.IsMatch(AccountID))
  3558. {
  3559. return 1;
  3560. }
  3561. if (!PasswordReg.IsMatch(Password))
  3562. {
  3563. return 2;
  3564. }
  3565. var account = GetAccount(AccountID);
  3566. if (account == null)
  3567. {
  3568. return 3;
  3569. }
  3570. if (account.Banned)
  3571. {
  3572. if (account.ExpiryDate > Now)
  3573. {
  3574. return 4;
  3575. }
  3576. account.Banned = false;
  3577. }
  3578. account.BanReason = string.Empty;
  3579. account.ExpiryDate = DateTime.MinValue;
  3580. if (string.CompareOrdinal(account.Password, Password) != 0)
  3581. {
  3582. if (account.WrongPasswordCount++ >= 5)
  3583. {
  3584. account.Banned = true;
  3585. account.BanReason = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.TooManyWrongLoginAttempts);
  3586. account.ExpiryDate = Now.AddMinutes(2);
  3587. return 5;
  3588. }
  3589. return 6;
  3590. }
  3591. account.WrongPasswordCount = 0;
  3592. return 7;
  3593. }
  3594. public void NewCharacter(ClientPackets.NewCharacter p, MirConnection c, bool IsGm)
  3595. {
  3596. if (!Settings.AllowNewCharacter)
  3597. {
  3598. c.Enqueue(new ServerPackets.NewCharacter { Result = 0 });
  3599. return;
  3600. }
  3601. if (ConnectionLogs.TryGetValue(c.IPAddress, out MirConnectionLog currentlog))
  3602. {
  3603. if (currentlog.CharactersMade.Count > 4)
  3604. {
  3605. IPBlocks[c.IPAddress] = Now.AddHours(24);
  3606. c.Enqueue(new ServerPackets.NewCharacter { Result = 0 });
  3607. return;
  3608. }
  3609. currentlog.CharactersMade.Add(Time);
  3610. for (int i = 0; i < currentlog.CharactersMade.Count; i++)
  3611. {
  3612. if ((currentlog.CharactersMade[i] + 60 * 60 * 1000) < Time)
  3613. {
  3614. currentlog.CharactersMade.RemoveAt(i);
  3615. break;
  3616. }
  3617. }
  3618. }
  3619. else
  3620. {
  3621. ConnectionLogs[c.IPAddress] = new MirConnectionLog() { IPAddress = c.IPAddress };
  3622. }
  3623. if (!CharacterReg.IsMatch(p.Name))
  3624. {
  3625. c.Enqueue(new ServerPackets.NewCharacter { Result = 1 });
  3626. return;
  3627. }
  3628. if (!IsGm && DisabledCharNames.Contains(p.Name.ToUpper()))
  3629. {
  3630. c.Enqueue(new ServerPackets.NewCharacter { Result = 1 });
  3631. return;
  3632. }
  3633. if (p.Gender != MirGender.Male && p.Gender != MirGender.Female)
  3634. {
  3635. c.Enqueue(new ServerPackets.NewCharacter { Result = 2 });
  3636. return;
  3637. }
  3638. if (p.Class != MirClass.Warrior && p.Class != MirClass.Wizard && p.Class != MirClass.Taoist &&
  3639. p.Class != MirClass.Assassin && p.Class != MirClass.Archer)
  3640. {
  3641. c.Enqueue(new ServerPackets.NewCharacter { Result = 3 });
  3642. return;
  3643. }
  3644. if (p.Class == MirClass.Assassin && !Settings.AllowCreateAssassin ||
  3645. p.Class == MirClass.Archer && !Settings.AllowCreateArcher)
  3646. {
  3647. c.Enqueue(new ServerPackets.NewCharacter { Result = 3 });
  3648. return;
  3649. }
  3650. var count = 0;
  3651. for (var i = 0; i < c.Account.Characters.Count; i++)
  3652. {
  3653. if (c.Account.Characters[i].Deleted) continue;
  3654. if (++count >= Globals.MaxCharacterCount)
  3655. {
  3656. c.Enqueue(new ServerPackets.NewCharacter { Result = 4 });
  3657. return;
  3658. }
  3659. }
  3660. lock (AccountLock)
  3661. {
  3662. if (CharacterExists(p.Name))
  3663. {
  3664. c.Enqueue(new ServerPackets.NewCharacter { Result = 5 });
  3665. return;
  3666. }
  3667. var info = new CharacterInfo(p, c) { Index = ++NextCharacterID, AccountInfo = c.Account };
  3668. c.Account.Characters.Add(info);
  3669. CharacterList.Add(info);
  3670. c.Enqueue(new ServerPackets.NewCharacterSuccess { CharInfo = info.ToSelectInfo() });
  3671. }
  3672. }
  3673. public bool CanCreateHero(ClientPackets.NewHero p, MirConnection c, bool IsGm)
  3674. {
  3675. if (!Settings.AllowNewHero)
  3676. {
  3677. c.Enqueue(new S.NewHero { Result = 0 });
  3678. return false;
  3679. }
  3680. if (!CharacterReg.IsMatch(p.Name))
  3681. {
  3682. c.Enqueue(new S.NewHero { Result = 1 });
  3683. return false;
  3684. }
  3685. if (!IsGm && DisabledCharNames.Contains(p.Name.ToUpper()))
  3686. {
  3687. c.Enqueue(new S.NewHero { Result = 1 });
  3688. return false;
  3689. }
  3690. if (p.Gender != MirGender.Male && p.Gender != MirGender.Female)
  3691. {
  3692. c.Enqueue(new S.NewHero { Result = 2 });
  3693. return false;
  3694. }
  3695. if (p.Class != MirClass.Warrior && p.Class != MirClass.Wizard && p.Class != MirClass.Taoist && p.Class != MirClass.Assassin && p.Class != MirClass.Archer)
  3696. {
  3697. c.Enqueue(new S.NewHero { Result = 3 });
  3698. return false;
  3699. }
  3700. if (p.Class == MirClass.Warrior && !Settings.Hero_CanCreateClass[0] || p.Class == MirClass.Wizard && !Settings.Hero_CanCreateClass[1] || p.Class == MirClass.Taoist && !Settings.Hero_CanCreateClass[2] || p.Class == MirClass.Assassin && !Settings.Hero_CanCreateClass[3] || p.Class == MirClass.Archer && !Settings.Hero_CanCreateClass[4])
  3701. {
  3702. c.Enqueue(new S.NewHero { Result = 3 });
  3703. return false;
  3704. }
  3705. lock (AccountLock)
  3706. {
  3707. if (CharacterExists(p.Name))
  3708. {
  3709. c.Enqueue(new S.NewHero { Result = 5 });
  3710. return false;
  3711. }
  3712. }
  3713. return true;
  3714. }
  3715. public bool AccountExists(string accountID)
  3716. {
  3717. for (var i = 0; i < AccountList.Count; i++)
  3718. if (string.Compare(AccountList[i].AccountID, accountID, StringComparison.OrdinalIgnoreCase) == 0)
  3719. return true;
  3720. return false;
  3721. }
  3722. public bool CharacterExists(string name)
  3723. {
  3724. for (var i = 0; i < CharacterList.Count; i++)
  3725. if (string.Compare(CharacterList[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  3726. return true;
  3727. return false;
  3728. }
  3729. public List<CharacterInfo> MatchPlayer(string PlayerID, bool match = false)
  3730. {
  3731. if (string.IsNullOrEmpty(PlayerID)) return new List<CharacterInfo>(CharacterList);
  3732. List<CharacterInfo> list = new List<CharacterInfo>();
  3733. for (int i = 0; i < CharacterList.Count; i++)
  3734. {
  3735. if (match)
  3736. {
  3737. if (CharacterList[i].Name.Equals(PlayerID, StringComparison.OrdinalIgnoreCase))
  3738. list.Add(CharacterList[i]);
  3739. }
  3740. else
  3741. {
  3742. if (CharacterList[i].Name.IndexOf(PlayerID, StringComparison.OrdinalIgnoreCase) >= 0)
  3743. list.Add(CharacterList[i]);
  3744. }
  3745. }
  3746. return list;
  3747. }
  3748. public List<CharacterInfo> MatchPlayerbyItem(string itemIdentifier, bool match = false)
  3749. {
  3750. List<CharacterInfo> list = new List<CharacterInfo>();
  3751. bool isNumeric = ulong.TryParse(itemIdentifier, out ulong itemId);
  3752. for (int i = 0; i < CharacterList.Count; i++)
  3753. {
  3754. if (match)
  3755. {
  3756. foreach (var item in CharacterList[i].Inventory)
  3757. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.Equals(itemIdentifier, StringComparison.OrdinalIgnoreCase))) && !list.Contains(CharacterList[i]))
  3758. list.Add(CharacterList[i]);
  3759. foreach (var item in CharacterList[i].AccountInfo.Storage)
  3760. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.Equals(itemIdentifier, StringComparison.OrdinalIgnoreCase))) && !list.Contains(CharacterList[i]))
  3761. list.Add(CharacterList[i]);
  3762. foreach (var item in CharacterList[i].QuestInventory)
  3763. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.Equals(itemIdentifier, StringComparison.OrdinalIgnoreCase))) && !list.Contains(CharacterList[i]))
  3764. list.Add(CharacterList[i]);
  3765. foreach (var item in CharacterList[i].Equipment)
  3766. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.Equals(itemIdentifier, StringComparison.OrdinalIgnoreCase))) && !list.Contains(CharacterList[i]))
  3767. list.Add(CharacterList[i]);
  3768. foreach (var mail in CharacterList[i].Mail)
  3769. foreach (var item in mail.Items)
  3770. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.Equals(itemIdentifier, StringComparison.OrdinalIgnoreCase))) && !list.Contains(CharacterList[i]))
  3771. list.Add(CharacterList[i]);
  3772. }
  3773. else
  3774. {
  3775. foreach (var item in CharacterList[i].Inventory)
  3776. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.IndexOf(itemIdentifier, StringComparison.OrdinalIgnoreCase) >= 0)) && !list.Contains(CharacterList[i]))
  3777. list.Add(CharacterList[i]);
  3778. foreach (var item in CharacterList[i].QuestInventory)
  3779. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.IndexOf(itemIdentifier, StringComparison.OrdinalIgnoreCase) >= 0)) && !list.Contains(CharacterList[i]))
  3780. list.Add(CharacterList[i]);
  3781. foreach (var item in CharacterList[i].Equipment)
  3782. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.IndexOf(itemIdentifier, StringComparison.OrdinalIgnoreCase) >= 0)) && !list.Contains(CharacterList[i]))
  3783. list.Add(CharacterList[i]);
  3784. foreach (var item in CharacterList[i].AccountInfo.Storage)
  3785. if (item != null && ((isNumeric && item.UniqueID == itemId) || (!isNumeric && item.FriendlyName.IndexOf(itemIdentifier, StringComparison.OrdinalIgnoreCase) >= 0)) && !list.Contains(CharacterList[i]))
  3786. list.Add(CharacterList[i]);
  3787. }
  3788. }
  3789. return list;
  3790. }
  3791. public AccountInfo GetAccount(string accountID)
  3792. {
  3793. for (var i = 0; i < AccountList.Count; i++)
  3794. if (string.Compare(AccountList[i].AccountID, accountID, StringComparison.OrdinalIgnoreCase) == 0)
  3795. return AccountList[i];
  3796. return null;
  3797. }
  3798. public AccountInfo GetAccountByCharacter(string name)
  3799. {
  3800. for (var i = 0; i < AccountList.Count; i++)
  3801. {
  3802. for (int j = 0; j < AccountList[i].Characters.Count; j++)
  3803. {
  3804. if (string.Compare(AccountList[i].Characters[j].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  3805. return AccountList[i];
  3806. }
  3807. }
  3808. return null;
  3809. }
  3810. public List<AccountInfo> MatchAccounts(string accountID, bool match = false)
  3811. {
  3812. if (string.IsNullOrEmpty(accountID)) return new List<AccountInfo>(AccountList);
  3813. var list = new List<AccountInfo>();
  3814. for (var i = 0; i < AccountList.Count; i++)
  3815. {
  3816. if (match)
  3817. {
  3818. if (AccountList[i].AccountID.Equals(accountID, StringComparison.OrdinalIgnoreCase))
  3819. list.Add(AccountList[i]);
  3820. }
  3821. else
  3822. {
  3823. if (AccountList[i].AccountID.IndexOf(accountID, StringComparison.OrdinalIgnoreCase) >= 0)
  3824. list.Add(AccountList[i]);
  3825. }
  3826. }
  3827. return list;
  3828. }
  3829. public List<AccountInfo> MatchAccountsByPlayer(string playerName, bool match = false)
  3830. {
  3831. if (string.IsNullOrEmpty(playerName)) return new List<AccountInfo>(AccountList);
  3832. var list = new List<AccountInfo>();
  3833. for (var i = 0; i < AccountList.Count; i++)
  3834. {
  3835. for (var j = 0; j < AccountList[i].Characters.Count; j++)
  3836. {
  3837. if (match)
  3838. {
  3839. if (AccountList[i].Characters[j].Name.Equals(playerName, StringComparison.OrdinalIgnoreCase))
  3840. list.Add(AccountList[i]);
  3841. }
  3842. else
  3843. {
  3844. if (AccountList[i].Characters[j].Name.IndexOf(playerName, StringComparison.OrdinalIgnoreCase) >= 0)
  3845. list.Add(AccountList[i]);
  3846. }
  3847. }
  3848. }
  3849. return list;
  3850. }
  3851. public List<AccountInfo> MatchAccountsByIP(string ipAddress, bool matchLastIP = false, bool match = false)
  3852. {
  3853. if (string.IsNullOrEmpty(ipAddress)) return new List<AccountInfo>(AccountList);
  3854. var list = new List<AccountInfo>();
  3855. for (var i = 0; i < AccountList.Count; i++)
  3856. {
  3857. string ipToMatch = matchLastIP ? AccountList[i].LastIP : AccountList[i].CreationIP;
  3858. if (match)
  3859. {
  3860. if (ipToMatch.Equals(ipAddress, StringComparison.OrdinalIgnoreCase))
  3861. list.Add(AccountList[i]);
  3862. }
  3863. else
  3864. {
  3865. if (ipToMatch.IndexOf(ipAddress, StringComparison.OrdinalIgnoreCase) >= 0)
  3866. list.Add(AccountList[i]);
  3867. }
  3868. }
  3869. return list;
  3870. }
  3871. public void CreateAccountInfo()
  3872. {
  3873. AccountList.Add(new AccountInfo { Index = ++NextAccountID });
  3874. }
  3875. public void CreateMapInfo()
  3876. {
  3877. MapInfoList.Add(new MapInfo { Index = ++MapIndex });
  3878. }
  3879. public void CreateItemInfo(ItemType type = ItemType.Nothing)
  3880. {
  3881. ItemInfoList.Add(new ItemInfo { Index = ++ItemIndex, Type = type, RandomStatsId = 255 });
  3882. }
  3883. public void CreateMonsterInfo()
  3884. {
  3885. MonsterInfoList.Add(new MonsterInfo { Index = ++MonsterIndex });
  3886. }
  3887. public void CreateNPCInfo()
  3888. {
  3889. NPCInfoList.Add(new NPCInfo { Index = ++NPCIndex });
  3890. }
  3891. public void CreateQuestInfo()
  3892. {
  3893. QuestInfoList.Add(new QuestInfo { Index = ++QuestIndex });
  3894. }
  3895. public void AddToGameShop(ItemInfo Info)
  3896. {
  3897. GameShopList.Add(new GameShopItem
  3898. {
  3899. GIndex = ++GameshopIndex,
  3900. GoldPrice = (uint)(1000 * Settings.CredxGold),
  3901. CreditPrice = 1000,
  3902. ItemIndex = Info.Index,
  3903. Info = Info,
  3904. Date = Now,
  3905. Class = "All",
  3906. Category = Info.Type.ToString()
  3907. });
  3908. }
  3909. public void Remove(MapInfo info)
  3910. {
  3911. MapInfoList.Remove(info);
  3912. //Desync all objects\
  3913. }
  3914. public void Remove(ItemInfo info)
  3915. {
  3916. ItemInfoList.Remove(info);
  3917. }
  3918. public void Remove(MonsterInfo info)
  3919. {
  3920. MonsterInfoList.Remove(info);
  3921. //Desync all objects\
  3922. }
  3923. public void Remove(NPCInfo info)
  3924. {
  3925. NPCInfoList.Remove(info);
  3926. //Desync all objects\
  3927. }
  3928. public void Remove(QuestInfo info)
  3929. {
  3930. QuestInfoList.Remove(info);
  3931. //Desync all objects\
  3932. }
  3933. public void Remove(GameShopItem info)
  3934. {
  3935. GameShopList.Remove(info);
  3936. if (GameShopList.Count == 0)
  3937. {
  3938. GameshopIndex = 0;
  3939. }
  3940. //Desync all objects\
  3941. }
  3942. public UserItem CreateFreshItem(ItemInfo info)
  3943. {
  3944. var item = new UserItem(info)
  3945. {
  3946. UniqueID = ++NextUserItemID,
  3947. CurrentDura = info.Durability,
  3948. MaxDura = info.Durability
  3949. };
  3950. UpdateItemExpiry(item);
  3951. return item;
  3952. }
  3953. public UserItem CreateDropItem(int index)
  3954. {
  3955. return CreateDropItem(GetItemInfo(index));
  3956. }
  3957. public UserItem CreateDropItem(ItemInfo info)
  3958. {
  3959. if (info == null) return null;
  3960. var item = new UserItem(info)
  3961. {
  3962. UniqueID = ++NextUserItemID,
  3963. MaxDura = info.Durability,
  3964. CurrentDura = (ushort)Math.Min(info.Durability, Random.Next(info.Durability) + 1000)
  3965. };
  3966. UpgradeItem(item);
  3967. UpdateItemExpiry(item);
  3968. if (!info.NeedIdentify) item.Identified = true;
  3969. return item;
  3970. }
  3971. public UserItem CreateShopItem(ItemInfo info, ulong id)
  3972. {
  3973. if (info == null) return null;
  3974. var item = new UserItem(info)
  3975. {
  3976. UniqueID = id,
  3977. CurrentDura = info.Durability,
  3978. MaxDura = info.Durability,
  3979. IsShopItem = true,
  3980. };
  3981. return item;
  3982. }
  3983. public void UpdateItemExpiry(UserItem item)
  3984. {
  3985. var expiryInfo = new ExpireInfo();
  3986. var r = new Regex(@"\[(.*?)\]");
  3987. var expiryMatch = r.Match(item.Info.Name);
  3988. if (expiryMatch.Success)
  3989. {
  3990. var parameter = expiryMatch.Groups[1].Captures[0].Value;
  3991. var numAlpha = new Regex("(?<Numeric>[0-9]*)(?<Alpha>[a-zA-Z]*)");
  3992. var match = numAlpha.Match(parameter);
  3993. var alpha = match.Groups["Alpha"].Value;
  3994. var num = 0;
  3995. int.TryParse(match.Groups["Numeric"].Value, out num);
  3996. switch (alpha)
  3997. {
  3998. case "m":
  3999. expiryInfo.ExpiryDate = Now.AddMinutes(num);
  4000. break;
  4001. case "h":
  4002. expiryInfo.ExpiryDate = Now.AddHours(num);
  4003. break;
  4004. case "d":
  4005. expiryInfo.ExpiryDate = Now.AddDays(num);
  4006. break;
  4007. case "M":
  4008. expiryInfo.ExpiryDate = Now.AddMonths(num);
  4009. break;
  4010. case "y":
  4011. expiryInfo.ExpiryDate = Now.AddYears(num);
  4012. break;
  4013. default:
  4014. expiryInfo.ExpiryDate = DateTime.MaxValue;
  4015. break;
  4016. }
  4017. item.ExpireInfo = expiryInfo;
  4018. }
  4019. }
  4020. public void UpgradeItem(UserItem item)
  4021. {
  4022. if (item.Info.RandomStats == null) return;
  4023. var stat = item.Info.RandomStats;
  4024. if (stat.MaxDuraChance > 0 && Random.Next(stat.MaxDuraChance) == 0)
  4025. {
  4026. var dura = RandomomRange(stat.MaxDuraMaxStat, stat.MaxDuraStatChance);
  4027. item.MaxDura = (ushort)Math.Min(ushort.MaxValue, item.MaxDura + dura * 1000);
  4028. item.CurrentDura = (ushort)Math.Min(ushort.MaxValue, item.CurrentDura + dura * 1000);
  4029. }
  4030. if (stat.MaxAcChance > 0 && Random.Next(stat.MaxAcChance) == 0) item.AddedStats[Stat.MaxAC] = (byte)(RandomomRange(stat.MaxAcMaxStat - 1, stat.MaxAcStatChance) + 1);
  4031. if (stat.MaxMacChance > 0 && Random.Next(stat.MaxMacChance) == 0) item.AddedStats[Stat.MaxMAC] = (byte)(RandomomRange(stat.MaxMacMaxStat - 1, stat.MaxMacStatChance) + 1);
  4032. if (stat.MaxDcChance > 0 && Random.Next(stat.MaxDcChance) == 0) item.AddedStats[Stat.MaxDC] = (byte)(RandomomRange(stat.MaxDcMaxStat - 1, stat.MaxDcStatChance) + 1);
  4033. if (stat.MaxMcChance > 0 && Random.Next(stat.MaxMcChance) == 0) item.AddedStats[Stat.MaxMC] = (byte)(RandomomRange(stat.MaxMcMaxStat - 1, stat.MaxMcStatChance) + 1);
  4034. if (stat.MaxScChance > 0 && Random.Next(stat.MaxScChance) == 0) item.AddedStats[Stat.MaxSC] = (byte)(RandomomRange(stat.MaxScMaxStat - 1, stat.MaxScStatChance) + 1);
  4035. if (stat.AccuracyChance > 0 && Random.Next(stat.AccuracyChance) == 0) item.AddedStats[Stat.Accuracy] = (byte)(RandomomRange(stat.AccuracyMaxStat - 1, stat.AccuracyStatChance) + 1);
  4036. if (stat.AgilityChance > 0 && Random.Next(stat.AgilityChance) == 0) item.AddedStats[Stat.Agility] = (byte)(RandomomRange(stat.AgilityMaxStat - 1, stat.AgilityStatChance) + 1);
  4037. if (stat.HpChance > 0 && Random.Next(stat.HpChance) == 0) item.AddedStats[Stat.HP] = (byte)(RandomomRange(stat.HpMaxStat - 1, stat.HpStatChance) + 1);
  4038. if (stat.MpChance > 0 && Random.Next(stat.MpChance) == 0) item.AddedStats[Stat.MP] = (byte)(RandomomRange(stat.MpMaxStat - 1, stat.MpStatChance) + 1);
  4039. if (stat.StrongChance > 0 && Random.Next(stat.StrongChance) == 0) item.AddedStats[Stat.Strong] = (byte)(RandomomRange(stat.StrongMaxStat - 1, stat.StrongStatChance) + 1);
  4040. if (stat.MagicResistChance > 0 && Random.Next(stat.MagicResistChance) == 0) item.AddedStats[Stat.MagicResist] = (byte)(RandomomRange(stat.MagicResistMaxStat - 1, stat.MagicResistStatChance) + 1);
  4041. if (stat.PoisonResistChance > 0 && Random.Next(stat.PoisonResistChance) == 0) item.AddedStats[Stat.PoisonResist] = (byte)(RandomomRange(stat.PoisonResistMaxStat - 1, stat.PoisonResistStatChance) + 1);
  4042. if (stat.HpRecovChance > 0 && Random.Next(stat.HpRecovChance) == 0) item.AddedStats[Stat.HealthRecovery] = (byte)(RandomomRange(stat.HpRecovMaxStat - 1, stat.HpRecovStatChance) + 1);
  4043. if (stat.MpRecovChance > 0 && Random.Next(stat.MpRecovChance) == 0) item.AddedStats[Stat.SpellRecovery] = (byte)(RandomomRange(stat.MpRecovMaxStat - 1, stat.MpRecovStatChance) + 1);
  4044. if (stat.PoisonRecovChance > 0 && Random.Next(stat.PoisonRecovChance) == 0) item.AddedStats[Stat.PoisonRecovery] = (byte)(RandomomRange(stat.PoisonRecovMaxStat - 1, stat.PoisonRecovStatChance) + 1);
  4045. if (stat.CriticalRateChance > 0 && Random.Next(stat.CriticalRateChance) == 0) item.AddedStats[Stat.CriticalRate] = (byte)(RandomomRange(stat.CriticalRateMaxStat - 1, stat.CriticalRateStatChance) + 1);
  4046. if (stat.CriticalDamageChance > 0 && Random.Next(stat.CriticalDamageChance) == 0) item.AddedStats[Stat.CriticalDamage] = (byte)(RandomomRange(stat.CriticalDamageMaxStat - 1, stat.CriticalDamageStatChance) + 1);
  4047. if (stat.FreezeChance > 0 && Random.Next(stat.FreezeChance) == 0) item.AddedStats[Stat.Freezing] = (byte)(RandomomRange(stat.FreezeMaxStat - 1, stat.FreezeStatChance) + 1);
  4048. if (stat.PoisonAttackChance > 0 && Random.Next(stat.PoisonAttackChance) == 0) item.AddedStats[Stat.PoisonAttack] = (byte)(RandomomRange(stat.PoisonAttackMaxStat - 1, stat.PoisonAttackStatChance) + 1);
  4049. if (stat.AttackSpeedChance > 0 && Random.Next(stat.AttackSpeedChance) == 0) item.AddedStats[Stat.AttackSpeed] = (sbyte)(RandomomRange(stat.AttackSpeedMaxStat - 1, stat.AttackSpeedStatChance) + 1);
  4050. if (stat.LuckChance > 0 && Random.Next(stat.LuckChance) == 0) item.AddedStats[Stat.Luck] = (sbyte)(RandomomRange(stat.LuckMaxStat - 1, stat.LuckStatChance) + 1);
  4051. if (stat.CurseChance > 0 && Random.Next(100) <= stat.CurseChance) item.Cursed = true;
  4052. if (stat.SlotChance > 0 && Random.Next(stat.SlotChance) == 0)
  4053. {
  4054. var slot = (byte)(RandomomRange(stat.SlotMaxStat - 1, stat.SlotStatChance) + 1);
  4055. if (slot > item.Info.Slots)
  4056. {
  4057. item.SetSlotSize(slot);
  4058. }
  4059. }
  4060. }
  4061. public int RandomomRange(int count, int rate)
  4062. {
  4063. var x = 0;
  4064. for (var i = 0; i < count; i++) if (Random.Next(rate) == 0) x++;
  4065. return x;
  4066. }
  4067. public bool BindItem(UserItem item)
  4068. {
  4069. for (var i = 0; i < ItemInfoList.Count; i++)
  4070. {
  4071. var info = ItemInfoList[i];
  4072. if (info.Index != item.ItemIndex) continue;
  4073. item.Info = info;
  4074. return BindSlotItems(item);
  4075. }
  4076. return false;
  4077. }
  4078. public bool BindGameShop(GameShopItem item, bool editEnvir = true)
  4079. {
  4080. for (var i = 0; i < Edit.ItemInfoList.Count; i++)
  4081. {
  4082. var info = Edit.ItemInfoList[i];
  4083. if (info.Index != item.ItemIndex) continue;
  4084. item.Info = info;
  4085. return true;
  4086. }
  4087. return false;
  4088. }
  4089. public bool BindSlotItems(UserItem item)
  4090. {
  4091. for (var i = 0; i < item.Slots.Length; i++)
  4092. {
  4093. if (item.Slots[i] == null) continue;
  4094. if (!BindItem(item.Slots[i])) return false;
  4095. }
  4096. return true;
  4097. }
  4098. public bool BindQuest(QuestProgressInfo quest)
  4099. {
  4100. for (var i = 0; i < QuestInfoList.Count; i++)
  4101. {
  4102. var info = QuestInfoList[i];
  4103. if (info.Index != quest.Index) continue;
  4104. quest.Info = info;
  4105. return true;
  4106. }
  4107. return false;
  4108. }
  4109. public Map GetMap(int index)
  4110. {
  4111. return MapList.FirstOrDefault(t => t.Info.Index == index);
  4112. }
  4113. public Map GetMap(string name, bool strict = true)
  4114. {
  4115. return MapList.FirstOrDefault(t => strict ? string.Equals(t.Info.Title, name, StringComparison.CurrentCultureIgnoreCase) : t.Info.Title.StartsWith(name, StringComparison.CurrentCultureIgnoreCase));
  4116. }
  4117. public Map GetWorldMap(string name)
  4118. {
  4119. return MapList.FirstOrDefault(t => t.Info.Title.StartsWith(name, StringComparison.CurrentCultureIgnoreCase) && t.Info.BigMap > 0);
  4120. }
  4121. public MapInfo GetMapInfo(int index)
  4122. {
  4123. return MapInfoList.FirstOrDefault(t => t.Index == index);
  4124. }
  4125. public Map GetMapByNameAndInstance(string name, int instanceValue = 0)
  4126. {
  4127. if (instanceValue < 0) instanceValue = 0;
  4128. if (instanceValue > 0) instanceValue--;
  4129. var instanceMapList = MapList.Where(t => string.Equals(t.Info.FileName, name, StringComparison.CurrentCultureIgnoreCase)).ToList();
  4130. return instanceValue < instanceMapList.Count() ? instanceMapList[instanceValue] : null;
  4131. }
  4132. public MapObject GetObject(uint objectID)
  4133. {
  4134. return Objects.FirstOrDefault(e => e.ObjectID == objectID);
  4135. }
  4136. public List<MapObject> GetObjects(int map, ObjectType race)
  4137. {
  4138. return Objects.Where(x => x.CurrentMapIndex == map && x.Race == race).ToList();
  4139. }
  4140. public MonsterInfo GetMonsterInfo(int index)
  4141. {
  4142. for (var i = 0; i < MonsterInfoList.Count; i++)
  4143. if (MonsterInfoList[i].Index == index) return MonsterInfoList[i];
  4144. return null;
  4145. }
  4146. public NPCInfo GetNPCInfo(int index)
  4147. {
  4148. for (var i = 0; i < NPCInfoList.Count; i++)
  4149. {
  4150. if (NPCInfoList[i].Index == index)
  4151. return NPCInfoList[i];
  4152. }
  4153. return null;
  4154. }
  4155. public MonsterInfo GetMonsterInfo(int ai, int effect = -1)
  4156. {
  4157. for (var i = 0; i < MonsterInfoList.Count; i++)
  4158. if (MonsterInfoList[i].AI == ai && (MonsterInfoList[i].Effect == effect || effect < 0)) return MonsterInfoList[i];
  4159. return null;
  4160. }
  4161. public NPCObject GetNPC(string name)
  4162. {
  4163. return MapList.SelectMany(t1 => t1.NPCs.Where(t => t.Info.Name == name)).FirstOrDefault();
  4164. }
  4165. public NPCObject GetWorldMapNPC(string name)
  4166. {
  4167. return MapList.SelectMany(t1 => t1.NPCs.Where(t => t.Info.GameName.StartsWith(name, StringComparison.CurrentCultureIgnoreCase) && t.Info.ShowOnBigMap)).FirstOrDefault();
  4168. }
  4169. public MonsterInfo GetMonsterInfo(int id, bool strict = false)
  4170. {
  4171. String monsterName = MonsterInfoList.FirstOrDefault(x => x.Index == id)?.Name;
  4172. if (monsterName == null)
  4173. {
  4174. return null;
  4175. }
  4176. else
  4177. {
  4178. return (GetMonsterInfo(monsterName, strict));
  4179. }
  4180. }
  4181. public MonsterInfo GetMonsterInfo(string name, bool Strict = false)
  4182. {
  4183. for (var i = 0; i < MonsterInfoList.Count; i++)
  4184. {
  4185. var info = MonsterInfoList[i];
  4186. if (Strict)
  4187. {
  4188. if (info.Name != name) continue;
  4189. return info;
  4190. }
  4191. else
  4192. {
  4193. if (string.Compare(info.Name, name, StringComparison.OrdinalIgnoreCase) != 0 &&
  4194. string.Compare(info.Name.Replace(" ", string.Empty), name.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase) != 0) continue;
  4195. return info;
  4196. }
  4197. }
  4198. return null;
  4199. }
  4200. public PlayerObject GetPlayer(string name)
  4201. {
  4202. for (var i = 0; i < Players.Count; i++)
  4203. if (string.Compare(Players[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  4204. return Players[i];
  4205. return null;
  4206. }
  4207. public PlayerObject GetPlayer(uint PlayerId)
  4208. {
  4209. for (var i = 0; i < Players.Count; i++)
  4210. if (Players[i].Info.Index == PlayerId)
  4211. return Players[i];
  4212. return null;
  4213. }
  4214. public CharacterInfo GetCharacterInfo(string name)
  4215. {
  4216. for (var i = 0; i < CharacterList.Count; i++)
  4217. if (string.Compare(CharacterList[i].Name, name, StringComparison.OrdinalIgnoreCase) == 0)
  4218. return CharacterList[i];
  4219. return null;
  4220. }
  4221. public CharacterInfo GetCharacterInfo(int index)
  4222. {
  4223. for (var i = 0; i < CharacterList.Count; i++)
  4224. if (CharacterList[i].Index == index)
  4225. return CharacterList[i];
  4226. return null;
  4227. }
  4228. public HeroInfo GetHeroInfo(int index)
  4229. {
  4230. return HeroList.FirstOrDefault(x => x.Index == index);
  4231. }
  4232. public ItemInfo GetItemInfo(int index)
  4233. {
  4234. for (var i = 0; i < ItemInfoList.Count; i++)
  4235. {
  4236. var info = ItemInfoList[i];
  4237. if (info.Index != index) continue;
  4238. return info;
  4239. }
  4240. return null;
  4241. }
  4242. public ItemInfo GetItemInfo(string name)
  4243. {
  4244. for (var i = 0; i < ItemInfoList.Count; i++)
  4245. {
  4246. var info = ItemInfoList[i];
  4247. if (string.Compare(info.Name.Replace(" ", ""), name, StringComparison.OrdinalIgnoreCase) != 0) continue;
  4248. return info;
  4249. }
  4250. return null;
  4251. }
  4252. public QuestInfo GetQuestInfo(int index)
  4253. {
  4254. return QuestInfoList.FirstOrDefault(info => info.Index == index);
  4255. }
  4256. public ItemInfo GetBook(short Skill)
  4257. {
  4258. for (var i = 0; i < ItemInfoList.Count; i++)
  4259. {
  4260. var info = ItemInfoList[i];
  4261. if (info.Type != ItemType.Book || info.Shape != Skill) continue;
  4262. return info;
  4263. }
  4264. return null;
  4265. }
  4266. public BuffInfo GetBuffInfo(BuffType type)
  4267. {
  4268. for (int i = 0; i < BuffInfoList.Count; i++)
  4269. {
  4270. var info = BuffInfoList[i];
  4271. if (info.Type != type) continue;
  4272. return info;
  4273. }
  4274. throw new NotImplementedException($"{type} has not been implemented.");
  4275. }
  4276. public void MessageAccount(AccountInfo account, string message, ChatType type)
  4277. {
  4278. if (account?.Characters == null) return;
  4279. for (var i = 0; i < account.Characters.Count; i++)
  4280. {
  4281. if (account.Characters[i].Player == null) continue;
  4282. account.Characters[i].Player.ReceiveChat(message, type);
  4283. return;
  4284. }
  4285. }
  4286. public void MailCharacter(CharacterInfo info, UserItem item = null, uint gold = 0, int reason = 0, string customMessage = null)
  4287. {
  4288. string sender = "Bichon Administrator";
  4289. string message = "You have been mailed due to the following reason:\r\n\r\n";
  4290. switch (reason)
  4291. {
  4292. case 1:
  4293. message += "Could not return item to bag after trade.";
  4294. break;
  4295. case 99:
  4296. message += "Code didn't correctly handle checking inventory space.";
  4297. break;
  4298. default:
  4299. message += customMessage ?? "No reason provided.";
  4300. break;
  4301. }
  4302. MailInfo mail = new MailInfo(info.Index)
  4303. {
  4304. Sender = sender,
  4305. Message = message,
  4306. Gold = gold
  4307. };
  4308. if (item != null)
  4309. {
  4310. mail.Items.Add(item);
  4311. }
  4312. mail.Send();
  4313. }
  4314. public GuildObject GetGuild(string name)
  4315. {
  4316. for (var i = 0; i < Guilds.Count; i++)
  4317. {
  4318. if (string.Compare(Guilds[i].Name.Replace(" ", ""), name, StringComparison.OrdinalIgnoreCase) != 0) continue;
  4319. return Guilds[i];
  4320. }
  4321. return null;
  4322. }
  4323. public GuildObject GetGuild(int index)
  4324. {
  4325. for (var i = 0; i < Guilds.Count; i++)
  4326. {
  4327. if (Guilds[i].Guildindex == index)
  4328. {
  4329. return Guilds[i];
  4330. }
  4331. }
  4332. return null;
  4333. }
  4334. public void ProcessNewDay()
  4335. {
  4336. foreach (var c in CharacterList)
  4337. {
  4338. ClearDailyQuests(c);
  4339. c.NewDay = true;
  4340. c.Player?.CallDefaultNPC(DefaultNPCType.Daily);
  4341. }
  4342. }
  4343. private void ProcessRentedItems()
  4344. {
  4345. foreach (var characterInfo in CharacterList)
  4346. {
  4347. if (characterInfo.RentedItems.Count <= 0)
  4348. {
  4349. continue;
  4350. }
  4351. foreach (var rentedItemInfo in characterInfo.RentedItems)
  4352. {
  4353. if (rentedItemInfo.ItemReturnDate >= Now)
  4354. continue;
  4355. var rentingPlayer = GetCharacterInfo(rentedItemInfo.RentingPlayerName);
  4356. for (var i = 0; i < rentingPlayer.Inventory.Length; i++)
  4357. {
  4358. if (rentedItemInfo.ItemId != rentingPlayer?.Inventory[i]?.UniqueID)
  4359. {
  4360. continue;
  4361. }
  4362. var item = rentingPlayer.Inventory[i];
  4363. if (item?.RentalInformation == null)
  4364. {
  4365. continue;
  4366. }
  4367. if (Now <= item.RentalInformation.ExpiryDate)
  4368. {
  4369. continue;
  4370. }
  4371. ReturnRentalItem(item, item.RentalInformation.OwnerName, rentingPlayer, false);
  4372. rentingPlayer.Inventory[i] = null;
  4373. rentingPlayer.HasRentedItem = false;
  4374. if (rentingPlayer.Player == null)
  4375. {
  4376. continue;
  4377. }
  4378. rentingPlayer.Player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ItemExpiredFromInventory), item.Info.FriendlyName), ChatType.Hint);
  4379. rentingPlayer.Player.Enqueue(new S.DeleteItem { UniqueID = item.UniqueID, Count = item.Count });
  4380. rentingPlayer.Player.RefreshStats();
  4381. }
  4382. for (var i = 0; i < rentingPlayer.Equipment.Length; i++)
  4383. {
  4384. var item = rentingPlayer.Equipment[i];
  4385. if (item?.RentalInformation == null)
  4386. {
  4387. continue;
  4388. }
  4389. if (Now <= item.RentalInformation.ExpiryDate)
  4390. {
  4391. continue;
  4392. }
  4393. ReturnRentalItem(item, item.RentalInformation.OwnerName, rentingPlayer, false);
  4394. rentingPlayer.Equipment[i] = null;
  4395. rentingPlayer.HasRentedItem = false;
  4396. if (rentingPlayer.Player == null)
  4397. {
  4398. continue;
  4399. }
  4400. rentingPlayer.Player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ItemExpiredInventory), item.Info.FriendlyName), ChatType.Hint);
  4401. rentingPlayer.Player.Enqueue(new S.DeleteItem { UniqueID = item.UniqueID, Count = item.Count });
  4402. rentingPlayer.Player.RefreshStats();
  4403. }
  4404. }
  4405. }
  4406. foreach (var characterInfo in CharacterList)
  4407. {
  4408. if (characterInfo.RentedItemsToRemove.Count <= 0)
  4409. {
  4410. continue;
  4411. }
  4412. foreach (var rentalInformationToRemove in characterInfo.RentedItemsToRemove)
  4413. {
  4414. characterInfo.RentedItems.Remove(rentalInformationToRemove);
  4415. }
  4416. characterInfo.RentedItemsToRemove.Clear();
  4417. }
  4418. }
  4419. public bool ReturnRentalItem(UserItem rentedItem, string ownerName, CharacterInfo rentingCharacterInfo, bool removeNow = true)
  4420. {
  4421. if (rentedItem.RentalInformation == null)
  4422. {
  4423. return false;
  4424. }
  4425. var owner = GetCharacterInfo(ownerName);
  4426. var returnItems = new List<UserItem>();
  4427. foreach (var rentalInformation in owner.RentedItems)
  4428. {
  4429. if (rentalInformation.ItemId == rentedItem.UniqueID)
  4430. {
  4431. owner.RentedItemsToRemove.Add(rentalInformation);
  4432. }
  4433. }
  4434. rentedItem.RentalInformation.BindingFlags = BindMode.None;
  4435. rentedItem.RentalInformation.RentalLocked = true;
  4436. rentedItem.RentalInformation.ExpiryDate = rentedItem.RentalInformation.ExpiryDate.AddDays(1);
  4437. returnItems.Add(rentedItem);
  4438. var mail = new MailInfo(owner.Index, true)
  4439. {
  4440. Sender = rentingCharacterInfo.Name,
  4441. Message = rentedItem.Info.FriendlyName,
  4442. Items = returnItems
  4443. };
  4444. mail.Send();
  4445. if (removeNow)
  4446. {
  4447. foreach (var rentalInformationToRemove in owner.RentedItemsToRemove)
  4448. {
  4449. owner.RentedItems.Remove(rentalInformationToRemove);
  4450. }
  4451. owner.RentedItemsToRemove.Clear();
  4452. }
  4453. return true;
  4454. }
  4455. private void ClearDailyQuests(CharacterInfo info)
  4456. {
  4457. foreach (var quest in QuestInfoList)
  4458. {
  4459. if (quest.Type != QuestType.Daily) continue;
  4460. for (var i = 0; i < info.CompletedQuests.Count; i++)
  4461. {
  4462. if (info.CompletedQuests[i] != quest.Index) continue;
  4463. info.CompletedQuests.RemoveAt(i);
  4464. }
  4465. }
  4466. info.Player?.GetCompletedQuests();
  4467. }
  4468. public GuildBuffInfo FindGuildBuffInfo(int Id)
  4469. {
  4470. for (var i = 0; i < Settings.Guild_BuffList.Count; i++)
  4471. {
  4472. if (Settings.Guild_BuffList[i].Id == Id)
  4473. {
  4474. return Settings.Guild_BuffList[i];
  4475. }
  4476. }
  4477. return null;
  4478. }
  4479. public void ClearGameshopLog()
  4480. {
  4481. Main.GameshopLog.Clear();
  4482. for (var i = 0; i < AccountList.Count; i++)
  4483. {
  4484. for (var f = 0; f < AccountList[i].Characters.Count; f++)
  4485. {
  4486. AccountList[i].Characters[f].GSpurchases.Clear();
  4487. }
  4488. }
  4489. ResetGS = false;
  4490. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.GameshopPurchaseLogsCleared));
  4491. }
  4492. public void Inspect(MirConnection con, uint id)
  4493. {
  4494. if (ObjectID == id) return;
  4495. PlayerObject player = Players.SingleOrDefault(x => x.ObjectID == id || x.Pets.Count(y => y.ObjectID == id && y is HumanWizard) > 0);
  4496. if (player == null) return;
  4497. Inspect(con, player.Info.Index);
  4498. }
  4499. public void Inspect(MirConnection con, int id)
  4500. {
  4501. if (ObjectID == id) return;
  4502. CharacterInfo player = GetCharacterInfo(id);
  4503. if (player == null) return;
  4504. CharacterInfo Lover = null;
  4505. string loverName = "";
  4506. if (player.Married != 0) Lover = GetCharacterInfo(player.Married);
  4507. if (Lover != null)
  4508. {
  4509. loverName = Lover.Name;
  4510. }
  4511. for (int i = 0; i < player.Equipment.Length; i++)
  4512. {
  4513. UserItem u = player.Equipment[i];
  4514. if (u == null) continue;
  4515. con.CheckItem(u);
  4516. }
  4517. string guildname = "";
  4518. string guildrank = "";
  4519. GuildObject guild = null;
  4520. GuildRank guildRank = null;
  4521. if (player.GuildIndex != -1)
  4522. {
  4523. guild = GetGuild(player.GuildIndex);
  4524. if (guild != null)
  4525. {
  4526. guildRank = guild.FindRank(player.Name);
  4527. if (guildRank == null)
  4528. {
  4529. guild = null;
  4530. }
  4531. else
  4532. {
  4533. guildname = guild.Name;
  4534. guildrank = guildRank.Name;
  4535. }
  4536. }
  4537. }
  4538. con.Enqueue(new S.PlayerInspect
  4539. {
  4540. Name = player.Name,
  4541. Equipment = player.Equipment,
  4542. GuildName = guildname,
  4543. GuildRank = guildrank,
  4544. Hair = player.Hair,
  4545. Gender = player.Gender,
  4546. Class = player.Class,
  4547. Level = player.Level,
  4548. LoverName = loverName,
  4549. AllowObserve = player.AllowObserve && Settings.AllowObserve
  4550. });
  4551. }
  4552. public void InspectHero(MirConnection con, int id)
  4553. {
  4554. if (ObjectID == id)
  4555. {
  4556. return;
  4557. }
  4558. HeroObject heroObject = Heroes.SingleOrDefault(h => h.ObjectID == id);
  4559. if (heroObject == null)
  4560. {
  4561. return;
  4562. }
  4563. HeroInfo heroInfo = GetHeroInfo(heroObject.Info.Index);
  4564. if (heroInfo == null)
  4565. {
  4566. return;
  4567. }
  4568. for (int i = 0; i < heroInfo.Equipment.Length; i++)
  4569. {
  4570. UserItem u = heroInfo.Equipment[i];
  4571. if (u == null)
  4572. {
  4573. continue;
  4574. }
  4575. con.CheckItem(u);
  4576. }
  4577. var ownerName = heroObject.Owner.Name;
  4578. con.Enqueue(new S.PlayerInspect
  4579. {
  4580. Name = GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.PlayerHero), ownerName),
  4581. Equipment = heroInfo.Equipment,
  4582. GuildName = String.Empty,
  4583. GuildRank = String.Empty,
  4584. Hair = heroInfo.Hair,
  4585. Gender = heroInfo.Gender,
  4586. Class = heroInfo.Class,
  4587. Level = heroInfo.Level,
  4588. LoverName = String.Empty,
  4589. AllowObserve = false,
  4590. IsHero = true
  4591. });
  4592. }
  4593. public void Observe(MirConnection con, string Name)
  4594. {
  4595. var player = GetPlayer(Name);
  4596. if (player == null) return;
  4597. if (!player.AllowObserve || !Settings.AllowObserve) return;
  4598. player.AddObserver(con);
  4599. }
  4600. public void GetRanking(MirConnection con, byte RankType, int RankIndex, bool OnlineOnly)
  4601. {
  4602. if (RankType > 6) return;
  4603. List<RankCharacterInfo> listings = RankType == 0 ? RankTop : RankClass[RankType - 1];
  4604. if (RankIndex >= listings.Count || RankIndex < 0) return;
  4605. S.Rankings p = new S.Rankings
  4606. {
  4607. RankType = RankType,
  4608. Count = OnlineOnly ? OnlineRankingCount[RankType] : listings.Count
  4609. };
  4610. if (con.Player != null)
  4611. {
  4612. if (RankType == 0)
  4613. p.MyRank = con.Player.Info.Rank[0];
  4614. else
  4615. p.MyRank = (byte)con.Player.Class == (RankType - 1) ? con.Player.Info.Rank[1] : 0;
  4616. }
  4617. int c = 0;
  4618. for (int i = RankIndex; i < listings.Count; i++)
  4619. {
  4620. if (OnlineOnly && GetPlayer(listings[i].Name) == null) continue;
  4621. if (!CheckListing(con, listings[i]))
  4622. p.ListingDetails.Add(listings[i]);
  4623. p.Listings.Add(listings[i].PlayerId);
  4624. c++;
  4625. if (c > 19 || c >= p.Count) break;
  4626. }
  4627. con.Enqueue(p);
  4628. }
  4629. private bool CheckListing(MirConnection con, RankCharacterInfo listing)
  4630. {
  4631. if (!con.SentRankings.ContainsKey(listing.PlayerId))
  4632. {
  4633. con.SentRankings.Add(listing.PlayerId, listing.LastUpdated);
  4634. return false;
  4635. }
  4636. DateTime lastUpdated = con.SentRankings[listing.PlayerId];
  4637. if (lastUpdated != listing.LastUpdated)
  4638. {
  4639. con.SentRankings[listing.PlayerId] = lastUpdated;
  4640. return false;
  4641. }
  4642. return true;
  4643. }
  4644. public int InsertRank(List<RankCharacterInfo> Ranking, RankCharacterInfo NewRank)
  4645. {
  4646. if (Ranking.Count == 0)
  4647. {
  4648. Ranking.Add(NewRank);
  4649. return Ranking.Count;
  4650. }
  4651. for (var i = 0; i < Ranking.Count; i++)
  4652. {
  4653. //if level is lower
  4654. if (Ranking[i].level < NewRank.level)
  4655. {
  4656. Ranking.Insert(i, NewRank);
  4657. return i + 1;
  4658. }
  4659. //if exp is lower but level = same
  4660. if (Ranking[i].level == NewRank.level && Ranking[i].Experience < NewRank.Experience)
  4661. {
  4662. Ranking.Insert(i, NewRank);
  4663. return i + 1;
  4664. }
  4665. }
  4666. Ranking.Add(NewRank);
  4667. return Ranking.Count;
  4668. }
  4669. public bool TryAddRank(List<RankCharacterInfo> Ranking, CharacterInfo info, byte type)
  4670. {
  4671. var NewRank = new RankCharacterInfo() { Name = info.Name, Class = info.Class, Experience = info.Experience, level = info.Level, PlayerId = info.Index, info = info, LastUpdated = Now };
  4672. var NewRankIndex = InsertRank(Ranking, NewRank);
  4673. if (NewRankIndex == 0) return false;
  4674. for (var i = NewRankIndex; i < Ranking.Count; i++)
  4675. {
  4676. SetNewRank(Ranking[i], i + 1, type);
  4677. }
  4678. info.Rank[type] = NewRankIndex;
  4679. return true;
  4680. }
  4681. public int FindRank(List<RankCharacterInfo> Ranking, CharacterInfo info, byte type)
  4682. {
  4683. var startindex = info.Rank[type];
  4684. if (startindex > 0) //if there's a previously known rank then the user can only have gone down in the ranking (or stayed the same)
  4685. {
  4686. for (var i = startindex - 1; i < Ranking.Count; i++)
  4687. {
  4688. if (Ranking[i].Name == info.Name)
  4689. return i;
  4690. }
  4691. info.Rank[type] = 0;//set the rank to 0 to tell future searches it's not there anymore
  4692. }
  4693. return -1;//index can be 0
  4694. }
  4695. public bool UpdateRank(List<RankCharacterInfo> Ranking, CharacterInfo info, byte type)
  4696. {
  4697. var CurrentRank = FindRank(Ranking, info, type);
  4698. if (CurrentRank == -1) return false;//not in ranking list atm
  4699. var NewRank = CurrentRank;
  4700. //next find our updated rank
  4701. for (var i = CurrentRank - 1; i >= 0; i--)
  4702. {
  4703. if (Ranking[i].level > info.Level || Ranking[i].level == info.Level && Ranking[i].Experience > info.Experience) break;
  4704. NewRank = i;
  4705. }
  4706. Ranking[CurrentRank].level = info.Level;
  4707. Ranking[CurrentRank].Experience = info.Experience;
  4708. Ranking[CurrentRank].LastUpdated = Now;
  4709. if (NewRank < CurrentRank)
  4710. {//if we gained any ranks
  4711. Ranking.Insert(NewRank, Ranking[CurrentRank]);
  4712. Ranking.RemoveAt(CurrentRank + 1);
  4713. for (var i = NewRank + 1; i < Math.Min(Ranking.Count, CurrentRank + 1); i++)
  4714. {
  4715. SetNewRank(Ranking[i], i + 1, type);
  4716. }
  4717. }
  4718. info.Rank[type] = NewRank + 1;
  4719. return true;
  4720. }
  4721. public void SetNewRank(RankCharacterInfo Rank, int Index, byte type)
  4722. {
  4723. Rank.LastUpdated = Now;
  4724. if (!(Rank.info is CharacterInfo Player)) return;
  4725. Player.Rank[type] = Index;
  4726. }
  4727. public void RemoveRank(CharacterInfo info)
  4728. {
  4729. List<RankCharacterInfo> Ranking;
  4730. var Rankindex = -1;
  4731. //first check overall top
  4732. Ranking = RankTop;
  4733. Rankindex = FindRank(Ranking, info, 0);
  4734. if (Rankindex >= 0)
  4735. {
  4736. Ranking.RemoveAt(Rankindex);
  4737. for (var i = Rankindex; i < Ranking.Count(); i++)
  4738. {
  4739. SetNewRank(Ranking[i], i, 0);
  4740. }
  4741. }
  4742. //next class based top
  4743. Ranking = RankTop;
  4744. Rankindex = FindRank(Ranking, info, 1);
  4745. if (Rankindex >= 0)
  4746. {
  4747. Ranking.RemoveAt(Rankindex);
  4748. for (var i = Rankindex; i < Ranking.Count(); i++)
  4749. {
  4750. SetNewRank(Ranking[i], i, 1);
  4751. }
  4752. }
  4753. }
  4754. public void CheckRankUpdate(CharacterInfo info)
  4755. {
  4756. List<RankCharacterInfo> Ranking;
  4757. //first check overall top
  4758. Ranking = RankTop;
  4759. if (!UpdateRank(Ranking, info, 0))
  4760. {
  4761. TryAddRank(Ranking, info, 0);
  4762. }
  4763. //now check class top
  4764. Ranking = RankClass[(byte)info.Class];
  4765. if (!UpdateRank(Ranking, info, 1))
  4766. {
  4767. TryAddRank(Ranking, info, 1);
  4768. }
  4769. }
  4770. public void ReloadNPCs()
  4771. {
  4772. SaveGoods(true);
  4773. Robot.Clear();
  4774. var keys = Scripts.Keys;
  4775. foreach (var key in keys)
  4776. {
  4777. Scripts[key].Load();
  4778. }
  4779. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NpcScriptsReloaded));
  4780. }
  4781. public void ReloadDrops()
  4782. {
  4783. for (var i = 0; i < MonsterInfoList.Count; i++)
  4784. {
  4785. string path = Path.Combine(Settings.DropPath, MonsterInfoList[i].Name + ".txt");
  4786. if (!string.IsNullOrEmpty(MonsterInfoList[i].DropPath))
  4787. {
  4788. path = Path.Combine(Settings.DropPath, MonsterInfoList[i].DropPath + ".txt");
  4789. }
  4790. MonsterInfoList[i].Drops.Clear();
  4791. DropInfo.Load(MonsterInfoList[i].Drops, MonsterInfoList[i].Name, path, 0, true);
  4792. }
  4793. FishingDrops.Clear();
  4794. for (int i = 0; i < 19; i++)
  4795. {
  4796. var path = Path.Combine(Settings.DropPath, Settings.FishingDropFilename + ".txt");
  4797. path = path.Replace("00", i.ToString("D2"));
  4798. DropInfo.Load(FishingDrops, $"Fishing {i}", path, (byte)i, i < 2);
  4799. }
  4800. AwakeningDrops.Clear();
  4801. DropInfo.Load(AwakeningDrops, "Awakening", Path.Combine(Settings.DropPath, Settings.AwakeningDropFilename + ".txt"));
  4802. StrongboxDrops.Clear();
  4803. DropInfo.Load(StrongboxDrops, "StrongBox", Path.Combine(Settings.DropPath, Settings.StrongboxDropFilename + ".txt"));
  4804. BlackstoneDrops.Clear();
  4805. DropInfo.Load(BlackstoneDrops, "Blackstone", Path.Combine(Settings.DropPath, Settings.BlackstoneDropFilename + ".txt"));
  4806. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.DropsLoaded));
  4807. }
  4808. public void ReloadLineMessages()
  4809. {
  4810. LineMessages.Clear();
  4811. var path = Path.Combine(Settings.EnvirPath, "LineMessage.txt");
  4812. if (!File.Exists(path))
  4813. {
  4814. File.WriteAllText(path, "");
  4815. }
  4816. else
  4817. {
  4818. var lines = File.ReadAllLines(path);
  4819. for (var i = 0; i < lines.Length; i++)
  4820. {
  4821. if (lines[i].StartsWith(";") || string.IsNullOrWhiteSpace(lines[i])) continue;
  4822. LineMessages.Add(lines[i]);
  4823. }
  4824. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.LineMessagesReloaded));
  4825. }
  4826. }
  4827. private WorldMapIcon ValidateWorldMap()
  4828. {
  4829. foreach (WorldMapIcon wmi in Settings.WorldMapSetup.Icons)
  4830. {
  4831. MapInfo info = GetMapInfo(wmi.MapIndex);
  4832. if (info == null)
  4833. return wmi;
  4834. }
  4835. return null;
  4836. }
  4837. public void DeleteGuild(GuildObject guild)
  4838. {
  4839. Guilds.Remove(guild);
  4840. GuildList.Remove(guild.Info);
  4841. GuildRefreshNeeded = true;
  4842. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GuildWillBeDeletedFromServer), guild.Info.Name));
  4843. }
  4844. }
  4845. }