1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754 |
- /*
- EQ2Emulator: Everquest II Server Emulator
- Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
- This file is part of EQ2Emulator.
- EQ2Emulator is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- EQ2Emulator is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <math.h>
- #include <iostream>
- #include <sstream>
- #include <iomanip>
- #include <ios>
- #include <assert.h>
- #include "WorldDatabase.h"
- #include "../common/debug.h"
- #include "../common/packet_dump.h"
- #include "../common/GlobalHeaders.h"
- #include "Items/Items.h"
- #include "Factions.h"
- #include "World.h"
- #include "Variables.h"
- #include "VisualStates.h"
- #include "Appearances.h"
- #include "Skills.h"
- #include "Quests.h"
- #include "LuaInterface.h"
- #include "classes.h"
- #include "../common/Log.h"
- #include "Rules/Rules.h"
- #include "Titles.h"
- #include "Languages.h"
- #include "Traits/Traits.h"
- #include "ClientPacketFunctions.h"
- #include "Zone/ChestTrap.h"
- #include "../common/version.h"
- extern Classes classes;
- extern Commands commands;
- extern MasterTitlesList master_titles_list;
- extern MasterItemList master_item_list;
- extern MasterSpellList master_spell_list;
- extern MasterTraitList master_trait_list;
- extern MasterFactionList master_faction_list;
- extern World world;
- extern Variables variables;
- extern VisualStates visual_states;
- extern Appearances master_appearance_list;
- extern MasterSkillList master_skill_list;
- extern MasterQuestList master_quest_list;
- extern LuaInterface* lua_interface;
- extern ZoneList zone_list;
- extern GuildList guild_list;
- extern MasterCollectionList master_collection_list;
- extern RuleManager rule_manager;
- extern MasterLanguagesList master_languages_list;
- extern ChestTrapList chest_trap_list;
- //devn00b: Fix for linux builds since we dont use stricmp we use strcasecmp
- #if defined(__GNUC__)
- #define stricmp strcasecmp
- #define strnicmp strncasecmp
- #endif
- WorldDatabase::WorldDatabase(){
- }
- WorldDatabase::~WorldDatabase(){
- }
- bool WorldDatabase::ConnectNewDatabase() {
- /*
- TESTS
- database_new.Connect();
- DatabaseResult result;
- database_new.Select(&result, "select name from characters where id=1");
- if (result.Next()) {
- printf("'%s'\n", result.GetStringStr("name"));
- printf("'%s'\n", result.GetStringStr("nameBAD"));
- printf("'%s'\n", result.GetString(3));
- }
- return true;
- */
- return database_new.Connect();
- }
- void WorldDatabase::PingNewDB()
- {
- database_new.PingNewDB();
- }
- void WorldDatabase::DeleteBuyBack(int32 char_id, int32 item_id, int16 quantity, int32 price) {
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "Deleting Buyback - Player: %u, Item ID: %u, Qty: %i, Price: %u", char_id, item_id, quantity, price);
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM character_buyback WHERE char_id = %u AND item_id = %u AND quantity = %i AND price = %u", char_id, item_id, quantity, price);
- }
- void WorldDatabase::LoadBuyBacks(Client* client) {
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "Loading Buyback - Player: %u", client->GetCharacterID());
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, item_id, quantity, price FROM character_buyback where char_id = %u ORDER BY id desc limit 10", client->GetCharacterID());
- int8 count = 0;
- int32 last_id = 0;
- if(result)
- {
- while(result && (row = mysql_fetch_row(result)))
- {
- LogWrite(MERCHANT__DEBUG, 5, "Merchant", "AddBuyBack: item: %u, qty: %i, price: %u", atoul(row[1]), atoi(row[2]), atoul(row[3]));
- last_id = atoul(row[0]);
- client->AddBuyBack(last_id, atoul(row[1]), atoi(row[2]), atoul(row[3]), false);
- count++;
- }
- if(count >= 10)
- {
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "Deleting excess Buyback from Player: %u", client->GetCharacterID());
- Query query2;
- query2.RunQuery2(Q_DELETE, "DELETE FROM character_buyback WHERE char_id = %u AND id < %u", client->GetCharacterID(), last_id);
- }
- }
- }
- void WorldDatabase::SaveBuyBacks(Client* client)
- {
- LogWrite(MERCHANT__DEBUG, 3, "Merchant", "Saving Buybacks - Player: %u", client->GetCharacterID());
- deque<BuyBackItem*>* buybacks = client->GetBuyBacks();
- if(buybacks && buybacks->size() > 0)
- {
- BuyBackItem* item = 0;
- deque<BuyBackItem*>::iterator itr;
- for(itr = buybacks->begin(); itr != buybacks->end(); itr++)
- {
- item = *itr;
- if(item && item->save_needed)
- {
- LogWrite(MERCHANT__DEBUG, 5, "Merchant", "SaveBuyBack: char: %u, item: %u, qty: %i, price: %u", client->GetCharacterID(), item->item_id, item->quantity, item->price);
- SaveBuyBack(client->GetCharacterID(), item->item_id, item->quantity, item->price);
- item->save_needed = false;
- }
- }
- }
- }
- void WorldDatabase::SaveBuyBack(int32 char_id, int32 item_id, int16 quantity, int32 price)
- {
- LogWrite(MERCHANT__DEBUG, 3, "Merchant", "Saving Buyback - Player: %u, Item ID: %u, Qty: %i, Price: %u", char_id, item_id, quantity, price);
- Query query;
- string insert = string("INSERT INTO character_buyback (char_id, item_id, quantity, price) VALUES (%u, %u, %i, %u) ");
- query.AddQueryAsync(char_id, this, Q_INSERT, insert.c_str(), char_id, item_id, quantity, price);
- }
- int32 WorldDatabase::LoadCharacterSpells(int32 char_id, Player* player)
- {
- LogWrite(SPELL__DEBUG, 0, "Spells", "Loading Character Spells for player %s...", player->GetName());
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spell_id, tier, knowledge_slot, spell_book_type, linked_timer_id FROM character_spells, spells where character_spells.spell_id = spells.id and character_spells.char_id = %u ORDER BY spell_id, tier desc", char_id);
- int32 old_spell_id = 0;
- int32 new_spell_id = 0;
- int32 count = 0;
- if(result && mysql_num_rows(result) >0)
- {
- while(result && (row = mysql_fetch_row(result)))
- {
- count++;
- new_spell_id = atoul(row[0]);
- if(new_spell_id == old_spell_id)
- continue;
- LogWrite(SPELL__DEBUG, 5, "Spells", "\tLoading SpellID: %u, tier: %i, slot: %i, type: %u linked_timer_id: %u", new_spell_id, atoi(row[1]), atoi(row[2]), atoul(row[3]), atoul(row[4]));
- player->AddSpellBookEntry(new_spell_id, atoi(row[1]), atoi(row[2]), atoul(row[3]), atoul(row[4]));
- old_spell_id = new_spell_id;
- }
- }
- return count;
- }
- void WorldDatabase::SavePlayerSpells(Client* client)
- {
- if(!client || client->GetCharacterID() < 1)
- return;
- LogWrite(SPELL__DEBUG, 3, "Spells", "Saving Spell(s) for Player: '%s'", client->GetPlayer()->GetName());
- vector<SpellBookEntry*>* spells = client->GetPlayer()->GetSpellsSaveNeeded();
- if(spells)
- {
- vector<SpellBookEntry*>::iterator itr;
- SpellBookEntry* spell = 0;
- for(itr = spells->begin(); itr != spells->end(); itr++)
- {
- spell = *itr;
- Query query;
- LogWrite(SPELL__DEBUG, 5, "Spells", "\tSaving SpellID: %u, tier: %i, slot: %i", spell->spell_id, spell->tier, spell->slot);
- query.AddQueryAsync(client->GetCharacterID(), this, Q_INSERT, "INSERT INTO character_spells (char_id, spell_id, tier) SELECT %u, %u, %i ON DUPLICATE KEY UPDATE tier = %i",
- client->GetPlayer()->GetCharacterID(), spell->spell_id, spell->tier, spell->tier);
- spell->save_needed = false;
- }
- safe_delete(spells);
- }
- }
- int32 WorldDatabase::LoadCharacterSkills(int32 char_id, Player* player)
- {
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT skill_id, current_val, max_val FROM character_skills, skills where character_skills.skill_id = skills.id and character_skills.char_id = %u", char_id);
- if(result && mysql_num_rows(result) >0)
- {
- while(result && (row = mysql_fetch_row(result)))
- {
- count++;
- LogWrite(SKILL__DEBUG, 5, "Skills", "Loading SkillID: %u, cur_val: %i, max_val: %l", strtoul(row[0], NULL, 0), atoi(row[1]), atoi(row[2]));
- player->AddSkill(strtoul(row[0], NULL, 0), atoi(row[1]), atoi(row[2]));
- }
- }
- return count;
- }
- void WorldDatabase::DeleteCharacterSkill(int32 char_id, Skill* skill)
- {
- if (char_id > 0 && skill)
- {
- LogWrite(SKILL__DEBUG, 0, "Skills", "Deleting Skill '%s' (%u) from char_id: %u", skill->name.data.c_str(), skill->skill_id, char_id);
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM `character_skills` WHERE `char_id`=%u AND `skill_id`=%u", char_id, skill->skill_id);
- }
- }
- int32 WorldDatabase::LoadSkills()
- {
- int32 total = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, short_name, name, description, skill_type, display FROM skills");
- if(result)
- {
- if (mysql_num_rows(result) >0)
- {
- Skill* skill = 0;
- while(result && (row = mysql_fetch_row(result)))
- {
- skill = new Skill();
- skill->skill_id = strtoul(row[0], NULL, 0);
- skill->short_name.data = string(row[1]);
- skill->short_name.size = skill->short_name.data.length();
- skill->name.data = string(row[2]);
- skill->name.size = skill->name.data.length();
- skill->description.data = string(row[3]);
- skill->description.size = skill->description.data.length();
- skill->skill_type = strtoul(row[4], NULL, 0);
- skill->display = atoi(row[5]);
- master_skill_list.AddSkill(skill);
- total++;
- LogWrite(SKILL__DEBUG, 5, "Skill", "---Loading Skill: %s (%u)", skill->name.data.c_str(), skill->skill_id);
- LogWrite(SKILL__DEBUG, 7, "Skill", "---short_name: %s, type: %i, display: %i", skill->short_name.data.c_str(), skill->skill_type, skill->display);
- }
- }
- }
- LogWrite(SKILL__DEBUG, 3, "Skill", "--Loaded %u Skill(s)", total);
- return total;
- }
- map<int8, vector<MacroData*> >* WorldDatabase::LoadCharacterMacros(int32 char_id)
- {
- Query query;
- MYSQL_ROW row;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT macro_number, macro_name, macro_icon, macro_text FROM character_macros where char_id = %u ORDER BY macro_number, id", char_id);
- if(result && mysql_num_rows(result) >0)
- {
- map<int8, vector<MacroData*> >* macros = new map<int8, vector<MacroData*> >;
- while(result && (row = mysql_fetch_row(result)))
- {
- MacroData* data = new MacroData;
- data->name = row[1];
- data->icon = atoi(row[2]);
- data->text = row[3];
- (*macros)[atoi(row[0])].push_back(data);
- total++;
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tLoading macro: %i. %s for player: %u", atoi(row[0]), row[1], char_id);
- }
- LogWrite(PLAYER__DEBUG, 0, "Player", "\tLoaded %u macro%s", total, total == 1 ? "" : "s");
- return macros;
- }
- return 0;
- }
- void WorldDatabase::UpdateCharacterMacro(int32 char_id, int8 number, const char* name, int16 icon, vector<string>* updates)
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Update player id %u macro: %i", char_id, number);
- Query query;
- Query query2;
- query.RunQuery2(Q_DELETE, "delete FROM character_macros where char_id = %u and macro_number = %i", char_id, number);
- if(name && updates && updates->size() > 0)
- {
- for(int8 i=0;i<updates->size();i++)
- {
- query2.RunQuery2(Q_INSERT, "insert into character_macros (char_id, macro_number, macro_name, macro_icon, macro_text) values(%u, %i, '%s', %i, '%s')", char_id, number, getSafeEscapeString(name).c_str(), icon, getSafeEscapeString(updates->at(i).c_str()).c_str());
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tAdding macro: %s, %s (Player: %u)", name, updates->at(i).c_str(), char_id);
- }
- }
- }
- //we use our timestamp just in case db is on another server, otherwise times might be off
- void WorldDatabase::UpdateVitality(int32 timestamp, float amount){
- Query query;
- LogWrite(PLAYER__DEBUG, 3, "Player", "Reset Vitality > 100: %f", amount);
- query.RunQuery2(Q_UPDATE, "update character_details set xp_vitality=100 where (xp_vitality + %f) > 100", amount);
- LogWrite(PLAYER__DEBUG, 3, "Player", "Update Vitality <= 100: %f", amount);
- query.RunQuery2(Q_UPDATE, "update character_details set xp_vitality=(xp_vitality+%f) where (xp_vitality + %f) <= 100", amount, amount);
- LogWrite(PLAYER__DEBUG, 3, "Player", "Update Vitality Timer: %u", timestamp);
- query.RunQuery2(Q_UPDATE, "update variables set variable_value=%u where variable_name='vitalitytimer'", timestamp);
- }
- void WorldDatabase::SaveVariable(const char* name, const char* value, const char* comment){
- LogWrite(WORLD__DEBUG, 0, "Variables", "Saving Variable: %s = %s", name, value);
- Query query;
- if(comment){
- query.RunQuery2(Q_REPLACE, "replace into variables (variable_name, variable_value, comment) values('%s', '%s', '%s')",
- getSafeEscapeString(name).c_str(), getSafeEscapeString(value).c_str(), getSafeEscapeString(comment).c_str());
- }
- else{
- query.RunQuery2(Q_REPLACE, "replace into variables (variable_name, variable_value) values('%s', '%s')",
- getSafeEscapeString(name).c_str(), getSafeEscapeString(value).c_str());
- }
- }
- void WorldDatabase::LoadGlobalVariables(){
- variables.ClearVariables ( );
- int32 total = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT variable_name, variable_value, comment FROM variables");
- while(result && (row = mysql_fetch_row(result)))
- {
- Variable* newVar = new Variable(row[0], row[1], row[2]);
- variables.AddVariable(newVar);
- total++;
- LogWrite(WORLD__DEBUG, 5, "World", "---Loading variable: '%s' = '%s'", row[0], row[1]);
- }
- LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u variables", total);
- }
- void WorldDatabase::LoadAppearanceMasterList()
- {
- DatabaseResult result;
- int32 total = 0;
- int32 appearance_id;
- int16 appearance_version;
- master_appearance_list.ClearAppearances();
- database_new.Select(&result, "SELECT appearance_id, `name`, min_client_version FROM appearances ORDER BY appearance_id");
- while( result.Next() )
- {
- appearance_id = result.GetInt32Str("appearance_id");
- const char *appearance_name = result.GetStringStr("name");
- appearance_version = result.GetInt16Str("min_client_version");
- Appearance* a = new Appearance(appearance_id, appearance_name, appearance_version);
- master_appearance_list.InsertAppearance(a);
- total++;
- LogWrite(WORLD__DEBUG, 5, "World", "---Loading appearances: '%s' (%i)", appearance_name, appearance_id);
- }
- LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u appearances", total);
- }
- void WorldDatabase::LoadVisualStates()
- {
- visual_states.Reset();
- int32 total = 0;
- Query query;
- Query query2;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT visual_state_id, name FROM visual_states");
- while(result && (row = mysql_fetch_row(result)))
- {
- VisualState* vs = new VisualState(atoi(row[0]), row[1]);
- visual_states.InsertVisualState(vs);
- total++;
- LogWrite(WORLD__DEBUG, 5, "World", "---Loading visual state: '%s' (%i)", row[1], atoi(row[0]));
- }
- LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u visual states", total);
- total = 0;
- result = query2.RunQuery2(Q_SELECT, "SELECT name, visual_state_id, message, targeted_message FROM emotes");
- while(result && (row = mysql_fetch_row(result)))
- {
- Emote* emote = new Emote(row[0], atoi(row[1]), row[2], row[3]);
- visual_states.InsertEmote(emote);
- total++;
- LogWrite(WORLD__DEBUG, 5, "World", "---Loading emote state: '%s' (%i)", row[1], atoi(row[0]));
- }
- LogWrite(WORLD__DEBUG, 3, "World", "--Loaded %u emote state(s)", total);
- }
- void WorldDatabase::LoadSubCommandList()
- {
- int32 total = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT command, subcommand, handler, required_status FROM commands where length(subcommand) > 0 ORDER BY handler asc");
- while(result && (row = mysql_fetch_row(result)))
- {
- commands.GetRemoteCommands()->CheckAddSubCommand(string(row[0]), EQ2_RemoteCommandString(row[1], (int32)strtoul(row[2], NULL, 0), atoi(row[3])));
- total++;
- LogWrite(COMMAND__DEBUG, 5, "Command", "---Loading Command: '%s', sub '%s', handler, %u status %i", row[0], row[1], atoul(row[2]), atoi(row[3]));
- }
- LogWrite(COMMAND__DEBUG, 3, "Command", "--Loaded %i Subcommand(s)", total);
- }
- void WorldDatabase::LoadCommandList()
- {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT command, handler, required_status FROM commands where length(subcommand) = 0 ORDER BY handler asc");
- int16 index = 0;
- while(result && (row = mysql_fetch_row(result)))
- {
- int32 handler = strtoul(row[1], NULL, 0);
- while(handler>index && handler != 999)
- {
- LogWrite(COMMAND__DEBUG, 5, "Command", "---Loading Remote Commands: handler %u, index %u", handler, index);
- commands.GetRemoteCommands()->addZero();
- index++;
- }
- LogWrite(COMMAND__DEBUG, 5, "Command", "---Loading Commands: handler %u, index %u", handler, index);
- commands.GetRemoteCommands()->addCommand(EQ2_RemoteCommandString(row[0], handler, atoi(row[2])));
- index++;
- }
- LogWrite(COMMAND__DEBUG, 3, "Command", "--Loaded %i Command%s", index, index > 0 ? "s" : "");
- LoadSubCommandList();
- }
- int32 WorldDatabase::LoadNPCSpells(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spell_list_id, spell_id, spell_tier FROM spawn_npc_spells where spell_list_id > 0");
- while(result && (row = mysql_fetch_row(result))){
- zone->AddNPCSpell(atoul(row[0]), atoul(row[1]), atoi(row[2]));
- count++;
- LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC Spell List: %u, spell id: %u, tier: %i", atoul(row[0]), atoul(row[1]), atoi(row[2]));
- }
- return count;
- }
- int32 WorldDatabase::LoadNPCSkills(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT skill_list_id, skill_id, starting_value FROM spawn_npc_skills");
- while(result && (row = mysql_fetch_row(result))){
- zone->AddNPCSkill(atoul(row[0]), atoul(row[1]), atoi(row[2]));
- count++;
- LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC Skill List: %u, skill id: %u, value: %i", atoul(row[0]), atoul(row[1]), atoi(row[2]));
- }
- return count;
- }
- int32 WorldDatabase::LoadNPCEquipment(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT equipment_list_id, item_id FROM spawn_npc_equipment");
- while(result && (row = mysql_fetch_row(result))){
- zone->AddNPCEquipment(atoul(row[0]), atoul(row[1]));
- count++;
- LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC Equipment List: %u, item: %u", atoul(row[0]), atoul(row[1]));
- }
- return count;
- }
- int8 WorldDatabase::GetAppearanceType(string type){
- int8 ret = 255;
- if (type == "soga_hair_face_highlight_color")
- ret = APPEARANCE_SOGA_HFHC;
- else if (type == "soga_hair_type_highlight_color")
- ret = APPEARANCE_SOGA_HTHC;
- else if (type == "soga_hair_face_color")
- ret = APPEARANCE_SOGA_HFC;
- else if (type == "soga_hair_type_color")
- ret = APPEARANCE_SOGA_HTC;
- else if (type == "soga_hair_highlight")
- ret = APPEARANCE_SOGA_HH;
- else if (type == "soga_hair_color1")
- ret = APPEARANCE_SOGA_HC1;
- else if (type == "soga_hair_color2")
- ret = APPEARANCE_SOGA_HC2;
- else if (type == "hair_type_color")
- ret = APPEARANCE_HTC;
- else if (type == "soga_skin_color")
- ret = APPEARANCE_SOGA_SC;
- else if (type == "soga_eye_color")
- ret = APPEARANCE_SOGA_EC;
- else if (type == "hair_type_highlight_color")
- ret = APPEARANCE_HTHC;
- else if (type == "hair_face_highlight_color")
- ret = APPEARANCE_HFHC;
- else if (type == "hair_face_color")
- ret = APPEARANCE_HFC;
- else if (type == "hair_highlight")
- ret = APPEARANCE_HH;
- else if (type == "hair_color1")
- ret = APPEARANCE_HC1;
- else if (type == "wing_color1")
- ret = APPEARANCE_WC1;
- else if (type == "hair_color2")
- ret = APPEARANCE_HC2;
- else if (type == "wing_color2")
- ret = APPEARANCE_WC2;
- else if (type == "skin_color")
- ret = APPEARANCE_SC;
- else if (type == "eye_color")
- ret = APPEARANCE_EC;
- else if (type == "soga_eye_brow_type")
- ret = APPEARANCE_SOGA_EBT;
- else if (type == "soga_cheek_type")
- ret = APPEARANCE_SOGA_CHEEKT;
- else if (type == "soga_nose_type")
- ret = APPEARANCE_SOGA_NT;
- else if (type == "soga_chin_type")
- ret = APPEARANCE_SOGA_CHINT;
- else if (type == "soga_lip_type")
- ret = APPEARANCE_SOGA_LT;
- else if (type == "eye_brow_type")
- ret = APPEARANCE_EBT;
- else if (type == "soga_ear_type")
- ret = APPEARANCE_SOGA_EART;
- else if (type == "soga_eye_type")
- ret = APPEARANCE_SOGA_EYET;
- else if (type == "cheek_type")
- ret = APPEARANCE_CHEEKT;
- else if (type == "nose_type")
- ret = APPEARANCE_NT;
- else if (type == "chin_type")
- ret = APPEARANCE_CHINT;
- else if (type == "ear_type")
- ret = APPEARANCE_EART;
- else if (type == "eye_type")
- ret = APPEARANCE_EYET;
- else if (type == "lip_type")
- ret = APPEARANCE_LT;
- else if (type == "shirt_color")
- ret = APPEARANCE_SHIRT;
- else if (type == "unknown_chest_color")
- ret = APPEARANCE_UCC;
- else if (type == "pants_color")
- ret = APPEARANCE_PANTS;
- else if (type == "unknown_legs_color")
- ret = APPEARANCE_ULC;
- else if (type == "unknown9")
- ret = APPEARANCE_U9;
- else if (type == "body_size")
- ret = APPEARANCE_BODY_SIZE;
- else if (type == "soga_wing_color1")
- ret = APPEARANCE_SOGA_WC1;
- else if (type == "soga_wing_color2")
- ret = APPEARANCE_SOGA_WC2;
- else if (type == "soga_shirt_color")
- ret = APPEARANCE_SOGA_SHIRT;
- else if (type == "soga_unknown_chest_color")
- ret = APPEARANCE_SOGA_UCC;
- else if (type == "soga_pants_color")
- ret = APPEARANCE_SOGA_PANTS;
- else if (type == "soga_unknown_legs_color")
- ret = APPEARANCE_SOGA_ULC;
- else if (type == "soga_unknown13")
- ret = APPEARANCE_SOGA_U13;
- else if (type == "body_age")
- ret = APPEARANCE_BODY_AGE;
- return ret;
- }
- int32 WorldDatabase::LoadAppearances(ZoneServer* zone, Client* client){
- Query query, query2;
- MYSQL_ROW row;
- int32 count = 0, spawn_id = 0, new_spawn_id = 0;
- Entity* entity = 0;
- if(client)
- entity = client->GetPlayer();
- map<string, int8> appearance_types;
- map<int32, map<int8, EQ2_Color> > appearance_colors;
- EQ2_Color color;
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- string type;
- MYSQL_RES* result = 0;
- if(!client)
- result = query.RunQuery2(Q_SELECT, "SELECT distinct `type` FROM npc_appearance where length(type) > 0");
- else
- result = query.RunQuery2(Q_SELECT, "SELECT distinct `type` FROM char_colors where length(type) > 0 and char_id=%u", client->GetCharacterID());
- while(result && (row = mysql_fetch_row(result))){
- type = string(row[0]);
- appearance_types[type] = GetAppearanceType(type);
- if(appearance_types[type] == 255)
- LogWrite(WORLD__ERROR, 0, "Appearance", "Unknown appearance type '%s' in LoadAppearances.", type.c_str());
- }
- MYSQL_RES* result2 = 0;
- if(!client)
- result2 = query2.RunQuery2(Q_SELECT, "SELECT `type`, spawn_id, signed_value, red, green, blue FROM npc_appearance where length(type) > 0 ORDER BY spawn_id");
- else
- result2 = query2.RunQuery2(Q_SELECT, "SELECT `type`, char_id, signed_value, red, green, blue FROM char_colors where length(type) > 0 and char_id=%u", client->GetCharacterID());
- while(result2 && (row = mysql_fetch_row(result2))){
- if(!client){
- new_spawn_id = atoul(row[1]);
- if(spawn_id != new_spawn_id){
- entity = zone->GetNPC(new_spawn_id, true);
- if(!entity)
- continue;
- if(spawn_id > 0)
- count++;
- spawn_id = new_spawn_id;
- }
- }
- if(appearance_types[row[0]] < APPEARANCE_SOGA_EBT){
- color.red = atoi(row[3]);
- color.green = atoi(row[4]);
- color.blue = atoi(row[5]);
- }
- switch(appearance_types[row[0]]){
- case APPEARANCE_SOGA_HFHC:{
- entity->features.soga_hair_face_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HTHC:{
- entity->features.soga_hair_type_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HFC:{
- entity->features.soga_hair_face_color = color;
- break;
- }
- case APPEARANCE_SOGA_HTC:{
- entity->features.soga_hair_type_color = color;
- break;
- }
- case APPEARANCE_SOGA_HH:{
- entity->features.soga_hair_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HC1:{
- entity->features.soga_hair_color1 = color;
- break;
- }
- case APPEARANCE_SOGA_HC2:{
- entity->features.soga_hair_color2 = color;
- break;
- }
- case APPEARANCE_SOGA_SC:{
- entity->features.soga_skin_color = color;
- break;
- }
- case APPEARANCE_SOGA_EC:{
- entity->features.soga_eye_color = color;
- break;
- }
- case APPEARANCE_HTHC:{
- entity->features.hair_type_highlight_color = color;
- break;
- }
- case APPEARANCE_HFHC:{
- entity->features.hair_face_highlight_color = color;
- break;
- }
- case APPEARANCE_HTC:{
- entity->features.hair_type_color = color;
- break;
- }
- case APPEARANCE_HFC:{
- entity->features.hair_face_color = color;
- break;
- }
- case APPEARANCE_HH:{
- entity->features.hair_highlight_color = color;
- break;
- }
- case APPEARANCE_HC1:{
- entity->features.hair_color1 = color;
- break;
- }
- case APPEARANCE_HC2:{
- entity->features.hair_color2 = color;
- break;
- }
- case APPEARANCE_WC1:{
- entity->features.wing_color1 = color;
- break;
- }
- case APPEARANCE_WC2:{
- entity->features.wing_color2 = color;
- break;
- }
- case APPEARANCE_SC:{
- entity->features.skin_color = color;
- break;
- }
- case APPEARANCE_EC:{
- entity->features.eye_color = color;
- break;
- }
- case APPEARANCE_SOGA_EBT:{
- for(int i=0;i<3;i++)
- entity->features.soga_eye_brow_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_CHEEKT:{
- for(int i=0;i<3;i++)
- entity->features.soga_cheek_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_NT:{
- for(int i=0;i<3;i++)
- entity->features.soga_nose_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_CHINT:{
- for(int i=0;i<3;i++)
- entity->features.soga_chin_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_LT:{
- for(int i=0;i<3;i++)
- entity->features.soga_lip_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_EART:{
- for(int i=0;i<3;i++)
- entity->features.soga_ear_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SOGA_EYET:{
- for(int i=0;i<3;i++)
- entity->features.soga_eye_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_EBT:{
- for(int i=0;i<3;i++)
- entity->features.eye_brow_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_CHEEKT:{
- for(int i=0;i<3;i++)
- entity->features.cheek_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_NT:{
- for(int i=0;i<3;i++)
- entity->features.nose_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_CHINT:{
- for(int i=0;i<3;i++)
- entity->features.chin_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_EART:{
- for(int i=0;i<3;i++)
- entity->features.ear_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_EYET:{
- for(int i=0;i<3;i++)
- entity->features.eye_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_LT:{
- for(int i=0;i<3;i++)
- entity->features.lip_type[i] = atoi(row[3+i]);
- break;
- }
- case APPEARANCE_SHIRT:{
- entity->features.shirt_color = color;
- break;
- }
- case APPEARANCE_UCC:{
- break;
- }
- case APPEARANCE_PANTS:{
- entity->features.pants_color = color;
- break;
- }
- case APPEARANCE_ULC:{
- break;
- }
- case APPEARANCE_U9:{
- break;
- }
- case APPEARANCE_BODY_SIZE:{
- entity->features.body_size = color.red;
- break;
- }
- case APPEARANCE_SOGA_WC1:{
- break;
- }
- case APPEARANCE_SOGA_WC2:{
- break;
- }
- case APPEARANCE_SOGA_SHIRT:{
- break;
- }
- case APPEARANCE_SOGA_UCC:{
- break;
- }
- case APPEARANCE_SOGA_PANTS:{
- break;
- }
- case APPEARANCE_SOGA_ULC:{
- break;
- }
- case APPEARANCE_SOGA_U13:{
- break;
- }
- case APPEARANCE_BODY_AGE: {
- entity->features.body_age = color.red;
- break;
- }
- }
- }
- return count;
- }
- void WorldDatabase::LoadNPCs(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- NPC* npc = 0;
- int32 id = 0;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT,"SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name, s.expansion_flag\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_npcs npc\n"
- "ON s.id = npc.spawn_id\n"
- "INNER JOIN spawn_location_entry le\n"
- "ON npc.spawn_id = le.spawn_id\n"
- "INNER JOIN spawn_location_placement lp\n"
- "ON le.spawn_location_id = lp.spawn_location_id\n"
- "WHERE lp.zone_id = %u and (lp.instance_id = 0 or lp.instance_id = %u)\n"
- "GROUP BY s.id",
- zone->GetZoneID(), zone->GetInstanceID());
- while(result && (row = mysql_fetch_row(result))){
- /*npc->SetAppearanceID(atoi(row[12]));
- AppearanceData* appearance = world.GetNPCAppearance(npc->GetAppearanceID());
- if(appearance)
- memcpy(&npc->appearance, appearance, sizeof(AppearanceData));
- */
- int32 npcXpackFlag = atoul(row[75]);
- if (!CheckExpansionFlags(zone, npcXpackFlag))
- continue;
- id = atoul(row[0]);
- if(zone->GetNPC(id, true))
- continue;
- npc = new NPC();
- npc->SetDatabaseID(id);
- strcpy(npc->appearance.name, row[1]);
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(atoul(row[9]));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(atoul(row[10]));
- if(primary_command_list){
- npc->SetPrimaryCommands(primary_command_list);
- npc->primary_command_list_id = atoul(row[9]);
- }
- if(secondary_command_list){
- npc->SetSecondaryCommands(secondary_command_list);
- npc->secondary_command_list_id = atoul(row[10]);
- }
- npc->appearance.min_level = atoi(row[2]);
- npc->appearance.max_level = atoi(row[3]);
- npc->appearance.level = atoi(row[2]);
- npc->appearance.encounter_level = atoi(row[4]);
- npc->appearance.race = atoi(row[5]);
- //npc->appearance.lua_race_id = atoi(row[75]);
- if (atoi(row[74]) > 0) {
- int16 xxx = atoi(row[75]);
- int8 yyy = 0;
- }
- npc->appearance.model_type = atoi(row[6]);
- npc->appearance.soga_model_type = atoi(row[62]);
- npc->appearance.adventure_class = atoi(row[7]);
- npc->appearance.gender = atoi(row[8]);
- npc->appearance.display_name = atoi(row[11]);
- npc->features.hair_type = atoi(row[14]);
- npc->features.hair_face_type = atoi(row[15]);
- npc->features.wing_type = atoi(row[16]);
- npc->features.chest_type = atoi(row[17]);
- npc->features.legs_type = atoi(row[18]);
- npc->features.soga_hair_type = atoi(row[19]);
- npc->features.soga_hair_face_type = atoi(row[20]);
- npc->appearance.attackable = atoi(row[21]);
- npc->appearance.show_level = atoi(row[22]);
- npc->appearance.targetable = atoi(row[23]);
- npc->appearance.show_command_icon = atoi(row[24]);
- npc->appearance.display_hand_icon = atoi(row[25]);
- npc->appearance.hide_hood = atoi(row[70]);
- npc->appearance.randomize = atoi(row[61]);
- npc->SetTotalHP(atoul(row[26]));
- npc->SetTotalPower(atoul(row[27]));
- npc->SetHP(npc->GetTotalHP());
- npc->SetPower(npc->GetTotalPower());
- if(npc->GetTotalHP() == 0){
- npc->SetTotalHP(15*npc->GetLevel() + 1);
- npc->SetHP(15*npc->GetLevel() + 1);
- }
- if(npc->GetTotalPower() == 0){
- npc->SetTotalPower(15*npc->GetLevel() + 1);
- npc->SetPower(15*npc->GetLevel() + 1);
- }
- npc->size = atoi(row[28]);
- npc->appearance.pos.collision_radius = atoi(row[29]);
- npc->appearance.action_state = atoi(row[30]);
- npc->appearance.visual_state = atoi(row[31]);
- npc->appearance.mood_state = atoi(row[32]);
- npc->appearance.emote_state = atoi(row[71]);
- npc->appearance.pos.state = atoi(row[33]);
- npc->appearance.activity_status = atoi(row[34]);
- npc->faction_id = atoul(row[35]);
- if(row[36]){
- if(strlen(row[36]) < sizeof(npc->appearance.sub_title))
- strcpy(npc->appearance.sub_title, row[36]);
- else
- strncpy(npc->appearance.sub_title, row[36], sizeof(npc->appearance.sub_title));
- }
- npc->SetMerchantID(atoul(row[37]));
- npc->SetMerchantType(atoi(row[38]));
- npc->SetSizeOffset(atoi(row[39]));
- npc->SetAttackType(atoi(row[40]));
- npc->SetAIStrategy(atoi(row[41]));
- npc->SetPrimarySpellList(atoul(row[42]));
- npc->SetSecondarySpellList(atoul(row[43]));
- npc->SetPrimarySkillList(atoul(row[44]));
- npc->SetSecondarySkillList(atoul(row[45]));
- npc->SetEquipmentListID(atoul(row[46]));
- InfoStruct* info = npc->GetInfoStruct();
- info->str_base = atoi(row[47]);
- info->sta_base = atoi(row[48]);
- info->wis_base = atoi(row[49]);
- info->intel_base = atoi(row[50]);
- info->agi_base = atoi(row[51]);
- info->heat_base = atoi(row[52]);
- info->cold_base = atoi(row[53]);
- info->magic_base = atoi(row[54]);
- info->mental_base = atoi(row[55]);
- info->divine_base = atoi(row[56]);
- info->disease_base = atoi(row[57]);
- info->poison_base = atoi(row[58]);
- info->alignment = atoi(row[64]);
- npc->SetAggroRadius(atof(row[59]));
- npc->SetCastPercentage(atoi(row[60]));
- npc->appearance.heroic_flag = atoi(row[63]);
- info->elemental_base = atoi(row[65]);
- info->arcane_base = atoi(row[66]);
- info->noxious_base = atoi(row[67]);
- npc->SetTotalSavagery(atoul(row[68]));
- npc->SetTotalDissonance(atoul(row[69]));
- npc->SetSavagery(npc->GetTotalSavagery());
- npc->SetDissonance(npc->GetTotalDissonance());
- if(npc->GetTotalSavagery() == 0){
- npc->SetTotalSavagery(15*npc->GetLevel() + 1);
- npc->SetSavagery(15*npc->GetLevel() + 1);
- }
- if(npc->GetTotalDissonance() == 0){
- npc->SetTotalDissonance(15*npc->GetLevel() + 1);
- npc->SetDissonance(15*npc->GetLevel() + 1);
- }
- npc->SetPrefixTitle(row[72]);
- npc->SetSuffixTitle(row[73]);
- npc->SetLastName(row[74]);
- zone->AddNPC(id, npc);
- total++;
- LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC: '%s' (%u)", npc->appearance.name, id);
- }
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC(s).", total);
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC Spell(s).", LoadNPCSpells(zone));
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC Skill(s).", LoadNPCSkills(zone));
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC Equipment Piece(s).", LoadNPCEquipment(zone));
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC Appearance(s).", LoadAppearances(zone));
- LogWrite(NPC__INFO, 0, "NPC", "--Loaded %i NPC Equipment Appearance(s).", LoadNPCAppearanceEquipmentData(zone));
- }
- void WorldDatabase::LoadSigns(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- Sign* sign = 0;
- int32 id = 0;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_signs ss\n"
- "ON s.id = ss.spawn_id\n"
- "INNER JOIN spawn_location_entry le\n"
- "ON ss.spawn_id = le.spawn_id\n"
- "INNER JOIN spawn_location_placement lp\n"
- "ON le.spawn_location_id = lp.spawn_location_id\n"
- "WHERE lp.zone_id = %u\n"
- "GROUP BY s.id",
- zone->GetZoneID());
- while(result && (row = mysql_fetch_row(result))){
- id = atoul(row[0]);
- if(zone->GetSign(id, true))
- continue;
- sign = new Sign();
- sign->SetDatabaseID(id);
- strcpy(sign->appearance.name, row[1]);
- sign->appearance.model_type = atoi(row[2]);
- sign->SetSize(atoi(row[3]));
- sign->appearance.show_command_icon = atoi(row[4]);
- sign->SetWidgetID(atoul(row[5]));
- sign->SetWidgetX(atof(row[6]));
- sign->SetWidgetY(atof(row[7]));
- sign->SetWidgetZ(atof(row[8]));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(atoul(row[9]));
- if(primary_command_list){
- sign->SetPrimaryCommands(primary_command_list);
- sign->primary_command_list_id = atoul(row[9]);
- }
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(atoul(row[10]));
- if (secondary_command_list){
- sign->SetSecondaryCommands(secondary_command_list);
- sign->secondary_command_list_id = atoul(row[10]);
- }
- sign->appearance.pos.collision_radius = atoi(row[11]);
- sign->SetSignIcon(atoi(row[12]));
- if(strncasecmp(row[13],"Generic", 7) == 0)
- sign->SetSignType(SIGN_TYPE_GENERIC);
- else if(strncasecmp(row[13],"Zone", 4) == 0)
- sign->SetSignType(SIGN_TYPE_ZONE);
- sign->SetSignTitle(row[14]);
- sign->SetSignDescription(row[15]);
- sign->SetSignDistance(atof(row[16]));
- sign->SetSignZoneID(atoul(row[17]));
- sign->SetSignZoneX(atof(row[18]));
- sign->SetSignZoneY(atof(row[19]));
- sign->SetSignZoneZ(atof(row[20]));
- sign->SetSignZoneHeading(atof(row[21]));
- sign->SetIncludeHeading(atoi(row[22]) == 1);
- sign->SetIncludeLocation(atoi(row[23]) == 1);
- sign->SetTransporterID(atoul(row[24]));
- sign->SetSizeOffset(atoi(row[25]));
- sign->appearance.display_hand_icon = atoi(row[26]);
- sign->SetVisualState(atoi(row[27]));
- zone->AddSign(id, sign);
- total++;
- LogWrite(SIGN__DEBUG, 5, "Sign", "---Loading Sign: '%s' (%u).", sign->appearance.name, id);
- }
- LogWrite(SIGN__DEBUG, 0, "Sign", "--Loaded %i Sign(s)", total);
- }
- void WorldDatabase::LoadWidgets(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- Widget* widget = 0;
- int32 id = 0;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon, s.expansion_flag\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_widgets sw\n"
- "ON s.id = sw.spawn_id\n"
- "INNER JOIN spawn_location_entry le\n"
- "ON sw.spawn_id = le.spawn_id\n"
- "INNER JOIN spawn_location_placement lp\n"
- "ON le.spawn_location_id = lp.spawn_location_id\n"
- "WHERE lp.zone_id = %u\n"
- "GROUP BY s.id",
- zone->GetZoneID());
- while(result && (row = mysql_fetch_row(result))){
- int32 widgetXpackFlag = atoul(row[32]);
- if (!CheckExpansionFlags(zone, widgetXpackFlag))
- continue;
- id = atoul(row[0]);
- if(zone->GetWidget(id, true))
- continue;
- widget = new Widget();
- widget->SetDatabaseID(id);
- strcpy(widget->appearance.name, row[1]);
- widget->appearance.model_type = atoi(row[2]);
- widget->SetSize(atoi(row[3]));
- widget->appearance.show_command_icon = atoi(row[4]);
- if (row[5] == NULL)
- widget->SetWidgetID(0xFFFFFFFF);
- else
- widget->SetWidgetID(atoul(row[5]));
- widget->SetWidgetX(atof(row[6]));
- widget->SetWidgetY(atof(row[7]));
- widget->SetWidgetZ(atof(row[8]));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(atoul(row[9]));
- if(primary_command_list){
- widget->SetPrimaryCommands(primary_command_list);
- widget->primary_command_list_id = atoul(row[9]);
- }
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(atoul(row[10]));
- if (secondary_command_list) {
- widget->SetSecondaryCommands(secondary_command_list);
- widget->secondary_command_list_id = atoul(row[10]);
- }
- widget->appearance.pos.collision_radius = atoi(row[11]);
- widget->SetIncludeHeading(atoi(row[12]) == 1);
- widget->SetIncludeLocation(atoi(row[13]) == 1);
- widget->SetWidgetIcon(atoi(row[14]));
- if (strncasecmp(row[15], "Generic", 7) == 0)
- widget->SetWidgetType(WIDGET_TYPE_GENERIC);
- else if (strncasecmp(row[15], "Door", 4) == 0)
- widget->SetWidgetType(WIDGET_TYPE_DOOR);
- else if (strncasecmp(row[15], "Lift", 4) == 0)
- widget->SetWidgetType(WIDGET_TYPE_LIFT);
- widget->SetOpenHeading(atof(row[16]));
- widget->SetOpenY(atof(row[17]));
- widget->SetActionSpawnID(atoul(row[18]));
- if(row[19] && strlen(row[19]) > 5)
- widget->SetOpenSound(row[19]);
- if(row[20] && strlen(row[20]) > 5)
- widget->SetCloseSound(row[20]);
- widget->SetOpenDuration(atoi(row[21]));
- widget->SetClosedHeading(atof(row[22]));
- widget->SetLinkedSpawnID(atoul(row[23]));
- widget->SetCloseY(atof(row[24]));
- widget->SetTransporterID(atoul(row[25]));
- widget->SetSizeOffset(atoi(row[26]));
- widget->SetHouseID(atoul(row[27]));
- widget->SetOpenX(atof(row[28]));
- widget->SetOpenZ(atof(row[29]));
- widget->SetCloseX(atof(row[30]));
- widget->SetCloseZ(atof(row[31]));
- widget->appearance.display_hand_icon = atoi(row[32]);
- zone->AddWidget(id, widget);
- total++;
- LogWrite(WIDGET__DEBUG, 5, "Widget", "---Loading Widget: '%s' (%u).", widget->appearance.name, id);
- }
- LogWrite(WIDGET__DEBUG, 0, "Widget", "--Loaded %i Widget(s)", total);
- }
- void WorldDatabase::LoadObjects(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- Object* object = 0;
- int32 id = 0;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id, s.expansion_flag\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_objects so\n"
- "ON s.id = so.spawn_id\n"
- "INNER JOIN spawn_location_entry le\n"
- "ON so.spawn_id = le.spawn_id\n"
- "INNER JOIN spawn_location_placement lp\n"
- "ON le.spawn_location_id = lp.spawn_location_id\n"
- "WHERE lp.zone_id = %u and (lp.instance_id = 0 or lp.instance_id = %u)\n"
- "GROUP BY s.id",
- zone->GetZoneID(), zone->GetInstanceID());
- while(result && (row = mysql_fetch_row(result))){
- int32 objXpackFlag = atoul(row[19]);
- if (!CheckExpansionFlags(zone, objXpackFlag))
- continue;
- id = atoul(row[0]);
- if(zone->GetObject(id, true))
- continue;
- object = new Object();
- object->SetDatabaseID(id);
- strcpy(object->appearance.name, row[1]);
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(atoul(row[4]));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(atoul(row[5]));
- if(primary_command_list){
- object->SetPrimaryCommands(primary_command_list);
- object->primary_command_list_id = atoul(row[4]);
- }
- if(secondary_command_list){
- object->SetSecondaryCommands(secondary_command_list);
- object->secondary_command_list_id = atoul(row[5]);
- }
- object->appearance.race = atoi(row[2]);
- object->appearance.model_type = atoi(row[3]);
- object->appearance.targetable = atoi(row[6]);
- object->size = atoi(row[7]);
- object->appearance.display_name = atoi(row[8]);
- object->appearance.visual_state = atoi(row[9]);
- object->appearance.attackable = atoi(row[10]);
- object->appearance.show_level = atoi(row[11]);
- object->appearance.show_command_icon = atoi(row[12]);
- object->appearance.display_hand_icon = atoi(row[13]);
- object->faction_id = atoul(row[14]);
- object->appearance.pos.collision_radius = atoi(row[15]);
- object->SetTransporterID(atoul(row[16]));
- object->SetSizeOffset(atoi(row[17]));
- object->SetDeviceID(atoi(row[18]));
- zone->AddObject(id, object);
- total++;
- LogWrite(OBJECT__DEBUG, 5, "Object", "---Loading Object: '%s' (%u)", object->appearance.name, id);
- }
- LogWrite(OBJECT__DEBUG, 0, "Object", "--Loaded %i Object(s)", total);
- }
- void WorldDatabase::LoadGroundSpawns(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- GroundSpawn* spawn = 0;
- int32 id = 0;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.expansion_flag\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_ground sg\n"
- "ON s.id = sg.spawn_id\n"
- "INNER JOIN spawn_location_entry le\n"
- "ON sg.spawn_id = le.spawn_id\n"
- "INNER JOIN spawn_location_placement lp\n"
- "ON le.spawn_location_id = lp.spawn_location_id\n"
- "WHERE lp.zone_id = %u\n"
- "GROUP BY s.id",
- zone->GetZoneID());
- while(result && (row = mysql_fetch_row(result))){
- int32 gsXpackFlag = atoul(row[21]);
- if (!CheckExpansionFlags(zone, gsXpackFlag))
- continue;
- id = atoul(row[0]);
- if(zone->GetGroundSpawn(id, true))
- continue;
- spawn = new GroundSpawn();
- spawn->SetDatabaseID(id);
- spawn->forceMapCheck = true;
- strcpy(spawn->appearance.name, row[1]);
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(atoul(row[4]));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(atoul(row[5]));
- if(primary_command_list){
- spawn->SetPrimaryCommands(primary_command_list);
- spawn->primary_command_list_id = atoul(row[4]);
- }
- if(secondary_command_list){
- spawn->SetSecondaryCommands(secondary_command_list);
- spawn->secondary_command_list_id = atoul(row[5]);
- }
- spawn->appearance.race = atoi(row[2]);
- spawn->appearance.model_type = atoi(row[3]);
- spawn->appearance.targetable = atoi(row[6]);
- spawn->size = atoi(row[7]);
- spawn->appearance.display_name = atoi(row[8]);
- spawn->appearance.visual_state = atoi(row[9]);
- spawn->appearance.attackable = atoi(row[10]);
- spawn->appearance.show_level = atoi(row[11]);
- spawn->appearance.show_command_icon = atoi(row[12]);
- spawn->appearance.display_hand_icon = atoi(row[13]);
- spawn->faction_id = atoul(row[14]);
- spawn->appearance.pos.collision_radius = atoi(row[15]);
- spawn->SetNumberHarvests(atoi(row[16]));
- spawn->SetAttemptsPerHarvest(atoi(row[17]));
- spawn->SetGroundSpawnEntryID(atoul(row[18]));
- spawn->SetCollectionSkill(row[19]);
- spawn->SetSizeOffset(atoi(row[20]));
- zone->AddGroundSpawn(id, spawn);
- total++;
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn: '%s' (%u)", spawn->appearance.name, id);
- }
- LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "--Loaded %i GroundSpawn(s)", total);
- }
- void WorldDatabase::LoadGroundSpawnItems(ZoneServer* zone) {
- Query query;
- MYSQL_ROW row;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT groundspawn_id, item_id, is_rare, grid_id FROM groundspawn_items;");
- while(result && (row = mysql_fetch_row(result)))
- {
- zone->AddGroundSpawnItem(atoul(row[0]), atoul(row[1]), atoi(row[2]), atoul(row[3]));
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn Items: ID: %u\n", atoul(row[0]));
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---item: %ul, rare: %i, grid: %ul", atoul(row[1]), atoi(row[2]), atoul(row[3]));
- total++;
- }
- LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "--Loaded %i GroundSpawn Item%s.", total, total == 1 ? "" : "s");
- }
- void WorldDatabase::LoadGroundSpawnEntries(ZoneServer* zone) {
- Query query;
- MYSQL_ROW row;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT groundspawn_id, min_skill_level, min_adventure_level, bonus_table, harvest1, harvest3, harvest5, harvest_imbue, harvest_rare, harvest10, harvest_coin FROM groundspawns WHERE enabled = 1;");
- while(result && (row = mysql_fetch_row(result)))
- {
- // this is getting ridonkulous...
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn ID: %u\n" \
- "---min_skill_level: %i, min_adventure_level: %i, bonus_table: %i\n" \
- "---harvest1: %.2f, harvest3: %.2f, harvest5: %.2f\n" \
- "---harvest_imbue: %.2f, harvest_rare: %.2f, harvest10: %.2f\n" \
- "---harvest_coin: %u", atoul(row[0]), atoi(row[1]), atoi(row[2]), atoi(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atof(row[9]), atoul(row[10]));
- zone->AddGroundSpawnEntry(atoul(row[0]), atoi(row[1]), atoi(row[2]), atoi(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atof(row[9]), atoul(row[10]));
- total++;
- }
- LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "--Loaded %i GroundSpawn Entr%s.", total, total == 1 ? "y" : "ies");
- LoadGroundSpawnItems(zone);
- }
- bool WorldDatabase::LoadCharacterStats(int32 id, int32 account_id, Client* client)
- {
- DatabaseResult result;
- if( database_new.Select(&result, "SELECT * FROM character_details WHERE char_id = %i LIMIT 0, 1", id) )
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loading character_details for '%s' (char_id: %u)", client->GetPlayer()->GetName(), id);
- while( result.Next() )
- {
- InfoStruct* info = client->GetPlayer()->GetInfoStruct();
- client->GetPlayer()->SetHP(result.GetSInt32Str("hp"));
- client->GetPlayer()->SetPower(result.GetSInt32Str("power"));
- info->max_concentration = result.GetInt8Str("max_concentration");
- info->attack_base = result.GetInt16Str("attack");
- info->mitigation_base = result.GetInt16Str("mitigation");
- info->avoidance_base = result.GetInt16Str("avoidance");
- info->parry_base = result.GetInt16Str("parry");
- info->deflection_base = result.GetInt16Str("deflection");
- info->block_base = result.GetInt16Str("block");
- info->str_base = result.GetInt16Str("str");
- info->sta_base = result.GetInt16Str("sta");
- info->agi_base = result.GetInt16Str("agi");
- info->wis_base = result.GetInt16Str("wis");
- info->intel_base = result.GetInt16Str("intel");
- // old resist types
- info->heat_base = result.GetInt16Str("heat");
- info->cold_base = result.GetInt16Str("cold");
- info->magic_base = result.GetInt16Str("magic");
- info->mental_base = result.GetInt16Str("mental");
- info->divine_base = result.GetInt16Str("divine");
- info->disease_base = result.GetInt16Str("disease");
- info->poison_base = result.GetInt16Str("poison");
- //
- info->coin_copper = result.GetInt32Str("coin_copper");
- info->coin_silver = result.GetInt32Str("coin_silver");
- info->coin_gold = result.GetInt32Str("coin_gold");
- info->coin_plat = result.GetInt32Str("coin_plat");
- strcpy(info->pet_name, result.GetStringStr("pet_name"));
- strcpy(info->biography, result.GetStringStr("biography"));
- info->status_points = result.GetInt32Str("status_points");
- client->GetPlayer()->GetPlayerInfo()->SetBindZone(result.GetInt32Str("bind_zone_id"));
- client->GetPlayer()->GetPlayerInfo()->SetBindX(result.GetFloatStr("bind_x"));
- client->GetPlayer()->GetPlayerInfo()->SetBindY(result.GetFloatStr("bind_y"));
- client->GetPlayer()->GetPlayerInfo()->SetBindZ(result.GetFloatStr("bind_z"));
- client->GetPlayer()->GetPlayerInfo()->SetBindHeading(result.GetFloatStr("bind_heading"));
- client->GetPlayer()->GetPlayerInfo()->SetHouseZone(result.GetInt32Str("house_zone_id"));
- client->GetPlayer()->SetTotalHP(result.GetSInt32Str("max_hp"));
- client->GetPlayer()->SetTotalPower(result.GetSInt32Str("max_power"));
- client->GetPlayer()->SetAssignedAA(result.GetInt16Str("assigned_aa"));
- client->GetPlayer()->SetUnassignedAA(result.GetInt16Str("unassigned_aa"));
- client->GetPlayer()->SetTradeskillAA(result.GetInt16Str("tradeskill_aa"));
- client->GetPlayer()->SetUnassignedTradeskillAA(result.GetInt16Str("unassigned_tradeskill_aa"));
- client->GetPlayer()->SetPrestigeAA(result.GetInt16Str("prestige_aa"));
- client->GetPlayer()->SetUnassignedPrestigeAA(result.GetInt16Str("unassigned_prestige_aa"));
- client->GetPlayer()->SetTradeskillPrestigeAA(result.GetInt16Str("tradeskill_prestige_aa"));
- client->GetPlayer()->SetUnassignedTradeskillPrestigeAA(result.GetInt16Str("unassigned_tradeskill_prestige_aa"));
- info->xp = result.GetInt32Str("xp");
- info->xp_needed = result.GetInt32Str("xp_needed");
- if(info->xp_needed == 0)
- client->GetPlayer()->SetNeededXP();
- info->xp_debt = result.GetInt32Str("xp_debt");
- info->xp_vitality = result.GetFloatStr("xp_vitality");
- info->ts_xp = result.GetInt32Str("tradeskill_xp");
- info->ts_xp_needed = result.GetInt32Str("tradeskill_xp_needed");
- if (info->ts_xp_needed == 0)
- client->GetPlayer()->SetNeededTSXP();
- info->tradeskill_xp_vitality = result.GetFloatStr("tradeskill_xp_vitality");
- client->GetPlayer()->SetTotalHPBase(client->GetPlayer()->GetTotalHP());
- client->GetPlayer()->SetTotalPowerBase(client->GetPlayer()->GetTotalPower());
- info->bank_coin_copper = result.GetInt32Str("bank_copper");
- info->bank_coin_silver = result.GetInt32Str("bank_silver");
- info->bank_coin_gold = result.GetInt32Str("bank_gold");
- info->bank_coin_plat = result.GetInt32Str("bank_plat");
- client->GetPlayer()->SetCombatVoice(result.GetInt16Str("combat_voice"));
- client->GetPlayer()->SetEmoteVoice(result.GetInt16Str("emote_voice"));
- client->GetPlayer()->SetBiography(result.GetStringStr("biography"));
- client->GetPlayer()->GetInfoStruct()->flags = result.GetInt32Str("flags");
- client->GetPlayer()->GetInfoStruct()->flags2 = result.GetInt32Str("flags2");
- client->GetPlayer()->SetLastName(result.GetStringStr("last_name"));
- // new resist types
- info->elemental_base = result.GetInt16Str("elemental");
- info->arcane_base = result.GetInt16Str("arcane");
- info->noxious_base = result.GetInt16Str("noxious");
- // new savagery and dissonance
- client->GetPlayer()->SetSavagery(result.GetSInt16Str("savagery"));
- client->GetPlayer()->SetDissonance(result.GetSInt16Str("dissonance"));
- client->GetPlayer()->SetTotalSavageryBase(client->GetPlayer()->GetTotalSavagery());
- client->GetPlayer()->SetTotalDissonanceBase(client->GetPlayer()->GetTotalDissonance());
- }
- return true;
- }
- else
- {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character_details for '%s' (char_id: %u)", client->GetPlayer()->GetName(), id);
- return false;
- }
- }
- bool WorldDatabase::loadCharacter(const char* ch_name, int32 account_id, Client* client){
- Query query, query4;
- MYSQL_ROW row, row4;
- int32 id = 0;
- query.escaped_name = getEscapeString(ch_name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, current_zone_id, x, y, z, heading, admin_status, race, model_type, class, deity, level, gender, tradeskill_class, tradeskill_level, wing_type, hair_type, chest_type, legs_type, soga_wing_type, soga_hair_type, soga_chest_type, soga_legs_type, 0xFFFFFFFF - crc32(name), facial_hair_type, soga_facial_hair_type,instance_id,last_saved, DATEDIFF(curdate(), created_date) as accage FROM characters where name='%s' and account_id=%i AND deleted = 0", query.escaped_name, account_id);
- // no character found
- if ( result == NULL ) {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character for '%s'", ch_name);
- return false;
- }
- if (mysql_num_rows(result) == 1){
- row = mysql_fetch_row(result);
- id = strtoul(row[0], NULL, 0);
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loading character for '%s' (char_id: %u)", ch_name, id);
- client->SetCharacterID(id);
- client->GetPlayer()->SetCharacterID(id);
- client->SetAccountID(account_id);
- client->GetPlayer()->SetName(ch_name);
- client->GetPlayer()->SetX(atof(row[2]));
- client->GetPlayer()->SetY(atof(row[3]));
- client->GetPlayer()->SetZ(atof(row[4]));
- client->GetPlayer()->SetHeading(atof(row[5]));
- client->SetAdminStatus(atoi(row[6]));
- client->GetPlayer()->SetRace(atoi(row[7]));
- client->GetPlayer()->SetModelType(atoi(row[8]));
- client->GetPlayer()->SetAdventureClass(atoi(row[9]));
- client->GetPlayer()->SetDeity(atoi(row[10]));
- client->GetPlayer()->SetLevel(atoi(row[11]));
- client->GetPlayer()->SetGender(atoi(row[12]));
- client->GetPlayer()->SetTradeskillClass(atoi(row[13]));
- client->GetPlayer()->SetTSLevel(atoi(row[14]));
- LogWrite(MISC__TODO, 1, "TODO", "Fix client->GetPlayer()->SetArtLevel(atoi(row[14]));\n\t(%s, function: %s, line #: %i)", __FILE__, __FUNCTION__, __LINE__);
- client->GetPlayer()->features.wing_type = atoi(row[15]);
- client->GetPlayer()->features.hair_type = atoi(row[16]);
- client->GetPlayer()->features.chest_type = atoi(row[17]);
- client->GetPlayer()->features.legs_type = atoi(row[18]);
- LogWrite(MISC__TODO, 1, "TODO", "Fix SOGA appearances here\n\t(%s, function: %s, line #: %i)", __FILE__, __FUNCTION__, __LINE__);
- client->GetPlayer()->features.wing_type = atoi(row[19]);
- client->GetPlayer()->features.soga_hair_type = atoi(row[20]);
- client->GetPlayer()->features.soga_chest_type = atoi(row[21]);
- client->GetPlayer()->features.soga_legs_type = atoi(row[22]);
- client->SetNameCRC(atoul(row[23]));
- client->GetPlayer()->features.hair_face_type = atoi(row[24]);
- client->GetPlayer()->features.soga_hair_face_type = atoi(row[25]);
- int32 instanceid = atoi(row[26]);
- int32 zoneid = atoul(row[1]);
- /*
- JA Notes on SOGA: I think there are many more settings to add than were commented out here,
- because I can load a SOGA model player, but some features are missing (Barbarian WOAD, Skin tons, etc)
- SOGA chars looked ok in LoginServer screen tho... odd.
- */
- // load character instances here
- if ( LoadCharacterInstances(client) )
- client->UpdateCharacterInstances();
- if ( instanceid > 0 )
- client->SetCurrentZoneByInstanceID(instanceid, zoneid);
- else
- client->SetCurrentZone(zoneid);
- int32 lastsavedtime = atoi(row[27]);
- client->SetLastSavedTimeStamp(lastsavedtime);
- if (row[28])
- client->GetPlayer()->GetPlayerInfo()->SetAccountAge(atoi(row[28]));
- LoadCharacterFriendsIgnoreList(client->GetPlayer());
- MYSQL_RES* result4 = query4.RunQuery2(Q_SELECT, "SELECT `guild_id` FROM `guild_members` WHERE `char_id`=%u", id);
- if (result4 && (row4 = mysql_fetch_row(result4))) {
- Guild* guild = guild_list.GetGuild(atoul(row4[0]));
- if (guild) {
- client->GetPlayer()->SetGuild(guild);
- string subtitle;
- subtitle.append("<").append(guild->GetName()).append(">");
- client->GetPlayer()->SetSubTitle(subtitle.c_str());
- }
- }
- LoadCharacterHistory(id, client->GetPlayer());
- LoadCharacterLUAHistory(id, client->GetPlayer());
- LoadPlayerStatistics(client->GetPlayer(), id);
- LoadPlayerCollections(client->GetPlayer());
- LoadPlayerRecipes(client->GetPlayer());
- //LoadPlayerAchievements(client->GetPlayer());
- LoadPlayerAchievementsUpdates(client->GetPlayer());
- LoadAppearances(client->GetCurrentZone(), client);
- return LoadCharacterStats(id, account_id, client);
- }
- // should not be here...
- LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character for '%s'", ch_name);
- return false;
- }
- bool WorldDatabase::InsertCharacterStats(int32 character_id, int8 class_id, int8 race_id){
- Query query1;
- Query query2;
- Query query3;
- Query query4;
- Query query5;
- /* Blank record */
- query1.RunQuery2(Q_INSERT, "INSERT INTO `character_details` (`char_id`) VALUES (%u)", character_id);
- /* Using the class id and race id */
- query2.RunQuery2(Q_UPDATE, "UPDATE character_details c, starting_details s SET c.max_hp = s.max_hp, c.hp = s.max_hp, c.max_power = s.max_power, c.power = s.max_power, c.str = s.str, c.sta = s.sta, c.agi = s.agi, c.wis = s.wis, c.intel = s.intel,c.heat = s.heat, c.cold = s.cold, c.magic = s.magic, c.mental = s.mental, c.divine = s.divine, c.disease = s.disease, c.poison = s.poison, c.coin_copper = s.coin_copper, c.coin_silver = s.coin_silver, c.coin_gold = s.coin_gold, c.coin_plat = s.coin_plat, c.status_points = s.status_points WHERE s.race_id = %d AND class_id = %d AND char_id = %u", race_id, class_id, character_id);
- if (query2.GetAffectedRows() > 0)
- return true;
- /* Using the class id and race id = 255 */
- query3.RunQuery2(Q_UPDATE, "UPDATE character_details c, starting_details s SET c.max_hp = s.max_hp, c.hp = s.max_hp, c.max_power = s.max_power, c.power = s.max_power, c.str = s.str, c.sta = s.sta, c.agi = s.agi, c.wis = s.wis, c.intel = s.intel,c.heat = s.heat, c.cold = s.cold, c.magic = s.magic, c.mental = s.mental, c.divine = s.divine, c.disease = s.disease, c.poison = s.poison, c.coin_copper = s.coin_copper, c.coin_silver = s.coin_silver, c.coin_gold = s.coin_gold, c.coin_plat = s.coin_plat, c.status_points = s.status_points WHERE s.race_id = 255 AND class_id = %d AND char_id = %u", class_id, character_id);
- if (query3.GetAffectedRows() > 0)
- return true;
- /* Using class id = 255 and the race id */
- query4.RunQuery2(Q_UPDATE, "UPDATE character_details c, starting_details s SET c.max_hp = s.max_hp, c.hp = s.max_hp, c.max_power = s.max_power, c.power = s.max_power, c.str = s.str, c.sta = s.sta, c.agi = s.agi, c.wis = s.wis, c.intel = s.intel,c.heat = s.heat, c.cold = s.cold, c.magic = s.magic, c.mental = s.mental, c.divine = s.divine, c.disease = s.disease, c.poison = s.poison, c.coin_copper = s.coin_copper, c.coin_silver = s.coin_silver, c.coin_gold = s.coin_gold, c.coin_plat = s.coin_plat, c.status_points = s.status_points WHERE s.race_id = %d AND class_id = 255 AND char_id = %u", race_id, character_id);
- if (query4.GetAffectedRows() > 0)
- return true;
- /* Using class id = 255 and race id = 255 */
- query5.RunQuery2(Q_UPDATE, "UPDATE character_details c, starting_details s SET c.max_hp = s.max_hp, c.hp = s.max_hp, c.max_power = s.max_power, c.power = s.max_power, c.str = s.str, c.sta = s.sta, c.agi = s.agi, c.wis = s.wis, c.intel = s.intel,c.heat = s.heat, c.cold = s.cold, c.magic = s.magic, c.mental = s.mental, c.divine = s.divine, c.disease = s.disease, c.poison = s.poison, c.coin_copper = s.coin_copper, c.coin_silver = s.coin_silver, c.coin_gold = s.coin_gold, c.coin_plat = s.coin_plat, c.status_points = s.status_points WHERE s.race_id = 255 AND class_id = 255 AND char_id = %u", character_id);
- if (query5.GetAffectedRows() > 0)
- return true;
- return false;
- }
- int32 WorldDatabase::GetCharacterTimeStamp(int32 character_id, int32 account_id,bool* char_exists){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT unix_timestamp FROM characters where id=%i and account_id=%i",character_id,account_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- *char_exists = true;
- return atoi(row[0]); // Return timestamp
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterTimeStamp query '%s': %s", query.GetQuery(), query.GetError());
- *char_exists = false;
- return 0;
- }
- int32 WorldDatabase::GetCharacterTimeStamp(int32 character_id) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES *result = query.RunQuery2(Q_SELECT, "SELECT unix_timestamp FROM characters WHERE id=%u", character_id);
- int32 ret = 0;
- if (result && (row = mysql_fetch_row(result)))
- ret = atoul(row[0]);
- return ret;
- }
- bool WorldDatabase::UpdateCharacterTimeStamp(int32 account_id, int32 character_id, int32 timestamp_update){
- Query query;
- string update_charts = string("update characters set unix_timestamp=%i where id=%i and account_id=%i");
- query.RunQuery2(Q_UPDATE, update_charts.c_str(),timestamp_update,character_id,account_id);
- if(!query.GetAffectedRows())
- {
- LogWrite(WORLD__ERROR, 0, "World", "Error in UpdateCharacterTimeStamp query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::insertCharacterProperty(Client* client, char* propName, char* propValue) {
- Query query;
- string update_status = string("update charactersProperties set propvalue='%s' where charid=%i and propname='%s'");
- query.RunQuery2(Q_UPDATE, update_status.c_str(), propValue, client->GetCharacterID(), propName);
- if (!query.GetAffectedRows())
- {
- query.RunQuery2(Q_UPDATE, "insert into charactersProperties (charid, propname, propvalue) values(%i, '%s', '%s')", client->GetCharacterID(), propName, propValue);
- if (query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF) {
- LogWrite(WORLD__ERROR, 0, "World", "Error in insertCharacterProperty query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- }
- return true;
- }
- bool WorldDatabase::loadCharacterProperties(Client* client) {
- Query query;
- MYSQL_ROW row;
- int32 id = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT propname, propvalue FROM charactersProperties where charid = %i", client->GetCharacterID());
- // no character found
- if (result == NULL) {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character properties for '%s'", client->GetPlayer()->GetName());
- return false;
- }
- while (result && (row = mysql_fetch_row(result))) {
- char* prop_name = row[0];
- char* prop_value = row[1];
- if (!prop_name || !prop_value)
- continue;
- if (!stricmp(prop_name, CHAR_PROPERTY_SPEED))
- {
- float new_speed = atof(prop_value);
- client->GetPlayer()->SetSpeed(new_speed,true);
- client->GetPlayer()->SetCharSheetChanged(true);
- }
- else if (!stricmp(prop_name, CHAR_PROPERTY_FLYMODE))
- {
- int8 flymode = atoi(prop_value);
- if (flymode) // avoid fly mode notification unless enabled
- ClientPacketFunctions::SendFlyMode(client, flymode, false);
- }
- else if (!stricmp(prop_name, CHAR_PROPERTY_INVUL))
- {
- int8 invul = atoi(prop_value);
- client->GetPlayer()->SetInvulnerable(invul == 1);
- if (client->GetPlayer()->GetInvulnerable())
- client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You are now invulnerable!");
- }
- else if (!stricmp(prop_name, CHAR_PROPERTY_GMVISION))
- {
- int8 val = atoi(prop_value);
- client->GetPlayer()->SetGMVision(val == 1);
- client->GetCurrentZone()->SendAllSpawnsForVisChange(client, false);
- if (val)
- client->SimpleMessage(CHANNEL_COLOR_YELLOW, "GM Vision Enabled!");
- }
- else if (!stricmp(prop_name, CHAR_PROPERTY_LUADEBUG))
- {
- int8 val = atoi(prop_value);
- if (val)
- {
- client->SetLuaDebugClient(true);
- if (lua_interface)
- lua_interface->UpdateDebugClients(client);
- client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You will now receive LUA error messages.");
- }
- }
- }
- return true;
- }
- //gets the name FROM the db with the right letters in caps
- string WorldDatabase::GetPlayerName(char* name){
- Query query;
- string ret = "";
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM characters where name='%s'", getSafeEscapeString(name).c_str());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(row[0])
- ret = string(row[0]);
- }
- return ret;
- }
- int32 WorldDatabase::GetCharacterID(const char* name) {
- int32 id = 0;
- Query query;
- if (name) {
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id` FROM `characters` WHERE `name`='%s'", name);
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- id = atoul(row[0]);
- }
- }
- return id;
- }
- int32 WorldDatabase::GetCharacterCurrentZoneID(int32 character_id) {
- int32 id = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `current_zone_id` FROM `characters` WHERE `id`=%u", character_id);
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- id = atoul(row[0]);
- }
- return id;
- }
- int32 WorldDatabase::GetCharacterAccountID(int32 character_id) {
- int32 id = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `account_id` FROM `characters` WHERE `id`=%u", character_id);
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- id = atoul(row[0]);
- }
- return id;
- }
- sint16 WorldDatabase::GetHighestCharacterAdminStatus(int32 account_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT max(admin_status) FROM characters where account_id=%i ",account_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if ( row[0] != NULL )
- return atoi(row[0]); // Return characters status
- else
- return 0;
- }
- return 0;
- }
- sint16 WorldDatabase::GetLowestCharacterAdminStatus(int32 account_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT min(admin_status) FROM characters where account_id=%i ",account_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if ( row[0] != NULL )
- return atoi(row[0]); // Return characters status
- else
- return 0;
- }
- return 0;
- }
- sint16 WorldDatabase::GetCharacterAdminStatus(char* character_name){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT admin_status FROM characters where name='%s'", getSafeEscapeString(character_name).c_str());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters level
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterAdminStatus query '%s': %s", query.GetQuery(), query.GetError());
- return -10;
- }
- sint16 WorldDatabase::GetCharacterAdminStatus(int32 account_id , int32 char_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT admin_status FROM characters where account_id=%i and id=%i",account_id,char_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters status
- }
- else{
- Query query2;
- result = query2.RunQuery2(Q_SELECT, "SELECT count(id) FROM characters where account_id=%i and id=%i",account_id,char_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(atoi(row[0]) == 0) //old character, needs to be deleted FROM login server
- return -10;
- return -8;
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterAdminStatus query '%s': %s", query.GetQuery(), query.GetError());
- }
- return PLAY_ERROR_PROBLEM;
- }
- bool WorldDatabase::UpdateAdminStatus(char* character_name, sint16 flag){
- Query query;
- string update_status = string("update characters set admin_status=%i where name='%s'");
- query.RunQuery2(Q_UPDATE, update_status.c_str(),flag,character_name);
- if(!query.GetAffectedRows())
- {
- LogWrite(WORLD__ERROR, 0, "World", "Error in UpdateAdminStatus query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- void WorldDatabase::SaveCharacterFloats(int32 char_id, const char* type, float float1, float float2, float float3){
- Query query;
- string create_char = string("insert into char_colors (char_id, type, red, green, blue, signed_value) values(%i,'%s',%i,%i,%i, 1)");
- query.RunQuery2(Q_INSERT, create_char.c_str(), char_id, type, (sint8)(float1*100), (sint8)(float2*100), (sint8)(float3*100));
- if(query.GetError() && strlen(query.GetError()) > 0){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveCharacterFloats query '%s': %s", query.GetQuery(), query.GetError());
- }
- }
- void WorldDatabase::SaveCharacterColors(int32 char_id, const char* type, EQ2_Color color){
- Query query;
- string create_char = string("insert into char_colors (char_id, type, red, green, blue) values(%i,'%s',%i,%i,%i)");
- query.RunQuery2(Q_INSERT, create_char.c_str(), char_id, type, color.red, color.green, color.blue);
- if(query.GetError() && strlen(query.GetError()) > 0){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveCharacterColors query '%s': %s", query.GetQuery(), query.GetError());
- }
- }
- void WorldDatabase::SaveNPCAppearanceEquipment(int32 spawn_id, int8 slot_id, int16 type, int8 red, int8 green, int8 blue, int8 hred, int8 hgreen, int8 hblue){
- Query query;
- string appearance = string("INSERT INTO npc_appearance_equip (spawn_id, slot_id, equip_type, red, green, blue, highlight_red, highlight_green, highlight_blue) values (%i, %i, %i, %i, %i, %i, %i, %i, %i) ON DUPLICATE KEY UPDATE equip_type=%i, red=%i, green=%i, blue=%i, highlight_red=%i, highlight_green=%i, highlight_blue=%i");
- query.RunQuery2(Q_INSERT, appearance.c_str(), spawn_id, slot_id, type, red, green, blue, hred, hgreen, hblue, type, red, green, blue, hred, hgreen, hblue);
- if(query.GetError() && strlen(query.GetError()) > 0){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveNPCAppearanceEquipment query '%s': %s", query.GetQuery(), query.GetError());
- }
- }
- int32 WorldDatabase::LoadNPCAppearanceEquipmentData(ZoneServer* zone){
- Query query;
- MYSQL_ROW row;
- int32 spawn_id = 0, new_spawn_id = 0, count = 0;
- NPC* npc = 0;
- int8 slot = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spawn_id, slot_id, equip_type, red, green, blue, highlight_red, highlight_green, highlight_blue FROM npc_appearance_equip ORDER BY spawn_id");
- while(result && (row = mysql_fetch_row(result))){
- new_spawn_id = atoul(row[0]);
- if(new_spawn_id != spawn_id){
- npc = zone->GetNPC(new_spawn_id, true);
- if(!npc)
- continue;
- if(spawn_id > 0)
- count++;
- spawn_id = new_spawn_id;
- }
- slot = atoi(row[1]);
- if(slot < NUM_SLOTS){
- npc->equipment.equip_id[slot] = atoi(row[2]);
- npc->equipment.color[slot].red = atoi(row[3]);
- npc->equipment.color[slot].green = atoi(row[4]);
- npc->equipment.color[slot].blue = atoi(row[5]);
- npc->equipment.highlight[slot].red = atoi(row[6]);
- npc->equipment.highlight[slot].green = atoi(row[7]);
- npc->equipment.highlight[slot].blue = atoi(row[8]);
- }
- }
- if(query.GetError() && strlen(query.GetError()) > 0)
- LogWrite(WORLD__ERROR, 0, "World", "Error in LoadNPCAppearanceEquipmentData query '%s': %s", query.GetQuery(), query.GetError());
- return count;
- }
- int16 WorldDatabase::GetAppearanceID(string name){
- int32 id = 0;
- Query query;
- MYSQL_ROW row;
- query.escaped_name = getEscapeString(name.c_str());
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT appearance_id FROM appearances where name='%s'", query.escaped_name);
- if(result && mysql_num_rows(result) == 1){
- row = mysql_fetch_row(result);
- id = atoi(row[0]);
- }
- return id;
- }
- vector<int16>* WorldDatabase::GetAppearanceIDsLikeName(string name, bool filtered) {
- vector<int16>* ids = 0;
- Query query;
- MYSQL_ROW row;
- query.escaped_name = getEscapeString(name.c_str());
- MYSQL_RES* result;
- if (filtered)
- result = query.RunQuery2(Q_SELECT, "SELECT `appearance_id` FROM `appearances` WHERE `name` RLIKE '%s' AND `name` NOT RLIKE 'ghost' AND `name` NOT RLIKE 'headless' AND `name` NOT RLIKE 'elemental' AND `name` NOT RLIKE 'test' AND `name` NOT RLIKE 'zombie' AND `name` NOT RLIKE 'vampire'", query.escaped_name);
- else
- result = query.RunQuery2(Q_SELECT, "SELECT `appearance_id` FROM `appearances` WHERE `name` RLIKE '%s' AND `name` NOT RLIKE 'ghost' AND `name`", query.escaped_name);
- while (result && (row = mysql_fetch_row(result))) {
- if (!ids)
- ids = new vector<int16>;
- ids->push_back(atoi(row[0]));
- }
- return ids;
- }
- string WorldDatabase::GetAppearanceName(int16 appearance_id) {
- Query query;
- MYSQL_ROW row;
- string name;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `name` FROM `appearances` WHERE `appearance_id`=%u", appearance_id);
- if (result && (row = mysql_fetch_row(result)))
- name = string(row[0]);
- return name;
- }
- void WorldDatabase::UpdateRandomize(int32 spawn_id, sint32 value) {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE `spawn_npcs` SET `randomize`=`randomize` + %i WHERE `spawn_id`=%u", value, spawn_id);
- }
- int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
- Query query;
- int8 race_id = create->getType_int8_ByName("race");
- int8 class_id = create->getType_int8_ByName("class");//Normal server
- //int8 class_id = 0; //CLassic Server Only
- int8 gender_id = create->getType_int8_ByName("gender");
- sint16 auto_admin_status = 0;
- // fetch rules related to setting auto-admin status for server
- bool auto_admin_players = rule_manager.GetGlobalRule(R_World, AutoAdminPlayers)->GetBool();
- bool auto_admin_gm = rule_manager.GetGlobalRule(R_World, AutoAdminGMs)->GetBool();
-
- /*
- The way I think this is supposed to work :) is if any of your chars are already GM, and AutoAdminGMs rule is true,
- set the new character's admin_status to your highest status for any character active on your loginID.
- - If status > 0, new character > 0
- - If status = 0, new character = 0
- - If status < 0, new character < 0, too... even if auto_admin_gm is true
- If we're not a GM (status = 0) but AutoAdminPlayers rule is true,
- set the new character's admin_status to the default set in AutoAdminStatusValue rule.
- Else, if both rules are False, set everyone to 0 like normal.
- */
- auto_admin_status = GetHighestCharacterAdminStatus(loginID);
- if( auto_admin_status > 0 && auto_admin_gm )
- LogWrite(WORLD__WARNING, 0, "World", "New character '%s' granted GM status (%i) from accountID: %i", create->getType_EQ2_16BitString_ByName("name").data.c_str(), auto_admin_status, loginID);
- else if( auto_admin_players )
- {
- auto_admin_status = rule_manager.GetGlobalRule(R_World, AutoAdminStatusValue)->GetSInt16();
- LogWrite(WORLD__DEBUG, 0, "World", "New character '%s' granted AutoAdminPlayer status: %i", create->getType_EQ2_16BitString_ByName("name").data.c_str(), auto_admin_status);
- }
- else
- auto_admin_status = 0;
- string create_char = string("Insert into characters (account_id, server_id, name, race, class, gender, deity, body_size, body_age, soga_wing_type, soga_chest_type, soga_legs_type, soga_hair_type, soga_model_type, legs_type, chest_type, wing_type, hair_type, model_type, facial_hair_type, soga_facial_hair_type, created_date, last_saved, admin_status) values(%i, %i, '%s', %i, %i, %i, %i, %f, %f, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, now(), unix_timestamp(), %i)");
- query.RunQuery2(Q_INSERT, create_char.c_str(),
- loginID,
- create->getType_int32_ByName("server_id"),
- create->getType_EQ2_16BitString_ByName("name").data.c_str(),
- race_id,
- class_id,
- gender_id,
- create->getType_int8_ByName("deity"),
- create->getType_float_ByName("body_size"),
- create->getType_float_ByName("body_age"),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_wing_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_chest_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_legs_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_hair_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_race_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("legs_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("chest_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("wing_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("hair_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("race_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("face_file").data),
- GetAppearanceID(create->getType_EQ2_16BitString_ByName("soga_face_file").data),
- auto_admin_status);
- if(query.GetError() && strlen(query.GetError()) > 0)
- {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error in SaveCharacter query '%s': %s", query.GetQuery(), query.GetError());
- return 0;
- }
- int32 last_insert_id = query.GetLastInsertedID();
- int32 char_id = last_insert_id;
- UpdateStartingFactions(char_id, create->getType_int8_ByName("starting_zone"));
- UpdateStartingZone(char_id, class_id, race_id, create->getType_int8_ByName("starting_zone"));
- UpdateStartingItems(char_id, class_id, race_id);
- UpdateStartingSkills(char_id, class_id, race_id);
- UpdateStartingSpells(char_id, class_id, race_id);
- UpdateStartingSkillbar(char_id, class_id, race_id);
- UpdateStartingTitles(char_id, class_id, race_id, gender_id);
- InsertCharacterStats(char_id, class_id, race_id);
- AddNewPlayerToServerGuild(loginID, char_id);
- SaveCharacterColors(char_id,"skin_color", create->getType_EQ2_Color_ByName("skin_color"));
- SaveCharacterColors(char_id,"eye_color", create->getType_EQ2_Color_ByName("eye_color"));
- SaveCharacterColors(char_id,"hair_color1", create->getType_EQ2_Color_ByName("hair_color1"));
- SaveCharacterColors(char_id,"hair_color2", create->getType_EQ2_Color_ByName("hair_color2"));
- SaveCharacterColors(char_id,"hair_highlight", create->getType_EQ2_Color_ByName("hair_highlight"));
- SaveCharacterColors(char_id,"hair_type_color", create->getType_EQ2_Color_ByName("hair_type_color"));
- SaveCharacterColors(char_id,"hair_type_highlight_color", create->getType_EQ2_Color_ByName("hair_type_highlight_color"));
- SaveCharacterColors(char_id,"hair_face_color", create->getType_EQ2_Color_ByName("hair_face_color"));
- SaveCharacterColors(char_id,"hair_face_highlight_color", create->getType_EQ2_Color_ByName("hair_face_highlight_color"));
- SaveCharacterColors(char_id,"wing_color1", create->getType_EQ2_Color_ByName("wing_color1"));
- SaveCharacterColors(char_id,"wing_color2", create->getType_EQ2_Color_ByName("wing_color2"));
- SaveCharacterColors(char_id,"shirt_color", create->getType_EQ2_Color_ByName("shirt_color"));
- SaveCharacterColors(char_id,"unknown_chest_color", create->getType_EQ2_Color_ByName("unknown_chest_color"));
- SaveCharacterColors(char_id,"pants_color", create->getType_EQ2_Color_ByName("pants_color"));
- SaveCharacterColors(char_id,"unknown_legs_color", create->getType_EQ2_Color_ByName("unknown_legs_color"));
- SaveCharacterColors(char_id,"unknown9", create->getType_EQ2_Color_ByName("unknown9"));
- SaveCharacterFloats(char_id,"eye_type", create->getType_float_ByName("eyes2",0), create->getType_float_ByName("eyes2",1), create->getType_float_ByName("eyes2",2));
- SaveCharacterFloats(char_id,"ear_type", create->getType_float_ByName("ears",0), create->getType_float_ByName("ears",1), create->getType_float_ByName("ears",2));
- SaveCharacterFloats(char_id,"eye_brow_type", create->getType_float_ByName("eye_brows",0), create->getType_float_ByName("eye_brows",1), create->getType_float_ByName("eye_brows",2));
- SaveCharacterFloats(char_id,"cheek_type", create->getType_float_ByName("cheeks",0), create->getType_float_ByName("cheeks",1), create->getType_float_ByName("cheeks",2));
- SaveCharacterFloats(char_id,"lip_type", create->getType_float_ByName("lips",0), create->getType_float_ByName("lips",1), create->getType_float_ByName("lips",2));
- SaveCharacterFloats(char_id,"chin_type", create->getType_float_ByName("chin",0), create->getType_float_ByName("chin",1), create->getType_float_ByName("chin",2));
- SaveCharacterFloats(char_id,"nose_type", create->getType_float_ByName("nose",0), create->getType_float_ByName("nose",1), create->getType_float_ByName("nose",2));
- SaveCharacterFloats(char_id,"body_size", create->getType_float_ByName("body_size",0), 0, 0);
- SaveCharacterColors(char_id,"soga_skin_color", create->getType_EQ2_Color_ByName("soga_skin_color"));
- SaveCharacterColors(char_id,"soga_eye_color", create->getType_EQ2_Color_ByName("soga_eye_color"));
- SaveCharacterColors(char_id,"soga_hair_color1", create->getType_EQ2_Color_ByName("soga_hair_color1"));
- SaveCharacterColors(char_id,"soga_hair_color2", create->getType_EQ2_Color_ByName("soga_hair_color2"));
- SaveCharacterColors(char_id,"soga_hair_highlight", create->getType_EQ2_Color_ByName("soga_hair_highlight"));
- SaveCharacterColors(char_id,"soga_hair_type_color", create->getType_EQ2_Color_ByName("soga_hair_type_color"));
- SaveCharacterColors(char_id,"soga_hair_type_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_type_highlight_color"));
- SaveCharacterColors(char_id,"soga_hair_face_color", create->getType_EQ2_Color_ByName("soga_hair_face_color"));
- SaveCharacterColors(char_id,"soga_hair_face_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_face_highlight_color"));
- SaveCharacterColors(char_id,"soga_wing_color1", create->getType_EQ2_Color_ByName("soga_wing_color1"));
- SaveCharacterColors(char_id,"soga_wing_color2", create->getType_EQ2_Color_ByName("soga_wing_color2"));
- SaveCharacterColors(char_id,"soga_shirt_color", create->getType_EQ2_Color_ByName("soga_shirt_color"));
- SaveCharacterColors(char_id,"soga_unknown_chest_color", create->getType_EQ2_Color_ByName("soga_unknown_chest_color"));
- SaveCharacterColors(char_id,"soga_pants_color", create->getType_EQ2_Color_ByName("soga_pants_color"));
- SaveCharacterColors(char_id,"soga_unknown_legs_color", create->getType_EQ2_Color_ByName("soga_unknown_legs_color"));
- SaveCharacterColors(char_id,"soga_unknown13", create->getType_EQ2_Color_ByName("soga_unknown13"));
- SaveCharacterFloats(char_id,"soga_eye_type", create->getType_float_ByName("soga_eyes2",0), create->getType_float_ByName("soga_eyes2",1), create->getType_float_ByName("soga_eyes2",2));
- SaveCharacterFloats(char_id,"soga_ear_type", create->getType_float_ByName("soga_ears",0), create->getType_float_ByName("soga_ears",1), create->getType_float_ByName("soga_ears",2));
- SaveCharacterFloats(char_id,"soga_eye_brow_type", create->getType_float_ByName("soga_eye_brows",0), create->getType_float_ByName("soga_eye_brows",1), create->getType_float_ByName("soga_eye_brows",2));
- SaveCharacterFloats(char_id,"soga_cheek_type", create->getType_float_ByName("soga_cheeks",0), create->getType_float_ByName("soga_cheeks",1), create->getType_float_ByName("soga_cheeks",2));
- SaveCharacterFloats(char_id,"soga_lip_type", create->getType_float_ByName("soga_lips",0), create->getType_float_ByName("soga_lips",1), create->getType_float_ByName("soga_lips",2));
- SaveCharacterFloats(char_id,"soga_chin_type", create->getType_float_ByName("soga_chin",0), create->getType_float_ByName("soga_chin",1), create->getType_float_ByName("soga_chin",2));
- SaveCharacterFloats(char_id,"soga_nose_type", create->getType_float_ByName("soga_nose",0), create->getType_float_ByName("soga_nose",1), create->getType_float_ByName("soga_nose",2));
- return char_id;
- }
- int8 WorldDatabase::CheckNameFilter(const char* name) {
- // the minimum 4 is enforced by the client too
- if(!name || strlen(name) < 4 || strlen(name) > 15) // Even 20 char length is long...
- return BADNAMELENGTH_REPLY;
- uchar* checkname = (uchar*)name;
- for (int32 i = 0; i < strlen(name); i++)
- {
- if(!alpha_check(checkname[i]))
- return NAMEINVALID_REPLY;
- }
- Query query;
- LogWrite(WORLD__DEBUG, 0, "World", "Name check on: %s", name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT count(*) FROM characters WHERE name='%s'",name);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(row[0] != 0 && atoi(row[0]) > 0)
- return NAMETAKEN_REPLY;
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in CheckNameFilter (name exist check) (Name query '%s': %s", query.GetQuery(), query.GetError());
- Query query3;
- LogWrite(WORLD__DEBUG, 0, "World", "Name check on: %s (Bots table)", name);
- MYSQL_RES* result3 = query3.RunQuery2(Q_SELECT, "SELECT count(*) FROM bots WHERE name='%s'", name);
- if (result3 && mysql_num_rows(result3) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result3);
- if (row[0] != 0 && atoi(row[0]) > 0)
- return NAMETAKEN_REPLY;
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in CheckNameFilter (name exist check, bot table) (Name query '%s': %s", query3.GetQuery(), query3.GetError());
- Query query2;
- MYSQL_RES* result2 = query2.RunQuery2(Q_SELECT, "SELECT count(*) FROM name_filter WHERE '%s' like name",name);
- if(result2 && mysql_num_rows(result2) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result2);
- if(row[0] != 0 && atoi(row[0]) > 0)
- return NAMEFILTER_REPLY;
- else if(row[0] != 0 && atoi(row[0]) == 0)
- return CREATESUCCESS_REPLY;
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in CheckNameFilter (name_filter check) query '%s': %s", query.GetQuery(), query.GetError());
- return UNKNOWNERROR_REPLY;
- }
- char* WorldDatabase::GetCharacterName(int32 character_id){
- LogWrite(WORLD__TRACE, 9, "World", "Enter: %s", __FUNCTION__);
- Query query;
- char* name = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM characters where id=%u",character_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(row[0] && strlen(row[0]) > 0)
- {
- name = new char[strlen(row[0])+1];
- memset(name,0, strlen(row[0])+1);
- strcpy(name, row[0]);
- }
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterName query '%s': %s", query.GetQuery(), query.GetError());
- LogWrite(WORLD__TRACE, 9, "World", "Exit: %s", __FUNCTION__);
- return name;
- }
- int8 WorldDatabase::GetCharacterLevel(int32 character_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT level FROM characters where id=%u",character_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters level
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterLevel query '%s': %s", query.GetQuery(), query.GetError());
- return 0;
- }
- int16 WorldDatabase::GetCharacterModelType(int32 character_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT model_type FROM characters where id=%u",character_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters race
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterModelType query '%s': %s", query.GetQuery(), query.GetError());
- return 0;
- }
- int8 WorldDatabase::GetCharacterClass(int32 character_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT class FROM characters where id=%u",character_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters class
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterClass query '%s': %s", query.GetQuery(), query.GetError());
- return 0;
- }
- int8 WorldDatabase::GetCharacterGender(int32 character_id){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT gender FROM characters where id=%u",character_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- return atoi(row[0]); // Return characters gender
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Error in GetCharacterGender query '%s': %s", query.GetQuery(), query.GetError());
- return 0;
- }
- void WorldDatabase::DeleteCharacterQuest(int32 quest_id, int32 char_id, bool repeated_quest) {
- if (repeated_quest) {
- if (!database_new.Query("UPDATE `character_quests` SET `given_date` = `completed_date` WHERE `char_id` = %u AND `quest_id` = %u", char_id, quest_id))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "Error (%u) in DeleteCharacterQuest query:\n%s", database_new.GetError(), database_new.GetErrorMsg());
- }
- else {
- if (!database_new.Query("DELETE FROM `character_quests` WHERE `char_id` = %u AND `quest_id` = %u", char_id, quest_id))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "Error (%u) in DeleteCharacterQuest query:\n%s", database_new.GetError(), database_new.GetErrorMsg());
- }
- if (!database_new.Query("DELETE FROM `character_quest_progress` WHERE `char_id` = %u AND `quest_id` = %u", char_id, quest_id))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "Error (%u) in DeleteCharacterQuest query:\n%s", database_new.GetError(), database_new.GetErrorMsg());
- }
- void WorldDatabase::SaveCharacterSkills(Client* client){
- vector<Skill*>* skills = client->GetPlayer()->GetSkills()->GetSaveNeededSkills();
- if(skills){
- Query query;
- if(skills->size() > 0){
- Skill* skill = 0;
- for(int32 i=0;i<skills->size();i++){
- skill = skills->at(i);
- query.AddQueryAsync(client->GetCharacterID(),this,Q_REPLACE, "replace into character_skills (char_id, skill_id, current_val, max_val) values(%u, %u, %i, %i)", client->GetCharacterID(), skill->skill_id, skill->current_val, skill->max_val);
- }
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveCharacterSkills query '%s': %s", query.GetQuery(), query.GetError());
- }
- safe_delete(skills);
- }
- }
- void WorldDatabase::SaveCharacterQuests(Client* client){
- Query query;
- map<int32, Quest*>::iterator itr;
- master_quest_list.LockQuests(); //prevent reloading until we are done
- client->GetPlayer()->LockQuests(); //prevent all quest modifications until we are done
- map<int32, Quest*>* quests = client->GetPlayer()->GetPlayerQuests();
- for(itr = quests->begin(); itr != quests->end(); itr++){
- if(client->GetCurrentQuestID() == itr->first){
- query.AddQueryAsync(client->GetCharacterID(),this,Q_UPDATE, "update character_quests set current_quest = 0 where char_id = %u", client->GetCharacterID());
- query.AddQueryAsync(client->GetCharacterID(), this,Q_UPDATE, "update character_quests set current_quest = 1 where char_id = %u and quest_id = %u", client->GetCharacterID(), itr->first);
- }
- if(itr->second->GetSaveNeeded()){
- query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "insert ignore into character_quests (char_id, quest_id, given_date, quest_giver) values(%u, %u, now(), %u)", client->GetCharacterID(), itr->first, itr->second->GetQuestGiver());
- query.AddQueryAsync(client->GetCharacterID(), this,Q_UPDATE, "update character_quests set tracked = %i, quest_flags = %u, hidden = %i, complete_count = %u where char_id = %u and quest_id = %u", itr->second->IsTracked() ? 1 : 0, itr->second->GetQuestFlags(), itr->second->IsHidden() ? 1 : 0, itr->second->GetCompleteCount(), client->GetCharacterID(), itr->first);
- SaveCharacterQuestProgress(client, itr->second);
- itr->second->SetSaveNeeded(false);
- }
- }
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveCharacterQuests query '%s': %s", query.GetQuery(), query.GetError());
- quests = client->GetPlayer()->GetCompletedPlayerQuests();
- for(itr = quests->begin(); itr != quests->end(); itr++){
- if(itr->second->GetSaveNeeded()){
- query.AddQueryAsync(client->GetCharacterID(), this,Q_DELETE, "delete FROM character_quest_progress where char_id = %u and quest_id = %u", client->GetCharacterID(), itr->first);
- /* incase the quest is completed before the quest could be inserted in the PlayerQuests loop, we first try to insert it. If it already exists then we can just update
- * the completed_date */
- query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "INSERT INTO character_quests (char_id, quest_id, quest_giver, current_quest, given_date, completed_date, complete_count) values (%u,%u,%u,0, now(),now(), %u) ON DUPLICATE KEY UPDATE completed_date = now(), complete_count = %u, current_quest = 0", client->GetCharacterID(), itr->first, itr->second->GetQuestGiver(), itr->second->GetCompleteCount(), itr->second->GetCompleteCount());
- itr->second->SetSaveNeeded(false);
- }
- }
- client->GetPlayer()->UnlockQuests();
- master_quest_list.UnlockQuests();
- }
- void WorldDatabase::SaveCharRepeatableQuest(Client* client, int32 quest_id, int16 quest_complete_count) {
- if (!database_new.Query("UPDATE `character_quests` SET `given_date` = now(), complete_count = %u WHERE `char_id` = %u AND `quest_id` = %u", quest_complete_count, client->GetCharacterID(), quest_id))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "DB Error %u\n%s", database_new.GetError(), database_new.GetErrorMsg());
- }
- void WorldDatabase::SaveCharacterQuestProgress(Client* client, Quest* quest){
- Query query;
- vector<QuestStep*>* steps = quest->GetQuestSteps();
- vector<QuestStep*>::iterator itr;
- QuestStep* step = 0;
- if(steps){
- for(itr = steps->begin(); itr != steps->end(); itr++){
- step = *itr;
- if(step && step->GetQuestCurrentQuantity() > 0)
- query.RunQuery2(Q_REPLACE, "replace into character_quest_progress (char_id, quest_id, step_id, progress) values(%u, %u, %u, %i)", client->GetCharacterID(), quest->GetQuestID(), step->GetStepID(), step->GetQuestCurrentQuantity());
- }
- }
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(WORLD__ERROR, 0, "World", "Error in SaveCharacterQuestProgress query '%s': %s", query.GetQuery(), query.GetError());
- }
- void WorldDatabase::LoadCharacterQuestProgress(Client* client){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT character_quest_progress.quest_id, step_id, progress FROM character_quest_progress, character_quests where character_quest_progress.char_id=%u and character_quest_progress.quest_id = character_quests.quest_id and character_quest_progress.char_id = character_quests.char_id ORDER BY character_quest_progress.quest_id",client->GetCharacterID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- Quest* quest = 0;
- int32 quest_id = 0;
- map<int32, int32>* progress_map = new map<int32, int32>();
- while(result && (row = mysql_fetch_row(result))){
- if(quest_id != atoul(row[0])){
- if(quest_id > 0){
- quest = client->GetPlayer()->GetQuest(quest_id);
- if(quest)
- client->SetPlayerQuest(quest, progress_map);
- }
- quest_id = atoul(row[0]);
- progress_map->clear();
- }
- (*progress_map)[atoul(row[1])] = atoul(row[2]);
- }
- if(progress_map->size() > 0){
- quest = client->GetPlayer()->GetQuest(quest_id);
- if(quest)
- client->SetPlayerQuest(quest, progress_map);
- }
- safe_delete(progress_map);
- }
- else if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(WORLD__ERROR, 0, "World", "Error in LoadCharacterQuestProgress query '%s': %s", query.GetQuery(), query.GetError());
- }
- void WorldDatabase::LoadCharacterQuests(Client* client){
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loading Character Quests...");
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT quest_id, DAY(given_date), MONTH(given_date), YEAR(given_date), DAY(completed_date), MONTH(completed_date), YEAR(completed_date), quest_giver, tracked, quest_flags, hidden, UNIX_TIMESTAMP(given_date), UNIX_TIMESTAMP(completed_date), complete_count FROM character_quests WHERE char_id=%u ORDER BY current_quest", client->GetCharacterID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- Quest* quest = 0;
- while(result && (row = mysql_fetch_row(result))){
- quest = master_quest_list.GetQuest(atoul(row[0]));
- if(quest) {
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tLoading quest_id: %u", atoul(row[0]));
- bool addQuest = true;
- if(row[4] && atoi(row[4]) > 0){
- quest->SetTurnedIn(true);
- if(row[4])
- quest->SetDay(atoi(row[4]));
- if(row[5])
- quest->SetMonth(atoi(row[5]));
- if(row[6] && atoi(row[6]) > 2000)
- quest->SetYear(atoi(row[6]) - 2000);
- client->GetPlayer()->AddCompletedQuest(quest);
- // Added timestamps to quickly compare given and completed dates
- int32 given_timestamp = atoul(row[11]);
- int32 completed_timestamp = atoul(row[12]);
- // If given timestamp is greater then completed then this is a repeatable quest we are working on
- // so get a fresh quest object to add as an active quest
- if (given_timestamp > completed_timestamp)
- quest = master_quest_list.GetQuest(atoul(row[0]));
- else
- addQuest = false;
- quest->SetCompleteCount(atoi(row[13]));
- }
- if (addQuest) {
- if(row[1])
- quest->SetDay(atoi(row[1]));
- if(row[2])
- quest->SetMonth(atoi(row[2]));
- if(row[3] && atoi(row[3]) > 2000)
- quest->SetYear(atoi(row[3]) - 2000);
- quest->SetQuestGiver(atoul(row[7]));
- quest->SetTracked(atoi(row[8]) == 1 ? true : false);
- quest->SetQuestFlags(atoul(row[9]));
- quest->SetHidden(atoi(row[10]) == 1 ? true : false);
- client->AddPlayerQuest(quest, false, false);
- }
- quest->SetSaveNeeded(false);
- // Changed this to call reload with step = 0 for all quests and not
- // just quests with quest flags to allow customized set up if needed
- if (lua_interface)
- lua_interface->CallQuestFunction(quest, "Reload", client->GetPlayer(), 0);
- }
- }
- LoadCharacterQuestProgress(client);
- }
- }
- void WorldDatabase::LoadCharacterFriendsIgnoreList(Player* player) {
- if (player) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `name`, `type` FROM `character_social` WHERE `char_id`=%u", player->GetCharacterID());
- while (result && (row = mysql_fetch_row(result))) {
- if (strncmp(row[1], "FRIEND", 6) == 0)
- player->AddFriend(row[0], false);
- else
- player->AddIgnore(row[0], false);
- }
- }
- }
- void WorldDatabase::LoadZoneInfo(ZoneServer* zone){
- Query query;
- int32 ruleset_id;
- char* escaped = getEscapeString(zone->GetZoneName());
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, file, description, underworld, safe_x, safe_y, safe_z, min_status, min_level, max_level, instance_type+0, shutdown_timer, zone_motd, default_reenter_time, default_reset_time, default_lockout_time, force_group_to_zone, safe_heading, xp_modifier, ruleset_id, expansion_id, weather_allowed, sky_file FROM zones where name='%s'",escaped);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- zone->SetZoneName(escaped);
- zone->SetZoneID(strtoul(row[0], NULL, 0));
- zone->SetZoneFile(row[1]);
- zone->SetZoneDescription(row[2]);
- zone->SetUnderWorld(atof(row[3]));
- zone->SetSafeX(atof(row[4]));
- zone->SetSafeY(atof(row[5]));
- zone->SetSafeZ(atof(row[6]));
- zone->SetMinimumStatus(atoi(row[7]));
- zone->SetMinimumLevel(atoi(row[8]));
- zone->SetMaximumLevel(atoi(row[9]));
- int8 type = (atoi(row[10]) == 0) ? 0 : atoi(row[10]) - 1;
- zone->SetInstanceType(type);
- zone->SetShutdownTimer(atoul(row[11]));
- char* zone_motd = row[12];
- if (zone_motd && strlen(zone_motd) > 0)
- zone->SetZoneMOTD(string(zone_motd));
- zone->SetDefaultReenterTime(atoi(row[13]));
- zone->SetDefaultResetTime(atoi(row[14]));
- zone->SetDefaultLockoutTime(atoi(row[15]));
- zone->SetForceGroupZoneOption(atoi(row[16]));
- zone->SetSafeHeading(atof(row[17]));
- zone->SetXPModifier(atof(row[18]));
- if ((ruleset_id = atoul(row[19])) > 0 && !rule_manager.SetZoneRuleSet(zone->GetZoneID(), ruleset_id))
- LogWrite(ZONE__ERROR, 0, "Zones", "Error setting rule set for zone '%s' (%u). A rule set with ID %u does not exist.", zone->GetZoneName(), zone->GetZoneID(), ruleset_id);
- // check data_version to see if client has proper expansion to enter a zone
- zone->SetMinimumVersion(GetMinimumClientVersion(atoi(row[20])));
- zone->SetWeatherAllowed(atoi(row[21]) == 0 ? false : true);
- zone->SetZoneSkyFile(row[22]);
- if (zone->IsInstanceZone())
- {
- if ( zone->GetInstanceID() < 1 )
- zone->SetupInstance(CreateNewInstance(zone->GetZoneID()));
- else
- zone->SetupInstance(zone->GetInstanceID());
- }
- }
- safe_delete_array(escaped);
- }
- void WorldDatabase::LoadZoneInfo(ZoneInfo* zone_info) {
- Query query;
- int32 ruleset_id;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name, file, description, underworld, safe_x, safe_y, safe_z, min_status, min_level, max_level, instance_type, shutdown_timer, zone_motd, default_reenter_time, default_reset_time, default_lockout_time, force_group_to_zone, lua_script, xp_modifier, ruleset_id, expansion_id, always_loaded, city_zone, start_zone, zone_type, weather_allowed FROM zones WHERE id = %u", zone_info->id);
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- strncpy(zone_info->name, row[0], sizeof(zone_info->name));
- strncpy(zone_info->file, row[1], sizeof(zone_info->file));
- strncpy(zone_info->description, row[2], sizeof(zone_info->description));
- zone_info->underworld = atof(row[3]);
- zone_info->safe_x = atof(row[4]);
- zone_info->safe_y = atof(row[5]);
- zone_info->safe_z = atof(row[6]);
- zone_info->min_status = atoi(row[7]);
- zone_info->min_level = atoi(row[8]);
- zone_info->max_level = atoi(row[9]);
- zone_info->instance_type = (atoi(row[10]) == 0) ? 0 : atoi(row[10]) - 1;
- zone_info->shutdown_timer = atoul(row[11]);
- row[12] == NULL ? strncpy(zone_info->zone_motd, "", sizeof(zone_info->zone_motd)) : strncpy(zone_info->zone_motd, row[12], sizeof(zone_info->zone_motd));
- zone_info->default_reenter_time = atoi(row[13]);
- zone_info->default_reset_time = atoi(row[14]);
- zone_info->default_lockout_time = atoi(row[15]);
- zone_info->force_group_to_zone = atoi(row[16]);
- row[17] == NULL ? strncpy(zone_info->lua_script, "", sizeof(zone_info->lua_script)) : strncpy(zone_info->lua_script, row[17], sizeof(zone_info->lua_script));
- zone_info->xp_modifier = atof(row[18]);
- zone_info->ruleset_id = atoul(row[19]);
- if ((ruleset_id = atoul(row[19])) > 0 && !rule_manager.SetZoneRuleSet(zone_info->id, ruleset_id))
- LogWrite(ZONE__ERROR, 0, "Zones", "Error setting rule set for zone '%s' (%u). A rule set with ID %u does not exist.", zone_info->name, zone_info->id, ruleset_id);
- zone_info->expansion_id = atoi(row[20]);
- zone_info->min_version = GetMinimumClientVersion(zone_info->expansion_id);
- zone_info->always_loaded = atoi(row[21]);
- zone_info->city_zone = atoi(row[22]);
- zone_info->start_zone = atoi(row[23]);
- row[24] == NULL ? strncpy(zone_info->zone_type, "", sizeof(zone_info->zone_type)) : strncpy(zone_info->zone_type, row[24], sizeof(zone_info->zone_type));
- zone_info->weather_allowed = atoi(row[25]);
- }
- }
- void WorldDatabase::SaveZoneInfo(int32 zone_id, const char* field, sint32 value) {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE `zones` SET `%s`=%i WHERE `id`=%u", field, value, zone_id);
- }
- void WorldDatabase::SaveZoneInfo(int32 zone_id, const char* field, float value) {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE `zones` SET `%s`=%f WHERE `id`=%u", field, value, zone_id);
- }
- void WorldDatabase::SaveZoneInfo(int32 zone_id, const char* field, const char* value) {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE `zones` SET `%s`='%s' WHERE `id`=%u", field, const_cast<char*>(getEscapeString(value)), zone_id);
- }
- int32 WorldDatabase::GetZoneID(const char* name) {
- int32 zone_id = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id` FROM zones WHERE `name`='%s'", name);
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- zone_id = atoi(row[0]);
- }
- return zone_id;
- }
- bool WorldDatabase::GetZoneRequirements(const char* zoneName, sint16* minStatus, int16* minLevel, int16* maxLevel, int16* minVersion) {
- Query query;
- char* escaped = getEscapeString(zoneName);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT min_status, min_level, max_level, expansion_id FROM zones where name='%s'",escaped);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- sint16 status = (sint16)atoi(row[0]);
- int16 levelMin = (int16)atoi(row[1]);
- int16 levelMax = (int16)atoi(row[2]);
- int8 expansion_id = (int8)atoi(row[3]);
- *minStatus = status;
- *minLevel = levelMin;
- *maxLevel = levelMax;
- if( expansion_id >= 40 ) // lowest client we support is RoK - exp04
- *minVersion = GetMinimumClientVersion(expansion_id);
- else
- *minVersion = 0;
- safe_delete_array(escaped);
- return true;
- }
- safe_delete_array(escaped);
- return false;
- }
- int16 WorldDatabase::GetMinimumClientVersion(int8 expansion_id)
- {
- /*
- 1 n/a Classic Expansion
- 2 adv01 Bloodline Chronicles
- 3 adv02 Splitpaw Saga
- 10 exp01 Desert of Flames
- 20 exp02 Kingdom of Sky
- 21 adv04 Fallen Dynasty
- 30 exp03 Echoes of Faydwer
- 40 exp04 Rise of Kunark
- 50 exp05 The Shadow Odyssey
- 60 exp06 Sentinel's Fate
- 61 halas Halas Reborn
- 70 exp07 Destiny of Velious
- 80 exp08 Age of Discovery
- */
- int16 minVer = 0;
- // TODO: eventually replace this with reading values from eq2expansions table
- switch(expansion_id)
- {
- case 40: // ROK
- {
- minVer = 843;
- break;
- }
- case 50: // TSO
- {
- minVer = 908;
- break;
- }
- case 60: // SF
- {
- minVer = 1008;
- break;
- }
- case 61: // Halas
- {
- minVer = 1045;
- break;
- }
- case 70: // DoV
- {
- minVer = 1096;
- break;
- }
- case 80: // AoD
- {
- minVer = 1144;
- break;
- }
- case 90: // CoE
- {
- minVer = 1188;
- break;
- }
- }
- return minVer;
- }
- // returns Expansion Name depending on the connected client's data version
- string WorldDatabase::GetExpansionIDByVersion(int16 version)
- {
- /*
- 0 n/a Classic Expansion
- 0 adv01 Bloodline Chronicles
- 0 adv02 Splitpaw Saga
- 0 exp01 Desert of Flames
- 0 exp02 Kingdom of Sky
- 0 adv04 Fallen Dynasty
- 0 exp03 Echoes of Faydwer
- 843 exp04 Rise of Kunark
- 908 exp05 The Shadow Odyssey
- 1008 exp06 Sentinel's Fate
- 1045 halas Halas Reborn
- 1096 exp07 Destiny of Velious
- 1142 exp08 Age of Discovery
- 1188 exp09 Chains of Eternity
- 9999 (and beyond)
- */
- string ret = "";
- if( version >= 9999 )
- ret = "Unknown";
- else if( version >= 1188 )
- ret = "Chains of Eternity";
- else if( version >= 1142 )
- ret = "Age of Discovery";
- else if( version >= 1096 )
- ret = "Destiny of Velious";
- else if( version >= 1045 )
- ret = "Halas Reborn";
- else if( version >= 1008 )
- ret = "Sentinel's Fate";
- else if( version >= 908 )
- ret = "The Shadow Odyssey";
- else if( version >= 843 )
- ret = "Rise of Kunark";
- else
- ret = "Any";
- return ret;
- }
- void WorldDatabase::LoadSpecialZones(){
- Query query;
- ZoneServer* zone = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, name, always_loaded, city_zone FROM zones where always_loaded = 1 or city_zone = 1");
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))){
- zone = new ZoneServer(row[1]);
- LoadZoneInfo(zone);
- zone->Init();
- zone->SetAlwaysLoaded(atoi(row[2]) == 1);
- zone->SetCityZone(atoi(row[3]) == 1);
- }
- }
- }
- bool WorldDatabase::SpawnGroupRemoveAssociation(int32 group1, int32 group2){
- Query query;
- query.RunQuery2(Q_DELETE, "delete FROM spawn_location_group_associations where (group_id1 = %u and group_id2 = %u) or (group_id1 = %u and group_id2 = %u)", group1, group2, group2, group1);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SpawnGroupRemoveSpawn query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::SpawnGroupAddAssociation(int32 group1, int32 group2){
- Query query;
- query.RunQuery2(Q_INSERT, "insert ignore into spawn_location_group_associations (group_id1, group_id2) values(%u, %u)", group1, group2);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SpawnGroupAddAssociation query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::SpawnGroupAddSpawn(Spawn* spawn, int32 group_id){
- Query query;
- query.RunQuery2(Q_INSERT, "insert ignore into spawn_location_group (group_id, placement_id) values(%u, %u)", group_id, spawn->GetSpawnLocationPlacementID());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SpawnGroupAddSpawn query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::SpawnGroupRemoveSpawn(Spawn* spawn, int32 group_id){
- Query query;
- query.RunQuery2(Q_DELETE, "delete FROM spawn_location_group where group_id = %u and placement_id = %u", group_id, spawn->GetSpawnLocationPlacementID());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SpawnGroupRemoveSpawn query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT count(group_id) FROM spawn_location_group where group_id = %u", group_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- if((row = mysql_fetch_row(result))){
- if(atoul(row[0]) == 0)
- DeleteSpawnGroup(group_id);
- }
- }
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SpawnGroupRemoveSpawn query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- int32 WorldDatabase::CreateSpawnGroup(Spawn* spawn, string name)
- {
- int32 group_id = 0;
- Query query;
- // JA: As of 0.7.1, DB Milestone 2, Content Team needs to use group_id's from Raw Data, so start any manual group_id's > 100,000
- query.RunQuery2(Q_INSERT, "INSERT INTO spawn_location_group (group_id, placement_id, name) SELECT IF(ISNULL(MAX(group_id))=1, 100000, MAX(group_id)+1), %u, '%s' FROM spawn_location_group", spawn->GetSpawnLocationPlacementID(), getSafeEscapeString(name.c_str()).c_str());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- return 0;
-
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT max(group_id) FROM spawn_location_group");
- if(result && mysql_num_rows(result) > 0)
- {
- MYSQL_ROW row;
- if((row = mysql_fetch_row(result)))
- {
- if(row[0])
- group_id = atoul(row[0]);
- }
- }
- return group_id;
- }
- void WorldDatabase::DeleteSpawnGroup(int32 id){
- Query query;
- query.RunQuery2(Q_DELETE, "delete FROM spawn_location_group where group_id = %u", id);
- }
- bool WorldDatabase::SetGroupSpawnChance(int32 id, float chance){
- Query query;
- query.RunQuery2(Q_UPDATE, "replace into spawn_location_group_chances (group_id, percentage) values(%u, %f)", id, chance);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in SetGroupSpawnChance query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- int32 WorldDatabase::LoadSpawnGroupChances(ZoneServer* zone){
- Query query;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT slgc.group_id, slgc.percentage FROM spawn_location_group_chances slgc, spawn_location_group slg, spawn_location_placement slp where slgc.group_id = slg.group_id and slg.placement_id = slp.id and slp.zone_id = %u", zone->GetZoneID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- int32 group_id = 0;
- float percent = 0;
- while(result && (row = mysql_fetch_row(result))){
- group_id = atoul(row[0]);
- percent = atof(row[1]);
- zone->AddSpawnGroupChance(group_id, percent);
- count++;
- }
- }
- return count;
- }
- int32 WorldDatabase::LoadSpawnLocationGroupAssociations(ZoneServer* zone){
- Query query;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT distinct slga.group_id1, slga.group_id2 FROM spawn_location_group_associations slga, spawn_location_group slg, spawn_location_placement slp where (slg.group_id = slga.group_id1 or slg.group_id = slga.group_id2) and slg.placement_id = slp.id and slp.zone_id = %u", zone->GetZoneID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))){
- zone->AddSpawnGroupAssociation(atoul(row[0]), atoul(row[1]));
- count++;
- }
- }
- return count;
- }
- int32 WorldDatabase::LoadSpawnLocationGroups(ZoneServer* zone){
- Query query;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT slg.group_id, slg.placement_id, slp.spawn_location_id FROM spawn_location_group slg, spawn_location_placement slp WHERE slg.placement_id = slp.id and slp.zone_id = %u", zone->GetZoneID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- int32 placement_id = 0;
- int32 group_id = 0;
- int32 spawn_location_id = 0;
- while(result && (row = mysql_fetch_row(result))){
- group_id = atoul(row[0]);
- placement_id = atoul(row[1]);
- spawn_location_id = atoul(row[2]);
- zone->AddSpawnGroupLocation(group_id, placement_id, spawn_location_id);
- count++;
- }
- }
- return count;
- }
- int32 WorldDatabase::ProcessSpawnLocations(ZoneServer* zone, const char* sql_query, int8 type){
- int32 number = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, sql_query, zone->GetZoneID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- int32 spawn_location_id = 0xFFFFFFFF;
- SpawnLocation* spawn_location = 0;
- while(result && (row = mysql_fetch_row(result))){
- if((spawn_location_id == 0xFFFFFFFF) || atoul(row[0]) != spawn_location_id){
- if(spawn_location){
- zone->AddSpawnLocation(spawn_location_id, spawn_location);
- number++;
- }
- spawn_location = new SpawnLocation();
- }
- SpawnEntry* entry = new SpawnEntry;
- spawn_location_id = atoul(row[0]);
- entry->spawn_location_id = spawn_location_id;
- entry->spawn_entry_id = atoul(row[1]);
- entry->spawn_type = type;
- entry->spawn_id = atoul(row[9]);
- entry->spawn_percentage = atof(row[10]);
- entry->respawn = atoul(row[11]);
- entry->expire_time = atoul(row[14]);
- entry->expire_offset = atoul(row[15]);
- spawn_location->x = atof(row[2]);
- spawn_location->y = atof(row[3]);
- spawn_location->z = atof(row[4]);
- spawn_location->x_offset = atof(row[5]);
- spawn_location->y_offset = atof(row[6]);
- spawn_location->z_offset = atof(row[7]);
- spawn_location->heading = atof(row[8]);
- spawn_location->pitch = atof(row[16]);
- spawn_location->roll = atof(row[17]);
- spawn_location->conditional = atoi(row[18]);
- spawn_location->total_percentage += entry->spawn_percentage;
- spawn_location->grid_id = strtoul(row[12], NULL, 0);
- spawn_location->placement_id = strtoul(row[13], NULL, 0);
- spawn_location->AddSpawn(entry);
- }
- if(spawn_location){
- zone->AddSpawnLocation(spawn_location_id, spawn_location);
- number++;
- }
- }
- return number;
- }
- void WorldDatabase::ResetDatabase(){
- Query query;
- query.RunQuery2("delete FROM table_versions where name != 'table_versions'", Q_DELETE);
- }
- void WorldDatabase::EnableConstraints(){
- Query query;
- query.RunQuery2("/*!40101 SET SQL_MODE=@OLD_SQL_MODE */", Q_DBMS);
- query.RunQuery2("/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */", Q_DBMS);
- }
- void WorldDatabase::DisableConstraints(){
- Query query;
- query.RunQuery2("/*!40101 SET NAMES utf8 */", Q_DBMS);
- query.RunQuery2("/*!40101 SET SQL_MODE=''*/", Q_DBMS);
- query.RunQuery2("/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */", Q_DBMS);
- query.RunQuery2("/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */", Q_DBMS);
- }
- void WorldDatabase::LoadSpawns(ZoneServer* zone)
- {
- Query query;
- int32 npcs = 0, objects = 0, widgets = 0, signs = 0, ground_spawns = 0, spawn_groups = 0, spawn_group_associations = 0, spawn_group_chances = 0;
- LogWrite(SPAWN__TRACE, 0, "Spawn", "Enter LoadSpawns");
- npcs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_npcs sn where sn.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_NPC);
- objects = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_objects so where so.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_OBJECT);
- widgets = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_widgets sw where sw.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_WIDGET);
- signs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_signs ss where ss.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_SIGN);
- ground_spawns = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_ground sg where sg.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_GROUNDSPAWN);
- spawn_groups = LoadSpawnLocationGroups(zone);
- spawn_group_associations = LoadSpawnLocationGroupAssociations(zone);
- spawn_group_chances = LoadSpawnGroupChances(zone);
- LogWrite(SPAWN__INFO, 0, "Spawn", "Loaded for zone '%s' (%u):\n\t%u NPC(s), %u Object(s), %u Widget(s)\n\t%u Sign(s), %u Ground Spawn(s), %u Spawn Group(s)\n\t%u Spawn Group Association(s), %u Spawn Group Chance(s)", zone->GetZoneName(), zone->GetZoneID(), npcs, objects, widgets, signs, ground_spawns, spawn_groups, spawn_group_associations, spawn_group_chances);
- LogWrite(SPAWN__TRACE, 0, "Spawn", "Exit LoadSpawns");
- }
- bool WorldDatabase::UpdateSpawnLocationSpawns(Spawn* spawn) {
- Query query;
- query.RunQuery2(Q_UPDATE, "update spawn_location_placement set x=%f, y=%f, z=%f, heading=%f, x_offset=%f, y_offset=%f, z_offset=%f, respawn=%u, expire_timer=%u, expire_offset=%u, grid_id=%u, pitch=%f, roll=%f where id = %u",
- spawn->GetX(), spawn->GetY(), spawn->GetZ(), spawn->GetHeading(), spawn->GetXOffset(), spawn->GetYOffset(), spawn->GetZOffset(), spawn->GetRespawnTime(), spawn->GetExpireTime(), spawn->GetExpireOffsetTime(), spawn->appearance.pos.grid_id, spawn->GetPitch(), spawn->GetRoll(), spawn->GetSpawnLocationPlacementID());
- if (query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF) {
- LogWrite(WORLD__ERROR, 0, "World", "Error in UpdateSpawnLocationSpawns query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::UpdateSpawnWidget(int32 widget_id, char* queryString) {
- Query query;
- query.RunQuery2(Q_UPDATE, "update spawn_widgets set %s where widget_id = %u",
- queryString, widget_id);
- if (query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF) {
- LogWrite(WORLD__ERROR, 0, "World", "Error in UpdateSpawnWidget query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- vector<string>* WorldDatabase::GetSpawnNameList(const char* in_name){
- Query query;
- string names = "";
- vector<string>* ret = 0;
- string name = getSafeEscapeString(in_name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT concat(spawn.id, ', ', name) FROM spawn where name like '%%%s%%'", name.c_str());
- if(result && mysql_num_rows(result) > 0){
- ret = new vector<string>;
- MYSQL_ROW row;
- int8 num = 0;
- while(result && (row = mysql_fetch_row(result))){
- if(num >= 10)
- break;
- ret->push_back(string(row[0]));
- num++;
- }
- char total[60] = {0};
- if(mysql_num_rows(result) > 10)
- sprintf(total, "Total number of results: %u (Limited to 10)", (int32)mysql_num_rows(result));
- else
- sprintf(total, "Total number of results: %u", (int32)mysql_num_rows(result));
- ret->push_back(string(total));
- }
- return ret;
- }
- string WorldDatabase::GetZoneName(char* zone_description){
- string ret;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM zones where description = '%s'", getSafeEscapeString(zone_description).c_str());
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row = mysql_fetch_row(result);
- ret = string(row[0]);
- }
- return ret;
- }
- void WorldDatabase::LoadRevivePoints(vector<RevivePoint*>* revive_points, int32 zone_id){
- if(revive_points && revive_points->size() > 0){
- LogWrite(WORLD__ERROR, 0, "World", "Revive points have already been loaded for this zone!");
- return;
- }
- else if(!revive_points || zone_id == 0){
- LogWrite(WORLD__ERROR, 0, "World", "LoadRevivePoints called with null variables!");
- return;
- }
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT respawn_zone_id, location_name, safe_x, safe_y, safe_z, heading FROM revive_points where zone_id=%u ORDER BY id asc", zone_id);
- if(revive_points && result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- int32 id = 0;
- RevivePoint* point = 0;
- while(result && (row=mysql_fetch_row(result))){
- point = new RevivePoint;
- point->id = id;
- point->zone_id = atoul(row[0]);
- point->location_name = string(row[1]);
- point->x = atof(row[2]);
- point->y = atof(row[3]);
- point->z = atof(row[4]);
- point->heading = atof(row[5]);
- revive_points->push_back(point);
- id++;
- }
- }
- }
- int32 WorldDatabase::GetNextSpawnIDInZone(int32 zone_id)
- {
- Query query;
- int32 ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT MAX(id) FROM spawn where id LIKE '%i____'", zone_id);
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(row[0])
- ret = atoi(row[0]) + 1;
- }
- if( ret == 0 )
- ret = zone_id * 10000; // there are no spawns for that zone yet, to start with the first ID
- LogWrite(WORLD__DEBUG, 0, "World", "Next Spawn ID for Zone %i: %u", zone_id, ret);
- return ret;
- }
- bool WorldDatabase::SaveSpawnInfo(Spawn* spawn){
- Query query;
- string name = getSafeEscapeString(spawn->GetName());
- string suffix = getSafeEscapeString(spawn->GetSuffixTitle());
- string prefix = getSafeEscapeString(spawn->GetPrefixTitle());
- string last_name = getSafeEscapeString(spawn->GetLastName());
- if(spawn->GetDatabaseID() == 0){
- int8 isInstanceType = (spawn->GetZone()->GetInstanceType() == Instance_Type::PERSONAL_HOUSE_INSTANCE);
- int32 new_spawn_id = GetNextSpawnIDInZone(spawn->GetZone()->GetZoneID());
- query.RunQuery2(Q_INSERT, "insert into spawn (id, name, race, model_type, size, targetable, show_name, command_primary, command_secondary, visual_state, attackable, show_level, show_command_icon, display_hand_icon, faction_id, collision_radius, hp, power, prefix, suffix, last_name, is_instanced_spawn) values(%u, '%s', %i, %i, %i, %i, %i, %u, %u, %i, %i, %i, %i, %i, %u, %i, %u, %u, '%s', '%s', '%s', %u)",
- new_spawn_id, name.c_str(), spawn->GetRace(), spawn->GetModelType(), spawn->GetSize(), spawn->appearance.targetable, spawn->appearance.display_name, spawn->GetPrimaryCommandListID(), spawn->GetSecondaryCommandListID(), spawn->GetVisualState(), spawn->appearance.attackable, spawn->appearance.show_level, spawn->appearance.show_command_icon, spawn->appearance.display_hand_icon, 0, spawn->appearance.pos.collision_radius, spawn->GetTotalHP(), spawn->GetTotalPower(), prefix.c_str(), suffix.c_str(), last_name.c_str(), isInstanceType);
- if( new_spawn_id > 0 )
- spawn->SetDatabaseID(new_spawn_id); // use the new zone_id range
- else if( query.GetLastInsertedID() > 0 )
- spawn->SetDatabaseID(query.GetLastInsertedID()); // else fall back to last_inserted_id
- else
- return false; // else, hang your head in shame as you are an utter failure
- if(spawn->IsNPC()){
- query.RunQuery2(Q_INSERT, "insert into spawn_npcs (spawn_id, min_level, max_level, enc_level, class_, gender, min_group_size, max_group_size, hair_type_id, facial_hair_type_id, wing_type_id, chest_type_id, legs_type_id, soga_hair_type_id, soga_facial_hair_type_id, soga_model_type, heroic_flag, action_state, mood_state, initial_state, activity_status, hide_hood, emote_state) values(%u, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)",
- spawn->GetDatabaseID(), spawn->GetLevel(), spawn->GetLevel(), spawn->appearance.encounter_level, spawn->GetAdventureClass(), spawn->GetGender(), 0, 0, ((NPC*)spawn)->features.hair_type, ((NPC*)spawn)->features.hair_face_type,
- ((NPC*)spawn)->features.wing_type, ((NPC*)spawn)->features.chest_type, ((NPC*)spawn)->features.legs_type, ((NPC*)spawn)->features.soga_hair_type, ((NPC*)spawn)->features.soga_hair_face_type, spawn->appearance.soga_model_type, spawn->appearance.heroic_flag, spawn->GetActionState(), spawn->GetMoodState(), spawn->GetInitialState(), spawn->GetActivityStatus(), spawn->appearance.hide_hood, spawn->appearance.emote_state);
- }
- else if(spawn->IsObject()){
- query.RunQuery2(Q_INSERT, "insert into spawn_objects (spawn_id) values(%u)", spawn->GetDatabaseID());
- }
- else if(spawn->IsWidget()){
- Widget* widget = (Widget*)spawn;
- query.RunQuery2(Q_INSERT, "insert into spawn_widgets (spawn_id, widget_id) values(%u, %u)", spawn->GetDatabaseID(), widget->GetWidgetID());
- }
- else if(spawn->IsSign()){
- query.RunQuery2(Q_INSERT, "insert into spawn_signs (spawn_id, description) values(%u, 'change me')", spawn->GetDatabaseID());
- }
- else if (spawn->IsGroundSpawn()) {
- query.RunQuery2(Q_INSERT, "insert into spawn_ground (spawn_id) values(%u)", spawn->GetDatabaseID());
- }
- }
- else{
- if(spawn->IsNPC()){
- query.RunQuery2(Q_UPDATE, "update spawn_npcs, spawn set name='%s', min_level=%i, max_level=%i, enc_level=%i, race=%i, model_type=%i, class_=%i, gender=%i, show_name=%i, attackable=%i, show_level=%i, targetable=%i, show_command_icon=%i, display_hand_icon=%i, hair_type_id=%i, facial_hair_type_id=%i, wing_type_id=%i, chest_type_id=%i, legs_type_id=%i, soga_hair_type_id=%i, soga_facial_hair_type_id=%i, soga_model_type=%i, size=%i, hp=%u, heroic_flag=%i, power=%u, collision_radius=%i, command_primary=%u, command_secondary=%u, visual_state=%i, action_state=%i, mood_state=%i, initial_state=%i, activity_status=%i, alignment=%i, faction_id=%u, hide_hood=%i, emote_state=%i, suffix ='%s', prefix='%s', last_name='%s' where spawn_npcs.spawn_id = spawn.id and spawn.id = %u",
- name.c_str(), spawn->GetLevel(), spawn->GetLevel(), spawn->appearance.encounter_level, spawn->GetRace(), spawn->GetModelType(),
- spawn->GetAdventureClass(), spawn->GetGender(), spawn->appearance.display_name, spawn->appearance.attackable, spawn->appearance.show_level, spawn->appearance.targetable, spawn->appearance.show_command_icon, spawn->appearance.display_hand_icon, ((NPC*)spawn)->features.hair_type,
- ((NPC*)spawn)->features.hair_face_type, ((NPC*)spawn)->features.wing_type, ((NPC*)spawn)->features.chest_type, ((NPC*)spawn)->features.legs_type, ((NPC*)spawn)->features.soga_hair_type, ((NPC*)spawn)->features.soga_hair_face_type, spawn->appearance.soga_model_type, spawn->GetSize(),
- spawn->GetTotalHP(), spawn->appearance.heroic_flag, spawn->GetTotalPower(), spawn->GetCollisionRadius(), spawn->GetPrimaryCommandListID(),
- spawn->GetSecondaryCommandListID(), spawn->GetVisualState(), spawn->GetActionState(), spawn->GetMoodState(), spawn->GetInitialState(),
- spawn->GetActivityStatus(), ((NPC*)spawn)->GetAlignment(), spawn->GetFactionID(), spawn->appearance.hide_hood, spawn->appearance.emote_state,
- suffix.c_str(), prefix.c_str(), last_name.c_str(), spawn->GetDatabaseID());
- }
- else if(spawn->IsObject()){
- query.RunQuery2(Q_UPDATE, "update spawn_objects, spawn set name='%s', model_type=%i, show_name=%i, targetable=%i, size=%i, command_primary=%u, command_secondary=%u, visual_state=%i, attackable=%i, show_level=%i, show_command_icon=%i, display_hand_icon=%i, collision_radius=%i, hp = %u, power = %u, device_id = %i where spawn_objects.spawn_id = spawn.id and spawn.id = %u",
- name.c_str(), spawn->GetModelType(), spawn->appearance.display_name, spawn->appearance.targetable, spawn->GetSize(), spawn->GetPrimaryCommandListID(), spawn->GetSecondaryCommandListID(), spawn->GetVisualState(), spawn->appearance.attackable, spawn->appearance.show_level, spawn->appearance.show_command_icon, spawn->appearance.display_hand_icon,
- spawn->GetCollisionRadius(), spawn->GetTotalHP(), spawn->GetTotalPower(), ((Object*)spawn)->GetDeviceID(), spawn->GetDatabaseID());
- }
- else if(spawn->IsWidget()){
- Widget* widget = (Widget*)spawn;
- char* openSound = 0;
- char* closeSound = 0;
- if (widget->GetOpenSound() != NULL) openSound = (char*)widget->GetOpenSound(); else openSound = (char*)string("0").c_str();
- if (widget->GetCloseSound() != NULL) closeSound = (char*)widget->GetCloseSound(); else closeSound = (char*)string("0").c_str();
- query.RunQuery2(Q_UPDATE, "update spawn_widgets, spawn set name='%s', race=%i, model_type=%i, show_name=%i, attackable=%i, show_level=%i, show_command_icon=%i, display_hand_icon=%i, size=%i, hp=%u, power=%u, collision_radius=%i, command_primary=%u, command_secondary=%u, visual_state=%i, faction_id=%u, suffix ='%s', prefix='%s', last_name='%s',widget_id = %u,widget_x = %f,widget_y = %f,widget_z = %f,include_heading = %u,include_location = %u,icon = %u,type='%s',open_heading = %f,closed_heading = %f,open_x = %f,open_y = %f,open_z = %f,action_spawn_id = %u,open_sound_file='%s',close_sound_file='%s',open_duration = %u,close_x = %f,close_y=%f,close_z=%f,linked_spawn_id = %u,house_id = %u where spawn_widgets.spawn_id = spawn.id and spawn.id = %u",
- name.c_str(), spawn->GetRace(), spawn->GetModelType(), spawn->appearance.display_name, spawn->appearance.attackable, spawn->appearance.show_level, spawn->appearance.show_command_icon, spawn->appearance.display_hand_icon, spawn->GetSize(),
- spawn->GetTotalHP(), spawn->GetTotalPower(), spawn->GetCollisionRadius(), spawn->GetPrimaryCommandListID(), spawn->GetSecondaryCommandListID(), spawn->GetVisualState(), spawn->GetFactionID(),
- suffix.c_str(), prefix.c_str(), last_name.c_str(), widget->GetWidgetID(), widget->GetX(), widget->GetY(), widget->GetZ(), widget->GetIncludeHeading(), widget->GetIncludeLocation(), widget->GetIconValue(), Widget::GetWidgetTypeNameByTypeID(widget->GetWidgetType()).c_str(),
- widget->GetOpenHeading(), widget->GetClosedHeading(), widget->GetOpenX(), widget->GetOpenY(), widget->GetOpenZ(),
- widget->GetActionSpawnID(), openSound, closeSound,widget->GetOpenDuration(),
- widget->GetCloseX(),widget->GetCloseY(),widget->GetCloseZ(),widget->GetLinkedSpawnID(),widget->GetHouseID(),
- spawn->GetDatabaseID());
- }
- else if(spawn->IsSign()){
- Sign* sign = (Sign*)spawn;
- query.RunQuery2(Q_UPDATE, "update spawn_signs, spawn set name='%s', race=%i, model_type=%i, show_name=%i, attackable=%i, show_level=%i, show_command_icon=%i, display_hand_icon=%i, size=%i, hp=%u, power=%u, collision_radius=%i, command_primary=%u, command_secondary=%u, visual_state=%i, faction_id=%u, suffix ='%s', prefix='%s', last_name='%s', type='%s', zone_id = %u, widget_id = %u, title='%s', widget_x = %f, widget_y = %f, widget_z = %f, icon = %u, description='%s', sign_distance = %f, zone_x = %f, zone_y = %f, zone_z = %f, zone_heading = %f, include_heading = %u, include_location = %u where spawn_signs.spawn_id = spawn.id and spawn.id = %u",
- name.c_str(), spawn->GetRace(), spawn->GetModelType(), spawn->appearance.display_name, spawn->appearance.attackable, spawn->appearance.show_level, spawn->appearance.show_command_icon, spawn->appearance.display_hand_icon, spawn->GetSize(),
- spawn->GetTotalHP(), spawn->GetTotalPower(), spawn->GetCollisionRadius(), spawn->GetPrimaryCommandListID(), spawn->GetSecondaryCommandListID(), spawn->GetVisualState(), spawn->GetFactionID(),
- suffix.c_str(), prefix.c_str(), last_name.c_str(), sign->GetSignType(), sign->GetSignZoneID(),
- sign->GetWidgetID(), sign->GetSignTitle(), sign->GetWidgetX(), sign->GetWidgetY(), sign->GetWidgetZ(),
- sign->GetIconValue(), sign->GetSignDescription(), sign->GetSignDistance(), sign->GetSignZoneX(),
- sign->GetSignZoneY(), sign->GetSignZoneZ(), sign->GetSignZoneHeading(), sign->GetIncludeHeading(),
- sign->GetIncludeLocation(), spawn->GetDatabaseID());
- }
- }
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(SPAWN__ERROR, 0, "Spawn", "Error in SaveSpawnInfo query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- int32 WorldDatabase::SaveCombinedSpawnLocation(ZoneServer* zone, Spawn* in_spawn, const char* name){
- vector<Spawn*>* spawns = in_spawn->GetSpawnGroup();
- uint32 spawnLocationID = 0;
- if(spawns && spawns->size() > 0){
- vector<Spawn*>::iterator itr;
- map<Spawn*, int32>::iterator freq_itr;
- Spawn* spawn = 0;
- map<Spawn*, int32> database_spawns;
- int32 total = 0;
- float x_offset = GetSpawnLocationPlacementOffsetX(in_spawn->GetSpawnLocationID());
- float y_offset = GetSpawnLocationPlacementOffsetY(in_spawn->GetSpawnLocationID());
- float z_offset = GetSpawnLocationPlacementOffsetZ(in_spawn->GetSpawnLocationID());
- int32 spawn_location_id = GetNextSpawnLocation();
- spawnLocationID = spawn_location_id;
- if(!name)
- name = "Combine SpawnGroup Generated";
- if(!CreateNewSpawnLocation(spawn_location_id, name)){
- safe_delete(spawns);
- return 0;
- }
- for(itr = spawns->begin();itr!=spawns->end();itr++){
- spawn = *itr;
- if (spawn) {
- RemoveSpawnFromSpawnLocation(spawn);
- spawn->SetSpawnLocationID(spawn_location_id);
- bool add = true;
- for (freq_itr = database_spawns.begin(); freq_itr != database_spawns.end(); freq_itr++) {
- if (spawn->GetDatabaseID() == freq_itr->first->GetDatabaseID()) {
- freq_itr->second++;
- total++;
- add = false;
- }
- }
- if (add) {
- database_spawns[spawn] = 1;
- total++;
- }
- }
- }
- for(freq_itr = database_spawns.begin(); freq_itr != database_spawns.end(); freq_itr++){
- int8 percent = (freq_itr->second*100)/total;
- if(!SaveSpawnEntry(freq_itr->first, name, percent, x_offset, y_offset, z_offset, freq_itr->first == in_spawn, false)){
- safe_delete(spawns);
- return 0;
- }
- }
- for(itr=spawns->begin();itr!=spawns->end();itr++){
- spawn = *itr;
- zone->RemoveSpawn(false, spawn);
- }
- safe_delete(spawns);
- }
- else{
- safe_delete(spawns);
- return 0;
- }
- return spawnLocationID;
- }
- bool WorldDatabase::SaveSpawnEntry(Spawn* spawn, const char* spawn_location_name, int8 percent, float x_offset, float y_offset, float z_offset, bool save_zonespawn, bool create_spawnlocation){
- Query query;
- Query query2;
- int32 count = 0;
- if(create_spawnlocation){
- count = GetSpawnLocationCount(spawn->GetSpawnLocationID());
- if(count == 0){
- if(!CreateNewSpawnLocation(spawn->GetSpawnLocationID(), spawn_location_name))
- return false;
- }
- }
- query.RunQuery2(Q_INSERT, "insert into spawn_location_entry (spawn_id, spawn_location_id, spawnpercentage) values(%u, %u, %i)", spawn->GetDatabaseID(), spawn->GetSpawnLocationID(), percent);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(SPAWN__ERROR, 0, "Spawn", "Error in SaveSpawnEntry query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- if(save_zonespawn){
- query2.RunQuery2(Q_INSERT, "insert into spawn_location_placement (zone_id, instance_id, spawn_location_id, x, y, z, x_offset, y_offset, z_offset, heading, grid_id) values(%u, %u, %u, %f, %f, %f, %f, %f, %f, %f, %u)", spawn->GetZone()->GetZoneID(), spawn->GetZone()->GetInstanceID(), spawn->GetSpawnLocationID(), spawn->GetX(), spawn->GetY(), spawn->GetZ(),x_offset, y_offset, z_offset, spawn->GetHeading(), spawn->appearance.pos.grid_id);
- if(query2.GetErrorNumber() && query2.GetError() && query2.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(SPAWN__ERROR, 0, "Spawn", "Error in SaveSpawnEntry query '%s': %s", query2.GetQuery(), query2.GetError());
- return false;
- }
- }
- return true;
- }
- float WorldDatabase::GetSpawnLocationPlacementOffsetX(int32 location_id) {
- Query query;
- MYSQL_ROW row;
- float ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `x_offset` FROM `spawn_location_placement` WHERE `spawn_location_id`=%u", location_id);
- if (result && (row = mysql_fetch_row(result))) {
- if (row[0])
- ret = atof(row[0]);
- }
- return ret;
- }
- float WorldDatabase::GetSpawnLocationPlacementOffsetY(int32 location_id) {
- Query query;
- MYSQL_ROW row;
- float ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `y_offset` FROM `spawn_location_placement` WHERE `spawn_location_id`=%u", location_id);
- if (result && (row = mysql_fetch_row(result))) {
- if (row[0])
- ret = atof(row[0]);
- }
- return ret;
- }
- float WorldDatabase::GetSpawnLocationPlacementOffsetZ(int32 location_id) {
- Query query;
- MYSQL_ROW row;
- float ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `z_offset` FROM `spawn_location_placement` WHERE `spawn_location_id`=%u", location_id);
- if (result && (row = mysql_fetch_row(result))) {
- if (row[0])
- ret = atof(row[0]);
- }
- return ret;
- }
- bool WorldDatabase::CreateNewSpawnLocation(int32 id, const char* name){
- Query query;
- if(!name)
- name = "Unknown Spawn Location Name";
- string str_name = getSafeEscapeString(name);
- query.RunQuery2(Q_INSERT, "insert into spawn_location_name (id, name) values(%u, '%s')", id, str_name.c_str());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(SPAWN__ERROR, 0, "Spawn", "Error in CreateNewSpawnLocation query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- int32 WorldDatabase::GetSpawnLocationCount(int32 location, Spawn* spawn){
- Query query;
- int32 ret = 0;
- MYSQL_RES* result = 0;
- if(spawn)
- result = query.RunQuery2(Q_SELECT, "SELECT count(id) FROM spawn_location_entry where spawn_location_id=%u and spawn_id=%u", location, spawn->GetDatabaseID());
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result)) && row[0]){
- ret = strtoul(row[0], NULL, 0);
- }
- }
- return ret;
- }
- int32 WorldDatabase::GetNextSpawnLocation(){
- Query query;
- int32 ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT max(id) FROM spawn_location_name");
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result)) && row[0]){
- ret = strtoul(row[0], NULL, 0);
- }
- }
- ret++;
- return ret;
- }
- bool WorldDatabase::RemoveSpawnFromSpawnLocation(Spawn* spawn){
- Query query;
- Query query2;
- int32 count = GetSpawnLocationCount(spawn->GetSpawnLocationID(), spawn);
- query.RunQuery2(Q_DELETE, "delete FROM spawn_location_placement where spawn_location_id=%u", spawn->GetSpawnLocationID());
- if(count == 1)
- query.RunQuery2(Q_DELETE, "delete FROM spawn_location_name where id=%u", spawn->GetSpawnLocationID());
- query2.RunQuery2(Q_DELETE, "delete FROM spawn_location_entry where spawn_id=%u and spawn_location_id = %u", spawn->GetDatabaseID(), spawn->GetSpawnLocationID());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(WORLD__ERROR, 0, "World", "Error in RemoveSpawnFromSpawnLocation query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- else if(query2.GetErrorNumber() && query2.GetError() && query2.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(SPAWN__ERROR, 0, "Spawn", "Error in RemoveSpawnFromSpawnLocation query '%s': %s", query2.GetQuery(), query.GetError());
- return false;
- }
- return true;
- }
- map<int32, string>* WorldDatabase::GetZoneList(const char* name, bool is_admin)
- {
- Query query;
- map<int32, string>* ret = 0;
- string zone_name = getSafeEscapeString(name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `name` FROM zones WHERE `name` RLIKE '%s' %s", zone_name.c_str(), (is_admin)?"":" LIMIT 0,10");
- if(result && mysql_num_rows(result) > 0)
- {
- ret = new map<int32, string>;
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result)))
- {
- zone_name = row[1];
- (*ret)[atoi(row[0])] = zone_name;
- }
- }
- return ret;
- }
- void WorldDatabase::UpdateStartingFactions(int32 char_id, int8 choice){
- Query query;
- query.RunQuery2(Q_INSERT, "insert into character_factions (char_id, faction_id, faction_level) select %u, faction_id, value FROM starting_factions where starting_city=%i", char_id, choice);
- }
- string WorldDatabase::GetStartingZoneName(int8 choice){
- Query query;
- string zone_name = "";
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM zones where start_zone = %u", choice);
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))){
- zone_name = string(row[0]);
- }
- }
- return zone_name;
- }
- void WorldDatabase::UpdateStartingZone(int32 char_id, int8 class_id, int8 race_id, int8 choice)
- {
- Query query;
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default zone for race: %i, class: %i for char_id: %u (choice: %i)", race_id, class_id, char_id, choice);
- // first, check to see if there is a starting_zones record for this race/class/choice combo (now using extended Archetype/BaseClass/Class combos
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `name` FROM starting_zones sz, zones z WHERE sz.zone_id = z.id AND class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255) AND choice IN (%i, 255)",
- classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id, choice);
- // TODO: verify client version so clients do not crash trying to enter zones they do not own (paks)
- if(result && mysql_num_rows(result) > 0)
- {
- string zone_name = "ERROR";
- MYSQL_ROW row;
- if( result && (row = mysql_fetch_row(result)) )
- zone_name = string(row[0]);
- query.RunQuery2(Q_UPDATE, "UPDATE characters c, zones z, starting_zones sz SET c.current_zone_id = z.id, c.x = z.safe_x, c.y = z.safe_y, c.z = z.safe_z, c.starting_city = %i WHERE z.id = sz.zone_id AND sz.class_id IN (%i, %i, %i, 255) AND sz.race_id IN (%i, 255) AND sz.choice IN (%i, 255) AND c.id = %u",
- choice, classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id, choice, char_id);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
- LogWrite(PLAYER__ERROR, 0, "Player", "Error in UpdateStartingZone custom starting_zones, query: '%s': %s", query.GetQuery(), query.GetError());
- return;
- }
- if(query.GetAffectedRows() > 0)
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Setting New Character Starting Zone to '%s' FROM starting_zones table.", zone_name.c_str());
- return;
- }
- }
- else
- {
- // there was no matching starting_zone value, so use default 'choice' starting city
- query.RunQuery2(Q_UPDATE, "UPDATE characters c, zones z SET c.current_zone_id = z.id, c.x = z.safe_x, c.y = z.safe_y, c.z = z.safe_z, c.starting_city = %i WHERE z.start_zone = %i and c.id = %u",
- choice, choice, char_id);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error in UpdateStartingZone player choice, query: '%s': %s", query.GetQuery(), query.GetError());
- return;
- }
- if(query.GetAffectedRows() > 0)
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Setting New Character Starting Zone to '%s' FROM player choice.", GetStartingZoneName(choice).c_str());
- return;
- }
- }
- // if we are here, it's a bad thing. zone tables have no start_city values to match client 'choice', so throw the player into zone according to R_World::DefaultStartingZoneID rule.
- // shout a few warnings so the admin fixes this asap!
- int16 default_zone_id = rule_manager.GetGlobalRule(R_World, DefaultStartingZoneID)->GetInt16();
- LogWrite(WORLD__WARNING, 0, "World", "No Starting City defined for player choice: %i! BAD! BAD! BAD! Defaulting player to zone %i.", choice, default_zone_id);
- query.RunQuery2(Q_UPDATE, "UPDATE characters c, zones z SET c.current_zone_id = z.id, c.x = z.safe_x, c.y = z.safe_y, c.z = z.safe_z, c.heading = z.safe_heading, c.starting_city = 1 WHERE z.id = %i and c.id = %u", default_zone_id, char_id);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- {
- LogWrite(PLAYER__ERROR, 0, "Player", "Error in UpdateStartingZone default zone %i, query: '%s': %s", default_zone_id, query.GetQuery(), query.GetError());
- return;
- }
- if(query.GetAffectedRows() > 0)
- LogWrite(PLAYER__DEBUG, 0, "Player", "Setting New Character Starting Zone to '%s' due to no valid options!", GetZoneName(1)->c_str());
- return;
- }
- void WorldDatabase::UpdateStartingItems(int32 char_id, int8 class_id, int8 race_id, bool base_class){
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default items for race: %i, class: %i for char_id: %u", race_id, class_id, char_id);
- Query query;
- Query query2;
- vector<Item*> items;
- vector<Item*> bags;
- map<int32, int8> total_slots;
- map<int32, int8> slots_left;
- map<int8, bool> equip_slots;
- map<Item*, StartingItem> item_list;
- int32 item_id = 0;
- Item* item = 0;
- StartingItem* starting_item = 0;
- //first get a list of the starting items for the character
- MYSQL_RES* result = 0;
- /*if(!base_class)
- result = query2.RunQuery2(Q_SELECT, "SELECT `type`, item_id, creator, condition_, attuned, count FROM starting_items where (class_id=%i and race_id=%i) or (class_id=%i and race_id=255) or (class_id=255 and race_id=%i) or (class_id=255 and race_id=255) ORDER BY id", class_id, race_id, class_id, race_id);
- else
- result = query2.RunQuery2(Q_SELECT, "SELECT `type`, item_id, creator, condition_, attuned, count FROM starting_items where (class_id=%i and race_id=%i) or (class_id=%i and race_id=255) ORDER BY id", class_id, race_id, class_id);*/
- result = query2.RunQuery2(Q_SELECT, "SELECT `type`, item_id, creator, condition_, attuned, count FROM starting_items WHERE class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255) ORDER BY id", classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id);
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))){
- item_id = atoul(row[1]);
- item = master_item_list.GetItem(item_id);
- if(item){
- starting_item = &(item_list[item]);
- starting_item->type = (row[0]) ? string(row[0]) : "";
- starting_item->item_id = atoul(row[1]);
- starting_item->creator = (row[2]) ? string(row[2]) : "";
- starting_item->condition = atoi(row[3]);
- starting_item->attuned = atoi(row[4]);
- starting_item->count = atoi(row[5]);
- item = master_item_list.GetItem(starting_item->item_id);
- if(item){
- if(bags.size() < NUM_INV_SLOTS && item->IsBag() && item->details.num_slots > 0)
- bags.push_back(item);
- else
- items.push_back(item);
- }
- }
- }
- }
- slots_left[0] = NUM_INV_SLOTS;
- //next create the bags in the inventory
- for(int8 i=0;i<bags.size();i++){
- item = bags[i];
- query.RunQuery2(Q_INSERT, "insert into character_items (char_id, type, slot, item_id, creator, condition_, attuned, bag_id, count) values(%u, '%s', %i, %u, '%s', %i, %i, %u, %i)",
- char_id, item_list[item].type.c_str(), i, item_list[item].item_id, getSafeEscapeString(item_list[item].creator.c_str()).c_str(), item_list[item].condition, item_list[item].attuned, 0, item_list[item].count);
- slots_left[query.GetLastInsertedID()] = item->details.num_slots;
- total_slots[query.GetLastInsertedID()] = item->details.num_slots;
- slots_left[0]--;
- }
- map<int32, int8>::iterator itr;
- int32 inv_slot = 0;
- int8 slot = 0;
- //finally process the rest of the items, placing them in the first available slot
- for(int32 x=0;x<items.size();x++){
- item = items[x];
- if(item_list[item].type.find("NOT") < 0xFFFFFFFF){ // NOT-EQUIPPED Items
- for(itr = slots_left.begin(); itr != slots_left.end(); itr++){
- if(itr->second > 0){
- if(itr->first == 0 && slots_left.size() > 1) //we want items to go into bags first, then inventory after bags are full
- continue;
- inv_slot = itr->first;
- slot = total_slots[itr->first] - itr->second;
- itr->second--;
- if(itr->second == 0)
- slots_left.erase(itr);
- break;
- }
- }
- query.RunQuery2(Q_INSERT, "insert into character_items (char_id, type, slot, item_id, creator, condition_, attuned, bag_id, count) values(%u, '%s', %i, %u, '%s', %i, %i, %u, %i)",
- char_id, item_list[item].type.c_str(), slot, item_list[item].item_id, getSafeEscapeString(item_list[item].creator.c_str()).c_str(), item_list[item].condition, item_list[item].attuned, inv_slot, item_list[item].count);
- }
- else{ //EQUIPPED Items
- for(int8 i=0;i<item->slot_data.size();i++){
- if(equip_slots.count(item->slot_data[i]) == 0){
- equip_slots[item->slot_data[i]] = true;
- query.RunQuery2(Q_INSERT, "insert into character_items (char_id, type, slot, item_id, creator, condition_, attuned, bag_id, count) values(%u, '%s', %i, %u, '%s', %i, %i, %u, %i)",
- char_id, item_list[item].type.c_str(), item->slot_data[i], item_list[item].item_id, getSafeEscapeString(item_list[item].creator.c_str()).c_str(), item_list[item].condition, item_list[item].attuned, 0, item_list[item].count);
- break;
- }
- }
- }
- }
- }
- void WorldDatabase::UpdateStartingSkills(int32 char_id, int8 class_id, int8 race_id)
- {
- Query query;
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default skills for race: %i, class: %i for char_id: %u", race_id, class_id, char_id);
- query.RunQuery2(Q_INSERT, "INSERT IGNORE INTO character_skills (char_id, skill_id, current_val, max_val) SELECT %u, skill_id, current_val, max_val FROM starting_skills WHERE class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255)",
- char_id, classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id);
- }
- void WorldDatabase::UpdateStartingSpells(int32 char_id, int8 class_id, int8 race_id){
- Query query;
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default spells for race: %i, class: %i for char_id: %u", race_id, class_id, char_id);
- query.RunQuery2(Q_INSERT, "INSERT IGNORE INTO character_spells (char_id, spell_id, tier, knowledge_slot) SELECT %u, spell_id, tier, knowledge_slot FROM starting_spells WHERE class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255)",
- char_id, classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id);
- }
- void WorldDatabase::UpdateStartingSkillbar(int32 char_id, int8 class_id, int8 race_id){
- Query query;
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default skillbar for race: %i, class: %i for char_id: %u", race_id, class_id, char_id);
- query.RunQuery2(Q_INSERT, "INSERT IGNORE INTO character_skillbar (char_id, type, hotbar, spell_id, slot, text_val) SELECT %u, type, hotbar, spell_id, slot, text_val FROM starting_skillbar WHERE class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255)",
- char_id, classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id);
- }
- void WorldDatabase::UpdateStartingTitles(int32 char_id, int8 class_id, int8 race_id, int8 gender_id) {
- Query query;
- LogWrite(PLAYER__DEBUG, 0, "Player", "Adding default titles for race: %i, class: %i, gender: %i for char_id: %u", race_id, class_id, gender_id, char_id);
- query.RunQuery2(Q_INSERT, "INSERT IGNORE INTO character_titles (char_id, title_id) SELECT %u, title_id FROM starting_titles WHERE class_id IN (%i, %i, %i, 255) AND race_id IN (%i, 255) and gender_id IN (%i, 255)",
- char_id, classes.GetBaseClass(class_id), classes.GetSecondaryBaseClass(class_id), class_id, race_id, gender_id);
- }
- string WorldDatabase::GetZoneDescription(int32 id){
- Query query;
- string ret = "";
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT description FROM zones where id = %u", id);
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- ret = string(row[0]);
- }
- return ret;
- }
- string* WorldDatabase::GetZoneName(int32 id){
- string* ret = new string;
- if (zone_names.count(id) > 0){
- ret->assign(zone_names[id]);
- return ret;
- }
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `name` FROM zones where `id` = %u", id);
- if(result && mysql_num_rows(result) > 0){
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- zone_names[id] = row[0];
- ret->assign(zone_names[id]);
- }
- return ret;
- }
- bool WorldDatabase::VerifyZone(const char* name){
- Query query;
- char* escaped = getEscapeString(name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT name FROM zones where name='%s'",escaped);
- safe_delete_array(escaped);
- if(result && mysql_num_rows(result) > 0)
- return true;
- else
- return false;
- }
- int8 WorldDatabase::GetInstanceTypeByZoneID(int32 zoneID)
- {
- DatabaseResult result;
- int8 ret = 0;
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Getting instances for zone_id %u", zoneID);
- if( !database_new.Select(&result, "SELECT instance_type+0 FROM zones WHERE id = %u", zoneID) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in GetInstanceTypeByZoneID() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return ret;
- }
- if( result.GetNumRows() > 0 )
- {
- result.Next();
- ret = (result.GetInt8Str("instance_type+0") == 0) ? 0 : result.GetInt8Str("instance_type+0") - 1;
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Found instance type %i for zone_id %u", ret, zoneID);
- }
- else
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "No instances found for zone_id %u", zoneID);
- return ret;
- }
- void WorldDatabase::Save(Client* client){
- Query query;
- Player* player = client->GetPlayer();
- if(!player->CheckPlayerInfo())
- return;
- int32 instance_id = 0;
- if ( client->GetCurrentZone ( ) != NULL )
- instance_id = client->GetCurrentZone()->GetInstanceID();
- int32 zone_id = 0;
- if(client->GetCurrentZone())
- zone_id = client->GetCurrentZone()->GetZoneID();
- query.AddQueryAsync(client->GetCharacterID(), this, Q_UPDATE, "update characters set current_zone_id=%u, x=%f, y=%f, z=%f, heading=%f, level=%i,instance_id=%i,last_saved=%i, `class`=%i, `tradeskill_level`=%i, `tradeskill_class`=%i where id = %u", zone_id, player->GetX(), player->GetY(), player->GetZ(), player->GetHeading(), player->GetLevel(), instance_id, client->GetLastSavedTimeStamp(), client->GetPlayer()->GetAdventureClass(), client->GetPlayer()->GetTSLevel(), client->GetPlayer()->GetTradeskillClass(), client->GetCharacterID());
- query.AddQueryAsync(client->GetCharacterID(), this, Q_UPDATE, "update character_details set hp=%u, power=%u, str=%i, sta=%i, agi=%i, wis=%i, intel=%i, heat=%i, cold=%i, magic=%i, mental=%i, divine=%i, disease=%i, poison=%i, coin_copper=%u, coin_silver=%u, coin_gold=%u, coin_plat=%u, max_hp = %u, max_power=%u, xp = %u, xp_needed = %u, xp_debt = %u, xp_vitality = %f, tradeskill_xp = %u, tradeskill_xp_needed = %u, tradeskill_xp_vitality = %f, bank_copper = %u, bank_silver = %u, bank_gold = %u, bank_plat = %u, bind_zone_id=%u, bind_x = %f, bind_y = %f, bind_z = %f, bind_heading = %f, house_zone_id=%u, combat_voice = %i, emote_voice = %i, biography='%s', flags=%u, flags2=%u, last_name='%s' where char_id = %u",
- player->GetHP(), player->GetPower(), player->GetStrBase(), player->GetStaBase(), player->GetAgiBase(), player->GetWisBase(), player->GetIntBase(), player->GetHeatResistanceBase(), player->GetColdResistanceBase(), player->GetMagicResistanceBase(),
- player->GetMentalResistanceBase(), player->GetDivineResistanceBase(), player->GetDiseaseResistanceBase(), player->GetPoisonResistanceBase(), player->GetCoinsCopper(), player->GetCoinsSilver(), player->GetCoinsGold(), player->GetCoinsPlat(), player->GetTotalHPBase(), player->GetTotalPowerBase(), player->GetXP(), player->GetNeededXP(), player->GetXPDebt(), player->GetXPVitality(), player->GetTSXP(), player->GetNeededTSXP(), player->GetTSXPVitality(), player->GetBankCoinsCopper(),
- player->GetBankCoinsSilver(), player->GetBankCoinsGold(), player->GetBankCoinsPlat(), client->GetPlayer()->GetPlayerInfo()->GetBindZoneID(), client->GetPlayer()->GetPlayerInfo()->GetBindZoneX(), client->GetPlayer()->GetPlayerInfo()->GetBindZoneY(), client->GetPlayer()->GetPlayerInfo()->GetBindZoneZ(), client->GetPlayer()->GetPlayerInfo()->GetBindZoneHeading(), client->GetPlayer()->GetPlayerInfo()->GetHouseZoneID(),
- client->GetPlayer()->GetCombatVoice(), client->GetPlayer()->GetEmoteVoice(), getSafeEscapeString(client->GetPlayer()->GetBiography().c_str()).c_str(), player->GetFlags(), player->GetFlags2(), client->GetPlayer()->GetLastName(), client->GetCharacterID());
- map<string, int8>::iterator itr;
- map<string, int8>* friends = player->GetFriends();
- if(friends && friends->size() > 0){
- for(itr = friends->begin(); itr != friends->end(); itr++){
- if(itr->second == 1){
- query.AddQueryAsync(client->GetCharacterID(), this, Q_INSERT, "insert ignore into character_social (char_id, name, type) values(%u, '%s', 'FRIEND')", client->GetCharacterID(), getSafeEscapeString(itr->first.c_str()).c_str());
- itr->second = 0;
- }
- else if(itr->second == 2){
- query.AddQueryAsync(client->GetCharacterID(), this, Q_DELETE, "delete FROM character_social where char_id = %u and name = '%s'", client->GetCharacterID(), getSafeEscapeString(itr->first.c_str()).c_str());
- itr->second = 3;
- }
- }
- }
- map<string, int8>* ignored = player->GetIgnoredPlayers();
- if(ignored && ignored->size() > 0){
- for(itr = ignored->begin(); itr != ignored->end(); itr++){
- if(itr->second == 1){
- query.AddQueryAsync(client->GetCharacterID(), this, Q_INSERT, "insert ignore into character_social (char_id, name, type) values(%u, '%s', 'IGNORE')", client->GetCharacterID(), getSafeEscapeString(itr->first.c_str()).c_str());
- itr->second = 0;
- }
- else if(itr->second == 2){
- query.AddQueryAsync(client->GetCharacterID(), this, Q_DELETE, "delete FROM character_social where char_id = %u and name = '%s'", client->GetCharacterID(), getSafeEscapeString(itr->first.c_str()).c_str());
- itr->second = 3;
- }
- }
- }
- SavePlayerFactions(client);
- SaveCharacterQuests(client);
- SaveCharacterSkills(client);
- SavePlayerSpells(client);
- SavePlayerMail(client);
- SavePlayerCollections(client);
- LogWrite(PLAYER__INFO, 3, "Player", "Player '%s' (%u) data saved.", player->GetName(), player->GetCharacterID());
- }
- void WorldDatabase::LoadEntityCommands(ZoneServer* zone) {
- int32 total = 0;
- int32 id = 0;
- EntityCommand* command = 0;
- DatabaseResult result;
- if (!database_new.Select(&result, "SELECT `command_list_id`, `command_text`, `distance`, `command`, `error_text`, `cast_time`, `spell_visual` FROM `entity_commands` ORDER BY `id`")) {
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- command = new EntityCommand;
- id = result.GetInt32(0);
- command->name = result.GetString(1);
- command->distance = result.GetFloat(2);
- command->command = result.GetString(3);
- command->error_text = result.GetString(4);
- command->cast_time = result.GetInt16(5);
- command->spell_visual = result.GetInt32(6);
- command->default_allow_list = true;
- zone->SetEntityCommandList(id, command);
- LogWrite(COMMAND__DEBUG, 5, "Command", "---Loading Command: '%s' (%s)", command->name.c_str(), command->command.c_str());
- total++;
- }
- LogWrite(COMMAND__DEBUG, 0, "Command", "--Loaded %i entity command(s)", total);
- }
- void WorldDatabase::LoadFactionAlliances()
- {
- LogWrite(FACTION__DEBUG, 1, "Faction", "-Loading faction alliances...");
- int32 total = 0;
- int32 fTotal = 0;
- int32 hTotal = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT faction_id, friend_faction, hostile_faction FROM faction_alliances");
- if(result && mysql_num_rows(result) > 0)
- {
- MYSQL_ROW row;
- int32 faction_id = 0;
- int32 friendly_id = 0;
- int32 hostile_id = 0;
- while(result && (row = mysql_fetch_row(result)))
- {
- faction_id = atoul(row[0]);
- friendly_id = atoul(row[1]);
- hostile_id = atoul(row[2]);
- if(friendly_id > 0)
- {
- master_faction_list.AddFriendlyFaction(faction_id, friendly_id);
- fTotal++;
- LogWrite(FACTION__DEBUG, 5, "Faction", "---Faction %i is friendly towards %i", faction_id, friendly_id);
- }
- if(hostile_id > 0)
- {
- master_faction_list.AddHostileFaction(faction_id, hostile_id);
- hTotal++;
- LogWrite(FACTION__DEBUG, 5, "Faction", "---Faction %i is hostile towards %i", faction_id, hostile_id);
- }
- total++;
- }
- }
- LogWrite(FACTION__DEBUG, 3, "Faction", "--Loaded %u Alliances: %i friendly, %i hostile", total, fTotal, hTotal);
- }
- bool WorldDatabase::UpdateSpawnScriptData(int32 spawn_id, int32 spawn_location_id, int32 spawnentry_id, const char* name){
- bool ret = false;
- if((spawn_id > 0 || spawn_location_id > 0 || spawnentry_id > 0) && name){
- Query query;
- int32 row_id = 0;
- if(spawn_id > 0){
- query.RunQuery2(Q_DELETE, "DELETE FROM spawn_scripts where spawn_id=%u", spawn_id);
- query.RunQuery2(Q_INSERT, "INSERT into spawn_scripts (spawn_id, lua_script) values(%u, '%s')", spawn_id, getSafeEscapeString(name).c_str());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(LUA__ERROR, 0, "LUA", "Error in UpdateSpawnScriptData, Query: %s, Error: %s", query.GetQuery(), query.GetError());
- else{
- row_id = query.GetLastInsertedID();
- if(row_id > 0)
- world.AddSpawnScript(row_id, name);
- ret = true;
- }
- }
- else if(spawn_location_id > 0){
- query.RunQuery2(Q_DELETE, "DELETE FROM spawn_scripts where spawn_location_id=%u", spawn_location_id);
- query.RunQuery2(Q_INSERT, "INSERT into spawn_scripts (spawn_location_id, lua_script) values(%u, '%s')", spawn_location_id, getSafeEscapeString(name).c_str());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(LUA__ERROR, 0, "LUA", "Error in UpdateSpawnScriptData, Query: %s, Error: %s", query.GetQuery(), query.GetError());
- else{
- row_id = query.GetLastInsertedID();
- if(row_id > 0)
- world.AddSpawnLocationScript(row_id, name);
- ret = true;
- }
- }
- else if(spawnentry_id > 0){
- query.RunQuery2(Q_DELETE, "DELETE FROM spawn_scripts where spawnentry_id=%u", spawnentry_id);
- query.RunQuery2(Q_INSERT, "INSERT into spawn_scripts (spawnentry_id, lua_script) values(%u, '%s')", spawnentry_id, getSafeEscapeString(name).c_str());
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- LogWrite(LUA__ERROR, 0, "LUA", "Error in UpdateSpawnScriptData, Query: %s, Error: %s", query.GetQuery(), query.GetError());
- else{
- row_id = query.GetLastInsertedID();
- if(row_id > 0)
- world.AddSpawnEntryScript(row_id, name);
- ret = true;
- }
- }
- }
- return ret;
- }
- void WorldDatabase::LoadSpawnScriptData() {
- int32 total = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spawn_id, spawnentry_id, spawn_location_id, lua_script FROM spawn_scripts");
- if(result && mysql_num_rows(result) > 0)
- {
- MYSQL_ROW row;
- int32 spawn_id = 0;
- int32 spawnentry_id = 0;
- int32 spawn_location_id = 0;
- while(result && (row = mysql_fetch_row(result)))
- {
- spawn_id = atoul(row[0]);
- spawnentry_id = atoul(row[1]);
- spawn_location_id = atoul(row[2]);
- string spawn_script = string(row[3]);
- if(spawnentry_id > 0)
- {
- world.AddSpawnEntryScript(spawnentry_id, row[3]);
- total++;
- }
- else if(spawn_location_id > 0)
- {
- world.AddSpawnLocationScript(spawn_location_id, row[3]);
- total++;
- }
- else if(spawn_id > 0)
- {
- world.AddSpawnScript(spawn_id, row[3]);
- total++;
- }
- else {
- if(row[3])
- LogWrite(LUA__ERROR, 0, "LUA", "Invalid Entry in spawn_scripts table for lua_script '%s' (spawn_id, spawnentry_id and spawn_location_id are all 0)", row[3]);
- else
- LogWrite(LUA__ERROR, 0, "LUA", "Invalid Entry in spawn_scripts table.");
- }
- if( spawn_id || spawnentry_id || spawn_location_id ) {
- LogWrite(LUA__DEBUG, 5, "LUA", "SpawnScript %s loaded.", spawn_script.c_str());
- }
- spawn_id = 0;
- spawnentry_id = 0;
- spawn_location_id = 0;
- }
- }
- LogWrite(LUA__DEBUG, 0, "LUA", "\tLoaded %u SpawnScript%s", total, total == 1 ? "" : "s");
- }
- void WorldDatabase::LoadZoneScriptData() {
- Query query;
- int32 total = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `lua_script` FROM `zones`");
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))) {
- if (row[1]) {
- int32 zone_id = atoul(row[0]);
- string zone_script = string(row[1]);
- if (zone_id > 0 && zone_script.length() > 0) {
- LogWrite(LUA__DEBUG, 5, "LUA", "ZoneScript: %s loaded.", zone_script.c_str());
- world.AddZoneScript(zone_id, zone_script.c_str());
- total++;
- }
- }
- }
- }
- LogWrite(LUA__DEBUG, 0, "LUA", "\tLoaded %u ZoneScript%s", total, total == 1 ? "" : "s");
- }
- int32 WorldDatabase::LoadSpellScriptData() {
- Query query;
- MYSQL_ROW row;
- int32 count;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `lua_script` FROM `spells`"); // WHERE is_active = 1
- while (result && (row = mysql_fetch_row(result))) {
- if (row[0] && strlen(row[0]) > 0) {
- if (lua_interface->LoadLuaSpell(row[0]))
- LogWrite(SPELL__DEBUG, 5, "Spells", "SpellScript: %s loaded.", row[0]);
- }
- }
- count = mysql_num_rows(result);
- LogWrite(SPELL__DEBUG, 0, "Spells", "\tLoaded %i SpellScript%s", count, count == 1 ? "" : "s");
- return count;
- }
- void WorldDatabase::LoadFactionList() {
- int32 total = 0;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, name, type, description, default_level, negative_change, positive_change FROM factions");
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- Faction* faction = 0;
- while(result && (row = mysql_fetch_row(result))){
- faction = new Faction;
- faction->id = atoul(row[0]);
- faction->name = string(row[1]);
- faction->type = string(row[2]);
- faction->description = string(row[3]);
- faction->default_value = atoi(row[4]);
- faction->negative_change = atoi(row[5]);
- faction->positive_change = atoi(row[6]);
- master_faction_list.AddFaction(faction);
- total++;
- LogWrite(FACTION__DEBUG, 5, "Faction", "---Loading Faction '%s' (%u)", faction->name.c_str(), faction->id);
- }
- }
- LogWrite(FACTION__DEBUG, 3, "Faction", "--Loaded %u Faction%s", total, total == 1 ? "" : "s");
- LoadFactionAlliances();
- }
- void WorldDatabase::SavePlayerFactions(Client* client){
- LogWrite(PLAYER__DEBUG, 3, "Player", "Saving Player Factions...");
- Query query;
- map<int32, sint32>* factions = client->GetPlayer()->GetFactions()->GetFactionValues();
- map<int32, sint32>::iterator itr;
- for(itr = factions->begin(); itr != factions->end(); itr++)
- query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "insert into character_factions (char_id, faction_id, faction_level) values(%u, %u, %i) ON DUPLICATE KEY UPDATE faction_level=%i", client->GetCharacterID(), itr->first, itr->second, itr->second);
- }
- bool WorldDatabase::LoadPlayerFactions(Client* client) {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loading Player Factions...");
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT faction_id, faction_level FROM character_factions where char_id=%i", client->GetCharacterID());
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- while(result && (row = mysql_fetch_row(result))){
- client->GetPlayer()->GetFactions()->SetFactionValue(atoul(row[0]), atol(row[1]));
- }
- }
- if(query.GetErrorNumber())
- return false;
- return true;
- }
- void WorldDatabase::SavePlayerMail(Mail* mail) {
- Query query_update;
- Query query_insert;
- if (mail) {
- query_update.AddQueryAsync(mail->player_to_id, this, Q_UPDATE, "UPDATE `character_mail` SET `already_read`=%u, `coin_copper`=%u, `coin_silver`=%u, `coin_gold`=%u, `coin_plat`=%u WHERE `id`=%u", mail->already_read, mail->coin_copper, mail->coin_silver, mail->coin_gold, mail->coin_plat, mail->mail_id);
- if (query_update.GetAffectedRows() == 0)
- query_insert.AddQueryAsync(mail->player_to_id, this, Q_UPDATE, "INSERT INTO `character_mail` (`player_to_id`, `player_from`, `subject`, `mail_body`, `already_read`, `mail_type`, `coin_copper`, `coin_silver`, `coin_gold`, `coin_plat`, `stack`, `postage_cost`, `attachment_cost`, `char_item_id`, `time_sent`, `expire_time`) VALUES (%u, '%s', '%s', '%s', %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", mail->player_to_id, mail->player_from.c_str(), getSafeEscapeString(mail->subject.c_str()).c_str(), getSafeEscapeString(mail->mail_body.c_str()).c_str(), mail->already_read, mail->mail_type, mail->coin_copper, mail->coin_silver, mail->coin_gold, mail->coin_plat, mail->stack, mail->postage_cost, mail->attachment_cost, mail->char_item_id, mail->time_sent, mail->expire_time);
- mail->save_needed = false;
- }
- }
- void WorldDatabase::SavePlayerMail(Client* client) {
- if (client) {
- MutexMap<int32, Mail*>* mail_list = client->GetPlayer()->GetMail();
- MutexMap<int32, Mail*>::iterator itr = mail_list->begin();
- while (itr.Next()) {
- Mail* mail = itr->second;
- if (mail->save_needed)
- SavePlayerMail(mail);
- }
- }
- }
- void WorldDatabase::LoadPlayerMail(Client* client, bool new_only) {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loading Player Mail...");
- if (client) {
- Query query;
- MYSQL_RES* result;
- if (new_only)
- result = query.RunQuery2(Q_SELECT, "SELECT `id`, `player_to_id`, `player_from`, `subject`, `mail_body`, `already_read`, `mail_type`, `coin_copper`, `coin_silver`, `coin_gold`, `coin_plat`, `stack`, `postage_cost`, `attachment_cost`, `char_item_id`, `time_sent`, `expire_time` FROM `character_mail` WHERE `player_to_id`=%u AND `unread`=1", client->GetCharacterID());
- else
- result = query.RunQuery2(Q_SELECT, "SELECT `id`, `player_to_id`, `player_from`, `subject`, `mail_body`, `already_read`, `mail_type`, `coin_copper`, `coin_silver`, `coin_gold`, `coin_plat`, `stack`, `postage_cost`, `attachment_cost`, `char_item_id`, `time_sent`, `expire_time` FROM `character_mail` WHERE `player_to_id`=%u", client->GetCharacterID());
- if (result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- client->SimpleMessage(CHANNEL_COLOR_MAIL, "You've got mail! :)");
- while (result && (row = mysql_fetch_row(result))) {
- Mail* mail = new Mail;
- mail->mail_id = atoul(row[0]);
- mail->player_to_id = atoul(row[1]);
- mail->player_from = string(row[2]);
- mail->subject = string(row[3]);
- if (row[4])
- mail->mail_body = string(row[4]);
- mail->already_read = atoi(row[5]);
- mail->mail_type = atoi(row[6]);
- mail->coin_copper = atoul(row[7]);
- mail->coin_silver = atoul(row[8]);
- mail->coin_gold = atoul(row[9]);
- mail->coin_plat = atoul(row[10]);
- mail->stack = atoi(row[11]);
- mail->postage_cost = atoul(row[12]);
- mail->attachment_cost = atoul(row[13]);
- mail->char_item_id = atoul(row[14]);
- mail->time_sent = atoul(row[15]);
- mail->expire_time = atoul(row[16]);
- mail->save_needed = false;
- client->GetPlayer()->AddMail(mail);
- LogWrite(PLAYER__DEBUG, 5, "Player", "Loaded Mail ID %i, to: %i, from: %s", atoul(row[0]), atoul(row[1]), string(row[2]).c_str());
- }
- }
- }
- }
- void WorldDatabase::DeletePlayerMail(Mail* mail) {
- Query query;
- if (mail)
- query.RunQuery2(Q_DELETE, "DELETE FROM `character_mail` WHERE `id`=%u", mail->mail_id);
- LogWrite(PLAYER__DEBUG, 0, "Player", "Delete Player Mail...");
- }
- vector<int32>* WorldDatabase::GetAllPlayerIDs() {
- Query query;
- vector<int32>* ids = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id` FROM `characters`");
- MYSQL_ROW row;
- while (result && (row = mysql_fetch_row(result))) {
- if (ids == 0)
- ids = new vector<int32>;
- ids->push_back(atoul(row[0]));
- }
- return ids;
- }
- void WorldDatabase::GetPetNames(ZoneServer* zone)
- {
- DatabaseResult result;
- int32 total = 0;
- if( database_new.Select(&result, "SELECT pet_name FROM spawn_pet_names") )
- {
- while(result.Next())
- {
- zone->pet_names.push_back(result.GetStringStr("pet_name"));
- total++;
- LogWrite(PET__DEBUG, 5, "Pet", "---Loading Pet Name: '%s'", result.GetStringStr("pet_name"));
- }
- LogWrite(PET__DEBUG, 0, "Pet", "--Loaded %u Pet Names", total);
- }
- }
- int32 WorldDatabase::CheckTableVersions(char* tablename) {
- Query query;
- char* escaped_name = getEscapeString(tablename);
- LogWrite(INIT__PATCHER_DEBUG, 1, "Patcher", "\tChecking current version for table: %s", tablename);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT version FROM table_versions WHERE name='%s';", escaped_name);
- int32 ret_version = 0;
- if(result && mysql_num_rows(result) > 0)
- {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- ret_version = atoul(row[0]);
- }
- safe_delete_array(escaped_name);
- return ret_version;
- }
- bool WorldDatabase::RunDatabaseQueries(TableQuery* queries, bool output_result, bool data){
- for(int16 i=0;i<queries->num_queries;i++){
- Query query;
- if(string(queries->GetQuery(i)).length() > 5)
- query.RunQuery2(string(queries->GetQuery(i)), Q_UPDATE);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- {
- if(output_result)
- LogWrite(INIT__PATCHER_ERROR, 0, "Patcher", "FAILED!");
- LogWrite(INIT__PATCHER_ERROR, 0, "Patcher", "Error in updating tables query '%s': %s", query.GetQuery(), query.GetError());
- return false;
- }
- }
- if(output_result)
- LogWrite(INIT__PATCHER_DEBUG, 0, "Patcher", "SUCCESS!");
- if(data)
- UpdateDataTableVersion(queries->tablename, queries->latest_version);
- else
- UpdateTableVersion(queries->tablename, queries->latest_version);
- return true;
- }
- void WorldDatabase::UpdateDataTableVersion(char* name, int32 version){
- Query query;
- char* escaped_name = getEscapeString(name);
- query.RunQuery2(Q_UPDATE, "update table_versions set download_version=%u where name='%s'", version, escaped_name);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- {
- LogWrite(INIT__PATCHER_ERROR, 0, "Patcher", "Error in updating version table query '%s': %s", query.GetQuery(), query.GetError());
- }
- safe_delete_array(escaped_name);
- }
- void WorldDatabase::UpdateTableVersion(char* name, int32 version){
- Query query;
- char* escaped_name = getEscapeString(name);
- query.RunQuery2(Q_UPDATE, "INSERT into table_versions (name, version) values('%s', %u) ON DUPLICATE KEY UPDATE version=%u", escaped_name, version, version);
- if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
- {
- LogWrite(WORLD__ERROR, 0, "Patcher", "Error in updating version table query '%s': %s", query.GetQuery(), query.GetError());
- }
- safe_delete_array(escaped_name);
- }
- bool WorldDatabase::CheckVersionTable() {
- Query query;
- // todo: suppress SQL errors while this command is running, because ERROR is normal on a new DB creation (Zcoretri)
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SHOW COLUMNS FROM table_versions");
- if(result && mysql_num_rows(result) > 0) {
- LogWrite(INIT__PATCHER_DEBUG, 0, "Patcher", "--DB Schema exists! Checking for updates...");
- return true;
- }
- else {
- LogWrite(INIT__PATCHER_ERROR, 0, "Patcher", "Version Table NOT Found! Creating...");
- Query query2;
- query2.RunQuery2(Q_UPDATE, "CREATE TABLE `table_versions` (`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(64) NOT NULL DEFAULT '',`version` INT(10) UNSIGNED NOT NULL DEFAULT '0',`download_version` INT(10) UNSIGNED NOT NULL DEFAULT '0',PRIMARY KEY (`id`),UNIQUE KEY `UniqueName` (`name`)) ENGINE=INNODB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;");
- LogWrite(INIT__PATCHER_DEBUG, 0, "Patcher", "--Setting table_version = 1...");
- Query query3;
- query3.RunQuery2(Q_INSERT, "INSERT INTO table_versions (name, version) VALUES ('table_versions', 1)");
- }
- return false;
- }
- sint32 WorldDatabase::GetLatestDataTableVersion(char* name){
- Query query;
- char* escaped_name = getEscapeString(name);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT download_version FROM table_versions where name='%s'", escaped_name);
- sint32 ret_version = 0;
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- ret_version = atol(row[0]);
- }
- safe_delete_array(escaped_name);
- return ret_version;
- }
- int32 WorldDatabase::GetMaxHotBarID(){
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT max(id) FROM character_skillbar");
- int32 ret = 0;
- if(result && mysql_num_rows(result) > 0) {
- MYSQL_ROW row;
- row = mysql_fetch_row(result);
- if(row && row[0])
- ret = strtoul(row[0], NULL, 0);
- }
- return ret;
- }
- void WorldDatabase::SaveQuickBar(int32 char_id, vector<QuickBarItem*>* quickbar_items){
- vector<QuickBarItem*>::iterator itr;
- QuickBarItem* qbi = 0;
- for(itr = quickbar_items->begin(); itr != quickbar_items->end(); itr++){
- qbi = *itr;
- if(!qbi)
- continue;
- if(qbi->deleted == false){
- Query query;
- if(qbi->text.size > 0){
- query.AddQueryAsync(char_id, this, Q_REPLACE, "replace into character_skillbar (id, hotbar, slot, char_id, spell_id, type, text_val, tier) values(%u, %u, %u, %u, %u, %i, '%s', %i)",
- qbi->unique_id, qbi->hotbar, qbi->slot, char_id, qbi->id, qbi->type, getSafeEscapeString(qbi->text.data.c_str()).c_str(), qbi->tier);
- }
- else{
- query.AddQueryAsync(char_id, this, Q_REPLACE, "replace into character_skillbar (id, hotbar, slot, char_id, spell_id, type, text_val, tier) values(%u, %u, %u, %u, %u, %i, 'Unused', %i)",
- qbi->unique_id, qbi->hotbar, qbi->slot, char_id, qbi->id, qbi->type, qbi->tier);
- }
- }
- else{
- Query query;
- query.AddQueryAsync(char_id, this, Q_DELETE, "delete FROM character_skillbar where hotbar=%u and slot=%u and char_id=%u", qbi->hotbar, qbi->slot, char_id);
- }
- }
- }
- map<int32, vector<LevelArray*> >* WorldDatabase::LoadSpellClasses(){
- map<int32, vector<LevelArray*> >* ret = new map<int32, vector<LevelArray*> >();
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT spell_id, adventure_class_id, tradeskill_class_id, level FROM spell_classes");
- MYSQL_ROW row;
- LevelArray* level = 0;
- while(result && (row = mysql_fetch_row(result))){
- level = new LevelArray();
- level->adventure_class = atoi(row[1]);
- level->tradeskill_class = atoi(row[2]);
- level->spell_level = atoi(row[3]);
- (*ret)[atoul(row[0])].push_back(level);
- }
- return ret;
- }
- void WorldDatabase::LoadTraits(){
- Query query;
- MYSQL_ROW row;
- TraitData* trait;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `spell_id`, `level`, `class_req`, `race_req`, `isTrait`,`isInate`, `isFocusEffect`, `isTraining`,`tier`, `group` FROM spell_traits");
- while (result && (row = mysql_fetch_row(result))){
- trait = new TraitData;
- int8 i = 0;
- trait->spellID = strtoul(row[0], NULL, 0);
- trait->level = atoi(row[(++i)]);
- trait->classReq = atoi(row[(++i)]);
- trait->raceReq = atoi(row[(++i)]);
- trait->isTrait = (atoi(row[(++i)]) == 0) ? false : true;
- trait->isInate = (atoi(row[(++i)]) == 0) ? false : true;
- trait->isFocusEffect = (atoi(row[(++i)]) == 0) ? false : true;
- trait->isTraining = (atoi(row[(++i)]) == 0) ? false : true;
- trait->tier = atoi(row[(++i)]);
- trait->group = atoi(row[(++i)]);
- master_trait_list.AddTrait(trait);
- }
- LogWrite(SPELL__INFO, 0, "Traits", "Loaded %u Trait(s)", master_trait_list.Size());
- }
- void WorldDatabase::LoadSpells()
- {
- DatabaseResult result;
- Spell *spell;
- SpellData *data;
- int32 t_now = Timer::GetUnixTimeStamp();
- int32 total = 0;
- map<int32, vector<LevelArray*> >* level_data = LoadSpellClasses();
- if( !database_new.Select(&result, "SELECT s.`id`, ts.spell_id, ts.index, `name`, `description`, `type`, `class_skill`, `mastery_skill`, `tier`, `is_aa`,`hp_req`, `power_req`,`power_by_level`, `cast_time`, `recast`, `radius`, `max_aoe_targets`, `req_concentration`, `range`, `duration1`, `duration2`, `resistibility`, `hp_upkeep`, `power_upkeep`, `duration_until_cancel`, `target_type`, `recovery`, `power_req_percent`, `hp_req_percent`, `icon`, `icon_heroic_op`, `icon_backdrop`, `success_message`, `fade_message`, `cast_type`, `lua_script`, `call_frequency`, `interruptable`, `spell_visual`, `effect_message`, `min_range`, `can_effect_raid`, `affect_only_group_members`, `hit_bonus`, `display_spell_tier`, `friendly_spell`, `group_spell`, `spell_book_type`, spell_type+0, s.is_active, savagery_req, savagery_req_percent, savagery_upkeep, dissonance_req, dissonance_req_percent, dissonance_upkeep, linked_timer_id, det_type, incurable, control_effect_type, cast_while_moving, casting_flags, persist_through_death, not_maintained, savage_bar, savage_bar_slot, soe_spell_crc "
- "FROM (spells s, spell_tiers st) "
- "LEFT JOIN spell_ts_ability_index ts "
- "ON s.`id` = ts.spell_id "
- "WHERE s.id = st.spell_id AND s.is_active = 1 "
- "ORDER BY s.`id`, `tier`") )
- {
- // error
- }
- else
- {
- while( result.Next() )
- {
- data = new SpellData;
- int32 spell_id = result.GetInt32Str("id");
- string spell_name = result.GetStringStr("name");
- /* General Spell info */
- data->id = spell_id;
- data->soe_spell_crc = result.GetInt32Str("soe_spell_crc");
- data->tier = result.GetInt8Str("tier");
- data->ts_loc_index = result.GetInt8Str("index");
- data->name.data = spell_name.c_str();
- data->name.size = data->name.data.length();
- data->description.data = result.GetStringStr("description");
- data->description.size = data->description.data.length();
- data->icon = result.GetSInt16Str("icon");
- data->icon_heroic_op = result.GetInt16Str("icon_heroic_op");
- data->icon_backdrop = result.GetInt16Str("icon_backdrop");
- data->spell_visual = result.GetInt32Str("spell_visual");
- data->type = result.GetInt16Str("type");
- data->target_type = result.GetInt8Str("target_type");
- data->cast_type = result.GetInt8Str("cast_type");
- data->spell_book_type = result.GetInt32Str("spell_book_type");
- data->det_type = result.GetInt8Str("det_type");
- data->incurable = (result.GetInt8Str("incurable") == 1);
- data->control_effect_type = result.GetInt8Str("control_effect_type");
- data->casting_flags = result.GetInt32Str("casting_flags");
- data->savage_bar = result.GetInt8Str("savage_bar");
- data->savage_bar_slot = result.GetInt8Str("savage_bar_slot");
- data->spell_type = result.IsNullStr("spell_type+0") ? 0 : result.GetInt8Str("spell_type+0");
- /* Toggles */
- data->interruptable = ( result.GetInt8Str("interruptable") == 1);
- data->duration_until_cancel = ( result.GetInt8Str("duration_until_cancel") == 1);
- data->can_effect_raid = result.GetInt8Str("can_effect_raid");
- data->affect_only_group_members = result.GetInt8Str("affect_only_group_members");
- data->display_spell_tier = result.GetInt8Str("display_spell_tier");
- data->friendly_spell = result.GetInt8Str("friendly_spell");
- data->group_spell = result.GetInt8Str("group_spell");
- data->is_active = result.GetInt8Str("is_active");
- data->persist_though_death = ( result.GetInt8Str("persist_through_death") == 1);
- data->cast_while_moving = ( result.GetInt8Str("cast_while_moving") == 1);
- data->not_maintained = ( result.GetInt8Str("not_maintained") == 1);
- data->is_aa = (result.GetInt8Str("is_aa") == 1);
- /* Skill Requirements */
- data->class_skill = result.GetInt32Str("class_skill");
- data->mastery_skill = result.GetInt32Str("mastery_skill");
- // no min_class_skill_req?
- /* Cost */
- data->req_concentration = result.GetInt16Str("req_concentration");
- data->hp_req = result.GetInt16Str("hp_req");
- data->hp_upkeep = result.GetInt16Str("hp_upkeep");
- data->hp_req_percent = result.GetInt8Str("hp_req_percent");
- data->power_req = result.GetFloatStr("power_req");
-
- data->power_by_level = ( result.GetInt8Str("power_by_level") == 0)? false : true;
- data->power_upkeep = result.GetInt16Str("power_upkeep");
- data->power_req_percent = result.GetInt8Str("power_req_percent");
- data->savagery_req = result.GetInt16Str("savagery_req");
- data->savagery_upkeep = result.GetInt16Str("savagery_upkeep");
- data->savagery_req_percent = result.GetInt8Str("savagery_req_percent");
- data->dissonance_req = result.GetInt16Str("dissonance_req");
- data->dissonance_upkeep = result.GetInt16Str("dissonance_upkeep");
- data->dissonance_req_percent = result.GetInt8Str("dissonance_req_percent");
- /* Spell Parameters */
- data->call_frequency = result.GetInt32Str("call_frequency");
- data->cast_time = result.GetInt16Str("cast_time");
- data->duration1 = result.GetInt32Str("duration1");
- data->duration2 = result.GetInt32Str("duration2");
- data->hit_bonus = result.GetFloatStr("hit_bonus");
- data->max_aoe_targets = result.GetInt16Str("max_aoe_targets");
- data->min_range = result.GetFloatStr("min_range");
- data->radius = result.GetFloatStr("radius");
- data->range = result.GetFloatStr("range");
- data->recast = result.GetFloatStr("recast");
- data->recovery = result.GetFloatStr("recovery");
- data->resistibility = result.GetFloatStr("resistibility");
- data->linked_timer = result.GetInt32Str("linked_timer_id");
- /* Cast Messaging */
- string message = result.GetStringStr("success_message");
- if( message.length() > 0 )
- data->success_message = message;
- message = result.GetStringStr("fade_message");
- if( message.length() > 0 )
- data->fade_message = string(message);
- message = result.GetStringStr("effect_message");
- if( message.length() > 0 )
- data->effect_message = string(message);
- string lua_script = result.GetStringStr("lua_script");
- if( lua_script.length() > 0 )
- data->lua_script = string(lua_script);
- /* Load spell level data */
- spell = new Spell(data);
- if(level_data && level_data->count(data->id) > 0)
- {
- vector<LevelArray*>* level_array = &((*level_data)[data->id]);
- for(int8 i=0; i<level_array->size(); i++)
- {
- spell->AddSpellLevel(level_array->at(i)->adventure_class, level_array->at(i)->tradeskill_class, level_array->at(i)->spell_level*10);
- }
- }
- /* Add spell to master list */
- master_spell_list.AddSpell(data->id, data->tier, spell);
- total++;
- if( lua_script.length() > 0 )
- LogWrite(SPELL__DEBUG, 5, "Spells", "\t%i. %s (Tier: %i) - '%s'", spell_id, spell_name.c_str(), data->tier, lua_script.c_str());
- else if(data->is_active)
- LogWrite(SPELL__WARNING, 1, "Spells", "\tSpell %s (%u, Tier: %i) set 'Active', but missing LUAScript", spell_name.c_str(), spell_id, data->tier);
- } // end while
- } // end else
-
- LogWrite(SPELL__DEBUG, 0, "Spells", "Loading Spell Effects...");
- LoadSpellEffects();
- LogWrite(SPELL__DEBUG, 0, "Spells", "Loading Spell LUA Data...");
- LoadSpellLuaData();
-
- if(lua_interface)
- {
- LogWrite(SPELL__DEBUG, 0, "Spells", "Loading Spells Scripts...");
- LoadSpellScriptData();
- }
- if (level_data) {
- map<int32, vector<LevelArray*> >::iterator map_itr;
- vector<LevelArray*>::iterator level_itr;
- for(map_itr = level_data->begin(); map_itr != level_data->end(); map_itr++)
- {
- for(level_itr = map_itr->second.begin(); level_itr != map_itr->second.end(); level_itr++)
- {
- safe_delete(*level_itr);
- }
- }
- }
- safe_delete(level_data);
- LogWrite(SPELL__INFO, 0, "Spells", "Loaded %u Spell%s (took %u seconds)", total, total == 1 ? "" : "s", Timer::GetUnixTimeStamp() - t_now);
- }
- void WorldDatabase::LoadSpellLuaData(){
- Spell *spell;
- Query query;
- MYSQL_ROW row;
- int32 total = 0;
- MYSQL_RES *result = query.RunQuery2(Q_SELECT, "SELECT `spell_id`,`tier`,`value_type`,`value`,`value2`,`dynamic_helper` "
- "FROM `spell_data` "
- "ORDER BY `index_field`");
- while (result && (row = mysql_fetch_row(result))) {
- if ((spell = master_spell_list.GetSpell(atoul(row[0]), atoi(row[1]))) && row[2] && row[3] && row[4] && row[4]) {
- LogWrite(SPELL__DEBUG, 5, "Spells", "\tLoading Spell LUA Data for spell_id: %u", atoul(row[0]));
- if (!strcmp(row[2], "INT"))
- spell->AddSpellLuaDataInt(atoi(row[3]), atoi(row[4]), string(row[5]));
- else if (!strcmp(row[2], "FLOAT"))
- spell->AddSpellLuaDataFloat(atof(row[3]), atof(row[4]),string(row[5]));
- else if (!strcmp(row[2], "BOOL"))
- spell->AddSpellLuaDataBool(!(strncasecmp(row[3], "true", 4)), string(row[5]));
- else if (!strcmp(row[2], "STRING"))
- spell->AddSpellLuaDataString(string(row[3]), string(row[4]), string(row[5]));
- else
- LogWrite(SPELL__ERROR, 0, "Spells", "Invalid Lua Spell data '%s' for Spell ID: %u", row[2], spell->GetSpellID());
- total++;
- }
- }
- LogWrite(SPELL__DEBUG, 0, "Spells", "\tLoaded %i Spell LUA Data entr%s.", total, total == 1 ? "y" : "ies");
- }
- void WorldDatabase::LoadSpellEffects() {
- Spell *spell;
- Query query;
- MYSQL_ROW row;
- int32 total = 0;
- MYSQL_RES *result = query.RunQuery2(Q_SELECT, "SELECT `spell_id`,`tier`,`percentage`,`bullet`,`description` "
- "FROM `spell_display_effects` "
- "ORDER BY `spell_id`,`id` ASC");
- while (result && (row = mysql_fetch_row(result))) {
- if ((spell = master_spell_list.GetSpell(atoul(row[0]), atoi(row[1]))) && row[4]) {
- LogWrite(SPELL__DEBUG, 5, "Spells", "\tLoading Spell Effects for spell_id: %u", atoul(row[0]));
- spell->AddSpellEffect(atoi(row[2]), atoi(row[3]), row[4]);
- total++;
- }
- }
- LogWrite(SPELL__DEBUG, 0, "Spells", "\tLoaded %u Spell Effect%s.", total, total == 1 ? "" : "s");
- }
- int32 WorldDatabase::LoadPlayerSkillbar(Client* client){
- client->GetPlayer()->ClearQuickbarItems();
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, type, spell_id, slot, text_val, hotbar, tier FROM character_skillbar where char_id = %u", client->GetCharacterID());
- MYSQL_ROW row;
- int32 count = 0;
- while(result && (row = mysql_fetch_row(result))){
- count++;
- int8 tier = atoi(row[6]);
- Spell* spell = master_spell_list.GetSpell(atoul(row[2]), tier);
- if(spell)
- client->GetPlayer()->AddQuickbarItem(atoul(row[5]), atoul(row[3]), atoul(row[1]), spell->GetSpellIcon(), spell->GetSpellIconBackdrop(), spell->GetSpellID(), spell->GetSpellTier(), atoul(row[0]), row[4], false);
- else if(atoul(row[1]) == QUICKBAR_MACRO)
- client->GetPlayer()->AddQuickbarItem(atoul(row[5]), atoul(row[3]), atoul(row[1]), client->GetPlayer()->macro_icons[atoul(row[2])], 0xFFFF, atoul(row[2]), 0, atoul(row[0]), row[4], false);
- else
- client->GetPlayer()->AddQuickbarItem(atoul(row[5]), atoul(row[3]), atoul(row[1]), 0, 0, atoul(row[2]), 0, atoul(row[0]), row[4], false);
- }
- return count;
- }
- bool WorldDatabase::DeleteCharacter(int32 account_id, int32 character_id){
- Guild *guild;
- if((guild = guild_list.GetGuild(GetGuildIDByCharacterID(character_id))))
- guild->RemoveGuildMember(character_id);
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM characters WHERE id=%u AND account_id=%u", character_id, account_id);
- if(!query.GetAffectedRows())
- {
- //No error just in case ppl try doing stupid stuff
- return false;
- }
- else{ //successfull, so the character did exist with that character_id and account_id
- // new DB constraints should handle all these deletes, and more... commenting out for now
- /*query.RunQuery2(Q_DELETE, "delete FROM character_details where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM character_factions where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM character_items where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM character_skillbar where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM character_skills where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM character_spells where char_id=%u", character_id);
- query.RunQuery2(Q_DELETE, "delete FROM char_colors where char_id=%u", character_id);*/
- }
- return true;
- }
- void WorldDatabase::DeleteCharacterSpell(int32 character_id, int32 spell_id) {
- if (character_id > 0 && spell_id > 0) {
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM character_spells WHERE char_id=%u AND spell_id=%u", character_id, spell_id);
- }
- }
- bool WorldDatabase::GetItemResultsToClient (Client* client, const char* varSearch, int maxResults) {
- Query query;
- MYSQL_ROW row;
- int results = 0;
- if( maxResults > 10 && client->GetAdminStatus ( ) < 100 )
- maxResults = 10;
- else if( maxResults > 20 )
- maxResults = 20;
- client->Message(CHANNEL_COLOR_YELLOW, "Item Search Results");
- client->Message(CHANNEL_COLOR_YELLOW, "ResultNum) [ItemID] ItemName");
- string itemsearch_query = string("SELECT id, name FROM items where name like '%%%s%%' limit %i");
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, itemsearch_query.c_str(),getSafeEscapeString(varSearch).c_str(),maxResults);
- while(result && (row = mysql_fetch_row(result))){
- results++;
- client->Message(CHANNEL_COLOR_YELLOW, "%i) [%s] %s",results,row[0],row[1]);
- }
- if(results == 0)
- {
- client->Message(CHANNEL_COLOR_YELLOW, "No Items Found.");
- return false;
- }
- client->Message(CHANNEL_COLOR_YELLOW, "%i Items Found.",results);
- return true;
- }
- void WorldDatabase::SaveWorldTime(WorldTime* time){
- Query query;
- query.RunQuery2(Q_REPLACE, "replace into variables (variable_name, variable_value) values('gametime', '%i/%i/%i %i:%i')", time->month, time->day, time->year, time->hour, time->minute);
- }
- void WorldDatabase::SaveBugReport(const char* category, const char* subcategory, const char* causes_crash, const char* reproducible, const char* summary, const char* description, const char* version, const char* player, int32 account_id, const char* spawn_name, int32 spawn_id, int32 zone_id){
- Query query;
- int32 dbVersion = rule_manager.GetGlobalRule(R_World, DatabaseVersion)->GetInt32();
- string bug_report = string("insert into bugs (category, subcategory, causes_crash, reproducible, summary, description, version, player, account_id, spawn_name, spawn_id, zone_id, dbversion, worldversion) values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %u, '%s', %u, %u, %u, '%s')");
- query.RunQuery2(Q_INSERT, bug_report.c_str(), getSafeEscapeString(category).c_str(), getSafeEscapeString(subcategory).c_str(),
- getSafeEscapeString(causes_crash).c_str(), getSafeEscapeString(reproducible).c_str(), getSafeEscapeString(summary).c_str(),
- getSafeEscapeString(description).c_str(), getSafeEscapeString(version).c_str(), getSafeEscapeString(player).c_str(), account_id,
- getSafeEscapeString(spawn_name).c_str(), spawn_id, zone_id, dbVersion, CURRENT_VERSION);
- FixBugReport();
- FixBugReport();
- FixBugReport();
- }
- void WorldDatabase::FixBugReport(){
- Query query;
- string bug_report = string("update bugs set description = REPLACE(description,SUBSTRING(description,INSTR(description,'%'), 3),char(CONV(SUBSTRING(description,INSTR(description,'%')+1, 2), 16, 10))), summary = REPLACE(summary,SUBSTRING(summary,INSTR(summary,'%'), 3),char(CONV(SUBSTRING(summary,INSTR(summary,'%')+1, 2), 16, 10)))");
- query.RunQuery2(bug_report.c_str(), Q_UPDATE);
- }
- int32 WorldDatabase::LoadQuests(){
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `quest_id`, `name`, `type`, `zone`, `level`, `enc_level`, `description`, `lua_script`, `completed_text`, `spawn_id` FROM `quests`");
- Quest* quest = 0;
- char* name = 0;
- char* type = 0;
- char* zone = 0;
- int8 level = 0;
- int8 enc_level = 0;
- char* description = 0;
- char* script = 0;
- int32 total = 0;
- int32 id = 0;
- char* completed_description = 0;
- int32 return_npc_id = 0;
- if(result){
- while(result && (row = mysql_fetch_row(result))){
- id = atoul(row[0]);
- name = row[1];
- type = row[2];
- zone = row[3];
- level = atoul(row[4]);
- enc_level = atoul(row[5]);
- description = row[6];
- script = row[7];
- completed_description = row[8];
- return_npc_id = atoi(row[9]);
- if(lua_interface) {
- quest = lua_interface->LoadQuest(id, name, type, zone, level, description, script);
- }
- if(quest){
- LogWrite(QUEST__DEBUG, 5, "Quests", "\tLoading Quest: '%s' (%u)", name, id);
- LoadQuestDetails(quest);
- string compDescription;
- if (completed_description == NULL)
- {
- compDescription = string("Missing! Notify Developer");
- LogWrite(QUEST__WARNING, 5, "Quests", "\tLoading Quest MISSING completed_text in quests table for: '%s' (%u)", name, id);
- }
- else
- compDescription = string(completed_description);
- quest->SetCompletedDescription(string(compDescription));
- quest->SetQuestReturnNPC(return_npc_id);
- quest->SetEncounterLevel(enc_level);
- total++;
- master_quest_list.AddQuest(id, quest);
- }
- }
- }
- LogWrite(QUEST__DEBUG, 0, "Quest", "\tLoaded %i Quest(s)", total);
- return total;
- }
- void WorldDatabase::LoadQuestDetails(Quest* quest) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `type`, `subtype`, `value`, `faction_id`, `quantity` FROM `quest_details` WHERE `quest_id`=%u", quest->GetQuestID());
- string type;
- string subtype;
- sint64 value;
- int32 faction_id;
- int32 quantity;
- while (result && (row = mysql_fetch_row(result))) {
- type = string(row[0]);
- subtype = string(row[1]);
- value = atoi(row[2]);
- faction_id = atoi(row[3]);
- quantity = atoi(row[4]);
- LogWrite(QUEST__DEBUG, 5, "Quests", "\t- Type: %s, SubType: %s, Val: %u, Faction: %u, Qty: %u", type.c_str(), subtype.c_str(), value, faction_id, quantity);
- if (type == "Prereq") {
- if (subtype == "Class")
- quest->AddPrereqClass(value);
- else if (subtype == "Faction")
- quest->AddPrereqFaction(faction_id, value);
- else if (subtype == "Item") {
- Item* master_item = master_item_list.GetItem(value);
- if (master_item) {
- Item* item = new Item(master_item);
- quest->AddPrereqItem(item);
- }
- }
- else if (subtype == "AdvLevel")
- quest->SetPrereqLevel(value);
- else if (subtype == "Quest")
- quest->AddPrereqQuest(value);
- else if (subtype == "Race")
- quest->AddPrereqRace(value);
- else if (subtype == "TSClass")
- quest->AddPrereqTradeskillClass(value);
- else if (subtype == "TSLevel")
- quest->SetPrereqTSLevel(value);
- else if (subtype == "MaxTSLevel")
- quest->SetPrereqMaxTSLevel(value);
- else if (subtype == "MaxAdvLevel")
- quest->SetPrereqMaxLevel(value);
- }
- else if (type == "Reward") {
- if (subtype == "Item") {
- Item* master_item = master_item_list.GetItem(value);
- if (master_item) {
- Item* item = new Item(master_item);
- item->details.count = quantity;
- quest->AddRewardItem(item);
- }
- }
- else if (subtype == "Selectable") {
- Item* master_item = master_item_list.GetItem(value);
- if (master_item) {
- Item* item = new Item(master_item);
- item->details.count = quantity;
- quest->AddSelectableRewardItem(item);
- }
- }
- else if (subtype == "Coin") {
- int32 copper = 0;
- int32 silver = 0;
- int32 gold = 0;
- int32 plat = 0;
- if (value >= 1000000) {
- plat = value / 1000000;
- value -= 1000000 * plat;
- }
- if (value >= 10000) {
- gold = value / 10000;
- value -= 10000 * gold;
- }
- if (value >= 100) {
- silver = value / 100;
- value -= 100 * silver;
- }
- if (value > 0)
- copper = value;
- quest->AddRewardCoins(copper, silver, gold, plat);
- }
- else if (subtype == "MaxCoin") {
- quest->AddRewardCoinsMax(value);
- }
- else if (subtype == "Faction")
- quest->AddRewardFaction(faction_id, value);
- else if (subtype == "Experience")
- quest->SetRewardXP(value);
- else if (subtype == "TSExperience")
- quest->SetRewardTSXP(value);
- }
- }
- }
- void WorldDatabase::LoadMerchantInformation() {
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "\tClearing Merchant Inventory...");
- world.DeleteMerchantItems();
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "\tLoading Merchant Inventory...");
- LoadMerchantInventory();
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT merchant_id, inventory_id FROM merchants ORDER BY merchant_id");
- int32 total = 0;
- int32 last_merchant_id = 0;
- int32 id = 0;
- MerchantInfo* merchant = 0;
- if(result) {
- while(result && (row = mysql_fetch_row(result))) {
- id = atoul(row[0]);
- LogWrite(MERCHANT__DEBUG, 5, "Merchant", "\tMerchantID: %u, InventoryID: %u", id, atoul(row[1]));
- if(id != last_merchant_id) {
- if(merchant)
- world.AddMerchantInfo(last_merchant_id, merchant);
- merchant = new MerchantInfo;
- last_merchant_id = id;
- total++;
- }
- merchant->inventory_ids.push_back(atoul(row[1]));
- }
- if(merchant)
- world.AddMerchantInfo(last_merchant_id, merchant);
- }
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "\tLoaded %i Merchant List(s)", total);
- }
- void WorldDatabase::LoadMerchantInventory(){
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT inventory_id, item_id, quantity, price_item_id, price_item_qty, price_item2_id, price_item2_qty, price_status, price_coins, price_stationcash FROM merchant_inventory ORDER BY inventory_id");
- int32 total = 0;
- int32 id;
- if(result) {
- while(result && (row = mysql_fetch_row(result))) {
- MerchantItemInfo ItemInfo;
- id = atoul(row[0]);
- ItemInfo.item_id = atoul(row[1]);
- ItemInfo.quantity = atoi(row[2]);
- ItemInfo.price_item_id = atoul(row[3]);
- ItemInfo.price_item_qty = atoi(row[4]);
- ItemInfo.price_item2_id = atoul(row[5]);
- ItemInfo.price_item2_qty = atoi(row[6]);
- ItemInfo.price_status = atoul(row[7]);
- ItemInfo.price_coins = atoul(row[8]);
- ItemInfo.price_stationcash = atoul(row[9]);
- LogWrite(MERCHANT__DEBUG, 5, "Merchant", "\tInventoryID: %u, ItemID: %u, Qty: %u", id, ItemInfo.item_id, ItemInfo.quantity);
- world.AddMerchantItem(id, ItemInfo);
- total++;
- }
- }
- LogWrite(MERCHANT__DEBUG, 0, "Merchant", "\tLoaded %i Merchant Inventory Item(s)", total);
- }
- string WorldDatabase::GetMerchantDescription(int32 merchant_id) {
- Query query;
- MYSQL_ROW row;
- string description;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `description` FROM `merchants` WHERE `merchant_id`=%u", merchant_id);
- if (result && (row = mysql_fetch_row(result)))
- description = string(row[0]);
- return description;
- }
- void WorldDatabase::LoadTransporters(ZoneServer* zone){
- int32 total = 0;
- zone->DeleteGlobalTransporters();
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT transport_id, transport_type, display_name, message, destination_zone_id, destination_x, destination_y, destination_z, destination_heading, trigger_location_zone_id, trigger_location_x, trigger_location_y, trigger_location_z, trigger_radius, cost, id, min_level, max_level, quest_req, quest_step_req, quest_completed, map_x, map_y FROM transporters ORDER BY transport_id");
- if(result){
- while(result && (row = mysql_fetch_row(result))){
- LogWrite(TRANSPORT__DEBUG, 5, "Transport", "---Loading Transporter ID: %u, transport_type: %s", row[0], row[1]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---display_name: %s, message: %s", row[2], row[3]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---destination_zone_id: %s", row[4]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---destination_x: %s, destination_y: %s, destination_z: %s, destination_heading: %s", row[5], row[6], row[7], row[8]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---trigger_location_zone_id: %s", row[9]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---trigger_location_x: %s, trigger_location_y: %s, trigger_location_z: %s", row[10], row[11], row[12], row[13]);
- LogWrite(TRANSPORT__DEBUG, 7, "Transport", "---trigger_radius: %s, cost: %s, id: %s", row[14], row[15]);
- string name = "";
- if(row[2])
- name = string(row[2]);
- string message = "";
- if(row[3])
- message = string(row[3]);
- if(row[1] && strcmp(row[1], "Zone") == 0)
- zone->AddTransporter(atoul(row[0]), TRANSPORT_TYPE_ZONE, name, message, atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), atoi(row[16]), atoi(row[17]), atoul(row[18]), atoi(row[19]), atoul(row[20]), atoul(row[21]), atoul(row[22]));
- else if(row[1] && strcmp(row[1], "Location") == 0)
- zone->AddLocationTransporter(atoul(row[9]), message, atof(row[10]), atof(row[11]), atof(row[12]), atof(row[13]), atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]));
- else
- zone->AddTransporter(atoul(row[0]), TRANSPORT_TYPE_GENERIC, "", message, atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), atoi(row[16]), atoi(row[17]), atoul(row[18]), atoi(row[19]), atoul(row[20]), atoul(row[21]), atoul(row[22]));
- total++;
- }
- }
- LogWrite(TRANSPORT__DEBUG, 0, "Transport", "--Loaded %i Transporter(s)", total);
- LoadTransportMaps(zone);
- }
- void WorldDatabase::LoadFogInit(string zone, PacketStruct* packet)
- {
- LogWrite(WORLD__TRACE, 9, "World", "Enter: %s", __FUNCTION__);
- if(!packet || zone.length() == 0)
- return;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT highest, lowest, zone_name, explored_map_name, unexplored_map_name, bounds1_x, bounds1_z, bounds2_x, bounds2_z, bounds3_x, bounds3_z, bounds4_x, bounds4_z, explored_key, unexplored_key, map_id FROM map_data where zone_name like '%s%%'", getSafeEscapeString(&zone).c_str());
- if(result){
- int count = mysql_num_rows(result);
- int i=0;
- int64 explored_key;
- int64 unexplored_key;
- packet->setArrayLengthByName("num_maps", count);
- while(result && (row = mysql_fetch_row(result))){
- packet->setDataByName("highest_z", atof(row[0]));
- packet->setDataByName("lowest_z", atof(row[1]));
- packet->setDataByName("map_id", atoul(row[15]));
- packet->setArrayDataByName("unknown7", 1600, i);
- packet->setArrayDataByName("unknown8", 1200, i);
- packet->setArrayDataByName("zone_name", row[2], i);
- packet->setArrayDataByName("explored_map_name", row[3], i);
- packet->setArrayDataByName("unexplored_map_name", row[4], i);
- packet->setArrayDataByName("map_bounds1_x", atof(row[5]), i);
- packet->setArrayDataByName("map_bounds1_z", atof(row[6]), i);
- packet->setArrayDataByName("map_bounds2_x", atof(row[7]), i);
- packet->setArrayDataByName("map_bounds2_z", atof(row[8]), i);
- packet->setArrayDataByName("map_bounds3_x", atof(row[9]), i);
- packet->setArrayDataByName("map_bounds3_z", atof(row[10]), i);
- packet->setArrayDataByName("map_bounds4_x", atof(row[11]), i);
- packet->setArrayDataByName("map_bounds4_z", atof(row[12]), i);
- #ifdef WIN32
- explored_key = _strtoui64(row[13], NULL, 10);
- unexplored_key = _strtoui64(row[14], NULL, 10);
- #else
- explored_key = strtoull(row[13], 0, 10);
- unexplored_key = strtoull(row[14], 0, 10);
- #endif
- packet->setArrayDataByName("explored_key", explored_key, i);
- packet->setArrayDataByName("unexplored_key", unexplored_key, i);
- i++;
- }
- }
- LogWrite(WORLD__TRACE, 9, "World", "Exit: %s", __FUNCTION__);
- }
- string WorldDatabase::GetColumnNames(char* name){
- Query query;
- MYSQL_ROW row;
- string columns = "";
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "show columns FROM %s", name);
- if(result && mysql_num_rows(result) > 0){
- int16 i = 0;
- while((row = mysql_fetch_row(result))){
- if(strcmp(row[0], "table_data_version") != 0){
- if(i>0)
- columns.append(",");
- columns.append(row[0]);
- i++;
- }
- }
- }
- columns.append("");
- return columns;
- }
- void WorldDatabase::ToggleCharacterOnline() {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE characters SET is_online = 0;");
- }
- void WorldDatabase::ToggleCharacterOnline(Client* client, int8 toggle) {
- if (client) {
- Query query;
- Player* player = client->GetPlayer();
- //if(!player->CheckPlayerInfo())
- // return;
- if (player)
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Toggling Character %s", toggle ? "ONLINE!" : "OFFLINE!");
- query.RunQuery2(Q_UPDATE, "UPDATE characters SET is_online=%i WHERE id = %u;", toggle, client->GetCharacterID());
- }
- }
- }
- void WorldDatabase::LoadPlayerStatistics(Player* player, int32 char_id) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT stat_id, stat_value, stat_date FROM statistics WHERE char_id=%i", char_id);
- while (result && (row = mysql_fetch_row(result))) {
- int32 stat_id = atoi(row[0]);
- sint32 stat_value = atoi(row[1]);
- int32 stat_date = atoi(row[2]);
- player->AddPlayerStatistic(stat_id, stat_value, stat_date);
- }
- }
- void WorldDatabase::WritePlayerStatistic(Player *player, Statistic* stat) {
- if (player && player->GetCharacterID() > 0 && stat) {
- Query query;
- query.RunQuery2(Q_INSERT, "INSERT INTO statistics (char_id, guild_id, stat_id, stat_value, stat_date) VALUES(%i, %i, %i, %i, %i) ON DUPLICATE KEY UPDATE stat_value = %i, stat_date = %i;",
- player->GetCharacterID(), 0, stat->stat_id, stat->stat_value, stat->stat_date,
- stat->stat_value, stat->stat_date);
- }
- }
- void WorldDatabase::LoadServerStatistics()
- {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT stat_id, stat_value, stat_date FROM statistics WHERE char_id=0 AND guild_id=0");
- while (result && (row = mysql_fetch_row(result))) {
- int32 stat_id = atoi(row[0]);
- sint32 stat_value = atoi(row[1]);
- int32 stat_date = atoi(row[2]);
- world.AddServerStatistic(stat_id, stat_value, stat_date);
- LogWrite(INIT__DEBUG, 5, "Stats", "Loading Stat ID %i, value: %i", stat_id, stat_value);
- }
- }
- void WorldDatabase::WriteServerStatistic(Statistic* stat) {
- if (stat) {
- Query query;
- query.RunQuery2(Q_INSERT, "INSERT INTO statistics (char_id, guild_id, stat_id, stat_value, stat_date) VALUES(0, 0, %i, %i, %i) ON DUPLICATE KEY UPDATE stat_value = %i, stat_date = %i;",
- stat->stat_id, stat->stat_value, stat->stat_date,
- stat->stat_value, stat->stat_date);
- }
- }
- void WorldDatabase::WriteServerStatistic(int32 stat_id, sint32 stat_value) {
- Query query;
- query.RunQuery2(Q_INSERT, "INSERT INTO statistics (char_id, guild_id, stat_id, stat_value, stat_date) VALUES(0, 0, %i, %i, %i) ON DUPLICATE KEY UPDATE stat_value = %i, stat_date = %i;",
- stat_id, stat_value, Timer::GetUnixTimeStamp(),
- stat_value, Timer::GetUnixTimeStamp());
- }
- void WorldDatabase::WriteServerStatisticsNeededQueries() {
- Query query1, query2, query3;
- MYSQL_ROW row1, row2, row3;
- // Number of unique accounts
- MYSQL_RES* result1 = query1.RunQuery2(Q_SELECT, "SELECT COUNT(DISTINCT account_id) FROM characters");
- if (result1 && (row1 = mysql_fetch_row(result1)) && row1[0] != NULL)
- WriteServerStatistic(STAT_SERVER_NUM_ACCOUNTS, atoi(row1[0]));
- else
- WriteServerStatistic(STAT_SERVER_NUM_ACCOUNTS, 0);
- // Number of characters
- MYSQL_RES* result2 = query2.RunQuery2(Q_SELECT, "SELECT COUNT(id) FROM characters");
- if (result2 && (row2 = mysql_fetch_row(result2)) && row2[0] != NULL)
- WriteServerStatistic(STAT_SERVER_NUM_CHARACTERS, atoi(row2[0]));
- else
- WriteServerStatistic(STAT_SERVER_NUM_CHARACTERS, 0);
- // Average character level
- MYSQL_RES* result3 = query3.RunQuery2(Q_SELECT, "SELECT ROUND(AVG(level)) FROM characters");
- if (result3 && (row3 = mysql_fetch_row(result3)) && row3[0] != NULL)
- WriteServerStatistic(STAT_SERVER_AVG_CHAR_LEVEL, atoi(row3[0]));
- else
- WriteServerStatistic(STAT_SERVER_AVG_CHAR_LEVEL, 0);
- }
- map<int32,int32>* WorldDatabase::GetInstanceRemovedSpawns(int32 instance_id, int8 type)
- {
- DatabaseResult result;
- map<int32,int32>* ret = NULL;
- LogWrite(SPAWN__TRACE, 1, "Spawn", "Enter %s", __FUNCTION__);
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Loading removed spawns for instance_id: %u, spawn_type: %i", instance_id, type);
- if( !database_new.Select(&result, "SELECT spawn_location_entry_id, respawn_time FROM instance_spawns_removed WHERE instance_id = %i AND spawn_type = %i", instance_id, type) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in GetInstanceRemovedSpawns() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return ret;
- }
- else
- {
- if( result.GetNumRows() > 0 )
- {
- ret = new map<int32,int32>;
- while( result.Next() )
- {
- int32 spawn_location_entry_id = result.GetInt32Str("spawn_location_entry_id");
- /*
- respawnTime == 0 - never respawn
- respawnTime = 1 - spawn now
- respawnTime > 1 (continue timer)
- */
- int32 respawntime = result.GetInt32Str("respawn_time");
- LogWrite(INSTANCE__DEBUG, 5, "Instance", "Found spawn point: %u, respawn time: %i", spawn_location_entry_id, respawntime);
- ret->insert(make_pair(spawn_location_entry_id, respawntime));
- }
- }
- else
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "No removed spawns found for instance_id: %u, spawn_type: %i", instance_id, type);
- }
- LogWrite(SPAWN__TRACE, 1, "Spawn", "Exit %s", __FUNCTION__);
- return ret;
- }
- bool WorldDatabase::CheckVectorForValue(vector<int32>* vector, int32 value) {
- if ( vector != NULL )
- {
- for(int32 i=0;i<vector->size();i++)
- {
- int32 compare = vector->at(i);
- if ( compare == value )
- return true;
- }
- }
- return false;
- }
- int32 WorldDatabase::CheckSpawnRemoveInfo(map<int32,int32>* inmap, int32 spawn_location_entry_id)
- {
- LogWrite(SPAWN__TRACE, 0, "Spawn", "Enter %s", __FUNCTION__);
- map<int32, int32>::iterator iter;
- if ( inmap != NULL )
- {
- for(iter=inmap->begin();iter!=inmap->end();iter++)
- {
- if ( iter->first == spawn_location_entry_id )
- return (int32)iter->second;
- }
- }
- return 1;
- }
- int32 WorldDatabase::AddCharacterInstance(int32 char_id, int32 instance_id, string zone_name, int8 instance_type, int32 last_success, int32 last_failure, int32 success_lockout, int32 failure_lockout)
- {
- int32 ret = 0;
- if( !database_new.Query("INSERT INTO character_instances (char_id, instance_id, instance_zone_name, instance_type, last_success_timestamp, last_failure_timestamp, success_lockout_time, failure_lockout_time) VALUES (%u, %u, '%s', %i, %u, %u, %u, %u) ", char_id, instance_id, database_new.EscapeStr(zone_name).c_str(), instance_type, last_success, last_failure, success_lockout, failure_lockout) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in AddCharacterInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return 0;
- }
- ret = database_new.LastInsertID();
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Adding character %u to instance: %u", char_id, instance_id);
- //LogWrite(INSTANCE__DEBUG, 1, "Instance", "-- Reenter: %u, Reset: %u, Lockout: %u", grant_reenter_time_left, grant_reset_time_left, lockout_time);
- return ret;
- }
- bool WorldDatabase::UpdateCharacterInstanceTimers(int32 char_id, int32 instance_id, int32 lockout_time, int32 reset_time, int32 reenter_time )
- {
- if ( lockout_time > 0 && reset_time > 0 && reenter_time > 0 )
- database_new.Query("UPDATE character_instances SET lockout_time = %i, grant_reset_time_left = %i, grant_reenter_time_left = %i WHERE char_id = %i AND instance_id = %i", lockout_time, reset_time, reenter_time, char_id, instance_id);
- else if ( lockout_time > 0 && reset_time > 0 )
- database_new.Query("UPDATE character_instances SET lockout_time = %i, grant_reset_time_left = %i WHERE char_id = %i AND instance_id = %i", lockout_time, reset_time, char_id, instance_id);
- else if ( reset_time > 0 && reenter_time > 0 )
- database_new.Query("UPDATE character_instances SET grant_reset_time_left = %i, grant_reenter_time_left = %i WHERE char_id = %i AND instance_id = %i",reset_time, reenter_time, char_id, instance_id);
- else if ( lockout_time > 0 && reenter_time > 0 )
- database_new.Query("UPDATE character_instances SET lockout_time = %i, grant_reenter_time_left = %i WHERE char_id = %i AND instance_id = %i", lockout_time, reenter_time, char_id, instance_id);
- else if ( lockout_time > 0 )
- database_new.Query("UPDATE character_instances SET lockout_time = %i WHERE char_id = %i AND instance_id = %i", lockout_time, char_id, instance_id);
- else if ( reset_time > 0 )
- database_new.Query("UPDATE character_instances SET grant_reset_time_left = %i WHERE char_id = %i AND instance_id = %i", reset_time, char_id, instance_id);
- else if ( reenter_time > 0 )
- database_new.Query("UPDATE character_instances SET grant_reenter_time_left = %i WHERE char_id = %i AND instance_id = %i", reenter_time, char_id, instance_id);
- if( database_new.GetError() )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in UpdateCharacterInstanceTimers() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- else
- {
- if ( database_new.AffectedRows() > 0 )
- {
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Updating instance timers for character %u to instance: %u", char_id, instance_id);
- LogWrite(INSTANCE__DEBUG, 1, "Instance", "-- Reenter: %u, Reset: %u, Lockout: %u", reenter_time, reset_time, lockout_time);
- return true;
- }
- else
- return false;
- }
- }
- bool WorldDatabase::UpdateCharacterInstance(int32 char_id, string zone_name, int32 instance_id, int8 type, int32 timestamp) {
- // type = 1 = success timestamp
- // type = 2 = failure timestamp
- if (instance_id > 0) {
- if (type == 1) {
- database_new.Query("UPDATE character_instances SET instance_id = %u, last_success_timestamp = %u WHERE char_id = %u AND instance_zone_name = '%s'", instance_id, timestamp, char_id, database_new.EscapeStr(zone_name).c_str());
- }
- else if (type == 2) {
- database_new.Query("UPDATE character_instances SET instance_id = %u, last_failure_timestamp = %u WHERE char_id = %u AND instance_zone_name = '%s'", instance_id, timestamp, char_id, database_new.EscapeStr(zone_name).c_str());
- }
- else {
- database_new.Query("UPDATE character_instances SET instance_id = %u WHERE char_id = %u AND instance_zone_name = '%s'", instance_id, char_id, database_new.EscapeStr(zone_name).c_str());
- }
- }
- else {
- if (type == 1) {
- database_new.Query("UPDATE character_instances SET last_success_timestamp = %u WHERE char_id = %u AND instance_zone_name = '%s'", timestamp, char_id, database_new.EscapeStr(zone_name).c_str());
- }
- else if (type == 2) {
- database_new.Query("UPDATE character_instances SET last_failure_timestamp = %u WHERE char_id = %u AND instance_zone_name = '%s'", timestamp, char_id, database_new.EscapeStr(zone_name).c_str());
- }
- }
- if (database_new.GetError()) {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in UpdateCharacterInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- return true;
- }
- bool WorldDatabase::VerifyInstanceID(int32 char_id, int32 instance_id) {
- DatabaseResult result;
- database_new.Select(&result, "SELECT COUNT(id) as num_instances FROM instances WHERE id = %u", instance_id);
- if (result.Next() && result.GetInt32Str("num_instances") == 0) {
- DeleteCharacterFromInstance(char_id, instance_id);
- return false;
- }
- return true;
- }
- bool WorldDatabase::UpdateInstancedSpawnRemoved(int32 spawn_location_entry_id, int32 spawn_type, int32 respawn_time, int32 instance_id )
- {
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Updating removed spawns for instance_id: %u", instance_id);
- LogWrite(INSTANCE__DEBUG, 1, "Instance", "-- Spawn Location Entry ID: %u, Type: %u, Respawn: %u", spawn_location_entry_id, spawn_type, respawn_time);
- if( !database_new.Query("UPDATE instance_spawns_removed SET respawn_time = %i WHERE spawn_location_entry_id = %i AND spawn_type = %i AND instance_id = %i", respawn_time, spawn_location_entry_id, spawn_type, instance_id) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in UpdateInstancedSpawnRemoved() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- if ( database_new.AffectedRows() > 0 )
- {
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Updated removed spawns for instance_id: %u", instance_id);
- return true;
- }
- else
- return false;
- }
- int32 WorldDatabase::CreateNewInstance(int32 zone_id)
- {
- int32 ret = 0;
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Creating new instance for zone: %u ", zone_id);
- if( !database_new.Query("INSERT INTO instances (zone_id) VALUES (%u)", zone_id) )
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in CreateNewInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- else
- ret = database_new.LastInsertID();
- if( ret > 0 )
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Created new instance_id %u for zone: %u ", ret, zone_id);
- return ret;
- }
- int32 WorldDatabase::CreateInstanceSpawnRemoved(int32 spawn_location_entry_id, int32 spawn_type, int32 respawn_time, int32 instance_id )
- {
- int32 ret = 0;
- LogWrite(INSTANCE__DEBUG, 3, "Instance", "Creating new instance spawn removed entries for instance_id: %u ", instance_id);
- LogWrite(INSTANCE__DEBUG, 5, "Instance", "-- Spawn Location Entry ID: %u, Type: %u, Respawn: %u", spawn_location_entry_id, spawn_type, respawn_time);
- if( !database_new.Query("INSERT INTO instance_spawns_removed (spawn_location_entry_id, spawn_type, instance_id, respawn_time) values(%u, %u, %u, %u)", spawn_location_entry_id, spawn_type, instance_id, respawn_time) )
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in CreateInstanceSpawnRemoved() query '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- else
- ret = database_new.LastInsertID();
- // potentially spammy, if it calls for every spawn added. Set to level 3 or 5?
- if( ret > 0 )
- LogWrite(INSTANCE__DEBUG, 5, "Instance", "Created new spawn removed entry: %u for instance_id %u", ret, instance_id);
- return ret;
- }
- bool WorldDatabase::DeleteInstance(int32 instance_id)
- {
- if( !database_new.Query("DELETE FROM instances WHERE id = %u", instance_id) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in DeleteInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
-
- /* JA: should not need this delete with FK/Constraints
- if( !database_new.Query("DELETE FROM instance_spawns_removed WHERE instance_id = %u", instance_id) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in DeleteInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- */
- // Remove the instance from the character_instances table
- database_new.Query("UPDATE `character_instances` SET `instance_id` = 0 WHERE `instance_id` = %u", instance_id);
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Deleted instance_id %u", instance_id);
- return true;
- }
- bool WorldDatabase::DeleteInstanceSpawnRemoved(int32 instance_id, int32 spawn_location_entry_id)
- {
- if( !database_new.Query("DELETE FROM instance_spawns_removed WHERE instance_id = %u AND spawn_location_entry_id = %u", instance_id, spawn_location_entry_id) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in DeleteInstanceSpawnRemoved() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Deleted removed spawn: %u for instance_id %u", spawn_location_entry_id, instance_id);
- return true;
- }
- bool WorldDatabase::DeleteCharacterFromInstance(int32 char_id, int32 instance_id)
- {
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "Delete character %u from instance_id %u.", char_id, instance_id);
- if( !database_new.Query("UPDATE `character_instances` SET `instance_id` = 0 WHERE `instance_id` = %u AND `char_id` = %u", instance_id, char_id) )
- {
- LogWrite(INSTANCE__ERROR, 0, "Instance", "Error in DeleteCharacterFromInstance() '%s': %i", database_new.GetErrorMsg(), database_new.GetError());
- return false;
- }
- if ( database_new.AffectedRows() == 0 ) // didn't find an instance to delete
- {
- LogWrite(INSTANCE__DEBUG, 1, "Instance", "No instance_id %u for character %u to delete.", instance_id, char_id);
- return false;
- }
- else
- {
- // delete entire instance if the last player has left
- DatabaseResult result;
- database_new.Select(&result, "SELECT count(id) as num_instances FROM character_instances where instance_id = %u",instance_id);
- if(result.Next() && result.GetInt32Str("num_instances") == 0)
- {
- LogWrite(INSTANCE__DEBUG, 0, "Instance", "No characters in instance: Delete instance_id %u.", instance_id);
- DeleteInstance(instance_id);
- }
- }
- return true;
- }
- bool WorldDatabase::LoadCharacterInstances(Client* client)
- {
- DatabaseResult result;
- DatabaseResult result2;
- bool addedInstance = false;
- database_new.Select(&result, "SELECT `id`, `instance_id`, `instance_zone_name`, `instance_type`, `last_success_timestamp`, `last_failure_timestamp`, `success_lockout_time`, `failure_lockout_time` FROM `character_instances` WHERE `char_id` = %u", client->GetCharacterID());
- if( result.GetNumRows() > 0 )
- {
- while( result.Next() )
- {
- int32 zone_id = 0;
- int32 instance_id = result.GetInt32Str("instance_id");
- // If `instance_id` is greater then 0 then get the zone id with it, else get the zone id from the zone name
- if (instance_id != 0) {
- if (database_new.Select(&result2, "SELECT `zone_id` FROM `instances` WHERE `id` = %u", instance_id)) {
- if (result2.Next())
- zone_id = result2.GetInt32Str("zone_id");
- }
- }
- if (zone_id == 0)
- zone_id = GetZoneID(result.GetStringStr("instance_zone_name"));
- client->GetPlayer()->GetCharacterInstances()->AddInstance(
- result.GetInt32Str("id"),
- instance_id,
- result.GetInt32Str("last_success_timestamp"),
- result.GetInt32Str("last_failure_timestamp"),
- result.GetInt32Str("success_lockout_time"),
- result.GetInt32Str("failure_lockout_time"),
- zone_id,
- result.GetInt8Str("instance_type"),
- string(result.GetStringStr("instance_zone_name"))
- );
- addedInstance = true;
- }
- }
- return addedInstance;
- }
- void WorldDatabase::UpdateLoginEquipment()
- {
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Updating `character_items` CRC in %s", __FUNCTION__);
- database_new.Query("UPDATE character_items SET login_checksum = CRC32(CRC32(type) + CRC32(slot) + CRC32(item_id)) WHERE `type` = 'EQUIPPED' AND ( slot <= 8 OR slot = 19 )");
- }
- MutexMap<int32, LoginEquipmentUpdate>* WorldDatabase::GetEquipmentUpdates()
- {
- DatabaseResult result;
- MutexMap<int32, LoginEquipmentUpdate>* ret = 0;
- LoginEquipmentUpdate update;
- int32 count = 0;
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Looking for Login Appearance Updates...");
-
- // TODO: Someday store the equipment colors in character_items, for custom colorization of gear (?)
- if( database_new.Select(&result, "SELECT ci.id, ci.char_id, ia.equip_type, ia.red, green, ia.blue, ia.highlight_red, ia.highlight_green, ia.highlight_blue, ci.slot FROM characters c JOIN character_items ci ON c.id = ci.char_id JOIN item_appearances ia ON ci.item_id = ia.item_id WHERE c.deleted = 0 AND ci.type = 'EQUIPPED' AND ( ci.slot <= 8 OR ci.slot = 19 ) AND ci.login_checksum <> CRC32(CRC32(`ci`.`type`) + CRC32(ci.slot) + CRC32(ci.item_id)) ORDER BY ci.char_id, ci.slot") )
- {
- while( result.Next() )
- {
- LogWrite(INIT__LOGIN_DEBUG, 5, "Login", "Found update for char_id %i!", result.GetInt32Str("char_id"));
- if(!ret)
- ret = new MutexMap<int32, LoginEquipmentUpdate>();
- update.world_char_id = result.GetInt32Str("char_id");
- update.equip_type = result.GetInt16Str("equip_type");
- update.red = result.GetInt8Str("red");
- update.green = result.GetInt8Str("green");
- update.blue = result.GetInt8Str("blue");
- update.highlight_red = result.GetInt8Str("highlight_red");
- update.highlight_green = result.GetInt8Str("highlight_green");
- update.highlight_blue = result.GetInt8Str("highlight_blue");
- update.slot = result.GetInt8Str("slot");
- ret->Put(result.GetInt32Str("id"), update);
- count++;
- }
- }
- if(count)
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Found %i Login Appearance Update%s...", count, count == 1 ? "" : "s");
- return ret;
- }
- MutexMap<int32, LoginEquipmentUpdate>* WorldDatabase::GetEquipmentUpdates(int32 char_id)
- {
- DatabaseResult result;
- MutexMap<int32, LoginEquipmentUpdate>* ret = 0;
- LoginEquipmentUpdate update;
- int32 count = 0;
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Looking for Login Appearance Updates for char_id: %u", char_id);
- // TODO: Someday store the equipment colors in character_items, for custom colorization of gear (?)
- if( database_new.Select(&result, "SELECT ci.id, ci.char_id, ia.equip_type, ia.red, green, ia.blue, ia.highlight_red, ia.highlight_green, ia.highlight_blue, ci.slot FROM characters c JOIN character_items ci ON c.id = ci.char_id JOIN item_appearances ia ON ci.item_id = ia.item_id WHERE c.deleted = 0 AND ci.type = 'EQUIPPED' AND ( ci.slot <= 8 OR ci.slot = 19 ) AND ci.login_checksum <> CRC32(CRC32(ci.type) + CRC32(ci.slot) + CRC32(ci.item_id)) AND ci.char_id = %u ORDER BY ci.slot", char_id) )
- {
- while( result.Next() )
- {
- LogWrite(INIT__LOGIN_DEBUG, 5, "Login", "Found update for char_id %i!", result.GetInt32Str("char_id"));
- if(!ret)
- ret = new MutexMap<int32, LoginEquipmentUpdate>();
- update.world_char_id = char_id;
- update.equip_type = result.GetInt16Str("equip_type");
- update.red = result.GetInt8Str("red");
- update.green = result.GetInt8Str("green");
- update.blue = result.GetInt8Str("blue");
- update.highlight_red = result.GetInt8Str("highlight_red");
- update.highlight_green = result.GetInt8Str("highlight_green");
- update.highlight_blue = result.GetInt8Str("highlight_blue");
- update.slot = result.GetInt8Str("slot");
- ret->Put(result.GetInt32Str("id"), update);
- count++;
- }
- }
-
- if(count)
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Found %i Login Appearance Update%s...", count, count == 1 ? "" : "s");
- return ret;
- }
- void WorldDatabase::UpdateLoginZones() {
- Query query;
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Updating `zones` CRC in %s", __FUNCTION__);
- query.RunQuery2("UPDATE zones SET login_checksum = CRC32(CRC32(id) + CRC32(`name`) + CRC32(`file`) + CRC32(description))", Q_UPDATE);
- }
- MutexMap<int32, LoginZoneUpdate>* WorldDatabase::GetZoneUpdates() {
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Looking for Login Zone Updates...");
- MutexMap<int32, LoginZoneUpdate>* ret = 0;
- LoginZoneUpdate update;
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, name, description FROM zones where login_checksum != crc32(crc32(id) + crc32(name) + crc32(file) + crc32(description))");
- while(result && (row = mysql_fetch_row(result))) {
- if(row[0] && row[1]) {
- LogWrite(INIT__LOGIN_DEBUG, 5, "Login", "Found update for zone_id %i!", atoi(row[0]));
- if(!ret)
- ret = new MutexMap<int32, LoginZoneUpdate>();
- update.name = string(row[1]);
- if(row[2])
- update.description = string(row[2]);
- else
- update.description = "";
- ret->Put(atoi(row[0]), update);
- count++;
- }
- }
- if(count)
- LogWrite(INIT__LOGIN_DEBUG, 0, "Login", "Found %i Login Zone Update%s...", count, count == 1 ? "" : "s");
- return ret;
- }
- void WorldDatabase::LoadLocationGrids(ZoneServer* zone) {
- if (zone) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `grid_id`, `name`, `include_y`, `discovery` FROM `locations` WHERE `zone_id`=%u", zone->GetZoneID());
- while (result && (row = mysql_fetch_row(result))) {
- LocationGrid* grid = new LocationGrid;
- grid->id = atoul(row[0]);
- grid->grid_id = atoul(row[1]);
- grid->name = string(row[2]);
- grid->include_y = (atoi(row[3]) == 1);
- grid->discovery = (atoi(row[4]) == 1);
- if (LoadLocationGridLocations(grid))
- zone->AddLocationGrid(grid);
- else
- safe_delete(grid);
- }
- }
- }
- bool WorldDatabase::LoadLocationGridLocations(LocationGrid* grid) {
- bool ret = false;
- if (grid) {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `x`, `y`, `z` FROM `location_details` WHERE `location_id`=%u", grid->id);
- if (result->row_count >= 3) {
- while (result && (row = mysql_fetch_row(result))) {
- Location* location = new Location;
- location->id = atoul(row[0]);
- location->x = atof(row[1]);
- location->y = atof(row[2]);
- location->z = atof(row[3]);
- grid->locations.Add(location);
- }
- ret = true;
- }
- else
- LogWrite(WORLD__ERROR, 0, "World", "Grid '%s' only has %u location(s). A minimum of 3 is needed.", grid->name.c_str(), result->row_count);
- }
- return ret;
- }
- int32 WorldDatabase::CreateLocation(int32 zone_id, int32 grid_id, const char* name, bool include_y) {
- int32 ret = 0;
- if (name && strlen(name) > 0) {
- Query query;
- query.RunQuery2(Q_INSERT, "INSERT INTO `locations` (`zone_id`, `grid_id`, `name`, `include_y`) VALUES (%u, %u, '%s', %u)", zone_id, grid_id, name, include_y == true ? 1 : 0);
- ret = query.GetLastInsertedID();
- }
- return ret;
- }
- bool WorldDatabase::AddLocationPoint(int32 location_id, float x, float y, float z) {
- bool ret = false;
- if (LocationExists(location_id)) {
- Query query;
- query.RunQuery2(Q_INSERT, "INSERT INTO `location_details` (`location_id`, `x`, `y`, `z`) VALUES (%u, %f, %f, %f)", location_id, x, y, z);
- ret = true;
- }
- return ret;
- }
- bool WorldDatabase::DeleteLocation(int32 location_id) {
- bool ret = false;
- if (LocationExists(location_id)) {
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM `locations` WHERE `id`=%u", location_id);
- ret = true;
- }
- return ret;
- }
- bool WorldDatabase::DeleteLocationPoint(int32 location_point_id) {
- Query query;
- query.RunQuery2(Q_DELETE, "DELETE FROM `location_details` WHERE `id`=%u", location_point_id);
- return true;
- }
- void WorldDatabase::ListLocations(Client* client) {
- if (client) {
- Query query;
- MYSQL_ROW row;
- client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Listing all locations:");
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `zone_id`, `grid_id`, `name` FROM `locations`");
- while (result && (row = mysql_fetch_row(result))) {
- int32 id = atoul(row[0]);
- int32 zone_id = atoul(row[1]);
- int32 grid_id = atoul(row[2]);
- const char* name = row[3];
- client->Message(CHANNEL_COLOR_YELLOW, "%u) Zone ID: %u Grid ID:%u Name: '%s'", id, zone_id, grid_id, name);
- }
- }
- }
- void WorldDatabase::ListLocationPoints(Client* client, int32 location_id) {
- if (client) {
- if (LocationExists(location_id)) {
- Query query;
- client->Message(CHANNEL_COLOR_YELLOW, "Listing all points for location ID %u:", location_id);
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id`, `x`, `y`, `z` FROM `location_details` WHERE `location_id`=%u", location_id);
- MYSQL_ROW row;
- while (result && (row = mysql_fetch_row(result))) {
- int32 id = atoul(row[0]);
- float x = atof(row[1]);
- float y = atof(row[2]);
- float z = atof(row[3]);
- client->Message(CHANNEL_COLOR_YELLOW, "%u) (%f, %f, %f)", id, x, y, z);
- }
- }
- else
- client->Message(CHANNEL_COLOR_YELLOW, "A location with ID %u does not exist", location_id);
- }
- }
- bool WorldDatabase::LocationExists(int32 location_id) {
- bool ret = false;
- Query query;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT COUNT(id) FROM `locations` WHERE `id`=%u", location_id);
- MYSQL_ROW row;
- if (result && (row = mysql_fetch_row(result))) {
- if (atoul(row[0]) > 0)
- ret = true;
- }
- return ret;
- }
- bool WorldDatabase::GetTableVersions(vector<TableVersion*>* table_versions) {
- DatabaseResult result;
- TableVersion *table_version;
- bool success;
- //don't treat 1146 (table not found) as an error since the patch server will create it
- database_new.SetIgnoredErrno(1146);
- success = database_new.Select(&result, "SELECT `name`,`version`,`download_version`\n"
- "FROM `table_versions`\n");
-
- database_new.RemoveIgnoredErrno(1146);
- if (!success)
- return false;
- while (result.Next()) {
- table_version = (TableVersion *)malloc(sizeof(*table_version));
- table_version->name_len = (unsigned int)strlcpy(table_version->name, result.GetString(0), sizeof(table_version->name));
- table_version->version = result.GetInt32(1);
- table_version->data_version = result.GetInt32(2);
- table_versions->push_back(table_version);
- }
- return true;
- }
- bool WorldDatabase::QueriesFromFile(const char * file) {
- return database_new.QueriesFromFile(file);
- }
- bool WorldDatabase::CheckBannedIPs(const char* loginIP)
- {
- // til you build the table, all IPs are allowed
- return false;
- }
- void WorldDatabase::LoadTitles(){
- int32 index = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, title, prefix FROM titles");
- if(result && mysql_num_rows(result) > 0){
- Title* title = 0;
- while(result && (row = mysql_fetch_row(result))){
- LogWrite(WORLD__DEBUG, 5, "World", "\tLoading Title '%s' (%u), Prefix: %i, Index: %u", row[1], atoul(row[0]), atoi(row[2]), index);
- title = new Title;
- title->SetID(index);
- title->SetName(row[1]);
- title->SetPrefix(atoi(row[2]));
- master_titles_list.AddTitle(title);
- index++;
- }
- }
- LogWrite(WORLD__DEBUG, 0, "World", "\tLoaded %u Title%s", index, index == 1 ? "" : "s");
- }
- int32 WorldDatabase::LoadCharacterTitles(int32 char_id, Player *player){
- LogWrite(WORLD__DEBUG, 0, "World", "Loading Titles for player '%s'...", player->GetName());
- Query query;
- MYSQL_ROW row;
- int32 index = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT title_id, title, prefix FROM character_titles, titles WHERE character_titles.title_id = titles.id AND character_titles.char_id = %u", char_id);
- if(result && mysql_num_rows(result) > 0){
- while(result && (row = mysql_fetch_row(result))){
- LogWrite(WORLD__DEBUG, 5, "World", "\tLoading Title ID: %u, Title: '%s' Index: %u", atoul(row[0]), row[1], index);
- player->AddTitle(index, row[1], atoi(row[2]));
- index++;
- }
- }
- return index;
- }
- sint16 WorldDatabase::GetCharPrefixIndex(int32 char_id, Player *player){
- LogWrite(PLAYER__DEBUG, 0, "Player", "Getting current title index for player '%s'...", player->GetName());
- Query query;
- MYSQL_ROW row;
- sint16 ret = -1;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT prefix_title FROM character_details WHERE char_id = %u", char_id);
- if(result && mysql_num_rows(result) > 0)
- while(result && (row = mysql_fetch_row(result))){
- ret = atoi(row[0]);
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tPrefix Index: %i", ret);
- }
- return ret;
- }
- sint16 WorldDatabase::GetCharSuffixIndex(int32 char_id, Player *player){
- LogWrite(PLAYER__DEBUG, 0, "Player", "Getting current title index for player '%s'...", player->GetName());
- Query query;
- MYSQL_ROW row;
- sint16 ret = -1;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT suffix_title FROM character_details WHERE char_id = %u", char_id);
- if(result && mysql_num_rows(result) > 0)
- while(result && (row = mysql_fetch_row(result))){
- ret = atoi(row[0]);
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tSuffix Index: %i", ret);
- }
- return ret;
- }
- void WorldDatabase::SaveCharPrefixIndex(sint16 index, int32 char_id, Client *client){
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE character_details SET prefix_title = %i WHERE char_id = %u", index, client->GetCharacterID());
- LogWrite(PLAYER__DEBUG, 0, "Player", "Saving Prefix Index %i for player '%s'...", index, client->GetPlayer()->GetName());
- }
- void WorldDatabase::SaveCharSuffixIndex(sint16 index, int32 char_id, Client *client){
- Query query;
- query.RunQuery2(Q_SELECT, "UPDATE character_details SET suffix_title = %i WHERE char_id = %u", index, client->GetCharacterID());
- LogWrite(PLAYER__DEBUG, 0, "Player", "Saving Suffix Index %i for player '%s'...", index, client->GetPlayer()->GetName());
- }
- void WorldDatabase::LoadLanguages()
- {
- int32 count = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, language FROM languages");
- if(result && mysql_num_rows(result) > 0)
- {
- Language* language = 0;
- while(result && (row = mysql_fetch_row(result)))
- {
- LogWrite(WORLD__DEBUG, 5, "World", "\tLoading language '%s' , ID: %u", row[1], atoul(row[0]));
- language = new Language;
- language->SetID(atoul(row[0]));
- language->SetName(row[1]);
- master_languages_list.AddLanguage(language);
- count++;
- }
- }
- LogWrite(WORLD__DEBUG, 0, "World", "\tLoaded %u Language%s", count, count == 1 ? "" : "s");
- }
- int32 WorldDatabase::LoadCharacterLanguages(int32 char_id, Player *player)
- {
- LogWrite(WORLD__DEBUG, 0, "World", "Loading Languages for player '%s'...", player->GetName());
- Query query;
- MYSQL_ROW row;
- int32 count = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT language_id, language FROM character_languages, languages WHERE character_languages.language_id = languages.id AND character_languages.char_id = %u", char_id);
- if(result && mysql_num_rows(result) > 0)
- {
- while(result && (row = mysql_fetch_row(result)))
- {
- LogWrite(WORLD__DEBUG, 5, "World", "\tLoading Language ID: %u, Language: '%s'", atoul(row[0]), row[1]);
- player->AddLanguage(atoul(row[0]), row[1]);
- count++;
- }
- }
- return count;
- }
- int16 WorldDatabase::GetCharacterCurrentLang(int32 char_id, Player *player)
- {
- LogWrite(PLAYER__DEBUG, 0, "Player", "Getting current language for player '%s'...", player->GetName());
- Query query;
- MYSQL_ROW row;
- int16 ret = 0;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT current_language FROM character_details WHERE char_id = %u", char_id);
- if(result && mysql_num_rows(result) > 0)
- while(result && (row = mysql_fetch_row(result)))
- {
- ret = atoi(row[0]);
- LogWrite(PLAYER__DEBUG, 5, "Player", "\tLanguage ID: %i", ret);
- }
- return ret;
- }
- void WorldDatabase::SaveCharacterCurrentLang(int32 id, int32 char_id, Client *client)
- {
- Query query;
- query.RunQuery2(Q_UPDATE, "UPDATE character_details SET current_language = %i WHERE char_id = %u", id, char_id);
- LogWrite(PLAYER__DEBUG, 3, "Player", "Saving current language ID %i for player '%s'...", id, client->GetPlayer()->GetName());
- }
- void WorldDatabase::SaveCharacterLang(int32 char_id, int32 lang_id) {
- if (!database_new.Query("INSERT INTO character_languages (char_id, language_id) VALUES (%u, %u)", char_id, lang_id))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- }
- // JA - this is not used yet, lots more to consider for storing player history
- void WorldDatabase::LoadCharacterHistory(int32 char_id, Player *player)
- {
- DatabaseResult result;
- // Use -1 on type and subtype to turn the enum into an int and make it a 0 index
- if (!database_new.Select(&result, "SELECT type-1, subtype-1, value, value2, location, event_id, event_date FROM character_history WHERE char_id = %u", char_id)) {
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- int8 type = result.GetInt8(0);
- int8 subtype = result.GetInt8(1);
- HistoryData* hd = new HistoryData;
- hd->Value = result.GetInt32(2);
- hd->Value2 = result.GetInt32(3);
- strcpy(hd->Location, result.GetString(4));
- // skipped event id as use for it has not been determined yet
- hd->EventDate = result.GetInt32(6);
- player->LoadPlayerHistory(type, subtype, hd);
- }
- }
- void WorldDatabase::LoadSpellErrors() {
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `version`, `error_index`, `value` FROM `spell_error_versions`");
- if (result && mysql_num_rows(result) > 0) {
- while ((row = mysql_fetch_row(result))) {
- master_spell_list.AddSpellError(atoi(row[0]), atoi(row[1]), atoi(row[2]));
- }
- }
- }
- void WorldDatabase::SaveCharacterHistory(Player* player, int8 type, int8 subtype, int32 value, int32 value2, char* location, int32 event_date) {
- string str_type;
- string str_subtype;
- switch (type) {
- case HISTORY_TYPE_NONE:
- str_type = "None";
- break;
- case HISTORY_TYPE_DEATH:
- str_type = "Death";
- break;
- case HISTORY_TYPE_DISCOVERY:
- str_type = "Discovery";
- break;
- case HISTORY_TYPE_XP:
- str_type = "XP";
- break;
- default:
- LogWrite(PLAYER__ERROR, 0, "Player", "WorldDatabase::SaveCharacterHistory() - Invalid history type given (%i) with subtype (%i), character history NOT saved.", type, subtype);
- return;
- }
- switch (subtype) {
- case HISTORY_SUBTYPE_NONE:
- str_subtype = "None";
- break;
- case HISTORY_SUBTYPE_ADVENTURE:
- str_subtype = "Adventure";
- break;
- case HISTORY_SUBTYPE_TRADESKILL:
- str_subtype = "Tradeskill";
- break;
- case HISTORY_SUBTYPE_QUEST:
- str_subtype = "Quest";
- break;
- case HISTORY_SUBTYPE_AA:
- str_subtype = "AA";
- break;
- case HISTORY_SUBTYPE_ITEM:
- str_subtype = "Item";
- break;
- case HISTORY_SUBTYPE_LOCATION:
- str_subtype = "Location";
- break;
- default:
- LogWrite(PLAYER__ERROR, 0, "Player", "WorldDatabase::SaveCharacterHistory() - Invalid history sub type given (%i) with type (%i), character history NOT saved.", subtype, type);
- return;
- }
- LogWrite(PLAYER__INFO, 1, "Player", "Saving character history, type = %s (%i) subtype = %s (%i)", (char*)str_type.c_str(), type, (char*)str_subtype.c_str(), subtype);
- Query query;
- query.AddQueryAsync(player->GetCharacterID(), this, Q_REPLACE, "replace into character_history (char_id, type, subtype, value, value2, location, event_date) values (%u, '%s', '%s', %i, %i, '%s', %u)",
- player->GetCharacterID(), str_type.c_str(), str_subtype.c_str(), value, value2, location, event_date);
- }
- void WorldDatabase::LoadTransportMaps(ZoneServer* zone) {
- int32 total = 0;
- LogWrite(TRANSPORT__DEBUG, 0, "Transport", "-Loading Transporter Maps...");
- zone->DeleteTransporterMaps();
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `transport_id`, `map_name` FROM `transport_maps`");
- if(result) {
- while(result && (row = mysql_fetch_row(result))){
- zone->AddTransportMap(atoul(row[0]), string(row[1]));
- total++;
- }
- }
- LogWrite(TRANSPORT__DEBUG, 0, "Transport", "--Loaded %i Transporter Maps", total);
- }
- bool WorldDatabase::LoadSign(ZoneServer* zone, int32 spawn_id) {
- Sign* sign = 0;
- int32 id = 0;
- DatabaseResult result;
- database_new.Select(&result, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_signs ss\n"
- "ON ss.spawn_id = s.id\n"
- "WHERE s.id = %u\n",
- spawn_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- id = result.GetInt32(0);
- sign = new Sign();
- sign->SetDatabaseID(id);
- strcpy(sign->appearance.name, result.GetString(1));
- sign->appearance.model_type = result.GetInt16(2);
- sign->SetSize(result.GetInt16(3));
- sign->appearance.show_command_icon = result.GetInt8(4);
- sign->SetWidgetID(result.GetInt32(5));
- sign->SetWidgetX(result.GetFloat(6));
- sign->SetWidgetY(result.GetFloat(7));
- sign->SetWidgetZ(result.GetFloat(8));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(result.GetInt32(9));
- if(primary_command_list){
- sign->SetPrimaryCommands(primary_command_list);
- sign->primary_command_list_id = result.GetInt32(9);
- }
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(result.GetInt32(10));
- if (secondary_command_list) {
- sign->SetSecondaryCommands(secondary_command_list);
- sign->secondary_command_list_id = result.GetInt32(10);
- }
- sign->appearance.pos.collision_radius = result.GetInt16(11);
- sign->SetSignIcon(result.GetInt8(12));
- if(strncasecmp(result.GetString(13), "Generic", 7) == 0)
- sign->SetSignType(SIGN_TYPE_GENERIC);
- else if(strncasecmp(result.GetString(13), "Zone", 4) == 0)
- sign->SetSignType(SIGN_TYPE_ZONE);
- sign->SetSignTitle(result.GetString(14));
- sign->SetSignDescription(result.GetString(15));
- sign->SetSignDistance(result.GetFloat(16));
- sign->SetSignZoneID(result.GetInt32(17));
- sign->SetSignZoneX(result.GetFloat(18));
- sign->SetSignZoneY(result.GetFloat(19));
- sign->SetSignZoneZ(result.GetFloat(20));
- sign->SetSignZoneHeading(result.GetFloat(21));
- sign->SetIncludeHeading(result.GetInt8(22) == 1);
- sign->SetIncludeLocation(result.GetInt8(23) == 1);
- sign->SetTransporterID(result.GetInt32(24));
- sign->SetSizeOffset(result.GetInt8(25));
- sign->appearance.display_hand_icon = result.GetInt8(26);
- sign->SetVisualState(result.GetInt16(27));
- zone->AddSign(id, sign);
- LogWrite(SIGN__DEBUG, 0, "Sign", "Loaded Sign: '%s' (%u).", sign->appearance.name, spawn_id);
- return true;
- }
- LogWrite(SIGN__DEBUG, 0, "Sign", "Unable to find a sign for spawn id of %u", spawn_id);
- return false;
- }
- bool WorldDatabase::LoadWidget(ZoneServer* zone, int32 spawn_id) {
- Widget* widget = 0;
- int32 id = 0;
- DatabaseResult result;
- database_new.Select(&result, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_widgets sw\n"
- "ON sw.spawn_id = s.id\n"
- "WHERE s.id = %u",
- spawn_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- id = result.GetInt32(0);
- widget = new Widget();
- widget->SetDatabaseID(id);
- strcpy(widget->appearance.name, result.GetString(1));
- widget->appearance.model_type = result.GetInt16(2);
- widget->SetSize(result.GetInt16(3));
- widget->appearance.show_command_icon = result.GetInt8(4);
- widget->SetWidgetID(result.GetInt32(5));
- widget->SetWidgetX(result.GetFloat(6));
- widget->SetWidgetY(result.GetFloat(7));
- widget->SetWidgetZ(result.GetFloat(8));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(result.GetInt32(9));
- if(primary_command_list){
- widget->SetPrimaryCommands(primary_command_list);
- widget->primary_command_list_id = result.GetInt32(9);
- }
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(result.GetInt32(10));
- if (secondary_command_list) {
- widget->SetSecondaryCommands(secondary_command_list);
- widget->secondary_command_list_id = result.GetInt32(10);
- }
- widget->appearance.pos.collision_radius = result.GetInt16(11);
- widget->SetIncludeHeading(result.GetInt8(12) == 1);
- widget->SetIncludeLocation(result.GetInt8(13) == 1);
- widget->SetWidgetIcon(result.GetInt8(14));
- if(strncasecmp(result.GetString(15),"Generic", 7) == 0)
- widget->SetWidgetType(WIDGET_TYPE_GENERIC);
- else if(strncasecmp(result.GetString(15),"Door", 4) == 0)
- widget->SetWidgetType(WIDGET_TYPE_DOOR);
- widget->SetOpenHeading(result.GetFloat(16));
- widget->SetOpenY(result.GetFloat(17));
- widget->SetActionSpawnID(result.GetInt32(18));
- if(!result.IsNull(19) && strlen(result.GetString(19)) > 5)
- widget->SetOpenSound(result.GetString(19));
- if(!result.IsNull(20) && strlen(result.GetString(20)) > 5)
- widget->SetCloseSound(result.GetString(20));
- widget->SetOpenDuration(result.GetInt16(21));
- widget->SetClosedHeading(result.GetFloat(22));
- widget->SetLinkedSpawnID(result.GetInt32(23));
- widget->SetCloseY(result.GetFloat(24));
- widget->SetTransporterID(result.GetInt32(25));
- widget->SetSizeOffset(result.GetInt8(26));
- widget->SetHouseID(result.GetInt32(27));
- widget->SetOpenX(result.GetFloat(28));
- widget->SetOpenZ(result.GetFloat(29));
- widget->SetCloseX(result.GetFloat(30));
- widget->SetCloseZ(result.GetFloat(31));
- widget->appearance.display_hand_icon = result.GetInt8(32);
- zone->AddWidget(id, widget);
- LogWrite(WIDGET__DEBUG, 0, "Widget", "Loaded Widget: '%s' (%u).", widget->appearance.name, spawn_id);
- return true;
- }
- LogWrite(WIDGET__DEBUG, 0, "Widget", "Unable to find a widget for spawn id of %u", spawn_id);
- return false;
- }
- bool WorldDatabase::LoadObject(ZoneServer* zone, int32 spawn_id) {
- Object* object = 0;
- int32 id = 0;
- DatabaseResult result;
- database_new.Select(&result, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_objects so\n"
- "ON so.spawn_id = s.id\n"
- "WHERE s.id = %u",
- spawn_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- id = result.GetInt32(0);
- object = new Object();
- object->SetDatabaseID(id);
- strcpy(object->appearance.name, result.GetString(1));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(result.GetInt32(4));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(result.GetInt32(5));
- if(primary_command_list){
- object->SetPrimaryCommands(primary_command_list);
- object->primary_command_list_id = result.GetInt32(4);
- }
- if(secondary_command_list){
- object->SetSecondaryCommands(secondary_command_list);
- object->secondary_command_list_id = result.GetInt32(5);
- }
- object->appearance.race = result.GetInt8(2);
- object->appearance.model_type = result.GetInt16(3);
- object->appearance.targetable = result.GetInt8(6);
- object->size = result.GetInt16(7);
- object->appearance.display_name = result.GetInt8(8);
- object->appearance.visual_state = result.GetInt16(9);
- object->appearance.attackable = result.GetInt8(10);
- object->appearance.show_level = result.GetInt8(11);
- object->appearance.show_command_icon = result.GetInt8(12);
- object->appearance.display_hand_icon = result.GetInt8(13);
- object->faction_id = result.GetInt32(14);
- object->appearance.pos.collision_radius = result.GetInt16(15);
- object->SetTransporterID(result.GetInt32(16));
- object->SetSizeOffset(result.GetInt8(17));
- object->SetDeviceID(result.GetInt8(18));
- zone->AddObject(id, object);
- LogWrite(OBJECT__DEBUG, 0, "Object", "Loaded Object: '%s' (%u).", object->appearance.name, spawn_id);
- return true;
- }
- LogWrite(OBJECT__DEBUG, 0, "Object", "Unable to find an object for spawn id of %u", spawn_id);
- return false;
- }
- bool WorldDatabase::LoadGroundSpawn(ZoneServer* zone, int32 spawn_id) {
- GroundSpawn* spawn = 0;
- int32 id = 0;
- DatabaseResult result;
- database_new.Select(&result, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.expansion_flag\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_ground sg\n"
- "ON sg.spawn_id = s.id\n"
- "WHERE s.id = %u",
- spawn_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- id = result.GetInt32(0);
- spawn = new GroundSpawn();
- spawn->SetDatabaseID(id);
- strcpy(spawn->appearance.name, result.GetString(1));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(result.GetInt32(4));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(result.GetInt32(5));
- if(primary_command_list){
- spawn->SetPrimaryCommands(primary_command_list);
- spawn->primary_command_list_id = result.GetInt32(4);
- }
- if(secondary_command_list){
- spawn->SetSecondaryCommands(secondary_command_list);
- spawn->secondary_command_list_id = result.GetInt32(5);
- }
- spawn->appearance.race = result.GetInt8(2);
- spawn->appearance.model_type = result.GetInt16(3);
- spawn->appearance.targetable = result.GetInt8(6);
- spawn->size = result.GetInt16(7);
- spawn->appearance.display_name = result.GetInt8(8);
- spawn->appearance.visual_state = result.GetInt16(9);
- spawn->appearance.attackable = result.GetInt8(10);
- spawn->appearance.show_level = result.GetInt8(11);
- spawn->appearance.show_command_icon = result.GetInt8(12);
- spawn->appearance.display_hand_icon = result.GetInt8(13);
- spawn->faction_id = result.GetInt32(14);
- spawn->appearance.pos.collision_radius = result.GetInt16(15);
- spawn->SetNumberHarvests(result.GetInt8(16));
- spawn->SetAttemptsPerHarvest(result.GetInt8(17));
- spawn->SetGroundSpawnEntryID(result.GetInt32(18));
- spawn->SetCollectionSkill(result.GetString(19));
- spawn->SetSizeOffset(result.GetInt8(20));
- zone->AddGroundSpawn(id, spawn);
- if (!zone->GetGroundSpawnEntries(spawn->GetGroundSpawnEntryID()))
- LoadGroundSpawnEntry(zone, spawn->GetGroundSpawnEntryID());
- LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "Loaded Ground Spawn: '%s' (%u).", spawn->appearance.name, spawn_id);
- return true;
- }
- LogWrite(GROUNDSPAWN__DEBUG, 0, "GSpawn", "Unable to find a ground spawn for spawn id of %u", spawn_id);
- return false;
- }
- void WorldDatabase::LoadGroundSpawnItems(ZoneServer* zone, int32 entry_id) {
- DatabaseResult result;
- database_new.Select(&result, "SELECT item_id, is_rare, grid_id\n"
- "FROM groundspawn_items\n"
- "WHERE groundspawn_id = %u",
- entry_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- zone->AddGroundSpawnItem(entry_id, result.GetInt32(0), result.GetInt8(1), result.GetInt32(2));
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn Items: ID: %u\n", entry_id);
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---item: %ul, rare: %i, grid: %ul", result.GetInt32(0), result.GetInt8(1), result.GetInt32(2));
- }
- }
- void WorldDatabase::LoadGroundSpawnEntry(ZoneServer* zone, int32 entry_id) {
- DatabaseResult result;
- database_new.Select(&result, "SELECT min_skill_level, min_adventure_level, bonus_table, harvest1, harvest3, harvest5, harvest_imbue, harvest_rare, harvest10, harvest_coin\n"
- "FROM groundspawns\n"
- "WHERE enabled = 1 AND groundspawn_id = %u",
- entry_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- // this is getting ridonkulous...
- LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn ID: %u\n" \
- "---min_skill_level: %i, min_adventure_level: %i, bonus_table: %i\n" \
- "---harvest1: %.2f, harvest3: %.2f, harvest5: %.2f\n" \
- "---harvest_imbue: %.2f, harvest_rare: %.2f, harvest10: %.2f\n" \
- "---harvest_coin: %u", entry_id, result.GetInt16(0), result.GetInt16(1), result.GetInt8(2), result.GetFloat(3), result.GetFloat(4), result.GetFloat(5), result.GetFloat(6), result.GetFloat(7), result.GetFloat(8), result.GetInt32(9));
- zone->AddGroundSpawnEntry(entry_id, result.GetInt16(0), result.GetInt16(1), result.GetInt8(2), result.GetFloat(3), result.GetFloat(4), result.GetFloat(5), result.GetFloat(6), result.GetFloat(7), result.GetFloat(8), result.GetInt32(9));
- LoadGroundSpawnItems(zone, entry_id);
- }
- }
- bool WorldDatabase::LoadNPC(ZoneServer* zone, int32 spawn_id) {
- NPC* npc = nullptr;
- int32 id = 0;
- DatabaseResult result;
-
- database_new.Select(&result, "SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name\n"
- "FROM spawn s\n"
- "INNER JOIN spawn_npcs npc\n"
- "ON npc.spawn_id = s.id\n"
- "WHERE s.id = %u",
- spawn_id);
- if (result.GetNumRows() > 0 && result.Next()) {
- id = result.GetInt32(0);
- npc = new NPC();
- npc->SetDatabaseID(id);
- strcpy(npc->appearance.name, result.GetString(1));
- vector<EntityCommand*>* primary_command_list = zone->GetEntityCommandList(result.GetInt32(9));
- vector<EntityCommand*>* secondary_command_list = zone->GetEntityCommandList(result.GetInt32(10));
- if(primary_command_list){
- npc->SetPrimaryCommands(primary_command_list);
- npc->primary_command_list_id = result.GetInt32(9);
- }
- if(secondary_command_list){
- npc->SetSecondaryCommands(secondary_command_list);
- npc->secondary_command_list_id = result.GetInt32(10);
- }
- npc->appearance.min_level = result.GetInt8(2);
- npc->appearance.max_level = result.GetInt8(3);
- npc->appearance.level = result.GetInt8(2);
- npc->appearance.encounter_level = result.GetInt8(4);
- npc->appearance.race = result.GetInt8(5);
-
- //npc->appearance.lua_race_id = result.GetInt16(74);
- npc->appearance.model_type = result.GetInt16(6);
- npc->appearance.soga_model_type = result.GetInt16(62);
- npc->appearance.adventure_class = result.GetInt8(7);
- npc->appearance.gender = result.GetInt8(8);
- npc->appearance.display_name = result.GetInt8(11);
- npc->features.hair_type = result.GetInt16(14);
- npc->features.hair_face_type = result.GetInt16(15);
- npc->features.wing_type = result.GetInt16(16);
- npc->features.chest_type = result.GetInt16(17);
- npc->features.legs_type = result.GetInt16(18);
- npc->features.soga_hair_type = result.GetInt16(19);
- npc->features.soga_hair_face_type = result.GetInt16(20);
- npc->appearance.attackable = result.GetInt8(21);
- npc->appearance.show_level = result.GetInt8(22);
- npc->appearance.targetable = result.GetInt8(23);
- npc->appearance.show_command_icon = result.GetInt8(24);
- npc->appearance.display_hand_icon = result.GetInt8(25);
- npc->appearance.hide_hood = result.GetInt8(70);
- npc->appearance.randomize = result.GetInt32(61);
- npc->SetTotalHP(result.GetInt32(26));
- npc->SetTotalPower(result.GetInt32(27));
- npc->SetHP(npc->GetTotalHP());
- npc->SetPower(npc->GetTotalPower());
- if(npc->GetTotalHP() == 0){
- npc->SetTotalHP(15*npc->GetLevel() + 1);
- npc->SetHP(15*npc->GetLevel() + 1);
- }
- if(npc->GetTotalPower() == 0){
- npc->SetTotalPower(15*npc->GetLevel() + 1);
- npc->SetPower(15*npc->GetLevel() + 1);
- }
- npc->size = result.GetInt16(28);
- npc->appearance.pos.collision_radius = result.GetInt16(29);
- npc->appearance.action_state = result.GetInt16(30);
- npc->appearance.visual_state = result.GetInt16(31);
- npc->appearance.mood_state = result.GetInt16(32);
- npc->appearance.emote_state = result.GetInt16(71);
- npc->appearance.pos.state = result.GetInt16(33);
- npc->appearance.activity_status = result.GetInt16(34);
- npc->faction_id = result.GetInt32(35);
- if(!result.IsNull(36)){
- if(strlen(result.GetString(36)) < sizeof(npc->appearance.sub_title))
- strcpy(npc->appearance.sub_title, result.GetString(36));
- else
- strncpy(npc->appearance.sub_title, result.GetString(36), sizeof(npc->appearance.sub_title));
- }
- npc->SetMerchantID(result.GetInt32(37));
- npc->SetMerchantType(result.GetInt8(38));
- npc->SetSizeOffset(result.GetInt8(39));
- npc->SetAttackType(result.GetInt8(40));
- npc->SetAIStrategy(result.GetInt8(41));
- npc->SetPrimarySpellList(result.GetInt32(42));
- npc->SetSecondarySpellList(result.GetInt32(43));
- npc->SetPrimarySkillList(result.GetInt32(44));
- npc->SetSecondarySkillList(result.GetInt32(45));
- npc->SetEquipmentListID(result.GetInt32(46));
- InfoStruct* info = npc->GetInfoStruct();
- info->str_base = result.GetInt16(47);
- info->sta_base = result.GetInt16(48);
- info->wis_base = result.GetInt16(49);
- info->intel_base = result.GetInt16(50);
- info->agi_base = result.GetInt16(51);
- info->heat_base = result.GetInt16(52);
- info->cold_base = result.GetInt16(53);
- info->magic_base = result.GetInt16(54);
- info->mental_base = result.GetInt16(55);
- info->divine_base = result.GetInt16(56);
- info->disease_base = result.GetInt16(57);
- info->poison_base = result.GetInt16(58);
- info->alignment = result.GetInt8(64);
- npc->SetAggroRadius(result.GetFloat(59));
- npc->SetCastPercentage(result.GetInt8(60));
- npc->appearance.heroic_flag = result.GetInt8(63);
- info->elemental_base = result.GetInt16(65);
- info->arcane_base = result.GetInt16(66);
- info->noxious_base = result.GetInt16(67);
- npc->SetTotalSavagery(result.GetInt32(68));
- npc->SetTotalDissonance(result.GetInt32(69));
- npc->SetSavagery(npc->GetTotalSavagery());
- npc->SetDissonance(npc->GetTotalDissonance());
- if(npc->GetTotalSavagery() == 0){
- npc->SetTotalSavagery(15*npc->GetLevel() + 1);
- npc->SetSavagery(15*npc->GetLevel() + 1);
- }
- if(npc->GetTotalDissonance() == 0){
- npc->SetTotalDissonance(15*npc->GetLevel() + 1);
- npc->SetDissonance(15*npc->GetLevel() + 1);
- }
- npc->SetPrefixTitle(result.GetString(72));
- npc->SetSuffixTitle(result.GetString(73));
- npc->SetLastName(result.GetString(74));
- zone->AddNPC(id, npc);
- //skipped spells/skills/equipment as it is all loaded, the following rely on a spawn to load
- LoadAppearance(zone, spawn_id);
- LoadNPCAppearanceEquipmentData(zone, spawn_id);
-
- LogWrite(NPC__DEBUG, 0, "NPC", "Loaded NPC: '%s' (%u).", npc->appearance.name, spawn_id);
- return true;
- }
- LogWrite(NPC__DEBUG, 0, "NPC", "Unable to find a npc for spawn id of %u", spawn_id);
- return false;
- }
- void WorldDatabase::LoadAppearance(ZoneServer* zone, int32 spawn_id) {
- Entity* entity = zone->GetNPC(spawn_id);
- if (!entity)
- return;
- DatabaseResult result, result2;
- map<string, int8> appearance_types;
- map<int32, map<int8, EQ2_Color> > appearance_colors;
- EQ2_Color color;
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- string type;
- database_new.Select(&result2, "SELECT distinct `type`\n"
- "FROM npc_appearance\n"
- "WHERE length(`type`) > 0 AND `spawn_id` = %u",
- spawn_id);
-
- while(result2.Next()) {
- type = string(result2.GetString(0));
- appearance_types[type] = GetAppearanceType(type);
- if(appearance_types[type] == 255)
- LogWrite(WORLD__ERROR, 0, "Appearance", "Unknown appearance type '%s' in LoadAppearances.", type.c_str());
- }
- database_new.Select(&result, "SELECT `type`, `signed_value`, `red`, `green`, `blue`\n"
- "FROM npc_appearance\n"
- "WHERE length(`type`) > 0 AND `spawn_id` = %u",
- spawn_id);
-
- while(result.Next()) {
- if(appearance_types[result.GetString(0)] < APPEARANCE_SOGA_EBT){
- color.red = result.GetInt8(2);
- color.green = result.GetInt8(3);
- color.blue = result.GetInt8(4);
- }
- switch(appearance_types[result.GetString(0)]){
- case APPEARANCE_SOGA_HFHC:{
- entity->features.soga_hair_face_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HTHC:{
- entity->features.soga_hair_type_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HFC:{
- entity->features.soga_hair_face_color = color;
- break;
- }
- case APPEARANCE_SOGA_HTC:{
- entity->features.soga_hair_type_color = color;
- break;
- }
- case APPEARANCE_SOGA_HH:{
- entity->features.soga_hair_highlight_color = color;
- break;
- }
- case APPEARANCE_SOGA_HC1:{
- entity->features.soga_hair_color1 = color;
- break;
- }
- case APPEARANCE_SOGA_HC2:{
- entity->features.soga_hair_color2 = color;
- break;
- }
- case APPEARANCE_SOGA_SC:{
- entity->features.soga_skin_color = color;
- break;
- }
- case APPEARANCE_SOGA_EC:{
- entity->features.soga_eye_color = color;
- break;
- }
- case APPEARANCE_HTHC:{
- entity->features.hair_type_highlight_color = color;
- break;
- }
- case APPEARANCE_HFHC:{
- entity->features.hair_face_highlight_color = color;
- break;
- }
- case APPEARANCE_HTC:{
- entity->features.hair_type_color = color;
- break;
- }
- case APPEARANCE_HFC:{
- entity->features.hair_face_color = color;
- break;
- }
- case APPEARANCE_HH:{
- entity->features.hair_highlight_color = color;
- break;
- }
- case APPEARANCE_HC1:{
- entity->features.hair_color1 = color;
- break;
- }
- case APPEARANCE_HC2:{
- entity->features.hair_color2 = color;
- break;
- }
- case APPEARANCE_WC1:{
- entity->features.wing_color1 = color;
- break;
- }
- case APPEARANCE_WC2:{
- entity->features.wing_color2 = color;
- break;
- }
- case APPEARANCE_SC:{
- entity->features.skin_color = color;
- break;
- }
- case APPEARANCE_EC:{
- entity->features.eye_color = color;
- break;
- }
- case APPEARANCE_SOGA_EBT:{
- for(int i=0;i<3;i++)
- entity->features.soga_eye_brow_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_CHEEKT:{
- for(int i=0;i<3;i++)
- entity->features.soga_cheek_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_NT:{
- for(int i=0;i<3;i++)
- entity->features.soga_nose_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_CHINT:{
- for(int i=0;i<3;i++)
- entity->features.soga_chin_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_LT:{
- for(int i=0;i<3;i++)
- entity->features.soga_lip_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_EART:{
- for(int i=0;i<3;i++)
- entity->features.soga_ear_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SOGA_EYET:{
- for(int i=0;i<3;i++)
- entity->features.soga_eye_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_EBT:{
- for(int i=0;i<3;i++)
- entity->features.eye_brow_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_CHEEKT:{
- for(int i=0;i<3;i++)
- entity->features.cheek_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_NT:{
- for(int i=0;i<3;i++)
- entity->features.nose_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_CHINT:{
- for(int i=0;i<3;i++)
- entity->features.chin_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_EART:{
- for(int i=0;i<3;i++)
- entity->features.ear_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_EYET:{
- for(int i=0;i<3;i++)
- entity->features.eye_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_LT:{
- for(int i=0;i<3;i++)
- entity->features.lip_type[i] = result.GetInt8(2+i);
- break;
- }
- case APPEARANCE_SHIRT:{
- entity->features.shirt_color = color;
- break;
- }
- case APPEARANCE_UCC:{
- break;
- }
- case APPEARANCE_PANTS:{
- entity->features.pants_color = color;
- break;
- }
- case APPEARANCE_ULC:{
- break;
- }
- case APPEARANCE_U9:{
- break;
- }
- case APPEARANCE_BODY_SIZE:{
- entity->features.body_size = color.red;
- break;
- }
- case APPEARANCE_SOGA_WC1:{
- break;
- }
- case APPEARANCE_SOGA_WC2:{
- break;
- }
- case APPEARANCE_SOGA_SHIRT:{
- break;
- }
- case APPEARANCE_SOGA_UCC:{
- break;
- }
- case APPEARANCE_SOGA_PANTS:{
- break;
- }
- case APPEARANCE_SOGA_ULC:{
- break;
- }
- case APPEARANCE_SOGA_U13:{
- break;
- }
- }
- }
- }
- void WorldDatabase::LoadNPCAppearanceEquipmentData(ZoneServer* zone, int32 spawn_id) {
- NPC* npc = zone->GetNPC(spawn_id);
- if(!npc) {
- LogWrite(NPC__ERROR, 0, "NPC", "Unable to get a valid npc (%u) in %s", spawn_id, __FUNCTION__);
- return;
- }
- DatabaseResult result;
- int8 slot = 0;
- if (!database_new.Select(&result, "SELECT slot_id, equip_type, red, green, blue, highlight_red, highlight_green, highlight_blue\n"
- "FROM npc_appearance_equip\n"
- "WHERE spawn_id = %u\n",
- spawn_id))
- {
-
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- slot = result.GetInt8(0);
- if(slot < NUM_SLOTS) {
- npc->equipment.equip_id[slot] = result.GetInt16(1);
- npc->equipment.color[slot].red = result.GetInt8(2);
- npc->equipment.color[slot].green = result.GetInt8(3);
- npc->equipment.color[slot].blue = result.GetInt8(4);
- npc->equipment.highlight[slot].red = result.GetInt8(5);
- npc->equipment.highlight[slot].green = result.GetInt8(6);
- npc->equipment.highlight[slot].blue = result.GetInt8(7);
- }
- }
- }
- void WorldDatabase::SaveCharacterPicture(int32 characterID, int8 type, uchar* picture, int32 picture_size) {
- stringstream ss_hex;
- stringstream ss_query;
- ss_hex.flags(ios::hex);
- for (int32 i = 0; i < picture_size; i++)
- ss_hex << setfill('0') << setw(2) << (int32)picture[i];
- ss_query << "INSERT INTO `character_pictures` (`char_id`, `pic_type`, `picture`) VALUES (" << characterID << ", " << (int32)type << ", '" << ss_hex.str() << "') ON DUPLICATE KEY UPDATE `picture` = '" << ss_hex.str() << "'";
-
- if (!database_new.Query(ss_query.str().c_str()))
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- }
- void WorldDatabase::LoadZoneFlightPaths(ZoneServer* zone) {
- DatabaseResult result;
- int32 total = 0;
- if (!database_new.Select(&result, "SELECT id, speed, flying, early_dismount FROM flight_paths WHERE zone_id = %u", zone->GetZoneID())) {
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- FlightPathInfo* info = new FlightPathInfo;
- int32 id = result.GetInt32(0);
- info->speed = result.GetFloat(1);
- info->flying = result.GetInt8(2) == 1 ? true : false;
- info->dismount = result.GetInt8(3) == 1 ? true : false;
- zone->AddFlightPath(id, info);
- total++;
- }
- LogWrite(ZONE__DEBUG, 0, "Zone", "Loaded %u flight paths for %s", total, zone->GetZoneDescription());
- LoadZoneFlightPathLocations(zone);
- }
- void WorldDatabase::LoadZoneFlightPathLocations(ZoneServer* zone) {
- DatabaseResult result;
- int32 total = 0;
- if (!database_new.Select(&result, "SELECT loc.flight_path, loc.x, loc.y, loc.z FROM flight_paths_locations loc\n"
- "INNER JOIN flight_paths path\n"
- "ON loc.flight_path = path.id\n"
- "WHERE path.zone_id = %u\n"
- "ORDER BY loc.id",
- zone->GetZoneID()))
- {
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- FlightPathLocation* loc = new FlightPathLocation;
- int32 id = result.GetInt32(0);
- loc->X = result.GetFloat(1);
- loc->Y = result.GetFloat(2);
- loc->Z = result.GetFloat(3);
- zone->AddFlightPathLocation(id, loc);
- total++;
- }
- LogWrite(ZONE__DEBUG, 0, "Zone", "Loaded %u flight path locations for %s", total, zone->GetZoneDescription());
- }
- void WorldDatabase::SaveCharacterLUAHistory(Player* player, int32 event_id, int32 value, int32 value2) {
- Query query;
- query.AddQueryAsync(player->GetCharacterID(), this, Q_REPLACE, "REPLACE INTO character_lua_history(char_id, event_id, value, value2) VALUES(% u, % u, % u, % u)", player->GetCharacterID(), event_id, value, value2);
- // if (!database_new.Query("REPLACE INTO character_lua_history (char_id, event_id, value, value2) VALUES (%u, %u, %u, %u)", player->GetCharacterID(), event_id, value, value2))
- // LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- }
- void WorldDatabase::LoadCharacterLUAHistory(int32 char_id, Player* player) {
- DatabaseResult result;
- int32 total = 0;
- if (!database_new.Select(&result, "SELECT event_id, value, value2 FROM character_lua_history WHERE char_id = %u", char_id)) {
- LogWrite(DATABASE__ERROR, 0, "DBNew", "MySQL Error %u: %s", database_new.GetError(), database_new.GetErrorMsg());
- return;
- }
- while (result.Next()) {
- int32 id = result.GetInt32(0);
- LUAHistory* hd = new LUAHistory;
- hd->Value = result.GetInt32(1);
- hd->Value2 = result.GetInt32(2);
- hd->SaveNeeded = false;
- player->LoadLUAHistory(id, hd);
- total++;
- }
- LogWrite(PLAYER__DEBUG, 0, "Player", "Loaded %u LUA history for %s", total, player->GetName());
- }
- void WorldDatabase::FindSpell(Client* client, char* findString)
- {
- DatabaseResult result;
- if (!database_new.Select(&result, "SELECT s.`id`, ts.spell_id, ts.index, `name`, `tier` "
- "FROM (spells s, spell_tiers st) "
- "LEFT JOIN spell_ts_ability_index ts "
- "ON s.`id` = ts.spell_id "
- "WHERE s.id = st.spell_id and s.name like '%%%s%%' AND s.is_active = 1 "
- "ORDER BY s.`id`, `tier` limit 50", findString))
- {
- // error
- }
- else
- {
- client->Message(CHANNEL_COLOR_YELLOW, "SpellID (SpellTier): SpellName for %s", findString);
- while (result.Next())
- {
- int32 spell_id = result.GetInt32Str("id");
- string spell_name = result.GetStringStr("name");
- int8 tier = result.GetInt8Str("tier");
- client->Message(CHANNEL_COLOR_YELLOW, "%i (%i): %s", spell_id, tier, spell_name.c_str());
- }
- client->Message(CHANNEL_COLOR_YELLOW, "End Spell Results for %s", findString);
- }
- }
- void WorldDatabase::LoadChestTraps() {
- chest_trap_list.Clear();
- int32 index = 0;
- Query query;
- MYSQL_ROW row;
- MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, applicable_zone_id, chest_min_difficulty, chest_max_difficulty, spell_id, spell_tier FROM chest_traps");
- if (result && mysql_num_rows(result) > 0) {
- Title* title = 0;
- while (result && (row = mysql_fetch_row(result))) {
- int32 dbid = atoul(row[0]);
- sint32 applicable_zone_id = atoi(row[1]);
- int32 mindifficulty = atoul(row[2]);
- int32 maxdifficulty = atoul(row[3]);
- int32 spellid = atoul(row[4]);
- int32 tier = atoul(row[5]);
- ChestTrap* trap = new ChestTrap(dbid,applicable_zone_id,mindifficulty,maxdifficulty,spellid,tier);
- chest_trap_list.AddChestTrap(trap);
- }
- }
- }
- bool WorldDatabase::CheckExpansionFlags(ZoneServer* zone, int32 spawnXpackFlag)
- {
- if (spawnXpackFlag == 0)
- return true;
- int32 globalXpackFlag = rule_manager.GetGlobalRule(R_Expansion, GlobalExpansionFlag)->GetInt32();
- int32 zoneXpackFlag = zone->GetExpansionFlag();
- // zone expansion flag takes priority
- if (zoneXpackFlag > 0 && (spawnXpackFlag & zoneXpackFlag) == 0)
- return false;
- // zone expansion flag fails, then if global expansion flag set, we see if that bit operand doesn't match, skip mob then
- else if (zoneXpackFlag == 0 && globalXpackFlag > 0 && (spawnXpackFlag & globalXpackFlag) == 0)
- return false;
- return true;
- }
- void WorldDatabase::GetHouseSpawnInstanceData(ZoneServer* zone, Spawn* spawn)
- {
- if (!spawn)
- return;
- if (zone->house_object_database_lookup.count(spawn->GetModelType()) < 1)
- zone->house_object_database_lookup.Put(spawn->GetModelType(), spawn->GetDatabaseID());
- DatabaseResult result;
- database_new.Select(&result, "SELECT pickup_item_id, pickup_unique_item_id\n"
- " FROM spawn_instance_data\n"
- " WHERE spawn_id = %u and spawn_location_id = %u",
- spawn->GetDatabaseID(),spawn->GetSpawnLocationID());
- if (result.GetNumRows() > 0 && result.Next()) {
- spawn->SetPickupItemID(result.GetInt32(0));
- spawn->SetPickupUniqueItemID(result.GetInt32(1));
- if (spawn->GetZone() != nullptr && spawn->GetZone()->zonemap != nullptr && spawn->GetZone()->zonemap->IsMapLoaded())
- {
- int32 newGrid = spawn->GetZone()->Grid->GetGridID(spawn);
- spawn->SetPos(&(spawn->appearance.pos.grid_id), newGrid);
- }
- }
- }
- int32 WorldDatabase::FindHouseInstanceSpawn(Spawn* spawn)
- {
- DatabaseResult result;
- database_new.Select(&result, "SELECT id\n"
- " FROM spawn\n"
- " WHERE model_type = %u and is_instanced_spawn=1 limit 1",
- spawn->GetModelType());
- if (result.GetNumRows() > 0 && result.Next()) {
- return result.GetInt32(0);
- }
- return 0;
- }
|