| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114 |
- // Developers notes
- /* # Coding guideline
- * Add +1 at the end of array declarations to visually account for null bit.
- * Always log first.
- * Always notify discord last.
- * Always wait for other queries to finish before initiating one: "sql_wait(sqlHandle); // Wait for other queries to finish"
- * Delete GVar strings as soon as possible, but at least before the player quits or the gamemode exits, as per: https://forum.sa-mp.com/showthread.php?t=151076
- */
- /* # Style guide
- * GLOBAL_CONSTANT
- * local_variable
- * someFunction
- * SomeClass
- * playerid // Variable storing in-game player ID
- * player_id // Variable storing database player ID
- */
- /* # Adding a discord bot to your guild.
- https://discordapp.com/oauth2/authorize?client_id=%CLIENT_ID%&scope=bot&permissions=3072
- Where %CLEINT_ID% is the client id.
- */
- /* # To do:
- * Add geoiplib, to make connect messages fancier, and add a locate command.
- * Show underscores as spaces and convert spaces in changename input to undescores before regex chack.
- * Vip limit on characters.
- * See why sql_insert_id wont work.
- * Add all ADMIN_ECHO_CHANNEL messages to admin chat. (not the real admin chat)
- * Check if timestamps work (implemented on temp ban), before implementing it more.
- * Normalise database column names.
- * Some SMALLINT fields are using SQL_INTERGER_LEGNTH for size and could be smaller.
- */
- /// Global definitions
- // Colours
- /*
- #define COLOR_GREEN 0x33AA33AA
- #define COLOR_YELLOW 0xFFFF00AA
- #define COLOR_WHITE 0xFFFFFFAA
- #define COLOR_BLUE 0x0000BBAA
- #define COLOR_LIGHTBLUE 0x33CCFFAA
- #define COLOR_ORANGE 0xFF9900AA
- #define COLOR_RED 0xAA3333AA
- #define COLOR_LIME 0x10F441AA
- #define COLOR_NAVY 0x000080AA
- #define COLOR_AQUA 0xF0F8FFAA
- #define COLOR_CRIMSON 0xDC143CAA
- #define COLOR_BISQUE 0xFFE4C4AA
- #define COLOR_BLACK 0x000000AA
- #define COLOR_CHARTREUSE 0x7FFF00AA
- #define COLOR_BROWN 0XA52A2AAA
- #define COLOR_CORAL 0xFF7F50AA
- #define COLOR_GOLD 0xB8860BAA
- #define COLOR_GREENYELLOW 0xADFF2FAA
- #define COLOR_INDIGO 0x4B00B0AA
- #define COLOR_IVORY 0xFFFF82AA
- #define COLOR_LAWNGREEN 0x7CFC00AA
- #define COLOR_SEAGREEN 0x20B2AAAA
- #define COLOR_SEAGREEN 0x2E8B57AA
- #define COLOR_LIMEGREEN 0x32CD32AA //<--- Dark lime
- #define COLOR_MIDNIGHTBLUE 0X191970AA
- #define COLOR_MAROON 0x800000AA
- #define COLOR_OLIVE 0x808000AA
- #define COLOR_ORANGERED 0xFF4500AA
- #define COLOR_PINK 0xFFC0CBAA // - Light light pink
- #define COLOR_SPRINGGREEN 0x00FF7FAA
- #define COLOR_TOMATO 0xFF6347AA // - Tomato >:/ sounds wrong lol... well... :P
- #define COLOR_YELLOWGREEN 0x9ACD32AA //- like military green
- #define COLOR_MEDIUMAQUA 0x83BFBFAA
- #define COLOR_MEDIUMMAGENTA 0x8B008BAA // dark magenta ^^
- */
- #define COLOR_ACTIVEBORDER 0xB4B4B4FF
- #define COLOR_ACTIVECAPTION 0x99B4D1FF
- #define COLOR_ACTIVECAPTIONTEXT 0x000000FF
- #define COLOR_ALICEBLUE 0xF0F8FFFF
- #define COLOR_ANTIQUEWHITE 0xFAEBD7FF
- #define COLOR_APPWORKSPACE 0xABABABFF
- #define COLOR_AQUA 0x00FFFFFF
- #define COLOR_AQUAMARINE 0x7FFFD4FF
- #define COLOR_AZURE 0xF0FFFFFF
- #define COLOR_BEIGE 0xF5F5DCFF
- #define COLOR_BISQUE 0xFFE4C4FF
- #define COLOR_BLACK 0x000000FF
- #define COLOR_BLANCHEDALMOND 0xFFEBCDFF
- #define COLOR_BLUE 0x0000FFFF
- #define COLOR_BLUEVIOLET 0x8A2BE2FF
- #define COLOR_BROWN 0xA52A2AFF
- #define COLOR_BURLYWOOD 0xDEB887FF
- #define COLOR_BUTTONFACE 0xF0F0F0FF
- #define COLOR_BUTTONHIGHLIGHT 0xFFFFFFFF
- #define COLOR_BUTTONSHADOW 0xA0A0A0FF
- #define COLOR_CADETBLUE 0x5F9EA0FF
- #define COLOR_CHARTREUSE 0x7FFF00FF
- #define COLOR_CHOCOLATE 0xD2691EFF
- #define COLOR_CONTROL 0xF0F0F0FF
- #define COLOR_CONTROLDARK 0xA0A0A0FF
- #define COLOR_CONTROLDARKDARK 0x696969FF
- #define COLOR_CONTROLLIGHT 0xE3E3E3FF
- #define COLOR_CONTROLLIGHTLIGHT 0xFFFFFFFF
- #define COLOR_CONTROLTEXT 0x000000FF
- #define COLOR_CORAL 0xFF7F50FF
- #define COLOR_CORNFLOWERBLUE 0x6495EDFF
- #define COLOR_CORNSILK 0xFFF8DCFF
- #define COLOR_CRIMSON 0xDC143CFF
- #define COLOR_CYAN 0x00FFFFFF
- #define COLOR_DARKBLUE 0x00008BFF
- #define COLOR_DARKCYAN 0x008B8BFF
- #define COLOR_DARKGOLDENROD 0xB8860BFF
- #define COLOR_DARKGRAY 0xA9A9A9FF
- #define COLOR_DARKGREEN 0x006400FF
- #define COLOR_DARKKHAKI 0xBDB76BFF
- #define COLOR_DARKMAGENTA 0x8B008BFF
- #define COLOR_DARKOLIVEGREEN 0x556B2FFF
- #define COLOR_DARKORANGE 0xFF8C00FF
- #define COLOR_DARKORCHID 0x9932CCFF
- #define COLOR_DARKRED 0x8B0000FF
- #define COLOR_DARKSALMON 0xE9967AFF
- #define COLOR_DARKSEAGREEN 0x8FBC8BFF
- #define COLOR_DARKSLATEBLUE 0x483D8BFF
- #define COLOR_DARKSLATEGRAY 0x2F4F4FFF
- #define COLOR_DARKTURQUOISE 0x00CED1FF
- #define COLOR_DARKVIOLET 0x9400D3FF
- #define COLOR_DEEPPINK 0xFF1493FF
- #define COLOR_DEEPSKYBLUE 0x00BFFFFF
- #define COLOR_DEFAULT_CHAT 0xFFFFFFFF
- #define COLOR_DESKTOP 0x000000FF
- #define COLOR_DIMGRAY 0x696969FF
- #define COLOR_DODGERBLUE 0x1E90FFFF
- #define COLOR_FIREBRICK 0xB22222FF
- #define COLOR_FLBLUE 0x6495EDAA
- #define COLOR_FLORALWHITE 0xFFFAF0FF
- #define COLOR_FORESTGREEN 0x228B22FF
- #define COLOR_GAINSBORO 0xDCDCDCFF
- #define COLOR_GHOSTWHITE 0xF8F8FFFF
- #define COLOR_GOLD 0xFFD700FF
- #define COLOR_GOLDENROD 0xDAA520FF
- #define COLOR_GRADIENTACTIVECAPTION 0xB9D1EAFF
- #define COLOR_GRADIENTINACTIVECAPTION 0xD7E4F2FF
- #define COLOR_GRAY 0x808080FF
- #define COLOR_GRAYTEXT 0x808080FF
- #define COLOR_GREEN 0x008000FF
- #define COLOR_GREENYELLOW 0xADFF2FFF
- #define COLOR_GREY 0xAFAFAFAA
- #define COLOR_HIGHLIGHT 0x3399FFFF
- #define COLOR_HIGHLIGHTTEXT 0xFFFFFFFF
- #define COLOR_HONEYDEW 0xF0FFF0FF
- #define COLOR_HOTPINK 0xFF69B4FF
- #define COLOR_HOTTRACK 0x0066CCFF
- #define COLOR_INACTIVEBORDER 0xF4F7FCFF
- #define COLOR_INACTIVECAPTION 0xBFCDDBFF
- #define COLOR_INACTIVECAPTIONTEXT 0x434E54FF
- #define COLOR_INDIANRED 0xCD5C5CFF
- #define COLOR_INDIGO 0x4B0082FF
- #define COLOR_INFO 0xFFFFE1FF
- #define COLOR_INFOTEXT 0x000000FF
- #define COLOR_IVORY 0xFFFFF0FF
- #define COLOR_KHAKI 0xF0E68CFF
- #define COLOR_LAVENDER 0xE6E6FAFF
- #define COLOR_LAVENDERBLUSH 0xFFF0F5FF
- #define COLOR_LAWNGREEN 0x7CFC00FF
- #define COLOR_LEMONCHIFFON 0xFFFACDFF
- #define COLOR_LIGHTBLUE 0xADD8E6FF
- #define COLOR_LIGHTCORAL 0xF08080FF
- #define COLOR_LIGHTCYAN 0xE0FFFFFF
- #define COLOR_LIGHTGOLDENRODYELLOW 0xFAFAD2FF
- #define COLOR_LIGHTGRAY 0xD3D3D3FF
- #define COLOR_LIGHTGREEN 0x90EE90FF
- #define COLOR_LIGHTPINK 0xFFB6C1FF
- #define COLOR_LIGHTSALMON 0xFFA07AFF
- #define COLOR_LIGHTSEAGREEN 0x20B2AAFF
- #define COLOR_LIGHTSKYBLUE 0x87CEFAFF
- #define COLOR_LIGHTSLATEGRAY 0x778899FF
- #define COLOR_LIGHTSTEELBLUE 0xB0C4DEFF
- #define COLOR_LIGHTYELLOW 0xFFFFE0FF
- #define COLOR_LIME 0x00FF00FF
- #define COLOR_LIMEGREEN 0x32CD32FF
- #define COLOR_LINEN 0xFAF0E6FF
- #define COLOR_MAGENTA 0xFF00FFFF
- #define COLOR_MAROON 0x800000FF
- #define COLOR_MEDIUMAQUAMARINE 0x66CDAAFF
- #define COLOR_MEDIUMBLUE 0x0000CDFF
- #define COLOR_MEDIUMORCHID 0xBA55D3FF
- #define COLOR_MEDIUMPURPLE 0x9370DBFF
- #define COLOR_MEDIUMSEAGREEN 0x3CB371FF
- #define COLOR_MEDIUMSLATEBLUE 0x7B68EEFF
- #define COLOR_MEDIUMSPRINGGREEN 0x00FA9AFF
- #define COLOR_MEDIUMTURQUOISE 0x48D1CCFF
- #define COLOR_MEDIUMVIOLETRED 0xC71585FF
- #define COLOR_MENU 0xF0F0F0FF
- #define COLOR_MENUBAR 0xF0F0F0FF
- #define COLOR_MENUHIGHLIGHT 0x3399FFFF
- #define COLOR_MENUTEXT 0x000000FF
- #define COLOR_MIDNIGHTBLUE 0x191970FF
- #define COLOR_MINTCREAM 0xF5FFFAFF
- #define COLOR_MISTYROSE 0xFFE4E1FF
- #define COLOR_MOCCASIN 0xFFE4B5FF
- #define COLOR_NAVAJOWHITE 0xFFDEADFF
- #define COLOR_NAVY 0x000080FF
- #define COLOR_OLDLACE 0xFDF5E6FF
- #define COLOR_OLIVE 0x808000FF
- #define COLOR_OLIVEDRAB 0x6B8E23FF
- #define COLOR_ORANGE 0xFFA500FF
- #define COLOR_ORANGERED 0xFF4500FF
- #define COLOR_ORCHID 0xDA70D6FF
- #define COLOR_PALEGOLDENROD 0xEEE8AAFF
- #define COLOR_PALEGREEN 0x98FB98FF
- #define COLOR_PALETURQUOISE 0xAFEEEEFF
- #define COLOR_PALEVIOLETRED 0xDB7093FF
- #define COLOR_PAPAYAWHIP 0xFFEFD5FF
- #define COLOR_PEACHPUFF 0xFFDAB9FF
- #define COLOR_PERU 0xCD853FFF
- #define COLOR_PINK 0xFFC0CBFF
- #define COLOR_PLUM 0xDDA0DDFF
- #define COLOR_POWDERBLUE 0xB0E0E6FF
- #define COLOR_PURPLE 0x800080FF
- #define COLOR_RED 0xFF0000FF
- #define COLOR_ROSYBROWN 0xBC8F8FFF
- #define COLOR_ROYALBLUE 0x4169E1FF
- #define COLOR_SADDLEBROWN 0x8B4513FF
- #define COLOR_SALMON 0xFA8072FF
- #define COLOR_SANDYBROWN 0xF4A460FF
- #define COLOR_SCROLLBAR 0xC8C8C8FF
- #define COLOR_SEAGREEN 0x2E8B57FF
- #define COLOR_SEASHELL 0xFFF5EEFF
- #define COLOR_SIENNA 0xA0522DFF
- #define COLOR_SILVER 0xC0C0C0FF
- #define COLOR_SKYBLUE 0x87CEEBFF
- #define COLOR_SLATEBLUE 0x6A5ACDFF
- #define COLOR_SLATEGRAY 0x708090FF
- #define COLOR_SNOW 0xFFFAFAFF
- #define COLOR_SPRINGGREEN 0x00FF7FFF
- #define COLOR_STEELBLUE 0x4682B4FF
- #define COLOR_TAN 0xD2B48CFF
- #define COLOR_TEAL 0x008080FF
- #define COLOR_THISTLE 0xD8BFD8FF
- #define COLOR_TOMATO 0xFF6347FF
- #define COLOR_TRANSPARENT 0xFFFFFF00
- #define COLOR_TURQUOISE 0x40E0D0FF
- #define COLOR_VIOLET 0xEE82EEFF
- #define COLOR_WHEAT 0xF5DEB3FF
- #define COLOR_WHITE 0xFFFFFFFF
- #define COLOR_WHITESMOKE 0xF5F5F5FF
- #define COLOR_WINDOW 0xFFFFFFFF
- #define COLOR_WINDOWFRAME 0x646464FF
- #define COLOR_WINDOWTEXT 0x000000FF
- #define COLOR_YELLOW 0xFFFF00FF
- #define COLOR_YELLOWGREEN 0x9ACD32FF
- #define COLOR_STEALTH_ORANGE 0xFF880000
- #define COLOR_STEALTH_OLIVE 0x66660000
- #define COLOR_STEALTH_GREEN 0x33DD1100
- #define COLOR_STEALTH_PINK 0xFF22EE00
- #define COLOR_STEALTH_BLUE 0x0077BB00
- // Color groups
- #define COLOR_COMMAND_OUTPUT 0xFFFFFFFF // White
- #define COLOR_NOTICE 0xAFAFAFAA // Grey
- #define COLOR_WARNING 0xFFA500FF // Orange? (Looks more yellow to me)
- #define COLOR_ERROR 0xFF0000FF // Red
- #define COLOR_GLOBAL_CHAT 0xFFFFFFFF // White
- #define COLOR_PM_CHAT 0xFFFF00FF // Yellow
- #define COLOR_VIP_CHAT 0x800080FF // Purple
- #define COLOR_CREW_CHAT 0xFF9900AA // Orange
- #define COLOR_ADMIN_CHAT 0xB8860BAA // Gold
- #define COLOR_POLICE 0x00008BFF //
- #define COLOR_MEDIC 0xFFC0CBAA // Light pink
- #define COLOR_FIRE 0xAA3333AA // Red
- #define COLOR_SHERIFF 0xF5F5DCFF // Beige
- #define COLOR_FBI 0x000080AA // Navy
- #define COLOR_DMV 0xF0F8FFAA // Aqua
- #define COLOR_NEWS 0x808000FF // Olive
- #define EMBED_COLOR_GREY "{838383}"
- #define EMBED_COLOR_RED "{FF0000}"
- #define EMBED_COLOR_WHITE "{FFFFFF}"
- // SQL datatypes
- #define MAX_SQL_INTEGER 10
- #define MAX_SQL_TIMESTAMP 19 // 1999-01-08 04:05:06 [5 + 4 + 2 + 2 +2 + 2 + 2]
- #define MAX_SQL_FLOAT 16
- #define MAX_SQL_HASH 128
- #define MAX_SQL_IP 45
- #define MAX_SQL_REASON 121
- // Log levels
- #define LOGLEVEL_CHAT -2
- #define LOGLEVEL_COMMAND -1
- #define LOGLEVEL_DEBUG 0
- #define LOGLEVEL_INFO 1
- #define LOGLEVEL_NOTICE 2
- #define LOGLEVEL_WARNING 3
- #define LOGLEVEL_ERROR 4
- #define LOGLEVEL_CRITICAL 5
- #define LOGLEVEL_PANIC 6
- // Userlevels
- enum{ // Noted values as comments, for database reference.
- UNREGISTERED_PLAYER, // 0
- REGISTERED_PLAYER, // 1
- REGULAR_PLAYER, // 2 Spent many hours in and around the comunity.
- VIP_PLAYER, // 3 Donated.
- MODERATOR_CREW, // 4
- VETERAN_CREW, // 5 Inactive admins and management that are allowed to keep their rights.
- ADMIN_CREW, // 6
- UNDERCOVER_ADMIN_CREW, // 7
- MANAGEMENT_CREW, // 8
- UNDRECOVER_MANAGEMENT_CREW, // 9
- FOUNDER_PLAYER, // 10
- UNDERCOVER_FOUNDER_PLAYER, // 11
- }
- // Discord channels
- enum{
- ECHO_CHANNEL,
- MAIN_CHANNEL,
- ADMIN_ECHO_CHANNEL,
- ADMIN_CHANNEL,
- MANAGEMENT_CHANNEL,
- }
- // Chats
- enum{
- CHAT_LOCAL, // Has to be 0, else a gVar would have to be created OnJoin, this conserves memory when no chatmode is set (which will be the case most likely)
- CHAT_WHISPER,
- CHAT_LOW,
- CHAT_ACTION,
- CHAT_SHOUT,
- CHAT_OC,
- CHAT_GLOBAL,
- CHAT_CALL,
- CHAT_SMS,
- CHAT_RADIO,
- CHAT_PM,
- CHAT_GANG,
- CHAT_GANG_OC,
- CHAT_FACTION,
- CHAT_FACTION_OC,
- CHAT_VIP,
- CHAT_CREW,
- CHAT_ADMIN,
- CHAT_MANAGEMENT,
- CHAT_UNDERCOVER,
- }
- // Dialogs
- enum{
- DIALOG_CHANGENAME,
- DIALOG_REGISTER,
- DIALOG_ACCOUNT_CREATED,
- DIALOG_LOGIN,
- DIALOG_CHANGE_USERNAME,
- DIALOG_CHARACTERS,
- DIALOG_LOGIN_FAILED,
- DIALOG_DELETE_CHARACTER,
- DIALOG_GOTO,
- DIALOG_GOTO_INTERIOR,
- DIALOG_GOTO_PLAYER,
- DIALOG_GOTO_247,
- DIALOG_GOTO_AVIATION,
- DIALOG_GOTO_AMMUNATION,
- DIALOG_GOTO_BURGLARY,
- DIALOG_GOTO_MISSION,
- DIALOG_GOTO_MISSIONEXT,
- DIALOG_GOTO_MISSIONHOUSE,
- DIALOG_GOTO_MODDING,
- DIALOG_GOTO_POLICE,
- DIALOG_GOTO_HOUSE,
- DIALOG_GOTO_SHOP,
- DIALOG_GOTO_STADIA,
- DIALOG_CREATE_PICKUP,
- DIALOG_CREATE_FACTION_PICKUP,
- DIALOG_DUTY_PD,
- DIALOG_POLICE_SKIN,
- DIALOG_DUTY_MD,
- DIALOG_MEDIC_SKIN,
- DIALOG_DUTY_FD,
- DIALOG_FIRE_SKIN,
- DIALOG_DUTY_SD,
- DIALOG_SHERIFF_SKIN,
- DIALOG_DUTY_FBI,
- DIALOG_FBI_SKIN,
- DIALOG_DUTY_DMV,
- DIALOG_DMV_SKIN,
- DIALOG_DUTY_NEWS,
- DIALOG_NEWS_SKIN,
- }
- // Pickups
- enum{
- PICKUP_FACTION_PD,
- PICKUP_FACTION_MD,
- PICKUP_FACTION_FD,
- PICKUP_FACTION_SD,
- PICKUP_FACTION_FBI,
- PICKUP_FACTION_DMV,
- PICKUP_FACTION_NEWS,
- PICKUP_PORTAL, // MUST be last as it's not in the pickup create dialog
- }
- // Location categories
- enum{
- GOTO_CATEGORY_INTERIOR,
- }
- enum{
- INTERIOR_CATEGORY_247,
- INTERIOR_CATEGORY_AVIATION,
- INTERIOR_CATEGORY_AMMUNATION,
- INTERIOR_CATEGORY_BUGRLARY,
- INTERIOR_CATEGORY_MISSION,
- INTERIOR_CATEGORY_MISSIONEXT,
- INTERIOR_CATEGORY_MISSIONHOUSE,
- INTERIOR_CATEGORY_MODSHOP,
- INTERIOR_CATEGORY_POLICE,
- INTERIOR_CATEGORY_HOUSES,
- INTERIOR_CATEGORY_SHOPS,
- INTERIOR_CATEGORY_STADIA,
- }
- enum{INTERIOR_247_LSHAPED, INTERIOR_247_OBLONG, INTERIOR_247_MEDIUM, INTERIOR_247_MEDIUM_NOEXIT, INTERIOR_247_LONG, INTERIOR_247_SQAURE}
- enum{
- INTERIOR_AVIATION_TICKET,
- INTERIOR_AVIATION_BAGGAGE,
- INTERIOR_AVIATION_SHAMAL,
- INTERIOR_AVIATION_ANDROMADA,
- INTERIOR_AVIATION_LSAIRPORT
- }
- enum{INTERIOR_AMMU_OCEAN, INTERIOR_AMMU_PALOMINO, INTERIOR_AMMU_ANGEL, INTERIOR_AMMU_QUEBRADOS, INTERIOR_AMMU_2STORIES, INTERIOR_AMMU_BOOTH, INTERIOR_AMMU_RANGE}
- enum{
- INTERIOR_BURGRLARY_LARGE,
- INTERIOR_BURGRLARY_MEDIUM,
- INTERIOR_BURGRLARY_SMALL,
- INTERIOR_BURGRLARY_VERYLARGE,
- INTERIOR_BURGRLARY_5,
- INTERIOR_BURGRLARY_6,
- INTERIOR_BURGRLARY_NOBATH,
- }
- enum{
- INTERIOR_MISSION_ATRIUM,
- INTERIOR_MISSION_BIGSMOKE,
- INTERIOR_MISSION_JEFFERSON,
- INTERIOR_MISSION_JIZZY,
- INTERIOR_MISSION_RC,
- INTERIOR_MISSION_WUZI,
- }
- enum{
- INTERIOR_MISSIONEXT_GAS,
- INTERIOR_MISSIONEXT_LIBERTY,
- INTERIOR_MISSIONEXT_SFGARAGE,
- }
- enum{
- INTERIOR_MISSIONHOUSE_DESIRE,
- INTERIOR_MISSIONHOUSE_COLONEL,
- INTERIOR_MISSIONHOUSE_RYDER,
- INTERIOR_MISSIONHOUSE_SWEET,
- INTERIOR_MISSIONHOUSE_CRACK,
- }
- enum{INTERIOR_MOD_LOCO, INTERIOR_MOD_WHEEL, INTERIOR_MOD_TRANSFENDER}
- enum{INTERIOR_PD_LV, INTERIOR_PD_LS, INTERIOR_PD_SF, INTERIOR_PD_BARBARA}
- enum{
- INTERIOR_HOUSE_GOLDEN,
- INTERIOR_HOUSE_HASHBURY,
- INTERIOR_HOUSE_JOHNSON,
- INTERIOR_HOUSE_MADDDOGG,
- INTERIOR_HOUSE_RED,
- INTERIOR_HOUSE_VERDANT,
- INTERIOR_HOUSE_UNUSED,
- }
- enum{
- INTERIOR_SHOP_TATTOO,
- INTERIOR_SHOP_BURGER,
- INTERIOR_SHOP_PIZZA,
- INTERIOR_SHOP_CLUCKIN,
- INTERIOR_SHOP_CALIGULAS,
- INTERIOR_SHOP_CASINO,
- INTERIOR_SHOP_4DRAGONS,
- INTERIOR_SHOP_DONUTS,
- INTERIOR_SHOP_RC,
- INTERIOR_SHOP_PUMP,
- }
- enum{
- INTERIOR_STADIUM_BLOODBOWL,
- INTERIOR_STADIUM_KICKSTART,
- INTERIOR_STADIUM_8TRACK,
- INTERIOR_STADIUM_DIRTBIKE,
- }
- // Factions
- enum{
- FACTION_NONE,
- FACTION_POLICE,
- FACTION_MEDIC,
- FACTION_FIRE,
- FACTION_SHERIFF,
- FACTION_FBI,
- FACTION_DMV,
- FACTION_NEWS,
- }
- // Jobs
- enum{
- JOB_NONE,
- JOB_POLICE,
- JOB_MEDIC,
- JOB_FIRE,
- JOB_SHERIFF,
- JOB_FBI,
- JOB_DMV,
- JOB_NEWS,
- }
- // Environment settings TODO: THESE SHOULD ALL BE READ FROM A CONFIG FILE!
- static bool:scriptDebug = true; // Debug setting
- #define MODE_NAME "0.0a Build 9"
- #define SERVER_NAME "Bone County RPG"
- #define PG_HOST "127.0.0.1"
- #define PG_ROLE "rpfw-dev"
- #define PG_PASS "nJd&1k$0fs"
- #define PG_DB "rpfw-dev"
- #define PG_PORT 5432
- #define DISCORD_HOME_GUILD_ID "666077037470941184" // Emerald City Roleplay
- #define DISCORD_ECHO_CHANNEL_ID "677855051166777344" // #bcrp-echo
- //#define DISCORD_ECHO_CHANNEL_ID "666078187079598080" // #ecrp-echo
- #define DISCORD_MAIN_CHANNEL_ID "677855315898793984" // #bcrp
- //#define DISCORD_MAIN_CHANNEL_ID "667396220402270228" // #development
- #define DISCORD_ADMIN_ECHO_CHANNEL_ID "672841892169383936" // #admin-echo
- #define DISCORD_ADMIN_CHANNEL_ID "667396026058932236" // #admins
- #define DISCORD_MANAGEMENT_CHANNEL_ID "666091376240361492" // #management
- // Game-mode limits
- #define MAX_CHARACTERS_PER_USER 20 // Maximum of MAX_CHARACTERS_PER_USER_DIGITS digits (Due to SQL query string length)
- #define MAX_CHARACTERS_PER_USER_DIGITS 3
- // SQL plugin
- new SQL:sqlHandle;
- // discord-connector
- //static DCC_Guild:homeGuild; // Discord guild controlled by game community.
- static DCC_Channel:echoChannel; // Public echo channel.
- static DCC_Channel:mainChannel; // Channel for communirty notifications.
- static DCC_Channel:adminEchoChannel; // Admin echo channel.
- static DCC_Channel:adminChannel; // Channel for admin notifications.
- static DCC_Channel:managementChannel; // Channel for management notifications.
- DiscordEcho(const message[], messageLevel){ // Write to echo channels.
- switch(messageLevel) // Output facilities.
- {
- case ECHO_CHANNEL: { // Public echo message
- DiscordSendChannelMessage(echoChannel, message);
- DiscordSendChannelMessage(adminEchoChannel, message); // Also send to admin echo channel, so admin can see everything in one channel without needing to constantly switch. Also handy as log on conflicts/complaints.
- }
- case MAIN_CHANNEL: {DiscordSendChannelMessage(mainChannel, message);} // Public notification
- case ADMIN_ECHO_CHANNEL: {DiscordSendChannelMessage(adminEchoChannel, message);} // Admin echo message
- case ADMIN_CHANNEL: {DiscordSendChannelMessage(adminChannel, message);} // Admin notification
- case MANAGEMENT_CHANNEL: {DiscordSendChannelMessage(managementChannel, message);} // Management notification
- }
- return 0;
- }
- // Natives
- native WP_Hash(buffer[], len, const str[]); // https://forum.sa-mp.com/showthread.php?t=570945
- //native Float:loadavg(); // https://forum.sa-mp.com/showthread.php?t=260206 LINUX ONLY
- // Includes
- #include <a_samp> // https://sa-mp.com
- #include <sql> // https://github.com/udan11/samp-plugin-sql (Fastest player in town and only one supporting postgreSQL) | Examples: https://pastebin.com/67y2nq2n https://github.com/udan11/samp-plugin-sql/issues/10
- #include <sscanf2> // Newest version: https://github.com/maddinat0r/sscanf/releases | Better readme: https://github.com/Y-Less/sscanf
- #include <strlib> // https://github.com/oscar-broman/strlib
- #include <Pawn.Regex> // https://github.com/urShadow/Pawn.Regex
- #include <Pawn.CMD> // https://github.com/urShadow/Pawn.CMD (Fastest player in town)
- #include <gvar> // https://github.com/samp-incognito/samp-gvar-plugin
- #include <discord-connector> // https://github.com/maddinat0r/samp-discord-connector (Only player in town)
- #include <streamer> // https://github.com/samp-incognisto/samp-streamer-plugin
- /// Middle-ware
- // Logging
- logger(const log_level, const message[]){ // Write to logging facility
- // Do not log commands or debug when script debugging is turned off.
- if(scriptDebug == false){ // Debug is off
- if(log_level == LOGLEVEL_COMMAND || log_level == LOGLEVEL_DEBUG){ // Command or debug message
- return 0; // Stop and do not log
- }
- }
-
- // Messagelevel tag
- new human_readable_log_level[8 + 1];
- switch(log_level){ // Assign log level.
- case LOGLEVEL_CHAT: human_readable_log_level = "chat";
- case LOGLEVEL_COMMAND: human_readable_log_level = "command";
- case LOGLEVEL_DEBUG: human_readable_log_level = "debug";
- case LOGLEVEL_INFO: human_readable_log_level = "info";
- case LOGLEVEL_NOTICE: human_readable_log_level = "notice";
- case LOGLEVEL_WARNING: human_readable_log_level = "warning";
- case LOGLEVEL_ERROR: human_readable_log_level = "error";
- case LOGLEVEL_CRITICAL: human_readable_log_level = "critical";
- case LOGLEVEL_PANIC: human_readable_log_level = "panic";
- }
-
- printf("[%s] %s", human_readable_log_level, message); // Print to STDOUT.
- return 0;
- }
- /*// SQL plugin (BROKEN, look at it again after I have more then a week of experience)
- //forward sqlQuery(SQL:handle, query[]);
- //public sqlQuery(SQL:handle, query[]){
- sqlQuery(SQL:handle, query[]){
- //sql_wait(handle); // Wait for all queries to finish.
- new Result:result = sql_query(handle, query);
- if(sql_error(result)){printf("SQL error");} // Did not work during a test with a faulty statement.
- return result;
- }*/
- // discord-connector
- DiscordSendChannelMessage(DCC_Channel:channel, const message[]){
- if(scriptDebug){ // Log middle-ware event in debugging mode only
- new channel_name[100 + 1]; // Default value from tutorial
- DCC_GetChannelName(channel, channel_name);
- new logMessage[26 + 100 + 2000 + 1]; // Discord max message length = 2000
- format(logMessage, sizeof(logMessage), "Send to discord channel %s: %s", channel_name, message);
- logger(LOGLEVEL_DEBUG, logMessage); // Actually log the message
- }
- DCC_SendChannelMessage(channel, message); // Call discord-connector DISABLE THIS TO STOP ALL OUTGOING DISCORD MESSAGES
- }
- /// Game-mode
- // Account functions
- forward changeName(playerid, const name[]);
- public changeName(playerid, const name[]){ // Check if name is valid and force change if needed.
- // Prevent regex error when comparing against null
- if(isempty(name)){ // No name entered
- ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "You must enter a name.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
-
- return 0;
- }
-
- // Check name
- new Regex:r = Regex_New("^[A-Z][a-z]{1,}([A-Z][a-z]{1,})?(_([A-Z][a-z]{1,}([A-Z][a-z]{1,})?|[A-Z]\\.(_[A-Z]\\.)?))?_[A-Z][a-z]{1,}([A-Z][a-z]{1,})?$"); // Regex name filter
- new isValidName = Regex_Check(name, r); // Validate name to filter
- Regex_Delete(r);
- if(!isValidName){ // Invalid role-play name
- ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Please pick a realistic name, separate first and last name with an underscore.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
- }
- else { // Valid role-play name
- // Check for name in use
- /*new escaped_name[MAX_PLAYER_NAME + 1]; // TODO should be more, to account for escape characters.
- sql_escape_string(sqlHandle, name, escaped_name, sizeof(escaped_name)); // Escape player name BROKEN argument type mismatch on argument 2, but name is a sting...*/
- new character_query[40 + MAX_PLAYER_NAME + 1], Result:character_result = sql_query(sqlHandle, character_query);
- format(character_query, sizeof(character_query), "SELECT id FROM character WHERE name = '%s'", name);
-
- if(sql_num_rows(character_result) > 0){ // Name taken
- ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Name already taken. Please pick an original name.", "Change", ""); // Force RP name.
- }
- else{ // Name free
- // Notify all players
- new message[11 + 4 + MAX_PLAYER_NAME + 1];
- format(message, sizeof(message), "* [%i] %s joined.", playerid, getCharacterName(playerid));
- SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players
- DiscordEcho(message, ECHO_CHANNEL); // Notify discord public echo
-
- new client_connect_username[MAX_PLAYER_NAME + 1], admin_message[38 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
- if(GetPlayerState(playerid) == PLAYER_STATE_NONE){ // Not spawned: character creation (Creating a character without registering)
- // Notify admins
-
- format(admin_message, sizeof(admin_message), "* [%i] %s temporary charcter, created by: %s", playerid, getCharacterName(playerid), client_connect_username);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- // Do nothing let continue to spawn, after spawn character will be saved to database.
- }
- else{ // Spawnedplayer: Creating permanent or renaming an existing permanent character
- // Notify admins
- format(admin_message, sizeof(admin_message), "* [%i] %s created by: %s", playerid, getCharacterName(playerid), client_connect_username);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
-
- // Send to skin selection
- ForceClassSelection(playerid);
- TogglePlayerSpectating(playerid, true);
- TogglePlayerSpectating(playerid, false);
- }
-
- // Change name (No way yet to change name ingame)
- /*if(GetGVarInt("userlevel", playerid) > 1){ // Registered player.
- // Get username
- new username[MAX_PLAYER_NAME + 1], message[75 + MAX_PLAYER_NAME + 1];
- GetGVarString("username", username, sizeof(username), playerid);
- // Update or create character name in database
- new callback[1];
- new Result:result;
- new query[51 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
- format(query, sizeof(query), "UPDATE \"user\"(name) VALUES('%s') WHERE username == '%s'", name, username);
- sql_wait(sqlHandle); // Wait for other queries to finish
- result = sql_query(sqlHandle, query, callback = "", "r");
-
- // Inform user
- format(message, sizeof(message), "SERVER: Your username remains unchanged, next time connect as: %s", client_connect_username);
- SendClientMessage(playerid, COLOR_WHITE, message);
- }*/
- SetPlayerName(playerid, name); // Change name in-game
- }
- }
-
- return 0;
- }
- forward register(playerid);
- public register(playerid){ // Register player in database
- if(GetPlayerState(playerid) == PLAYER_STATE_NONE){ // Not spawned
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "ERROR: You need to have spawned to register.");
- }
- else{ // Spawned player
- if(GetGVarInt("userlevel", playerid) != UNREGISTERED_PLAYER){ // Registered player.
- new message[35 + MAX_PLAYER_NAME + 1];
- format(message, sizeof(message), "ERROR: You are already registered"); //, %s.",
- SendClientMessage(playerid, COLOR_WHITE, message);
- }
- else{ // Unregistered player.
- ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password", "Please pick a strong and safe password, that you are able to remember.", "Continue", "Cancel"); // Password prompt
- }
- }
- }
- forward createCharacterRecord(playerid, id);
- public createCharacterRecord(playerid, id){
- new character_query[94 + MAX_SQL_INTEGER + MAX_PLAYER_NAME + 3 + 1];
- format(character_query, sizeof(character_query), "INSERT INTO character(user_id, name, skin_id) VALUES(%i, '%s', %i)", id, getPlayerName(playerid), GetPlayerSkin(playerid));
- sql_query(sqlHandle, character_query);
- }
- forward authenticate(playerid);
- public authenticate(playerid){
- ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Sign in", "Enter your password to log on", "Log in", "Cancel"); // Show password confirmation dialog
- }
- forward characterSelection(playerid);
- public characterSelection(playerid){
- if(GetGVarInt("userlevel", playerid) < REGISTERED_PLAYER){ // Unregistered player (Or worse?)
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Register first with: /my account register");
- }
- else{ // Registered player
- // If spawned, save current character
- if(GetPlayerState(playerid) != PLAYER_STATE_NONE){
- savePlayerState(playerid);
- }
- new id = getUserID(playerid);
- new character_query[75 + MAX_SQL_INTEGER + MAX_CHARACTERS_PER_USER_DIGITS + 1];
- format(character_query, sizeof(character_query), "SELECT id, name FROM character WHERE user_id = %i LIMIT %i", id, MAX_CHARACTERS_PER_USER);
- new Result:character_result = sql_query(sqlHandle, character_query);
- new character_string[(MAX_PLAYER_NAME * MAX_CHARACTERS_PER_USER) + 1], character_array[MAX_CHARACTERS_PER_USER + 1];
- for(new i = 0; i < sql_num_rows(character_result); i++){
- new name[MAX_PLAYER_NAME + 1];
- sql_get_field_assoc_ex(character_result, i, "name", name, sizeof(name));
- format(character_string, sizeof(character_string), "%s%s\n", character_string, name);
- character_array[i] = sql_get_field_assoc_int_ex(character_result, i, "id");
- printf("Character ID from array: %i", character_array[i]);
- }
- new character_array_string[MAX_CHARACTERS_PER_USER * MAX_SQL_INTEGER + 1];
- strfrombin(character_array_string, character_array); // Convert array to string for use with GVar
- SetGVarString("character_array_string", character_array_string, playerid);
- ShowPlayerDialog(playerid, DIALOG_CHARACTERS, DIALOG_STYLE_LIST, "Characters", character_string, "Spawn", "New");
- }
- }
- forward savePlayerState(playerid);
- public savePlayerState(playerid){
- new escaped_playername[MAX_PLAYER_NAME + 1], character_query[210 + MAX_SQL_INTEGER + 3 + 3 + 1 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_PLAYER_NAME + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1]; // Should be longer to allow for escaped characters
- sql_escape_string(sqlHandle, getPlayerName(playerid), escaped_playername, sizeof(escaped_playername)); // Escape player name
- new Float:health, Float:armour, Float:x, Float:y, Float:z, Float:Angle;
- // Unrealiable TODO change to gvars
- GetPlayerHealth(playerid, health);
- GetPlayerArmour(playerid, armour);
- GetPlayerPos(playerid, x, y, z);
- GetPlayerFacingAngle(playerid, Angle);
- new world_id = GetPlayerVirtualWorld(playerid);
- new interior_id = GetPlayerInterior(playerid);
-
- format(character_query, sizeof(character_query), "UPDATE character SET (cash, health, armour, jailed, pos_x, pos_y, pos_z, rotation, world_id, interior_id) = (%i, '%f', '%f', %i, '%f', '%f', '%f', '%f', %i, %i) WHERE name = '%s'", GetPlayerMoney(playerid), health, armour, 0, x, y, z, Angle, world_id, interior_id, escaped_playername);
- sql_query(sqlHandle, character_query);
- }
- forward kickPlayerDelay(playerid);
- public kickPlayerDelay(playerid){
- Kick(playerid);
- }
- forward kickPlayer(playerid, kickerid, const reason[], banned);
- public kickPlayer(playerid, kickerid, const reason[], banned){ // Kick a player
- // Issuer of kick
- new kickername[MAX_PLAYER_NAME + 1], kicker_id[MAX_SQL_INTEGER + 1];
- if(kickerid == -1){ // Not kicked by in-game player
- kickername = "SERVER";
- kicker_id = "NULL";
- }
- else{ // Kicked by in-game player
- kickername = getPlayerName(playerid);
- kicker_id = "%s", getUserID(kickerid);
- }
- strreplace(kickername, "_", " ");
- // Action
- new action[16 + MAX_SQL_INTEGER + 1];
- if(banned){
- if(banned < 1){ // Permanent ban
- action = "banned permanently";
- }
- else{ // Temporary ban
- format(action, sizeof(action), "banned for %i days", banned);
- }
- }
- else{
- action = "kicked";
- }
- // Notify all players
- new playername[MAX_PLAYER_NAME + 1], message[16 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 16 + MAX_SQL_REASON + 1], admin_message[23 + 4 + MAX_PLAYER_NAME + 16 + MAX_PLAYER_NAME + MAX_SQL_REASON + 1]; // Max samp chat message length 128 - 8 for "/kick ? ".
- GetPlayerName(playerid, playername, sizeof(playername));
- format(message, sizeof(message), "* [%i] %s %s, reason: %s", playerid, getCharacterName(playerid), action, reason);
- format(admin_message, sizeof(admin_message), "* [%i] %s kicked %s, reason: %s", kickerid, kickername, getCharacterName(playerid), action, reason);
- logger(LOGLEVEL_INFO, message); // Log event
- SendClientMessageToAll(COLOR_NOTICE, message);
- DiscordEcho(message, ECHO_CHANNEL);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- // Inform player (Redundant, but some people are blind or stupid)
- new player_message[30 + 6 + MAX_PLAYER_NAME + MAX_SQL_REASON + 1]; // Max samp chat message length 128 - 8 for "/kick ? ".
- format(player_message, sizeof(player_message), "SERVER: You have been %s, reason: %s", action, reason);
- SendClientMessage(playerid, COLOR_ERROR, player_message); // Notify player
- if(banned){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "You may appeal this ban via the forum or Discord.");
- }
- new ip_id = getIPID(playerid);
- // Crearte IP kick record
- new ip_query[61 + 4 + MAX_SQL_REASON + 4 + 1];
- format(ip_query, sizeof(ip_query), "INSERT INTO ip_kick(ip_id, reason, kicker_id) VALUES(%i, '%s', %s)", ip_id, reason, kicker_id);
- sql_query(sqlHandle, ip_query);
- // Get IP kick record
- new ip_id_query[64 + 4 + MAX_SQL_REASON + 4 + 1];
- format(ip_id_query, sizeof(ip_id_query), "SELECT id FROM ip_kick WHERE ip_id = %i ORDER BY id DESC LIMIT 1", ip_id);
- new Result:ip_id_result = sql_query(sqlHandle, ip_id_query);
- new ip_kick_id = sql_get_field_assoc_int(Result:ip_id_result, "id");
- // User kick record
- printf("Userlevel: %i", GetGVarInt("userlevel", playerid));
- if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Not logged in to a user account
- new user_query[79 + 4 + MAX_SQL_REASON + 4 + 1];
- format(user_query, sizeof(user_query), "INSERT INTO user_kick(user_id, reason, kicker_id, ip_kick_id) VALUES(%i, '%s', %s, %i)", getUserID(playerid), reason, kicker_id, ip_kick_id);
- sql_query(sqlHandle, user_query);
- }
- SetTimerEx("kickPlayerDelay", 50, false, "i", playerid); // Give the message 50 milliseconds to reach the player before kicking.
- }
- banExpiration(days);
- banExpiration(days){
- if(days < 1){ // Permanent ban
- new foo[MAX_SQL_TIMESTAMP + 1] = "0";
- return foo;
- }
- else{ // Temporary ban
- new year, month, day, hour, minute, second, expires[MAX_SQL_TIMESTAMP + 1];
- getdate(year, month, day);
- gettime(hour, minute, second);
- day = day + days;
- format(expires, sizeof(expires), "%i-%i-%i %i:%i:%i", year, month, day, hour, minute, second);
-
- return expires;
- //return year, month, day, hour, minute, second;
- //return 0;
- }
- }
- forward banPlayer(playerid, bannerid, const reason[], days);
- public banPlayer(playerid, bannerid, const reason[], days){ // Ban & kick a player
- new ip_id = getIPID(playerid);
- // Create IP ban record
- new banner_id, ip_query[72 + MAX_SQL_INTEGER + MAX_SQL_TIMESTAMP + MAX_SQL_REASON + MAX_SQL_INTEGER + 1];
- if(bannerid < 0){ // Not banned by in-game player
- format(ip_query, sizeof(ip_query), "INSERT INTO ip_ban(ip_id, expires, reason) VALUES(%i, '%s', '%s')", ip_id, banExpiration(days), reason);
- }
- else{ // Banned by in-game player
- banner_id = getUserID(bannerid);
- format(ip_query, sizeof(ip_query), "INSERT INTO ip_ban(ip_id, expires, reason, banner_id) VALUES(%i, '%s', '%s', %i)", ip_id, banExpiration(days), reason, banner_id);
- }
- sql_query(sqlHandle, ip_query);
- // Get IP ban record ID
- new ban_id_query[61 + MAX_PLAYER_NAME + 1];
- format(ban_id_query, sizeof(ban_id_query), "SELECT id FROM ip_ban WHERE ip_id = %i ORDER BY id DESC LIMIT 1", ip_id);
- new Result:ban_id_result = sql_query(sqlHandle, ban_id_query);
- new ip_ban_id = sql_get_field_assoc_int(ban_id_result, "id");
- // User ban record (As banned players get only kicked, noneed to check for active ban)
- if(GetGVarInt("userlevel", playerid) > 1){ // Registered player
- new user_query[97 + MAX_SQL_INTEGER + MAX_SQL_TIMESTAMP + MAX_SQL_REASON + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(user_query, sizeof(user_query), "INSERT INTO user_ban(user_id, expires, reason, banner_id, ip_ban_id) VALUES(%i, %s, %s, %i, %i) WHERE id = %i", ip_id, banExpiration(days), reason, banner_id, ip_ban_id);
- sql_query(sqlHandle, user_query);
- }
- // Kick player
- kickPlayer(playerid, bannerid, reason, days);
- }
- // Database functions
- forward getIPID(playerid);
- public getIPID(playerid){
- new player_ip[MAX_SQL_IP + 1], query[37 + MAX_SQL_IP + 1]; // Create varaibles
- GetPlayerIp(playerid, player_ip, sizeof(player_ip)); // Polulate player_ip variable
- format(query, sizeof(query), "SELECT id FROM ip WHERE address = '%s'", player_ip); // Format query string
- new Result:result = sql_query(sqlHandle, query); // Execute query
-
- return sql_get_field_assoc_int(result, "id"); // Get id from result
- }
- forward getUserID(playerid);
- public getUserID(playerid){
- // SQL escape username
- new client_connect_username[MAX_PLAYER_NAME + 1], escaped_username[MAX_PLAYER_NAME + 1]; // TODO escaped_username should be longer to account for escape characters (Also increate database column size!)
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
- sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username)); // Escape player name
- // Get user ID
- new userid_query[47 + MAX_PLAYER_NAME + 1];
- format(userid_query, sizeof(userid_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
- new Result:result = sql_query(sqlHandle, userid_query);
- return sql_get_field_assoc_int(result, "id");
- }
- // Player functions
- forward deleteAllGVars(playerid);
- public deleteAllGVars(playerid){ // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
- DeleteGVar("client_connect_username", playerid); // From OnPlayerConnect()
- DeleteGVar("userlevel", playerid); // From OnPlayerConnect()
- DeleteGVar("hash", playerid); // From DIALOG_REGISTER
- DeleteGVar("character_array_string", playerid); // From OnDialogResponse()
- DeleteGVar("authentication_count", playerid); // From DIALOG_LOGIN
- DeleteGVar("character_id", playerid); // From DIALOG_CHARACTERS
- DeleteGVar("chatmode", playerid); // From cmd:my()
- DeleteGVar("disable_pickups", playerid); // From OnPlayerPickUpDynamicPickup()
- DeleteGVar("goto_target", playerid); // From cmd:my() & cmd:p()
- DeleteGVar("job", playerid); // From OnDialogResponse()
- }
- getPlayerName(playerid);
- getPlayerName(playerid){
- // new playername[MAX_PLAYER_NAME + 1];
- new const playername[MAX_PLAYER_NAME + 1];
- GetPlayerName(playerid, playername, sizeof(playername));
- // new output[MAX_PLAYER_NAME + 1];
- // strfromliteral(output, playername);
-
- return playername;
- }
- forward teleportPlayer(playerid, Float:x, Float:y, Float:z, world, interior, Float:angle, const name[]);
- public teleportPlayer(playerid, Float:x, Float:y, Float:z, world, interior, Float:angle, const name[]){
- SetPlayerPos(playerid, x, y, z);
- SetPlayerVirtualWorld(playerid, world);
- SetPlayerInterior(playerid, interior);
- SetPlayerFacingAngle(playerid, angle);
-
- // Inform admins
- new admin_message[21 + 4 + MAX_PLAYER_NAME + 5 + 4 + MAX_PLAYER_NAME + 1 + 1]; // 5 + 4 + MAX_PLAYER_NAME + 1 = name
- format(admin_message, sizeof(admin_message), "* [%i] %s teleported to: %s", playerid, getCharacterName(playerid), name);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- forward setPlayerSkin(playerid, skinid);
- public setPlayerSkin(playerid, skinid){
- print("Called setPlayerSkin()");
- new
- Float:tmpPos[4],
- vehicleid = GetPlayerVehicleID(playerid),
- seatid = GetPlayerVehicleSeat(playerid);
- GetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
- GetPlayerFacingAngle(playerid, tmpPos[3]);
- if(skinid < 0 || skinid > 299) return 0;
- if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_DUCK)
- {
- SetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
- SetPlayerFacingAngle(playerid, tmpPos[3]);
- TogglePlayerControllable(playerid, 1); // preventing any freeze - optional
- return SetPlayerSkin(playerid, skinid);
- }
- else if(IsPlayerInAnyVehicle(playerid))
- {
- new
- tmp;
- RemovePlayerFromVehicle(playerid);
- SetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
- SetPlayerFacingAngle(playerid, tmpPos[3]);
- TogglePlayerControllable(playerid, 1); // preventing any freeze - important - because of doing animations of exiting vehicle
- tmp = SetPlayerSkin(playerid, skinid);
- PutPlayerInVehicle(playerid, vehicleid, (seatid == 128) ? 0 : seatid);
- return tmp;
- }
- else
- {
- return SetPlayerSkin(playerid, skinid);
- }
- }
- // Chat functions
- getCharacterName(playerid);
- getCharacterName(playerid){ // Convert name from player name
- new playername[MAX_PLAYER_NAME + 1], output[MAX_PLAYER_NAME + 1];
- GetPlayerName(playerid, playername, sizeof(playername));
- strfromliteral(output, playername);
- strreplace(output, "_", " ");
- return output;
- }
- forward sendToChat(playerid, target, text[128 + 1], receiver_id, DCC_User:author);
- public sendToChat(playerid, target, text[128 + 1], receiver_id, DCC_User:author){
- strtrim(text); // Trim edge whitespaces
- if(isempty(text)){
- return 0; // Fail if text is empty
- }
- new playername[MAX_PLAYER_NAME + 1];
- if(playerid < 0){
- DCC_GetUserName(author, playername, sizeof(playername));
- print("Hit playerid < 0");
- print(text);
- } // Discord messagge
- else{playername = getCharacterName(playerid);}
-
- new chat_format, chat_color, chat_range, chat_userlevel, chat_character[1 + 1], chat_name[13 + 1], discord_channel;
- switch(target){
- case CHAT_WHISPER:{
- chat_format = 2;
- chat_range = 3;
- chat_name = "whispers";
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_LOW:{
- chat_format = 2;
- chat_range = 10;
- chat_name = "speaks softly";
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_LOCAL:{
- chat_format = 1;
- chat_range = 20;
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_SHOUT:{
- chat_format = 2;
- chat_range = 50;
- chat_name = "shouts";
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_ACTION:{
- chat_format = 0;
- chat_range = 20;
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_OC:{
- chat_format = 3;
- chat_range = 20;
- chat_character = "'";
- chat_name = "OOC";
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_GLOBAL:{
- chat_format = 3;
- chat_character = "`";
- chat_name = "Global";
- chat_color = COLOR_COMMAND_OUTPUT;
- discord_channel = ECHO_CHANNEL;
- }
- case CHAT_GANG:{
- chat_format = 3;
- chat_character = "~";
- chat_name = "Gang";
- chat_color = COLOR_CREW_CHAT;
- // TODO: Output to gang Discord channel
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_GANG_OC:{
- chat_format = 3;
- chat_character = "$";
- chat_name = "Gang OC";
- chat_color = COLOR_CREW_CHAT;
- // TODO: Output to gang Discord channel
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_FACTION:{
- chat_format = 3;
- chat_character = "!";
- chat_name = "Faction";
- chat_color = COLOR_CREW_CHAT;
- // TODO: Output to faction Discord channel
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_FACTION_OC:{
- chat_format = 3;
- chat_character = "%";
- chat_name = "Faction OC";
- chat_color = COLOR_CREW_CHAT;
- // TODO: Output to faction Discord channel
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_CREW:{
- chat_format = 3;
- chat_character = "@";
- chat_name = "Crew";
- chat_color = COLOR_CREW_CHAT;
- chat_userlevel = MODERATOR_CREW;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_ADMIN:{
- chat_format = 3;
- chat_character = "#";
- chat_name = "Admin";
- chat_color = COLOR_ADMIN_CHAT;
- chat_userlevel = ADMIN_CREW;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_MANAGEMENT:{
- chat_format = 3;
- chat_character = "&";
- chat_name = "Management";
- chat_color = COLOR_ADMIN_CHAT;
- chat_userlevel = MANAGEMENT_CREW;
- discord_channel = MANAGEMENT_CHANNEL;
- }
- case CHAT_VIP:{
- chat_format = 3;
- chat_character = "^";
- chat_name = "VIP";
- chat_color = COLOR_VIP_CHAT;
- chat_userlevel = VIP_PLAYER;
- discord_channel = ADMIN_ECHO_CHANNEL;
- //TODO: Add VIP discord channel.
- }
- case CHAT_UNDERCOVER:{
- chat_format = -1;
- chat_character = "*";
- chat_color = COLOR_COMMAND_OUTPUT;
- chat_userlevel = ADMIN_CREW;
- discord_channel = ECHO_CHANNEL;
- }
- case CHAT_PM:{
- chat_format = 3;
- chat_character = ">";
- chat_name = "PM";
- chat_color = COLOR_PM_CHAT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_CALL:{
- chat_format = 3;
- chat_character = "+";
- chat_name = "Call";
- chat_color = COLOR_PM_CHAT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_SMS:{
- chat_format = 3;
- chat_character = "-";
- chat_name = "SMS";
- chat_color = COLOR_PM_CHAT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- case CHAT_RADIO:{
- chat_format = 3;
- chat_character = "=";
- chat_name = "Radio";
- chat_color = COLOR_PM_CHAT;
- discord_channel = ADMIN_ECHO_CHANNEL;
- }
- }
-
- // Format chat message
- new message[9 + sizeof(chat_character) + (6 * 8) + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 128 + 1];
- new discord_message[23 + sizeof(chat_character) + sizeof(chat_name) + sizeof(playerid) + MAX_PLAYER_NAME + 128 + 1];
- switch(chat_format){
- case -1:{
- format(message, sizeof(message), "%s %s", chat_character, text);
- format(discord_message, sizeof(discord_message), "```css\n%s %s\n```", chat_character, text);
- }
- case 0:{
- format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
- format(discord_message, sizeof(discord_message), "```css\n[%i] %s %s\n```", playerid, playername, text);
- }
- case 1:{
- format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s"EMBED_COLOR_GREY":{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
- format(discord_message, sizeof(discord_message), "```css\n[%i] %s: %s\n```", playerid, playername, text);
- }
- case 2:{
- format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s %s"EMBED_COLOR_GREY":{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_name, chat_color >>> 8, text);
- format(discord_message, sizeof(discord_message), "```css\n[%i] %s %s: %s\n```", playerid, playername, chat_name, text);
- }
- case 3:{
- format(message, sizeof(message), "%s "EMBED_COLOR_GREY"({%06x}%s"EMBED_COLOR_GREY") [{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s"EMBED_COLOR_GREY":{%06x} %s", chat_character, chat_color >>> 8, chat_name, GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
- format(discord_message, sizeof(discord_message), "```css\n%s (%s) [%i] %s: %s\n```", chat_character, chat_name, playerid, playername, text);
- }// Good discord tag options for color effects: yaml, css, moon, elixir, haxe, groovy, brainfuck, accesslog,inform7, c,
- }
-
- // Authorisation
- if(chat_userlevel && chat_userlevel > GetGVarInt("userlevel", playerid)){ // User not privilged to read chat
- if(target == CHAT_CREW){ // Show the user the message was sent to crew chat.
- SendClientMessage(playerid, chat_color, message);
- }
- else{
- SendClientMessage(playerid, COLOR_CREW_CHAT, "ERROR: You are not authorized to speak in this chat.");
- return 0; // Fail to send the message
- }
- }
-
- // Send TODO: Add checks for muted.
- if(chat_range){ // Ranged chats
- logger(LOGLEVEL_CHAT, message); // Log event
-
- // Show message to players in range
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- for(new recipient_id, a = GetMaxPlayers(); recipient_id < a; recipient_id++){
- if(IsPlayerConnected(receiver_id)){
- new Float:distance = GetPlayerDistanceFromPoint(recipient_id, x, y, z);
- if(distance <= chat_range){ // Player nearby
- sendClientMultiMessage(recipient_id, chat_color, message, Bool:false);
- }
- }
- }
- DiscordEcho(discord_message, discord_channel);
- }
- else{ // Global chats
- if(target == CHAT_GLOBAL){ // Public chat
- logger(LOGLEVEL_CHAT, message); // Log event
- sendClientMultiMessage(0, chat_color, message, Bool:true);
- DiscordEcho(discord_message, discord_channel);
- }
- else if(target == CHAT_GANG || target == CHAT_GANG_OC || target == CHAT_FACTION || target == CHAT_FACTION_OC || target == CHAT_CALL || target == CHAT_SMS || target == CHAT_RADIO ){
- // TODO
- // TODO sendToAdmins();
- // TODO send to specific discord channel
- SendClientMessage(playerid, chat_color, "You are not a member of the required entity.");
- }
- else if(target == CHAT_PM){
- new output[sizeof(message)];
- strdel(message, 0, 1);
- format(output, sizeof(output), "<%s", message);
- sendClientMultiMessage(receiver_id, chat_color, output, Bool:false);
-
- new receipt[12 + 1 + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 128 + 1];
- format(receipt, sizeof(receipt), "%s (%s) to [%i] %s: %s", chat_character, chat_name, receiver_id, playername, text);
- sendClientMultiMessage(playerid, chat_color, receipt, Bool:false);
- new admin_message[15 + 1 + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 4 + 128 + 1];
- format(admin_message, sizeof(admin_message), "%s (%s) [%i] %s to [%i]: %s", chat_character, chat_name, playerid, playername, receiver_id, text);
- logger(LOGLEVEL_CHAT, admin_message); // Log event
-
- sendToAdmins(chat_color, admin_message);
- DiscordEcho(discord_message, discord_channel);
- }
-
- else{ // Chat with select users
- for(new recipient_id, a = GetMaxPlayers(); recipient_id < a; recipient_id++){
- if(IsPlayerConnected(recipient_id)){
- if(GetGVarInt("userlevel", recipient_id) >= chat_userlevel){ // Privileged
- logger(LOGLEVEL_CHAT, message); // Log event
- sendClientMultiMessage(recipient_id, chat_color, message, Bool:false);
- DiscordEcho(discord_message, discord_channel);
- }
- }
- }
- }
- }
- return 1;
- }
- forward sendToAdmins(chat_color, const message[]);
- public sendToAdmins(chat_color, const message[]){
- for(new recipient_id, a = GetMaxPlayers(); recipient_id < a; recipient_id++){
- if(IsPlayerConnected(recipient_id)){
- if(GetGVarInt("userlevel", recipient_id) >= ADMIN_CREW){ // Privileged
- SendClientMessage(recipient_id, chat_color, message);
- }
- }
- }
- }
- forward sendPM(playerid, text[128 + 1], recipient_id);
- public sendPM(playerid, text[128 + 1], recipient_id){
- if (recipient_id == INVALID_PLAYER_ID){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "ERROR: Player not found.");
- }
- else{
- sendToChat(playerid, CHAT_PM, text, recipient_id, DCC_INVALID_USER);
- // Todo: Send to admins and admin echo
- }
- }
- forward sendClientMultiMessage(recipient_id, chat_color, const message[], Bool:toall);
- public sendClientMultiMessage(recipient_id, chat_color, const message[], Bool:toall){
- if(strlen(message) > 144){ // SAMP does not send messages longer than 144 characters
- new part_1[144 + 1], part_2[144 + 1];
- strmid(part_1, message, 0, 143); // TODO see if this can be moved 1 bit
- strmid(part_2, message, 143, 286);
- if(toall){
- SendClientMessageToAll(chat_color, part_1);
- SendClientMessageToAll(chat_color, part_2);
- }
- else{
- SendClientMessage(recipient_id, chat_color, part_1);
- SendClientMessage(recipient_id, chat_color, part_2);
- }
- }
- else{
- if(toall){SendClientMessageToAll(chat_color, message);}
- else{SendClientMessage(recipient_id, chat_color, message);}
- }
- }
- // Pickup functions
- forward createDynamicPickup(object, Float:x, Float:y, Float:z, world, interior, pickup_type);
- public createDynamicPickup(object, Float:x, Float:y, Float:z, world, interior, pickup_type){
- // Object position corrections
- if(object == 19902){
- z = z - 0.5;
- }
- else if(object == 19607){
- z = z - 0.5;
- }
-
- // Pickup types
- new type;
- switch(pickup_type){
- case 99999: type = 2;
- default: type = 1;
- }
- new pickupid = CreateDynamicPickup(object, type, x, y, z, world, interior);
- SetGVarInt("pickup_type", pickup_type, pickupid);
- printf("new pickupid = CreateDynamicPickup(%i, %i, %f, %f, %f, %i, %i);", pickupid, object, type, x, y, z, world, interior);
- return pickupid;
- }
- forward spawnPortal(id, object, Float:pos_x, Float:pos_y, Float:pos_z, world, interior, exit_object, Float:exit_pos_x, Float:exit_pos_y, Float:exit_pos_z, exit_world, exit_interior);
- public spawnPortal(id, object, Float:pos_x, Float:pos_y, Float:pos_z, world, interior, exit_object, Float:exit_pos_x, Float:exit_pos_y, Float:exit_pos_z, exit_world, exit_interior){
- new pickup_id = createDynamicPickup(object, pos_x, pos_y, pos_z, world, interior, PICKUP_PORTAL);
- SetGVarFloat("pickup_x", exit_pos_x, pickup_id);
- SetGVarFloat("pickup_y", exit_pos_y, pickup_id);
- SetGVarFloat("pickup_z", exit_pos_z, pickup_id);
- SetGVarInt("pickup_world", exit_world, pickup_id);
- SetGVarInt("pickup_interior", exit_interior, pickup_id);
- new exit_pickup_id = createDynamicPickup(exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior, PICKUP_PORTAL);
- SetGVarFloat("pickup_x", pos_x, exit_pickup_id);
- SetGVarFloat("pickup_y", pos_y, exit_pickup_id);
- SetGVarFloat("pickup_z", pos_z, exit_pickup_id);
- SetGVarInt("pickup_world", world, exit_pickup_id);
- SetGVarInt("pickup_interior", interior, exit_pickup_id);
- new portal_query[64 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(portal_query, sizeof(portal_query), "UPDATE portal SET (pickup_id, exit_pickup_id) = (%i, %i) WHERE id = %i", pickup_id, exit_pickup_id, id);
- sql_query(sqlHandle, portal_query);
- }
- forward destroyPortal(id);
- public destroyPortal(id){
- DestroyDynamicPickup(id);
- DeleteGVar("pickup_type", id);
- DeleteGVar("pickup_x", id);
- DeleteGVar("pickup_y", id);
- DeleteGVar("pickup_z", id);
- DeleteGVar("pickup_world", id);
- DeleteGVar("pickup_interior", id);
- }
- // Command functions
- public OnPlayerCommandPerformed(playerid, cmd[], params[], result, flags){
- if(result == -1){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Unknown command.");
- return 0;
- }
- return 1;
- }
- public OnPlayerCommandReceived(playerid, cmd[], params[], flags){
- new userlevel = GetGVarInt("userlevel", playerid);
- if(flags){
- if(flags > userlevel){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
- printf("player %d doesn�t have access to command '%s'", playerid, cmd); // TODO decide to send this to a chat or not.
-
- return 0;
- }
- }
- return 1;
- }
- public PC_OnInit(){ // TODO
-
- return 1; // Remove this once stuff is in place.
- }
- flags:test(ADMIN_CREW);
- cmd:test(playerid, params[]){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Executed");
- return 1;
- }
- // Command commands
- cmd:help(playerid, params[]){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Ask questions in the chat, on Discord or the forum.\nTo list all commands: /cmds");
- return 1;
- }
- alias:help("h");
- cmd:cmds(playerid, params[]){
- SendClientMessage(playerid, COLOR_NOTICE, "Command help syntax: \"/\" = start of cmd, \"()\" = cmd aliasses, \"|\" = or, \"<>\" = required parameter, \"[]\" = optional parameter, \",\" = next item.");
- SendClientMessage(playerid, COLOR_NOTICE, "Command help syntax example: /command (/alias | /other_alias) <parameter> [optional_parameter], /next_command");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "General commands: /help (/h), /cmds (/cmd | /commands), /my (/myself | /mine), /v (/vehivle | /veh), /p (/player)");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Chat commands: /me (/emote | /action), /w (/whisper), /low (/soft), /l (/local), /s (/shout | /scream), /o (' | /oc | /ooc)");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Chat commands: /g (` | /global | /public), /gc (~) /fc (!), /vc (&), /cc (@), /my chatmode <value>");
- if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin commands: /property");
- }
- return 0;
- }
- alias:cmds("commands", "cmd");
- // User commands
- cmd:register(playerid, params[]){
- register(playerid);
- }
- cmd:my(playerid, params[]){
- // No option specified
- if(strlen(params) < 1){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my <option> <value>");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Options: account chatmode");
- if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin options: goto");
- }
- return 0;
- }
-
- // Options
- if(!strcmp(params, "account", true, 7)){ // /my account
- strdel(params, 0, 8); // Remove first 8 characters, "account ", from the string.
- // Values
- if (isequal(params, "register", .ignorecase = true)){ // /my account register
- register(playerid); // Call public register function
- }
- else if (isequal(params, "characters", .ignorecase = true)){ // /my account characters
- characterSelection(playerid);
- }
- else if (isequal(params, "deletecharacter", .ignorecase = true)){ // /my account characters
- ShowPlayerDialog(playerid, DIALOG_DELETE_CHARACTER, DIALOG_STYLE_MSGBOX, "Charater deletion", "You are about to permanently delete this charater and all it's assets.\n This can NOT be undone.", "Destroy", "Abort");
- }
- else{ // Invalid value
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my account <value>");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Values: register characters deletecharacter");
- }
- }
- else if(!strcmp(params, "chatmode", true, 8)){ // /my chatmode
- strdel(params, 0, 9); // Remove first 9 characters, "account ", from the string.
- // Values
- if (isequal(params, "whisper", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_WHISPER, playerid);
- }
- else if (isequal(params, "low", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_LOW, playerid);
- }
- else if (isequal(params, "local", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_LOCAL, playerid);
- }
- else if (isequal(params, "shout", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_SHOUT, playerid);
- }
- else if (isequal(params, "oc", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_OC, playerid);
- }
- else if (isequal(params, "global", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_GLOBAL, playerid);
- }
- else if (isequal(params, "gang", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_GANG, playerid);
- }
- else if (isequal(params, "faction", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_FACTION, playerid);
- }
- else if (isequal(params, "vip", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_VIP, playerid);
- }
- else if (isequal(params, "crew", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_CREW, playerid);
- }
- else if (isequal(params, "admin", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_ADMIN, playerid);
- }
- else if (isequal(params, "management", .ignorecase = true)){
- SetGVarInt("chatmode", CHAT_MANAGEMENT, playerid);
- }
- else{ // Invalid value
- printf("else isequals register");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my chatmode <value>");
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Values: whisper low local shout oc global gang faction vip crew admin management");
- }
- }
- else if(!strcmp(params, "goto", true, 4) || !strcmp(params, "sendto", true, 6) || !strcmp(params, "teleport", true, 8)){
- if(GetGVarInt("userlevel", playerid) < ADMIN_CREW){
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
- }
-
- SetGVarInt("goto_target", playerid, playerid);
- ShowPlayerDialog(playerid, DIALOG_GOTO, DIALOG_STYLE_LIST, "Categories", "Interiors\nPlayers", "Select", "Cancel");
- }
- else{ // Invalid option
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/my options: account chatmode");
- if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin options: goto");
- }
- }
- return 0;
- }
- alias:my("myself", "mine");
- // Chat commands
- cmd:w(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_WHISPER, params, 0, DCC_INVALID_USER);
-
- return 1;
- }
- alias:w("whisper");
- cmd:low(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_LOW, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:low("soft");
- cmd:l(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_LOCAL, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:l("local");
- cmd:me(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_ACTION, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:me("emote", "action");
- cmd:s(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_SHOUT, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:s("shout", "scream");
- cmd:o(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_OC, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:o("oc", "ooc");
- cmd:g(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_GLOBAL, params, 0, DCC_INVALID_USER);
- return 1;
- }
- alias:g("global", "public");
- cmd:gc(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_GANG, params, 0, DCC_INVALID_USER);
- return 1;
- }
- cmd:fc(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_FACTION, params, 0, DCC_INVALID_USER);
- return 1;
- }
- cmd:vc(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_VIP, params, 0, DCC_INVALID_USER);
- return 1;
- }
- cmd:cc(playerid, params[128 + 1]){
- sendToChat(playerid, CHAT_CREW, params, 0, DCC_INVALID_USER);
- return 1;
- }
- cmd:pm(playerid, params[128 + 1]){
- new recipient_id, message[128 + 1];
- if (sscanf(params, "u s", recipient_id, message)){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /pm <playerid> <message>");
- }
- else{
- sendPM(playerid, message, recipient_id);
- }
- return 1;
- }
- alias:pm("msg", "dm");
- // Vehicle commands
- cmd:v(playerid, params[]){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "health/armor [AMOUNT]");
- return 1;
- }
- alias:v("vehicle", "veh");
- // Player commands
- cmd:p(playerid, params[]){
- // No parameters
- if(strlen(params) < 1){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /p <ID> option");
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
- }
- // Syntax
- new player_id, option[123 + 1];
- if(sscanf(params, "i s", player_id, option)){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /p <ID> <option>");
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
- }
-
- if(!strcmp(option, "admin", true, 5)){
- SetGVarInt("userlevel", ADMIN_CREW, player_id);
- // TODO take admin if already admin
- // TODO notify admins
- }
- else if(!strcmp(option, "goto", true, 4) && !strcmp(option, "sendto", true, 6 && !strcmp(option, "teleport", true, 8)) ){
- if(GetGVarInt("userlevel", playerid) < ADMIN_CREW){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
-
- SetGVarInt("goto_target", player_id);
- }
- }
- else{
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p <ID> options: admin, goto");
- }
-
- return 1;
- }
- alias:p("player");
- // Admin commands
- flags:property(ADMIN_CREW);
- cmd:property(playerid, params[]){
- // No option specified
- if(strlen(params) < 1){
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property options: pickup, portal");
- }
- // Options
- if(!strcmp(params, "pickup", true, 6)){ // /property pickup
- strdel(params, 0, 7); // Remove first 7 characters, "pickup ", from the string.
-
- // No parameters
- if(strlen(params) < 1){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property pickup <create | ID <goto | move | delete>>");
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
- }
-
- // Values
- new pickup_id, option[110 + 1];
- if(!strcmp(params, "create", true)){ // /property pickup create
- ShowPlayerDialog(playerid, DIALOG_CREATE_PICKUP, DIALOG_STYLE_LIST, "Pickup caterogy", "Faction", "Select", "Cancel");
- }
- else if (!sscanf(params, "i s", pickup_id, option)){
- new pickup_query[62 + MAX_SQL_INTEGER + 1];
- format(pickup_query, sizeof(pickup_query), "SELECT object_id, type_id, pickup_id, pos_x, pos_y, pos_z, world_id, pickup_id FROM pickup WHERE id = %i", pickup_id);
- new Result:pickup_result = sql_query(sqlHandle, pickup_query);
- if(sql_num_rows(pickup_result) < 1){ // Invalid pickup ID
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid pickup ID");
- }
-
- new pickupid = sql_get_field_assoc_int(pickup_result, "pickup_id");
- print(option);
- if(!strcmp(option, "move", true)){
- print("move");
- // Destroy old pickup
- DestroyDynamicPickup(pickupid);
-
- // Create new pickup
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new interior = GetPlayerInterior(playerid);
- new world = GetPlayerVirtualWorld(playerid);
-
- new object_id = sql_get_field_assoc_int(Result:pickup_result, "object_id");
- new type_id = sql_get_field_assoc_int(Result:pickup_result, "type_id");
- new new_pickupid = createDynamicPickup(object_id, x, y, z, world, interior, type_id);
- // Update pickup record
- new update_query[109 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(update_query, sizeof(update_query), "UPDATE pickup SET pos_x = '%f', pos_y = '%f', pos_z = '%f', world_id = %i, interior_id = %i, pickup_id = %i WHERE id = %i", x, y, z, world, interior, new_pickupid, pickup_id);
- sql_query(sqlHandle, update_query);
-
- // Inform admins
- new admin_message[39 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(admin_message, sizeof(admin_message), "* [%i] %s modified the location of pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- else if(!strcmp(option, "delete", true)){
- // Destroy pickup
- DestroyDynamicPickup(pickupid);
-
- // Delete pickup record
- new update_query[95 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(update_query, sizeof(update_query), "DELETE FROM pickup WHERE id = %i", pickup_id);
- sql_query(sqlHandle, update_query);
- // Inform admins
- new admin_message[39 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(admin_message, sizeof(admin_message), "* [%i] %s deleted pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- else if(!strcmp(option, "goto", true)){
- SetPlayerPos(playerid, sql_get_field_assoc_int(Result:pickup_result, "pos_x"), sql_get_field_assoc_int(Result:pickup_result, "pos_y"), sql_get_field_assoc_int(Result:pickup_result, "pos_z"));
- SetPlayerVirtualWorld(playerid, sql_get_field_assoc_int(Result:pickup_result, "world_id"));
- SetPlayerInterior(playerid, sql_get_field_assoc_int(Result:pickup_result, "interior_id"));
- }
- else{ // Invalid option.
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property pickup <ID> usage: goto, move, delete");
- }
- }
- else{ // Invalid value
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property pickup usage: create, <ID> <goto | move | delete>");
- }
- }
- else if(!strcmp(params, "portal", true, 6)){ // /property portal
- strdel(params, 0, 7); // Remove first 7 characters, "portal ", from the string.
- // No parameters
- if(strlen(params) < 1){
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property portal <create | ID <goto | exit | entrance | object | delete>>");
- }
-
- // Values
- new portal_id, option[116 + 1];
- if (!strcmp(params, "create", true, 6)){ // /property portal create
- strdel(params, 0, 7); // Remove first 7 characters, "create ", from the string.
- // Worlds
- new world[105 + 1], world_id;
- if (sscanf(params, "s", world)){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "For a portal that works in all worlds use: /property portal create all");
- }
- if(!strcmp(world, "all", true)){
- world_id = -1;
- }
- else{
- world_id = GetPlayerVirtualWorld(playerid);
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid world option, creating default portal.");
- }
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new interior = GetPlayerInterior(playerid);
-
- new pickup_id = createDynamicPickup(19902, x, y, z, world_id, interior, PICKUP_PORTAL);
- // Create portal database record
- new portal_query[111 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + 1];
- format(portal_query, sizeof(portal_query), "INSERT INTO portal(object, pos_x, pos_y, pos_z, world, pickup_id, interior_id) VALUES (19902, '%f', '%f', '%f', %i, %i, %i)", x, y, z, world_id, pickup_id, interior);
- sql_query(sqlHandle, portal_query);
-
- // Inform user(s)
- new portal_id_query[91 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + 1];
- format(portal_id_query, sizeof(portal_id_query), "SELECT id FROM portal WHERE pos_x = '%f' AND pos_y = '%f' AND pos_z = '%f' AND world = %i AND interior_id = %i", x, y, z, world_id, interior);
- new Result:portal_id_result = sql_query(sqlHandle, portal_id_query);
- portal_id = sql_get_field_assoc_int(Result:portal_id_result, "id");
- new message[69 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1], admin_message[21 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(message, sizeof(message), "Portal %i created. Create the other side with: /property portal %i exit", portal_id, portal_id);
- format(admin_message, sizeof(admin_message), "* [%i] %s created portal: %i", playerid, getPlayerName(playerid), portal_id);
- sendToAdmins(COLOR_NOTICE , admin_message);
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- else if (!sscanf(params, "i s", portal_id, option)){
- // Get portal record
- new portal_query[171 + MAX_SQL_INTEGER + 1];
- format(portal_query, sizeof(portal_query), "SELECT object, pos_x, pos_y, pos_z, world, interior_id, pickup_id, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior_id, exit_pickup_id FROM portal WHERE id = %i", portal_id);
- new Result:portal_result = sql_query(sqlHandle, portal_query);
-
- // Invalid portal ID
- if(sql_num_rows(portal_result) < 1){ // Invalid portal ID
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid portal ID");
- }
-
- if (!strcmp(option, "exit", true, 4)){
- new Float:pos_x = sql_get_field_assoc_float(portal_result, "pos_x");
- new Float:pos_y = sql_get_field_assoc_float(portal_result, "pos_y");
- new Float:pos_z = sql_get_field_assoc_float(portal_result, "pos_z");
- new world_id = sql_get_field_assoc_int(portal_result, "world");
- new interior_id = sql_get_field_assoc_int(portal_result, "interior_id");
- new session_id = sql_get_field_assoc_int(portal_result, "pickup_id");
- new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
-
- // World
- new world;
- if(world_id != -1){ // Not an all-world portal
- world = GetPlayerVirtualWorld(playerid);
- }
- else{
- world = world_id;
- }
- // Location
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new interior = GetPlayerInterior(playerid);
- // Delete old exit if exists
- if(exit_pickup_id){
- destroyPortal(exit_pickup_id);
- }
- new pickup_id = createDynamicPickup(19607, x, y, z, world, interior, PICKUP_PORTAL);
- SetGVarFloat("pickup_x", pos_x, pickup_id);
- SetGVarFloat("pickup_y", pos_y, pickup_id);
- SetGVarFloat("pickup_z", pos_z, pickup_id);
- SetGVarInt("pickup_world", world_id, pickup_id);
- SetGVarInt("pickup_interior", interior_id, pickup_id);
- SetGVarFloat("pickup_x", x, session_id);
- SetGVarFloat("pickup_y", y, session_id);
- SetGVarFloat("pickup_z", z, session_id);
- SetGVarInt("pickup_world", world, session_id);
- SetGVarInt("pickup_interior", interior, session_id);
- // Update portal record
- new update_query[155 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(update_query, sizeof(update_query), "UPDATE portal SET exit_object = 19607, exit_pos_x = '%f', exit_pos_y = '%f', exit_pos_z = '%f', exit_world = %i, exit_interior_id = %i, exit_pickup_id = %i WHERE id = %i", x, y, z, world, interior, pickup_id, portal_id);
- sql_query(sqlHandle, update_query);
- // Inform admins and Discord
- new admin_message[61 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(admin_message, sizeof(admin_message), "* [%i] %s modified the exit location of portal: %i", playerid, getPlayerName(playerid), portal_id);
- sendToAdmins(COLOR_NOTICE , admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- else if(!strcmp(option, "object", true, 6)){
- new object, exit_object;
- if (sscanf(option, "i i", object, exit_object)){
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid syntax, specify two object ID's: /property portal <ID> object <ID> <ID>");
- }
- new Float:pos_x = sql_get_field_assoc_float(portal_result, "pos_x");
- new Float:pos_y = sql_get_field_assoc_float(portal_result, "pos_y");
- new Float:pos_z = sql_get_field_assoc_float(portal_result, "pos_z");
- new world_id = sql_get_field_assoc_int(portal_result, "world");
- new interior_id = sql_get_field_assoc_int(portal_result, "interior_id");
- new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
- new Float:exit_pos_x = sql_get_field_assoc_float(portal_result, "exit_pos_x");
- new Float:exit_pos_y = sql_get_field_assoc_float(portal_result, "exit_pos_y");
- new Float:exit_pos_z = sql_get_field_assoc_float(portal_result, "exit_pos_z");
- new exit_world_id = sql_get_field_assoc_int(portal_result, "exit_world");
- new exit_interior_id = sql_get_field_assoc_int(portal_result, "exit_interior_id");
- new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
- destroyPortal(exit_pickup_id);
- destroyPortal(pickup_id);
- spawnPortal(portal_id, object, pos_x, pos_y, pos_z, world_id, interior_id, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world_id, exit_interior_id);
- new update_query[57 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(update_query, sizeof(update_query), "UPDATE portal SET (object, exit_object) = (%i, %i) WHERE id = %i", object, exit_object, portal_id);
- sql_query(sqlHandle, portal_query);
- }
- else if(!strcmp(option, "delete", true, 6)){
- new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
- new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
- // TODO: Confirmation, by spectating the pickup or having to be near.
- destroyPortal(exit_pickup_id);
- destroyPortal(pickup_id);
- // Delete portal record
- new delete_query[31 + MAX_SQL_INTEGER + 1];
- format(delete_query, sizeof(delete_query), "DELETE FROM portal WHERE id = %i", portal_id);
- sql_query(sqlHandle, delete_query);
- }
- else if(!strcmp(option, "entrance", true, 8)){
- new object = sql_get_field_assoc_int(portal_result, "object");
- //new Float:x = sql_get_field_assoc_float(portal_result, "pos_x");
- //new Float:y = sql_get_field_assoc_float(portal_result, "pos_y");
- //new Float:z = sql_get_field_assoc_float(portal_result, "pos_z"); todo shorten qeury
- new world = sql_get_field_assoc_int(portal_result, "world");
- new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
- new Float:pos_x = sql_get_field_assoc_float(portal_result, "exit_pos_x");
- new Float:pos_y = sql_get_field_assoc_float(portal_result, "exit_pos_y");
- new Float:pos_z = sql_get_field_assoc_float(portal_result, "exit_pos_z");
- new world_id = sql_get_field_assoc_int(portal_result, "exit_world");
- new interior_id = sql_get_field_assoc_int(portal_result, "exit_interior");
- if(sql_num_rows(portal_result) < 1){ // Invalid portal ID
- return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid portal ID");
- }
- // World
- if(world_id != -1){ // Not an all-world portal
- world = GetPlayerVirtualWorld(playerid);
- }
- else{
- world = world_id;
- }
- // Location
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new interior = GetPlayerInterior(playerid);
- destroyPortal(pickup_id); // Despawn old pickups and remove GVars
- new pickupid = createDynamicPickup(object, x, y, z, world, interior, PICKUP_PORTAL);
- SetGVarFloat("pickup_x", pos_x, pickupid);
- SetGVarFloat("pickup_y", pos_y, pickupid);
- SetGVarFloat("pickup_z", pos_z, pickupid);
- SetGVarInt("pickup_world", world_id, pickupid);
- SetGVarInt("pickup_interior", interior_id, pickupid);
- // Inform admins and Discord
- new admin_message[65 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(admin_message, sizeof(admin_message), "* [%i] %s modified the entrance location of portal: %i", playerid, getPlayerName(playerid), portal_id);
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- else if(!strcmp(option, "goto", true)){
- SetPlayerPos(playerid, sql_get_field_assoc_int(Result:portal_result, "exit_pos_x"), sql_get_field_assoc_int(Result:portal_result, "exit_pos_y"), sql_get_field_assoc_int(Result:portal_result, "exit_pos_z"));
- SetPlayerVirtualWorld(playerid, sql_get_field_assoc_int(Result:portal_result, "exit_world_id"));
- SetPlayerInterior(playerid, sql_get_field_assoc_int(Result:portal_result, "exit_interior_id"));
- }
- else{ // Invalid option
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property portal <ID> options: goto, exit, entrance, object, delete");
- }
- }
- else{ // Invalid value
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property portal <create | ID <goto | exit | entrance | object | delete>>");
- }
- }
- else{ // Invalid option
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property options: pickup, portal");
- }
-
- return 1;
- }
- // Dialog functions
- forward dialogGotoInterior(playerid);
- public dialogGotoInterior(playerid){
- ShowPlayerDialog(playerid, DIALOG_GOTO_INTERIOR, DIALOG_STYLE_LIST, "Categories", "24/7's\nAvaition\nAmmunation's\nBurglary houses\nMissions\nMission exteriors\nMission houses\nModding shops\nPolice departments\nSafe houses\nShops & casino's\nStadia", "Select", "Back");
- }
- forward dialogGotoPlayer(playerid);
- public dialogGotoPlayer(playerid){
- for(new targetid, a = GetMaxPlayers(); targetid < a; targetid++){
- if(IsPlayerConnected(targetid)){
- // TODO: Decide to use this or TABplayer list.
- }
- }
- ShowPlayerDialog(playerid, DIALOG_GOTO_PLAYER, DIALOG_STYLE_LIST, "Players", "", "Goto", "Back");
- }
- // a_samp events
- public OnGameModeInit(){
- new message[36 + 22 + 1];
- format(message, sizeof(message), "* Global game-mode initialization: v%s", MODE_NAME);
- logger(LOGLEVEL_NOTICE, "* Global game-mode initialization."); // Log event.
- // Player radar blip markers only visible to nearby players.
- ShowPlayerMarkers(PLAYER_MARKERS_MODE_STREAMED);
- LimitPlayerMarkerRadius(15);
-
- // Set mode name
- SetGameModeText(MODE_NAME);
- // SQL log level
- if(scriptDebug){
- sql_debug(LOG_ALL, LOG_ALL); // Log everything everywhere.
- }
- else{
- sql_debug(LOG_INFO, LOG_WARNING); // Loglevel info for file and worning for console.
- }
- // Connect to database
- sqlHandle = SQL:sql_connect(SQL_HANDLER_POSTGRESQL, PG_HOST, PG_ROLE, PG_PASS, PG_DB, PG_PORT);
- printf("sqlconnection = %d", _:sqlHandle);
- if(!sql_ping(sqlHandle)){
- print( " + Database connection" );
- }
- else{
- print( "Database connection failed" );
- }
- // Initialize Discord
- //homeGuild = DCC_GetGuildId(DISCORD_HOME_GUILD_ID); // Set home guild ID. NOT NEEDED FOR NOW AND BROKEN
- echoChannel = DCC_FindChannelById(DISCORD_ECHO_CHANNEL_ID); // Set main echo channel ID.
- mainChannel = DCC_FindChannelById(DISCORD_MAIN_CHANNEL_ID); // Set main notification channel ID.
- adminEchoChannel = DCC_FindChannelById(DISCORD_ADMIN_ECHO_CHANNEL_ID); // Set admin echo channel ID.
- adminChannel = DCC_FindChannelById(DISCORD_ADMIN_CHANNEL_ID); // Set admin notification channel ID.
- managementChannel = DCC_FindChannelById(DISCORD_MANAGEMENT_CHANNEL_ID); // Set management notification channel ID.
-
- DiscordEcho(message, ECHO_CHANNEL); // Notify Discord
- //DiscordEcho(message, MAIN_CHANNEL); // TODO Enable after we are stable
-
- // Portals
- new Result:portal_result = sql_query(sqlHandle, "SELECT id, object, pos_x, pos_y, pos_z, world, interior_id, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior_id FROM portal");
- for(new i = 0; i < sql_num_rows(portal_result); i++){
- new id = sql_get_field_assoc_int_ex(portal_result, i, "id");
- new object = sql_get_field_assoc_int_ex(portal_result, i, "object");
- new Float:pos_x = sql_get_field_assoc_float_ex(portal_result, i, "pos_x");
- new Float:pos_y = sql_get_field_assoc_float_ex(portal_result, i, "pos_y");
- new Float:pos_z = sql_get_field_assoc_float_ex(portal_result, i, "pos_z");
- new world = sql_get_field_assoc_int_ex(portal_result, i, "world");
- new interior = sql_get_field_assoc_int_ex(portal_result, i, "interior_id");
- new exit_object = sql_get_field_assoc_int_ex(portal_result, i, "exit_object");
- new Float:exit_pos_x = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_x");
- new Float:exit_pos_y = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_y");
- new Float:exit_pos_z = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_z");
- new exit_world = sql_get_field_assoc_int_ex(portal_result, i, "exit_world");
- new exit_interior = sql_get_field_assoc_int_ex(portal_result, i, "exit_interior_id");
-
- spawnPortal(id, object, pos_x, pos_y, pos_z, world, interior, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior);
- }
-
- // Pickups
- new Result:pickup_result = sql_query(sqlHandle, "SELECT id, object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id FROM pickup");
- for(new i = 0; i < sql_num_rows(pickup_result); i++){
- new id = sql_get_field_assoc_int(pickup_result, "id");
- new object_id = sql_get_field_assoc_int_ex(pickup_result, i, "object_id");
- new Float:pos_x = sql_get_field_assoc_float_ex(pickup_result, i, "pos_x");
- new Float:pos_y = sql_get_field_assoc_float_ex(pickup_result, i, "pos_y");
- new Float:pos_z = sql_get_field_assoc_float_ex(pickup_result, i, "pos_z");
- new world_id = sql_get_field_assoc_int_ex(pickup_result, i, "world_id");
- new interior_id = sql_get_field_assoc_int_ex(pickup_result, i, "interior_id");
- new type_id = sql_get_field_assoc_int_ex(pickup_result, i, "type_id");
-
- new pickupid = createDynamicPickup(object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id);
- printf("On connect pickupid: %i", pickupid);
- // Update pickup record
- new pickup_query[44 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(pickup_query, sizeof(pickup_query), "UPDATE pickup SET pickup_id = %i WHERE id = %i", pickupid, id);
- sql_query(sqlHandle, pickup_query);
- }
-
- // Hobo's with a cane (0 ammo value makes them lose the cane as soon as they switch weapon)
- // Only homeless skins, as players should slowly class up in society.
- AddPlayerClass(134, -184.7607, 950.5010, 16.7740, 358.3032, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard right curb.
- AddPlayerClass(10, -184.7607, 950.5010, 16.7740, 358.3032, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard right curb.
- AddPlayerClass(78, 111.0115, 1189.2029, 18.1627, 89.0095, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard left curb.
- AddPlayerClass(129, 111.0115, 1189.2029, 18.1627, 89.0095, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard left curb.
- AddPlayerClass(162, -109.4227, 1242.4860, 16.8223, 183.5798, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard left curb.
- AddPlayerClass(77, -109.4227, 1242.4860, 16.8223, 183.5798, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard left curb.
- AddPlayerClass(79, -201.5379, 948.1683, 15.9131, 359.9720, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard left curb.
- AddPlayerClass(196, -201.5379, 948.1683, 15.9131, 359.9720, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard left curb.
- AddPlayerClass(239, 62.4694, 1205.0531, 18.8153, 89.9380, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard right curb.
- AddPlayerClass(89, 62.4694, 1205.0531, 18.8153, 89.9380, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard right curb.
- AddPlayerClass(135, -126.0831, 1242.5745, 18.6138, 183.2986, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard right curb.
- AddPlayerClass(197, -126.0831, 1242.5745, 18.6138, 183.2986, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard right curb.
- return 1;
- }
- public OnGameModeExit(){
- // Cycle every player
- for(new playerid, a = GetMaxPlayers(); playerid < a; playerid++){
- if(IsPlayerConnected(playerid)){
- // Set name back to username
- //new client_connect_username[MAX_PLAYER_NAME + 1];
- //GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
- //SetPlayerName(playerid, client_connect_username); // Change name in-game back to username, for login after restart PROBLEM: Crashses the server on GMX.
- deleteAllGVars(playerid); // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
- // TODO think of somthing for the usernames, kickign every player, or accapting character names as usersnames.
- }
- }
- logger(LOGLEVEL_NOTICE, "* Global game-mode termination."); // Log event
- sql_wait(sqlHandle); // Wait for queries to finish.
- sql_disconnect(sqlHandle); // Disconnect from database.
- DiscordEcho("* Global game-mode termination.", ECHO_CHANNEL); // Notify discord
- //DiscordEcho("* Global game-mode termination.", MAIN_CHANNEL); // Enable when stable
-
- return 1;
- }
- public OnPlayerRequestClass(playerid, classid){ // Skin selection before spawn.
- if(scriptDebug){
- new message[23 + 4 + MAX_PLAYER_NAME + 1];
- format(message, sizeof(message), "* [%i] %s Class selection.", playerid, getCharacterName(playerid));
- logger(LOGLEVEL_DEBUG, message); // Log event.
- }
- SetPlayerPos(playerid, -185.5514, 944.2042, 15.9337); // In front of Fort Carson city limits sign.
- SetPlayerFacingAngle(playerid, 182.7345); // Charater looks toward the camera.
- SetPlayerCameraPos(playerid, -185.5514, 939.0957, 15.6594); // Further in front of the Fort Carson city limits sign.
- SetPlayerCameraLookAt(playerid, -185.5514, 944.2042, 15.9337); // In front of Fort Carson city limits sign.
- return 1; // Must return one, or skin selection breaks
- }
- public OnPlayerConnect(playerid){
- SetPlayerColor(playerid, COLOR_BLACK);
-
- // Create & populate variables
- new playername[MAX_PLAYER_NAME + 1], playerip[MAX_SQL_IP + 1];
- playername = getPlayerName(playerid);
- GetPlayerIp(playerid, playerip, sizeof(playerip));
- // Global connection notification
- new admin_message[23 + MAX_PLAYER_NAME + MAX_SQL_IP + 1];
- format(admin_message, sizeof(admin_message), "* [%d] %s (IP: %s) connected.", playerid, getCharacterName(playerid), playerip);
- logger(LOGLEVEL_INFO, admin_message); // Log event
- sendToAdmins(COLOR_NOTICE, admin_message); // Notify all admins.
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL); // Notify Discord admin echo.
- // Create IP record or update connection attempts
- new ip_query[109 + MAX_SQL_IP + 1];
- format(ip_query, sizeof(ip_query), "INSERT INTO ip(address) VALUES('%s') ON CONFLICT (address) DO UPDATE SET connections = ip.connections+1", playerip);
- sql_query(sqlHandle, ip_query);
-
- // Check if IP is banned
- new ip_id = getIPID(playerid);
-
- new ban_query[75 + MAX_SQL_INTEGER + 1];
- format(ban_query, sizeof(ban_query), "SELECT id, reason FROM ip_ban WHERE ip_id = %i AND expires > NOW()::timestamp", ip_id);
- new Result:ban_result = sql_query(sqlHandle, ban_query);
- if(sql_num_rows(ban_result) > 0){ // Banned
- new kick_message[8 + MAX_SQL_REASON + 1];
- format(kick_message, sizeof(kick_message), "Banned: %s", sql_get_field_assoc_int(ban_result, "reason"));
- kickPlayer(playerid, -1, kick_message, 1);
- }
- // Get user record
- new escaped_username[MAX_PLAYER_NAME + 1], user_query[47 + MAX_PLAYER_NAME + 1]; // Should be longer to allow for escaped characters
- sql_escape_string(sqlHandle, playername, escaped_username, sizeof(escaped_username)); // Escape player name
- format(user_query, sizeof(user_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
- //new Result:result = sqlQuery(sqlHandle, user_query); // Middleware broken.
- new Result:result = sql_query(sqlHandle, user_query);
-
- SetGVarString("client_connect_username", playername, playerid); // Used by register, DIALOG_LOGIN, getUserID & OnGameModeExit
-
- if(sql_num_rows(result) == 0){ // Unkown user
- SetGVarInt("userlevel", UNREGISTERED_PLAYER, playerid); // Set userlevel unregistered
- changeName(playerid, playername); // Check, force and set role-play name
- }
- else{ // Known user
- ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Sign in", "Enter your password to log on", "Log in", "Cancel"); // Show password confirmation dialog
- }
- //return 1;
- }
- public OnPlayerDisconnect(playerid, reason){
- if(GetPlayerState(playerid) != PLAYER_STATE_NONE){ // Only save character if spawned
- savePlayerState(playerid); // Save character
- }
- deleteAllGVars(playerid); // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
-
- new playername[MAX_PLAYER_NAME + 1], message[40 + 4 + MAX_PLAYER_NAME + 1];
- playername = getPlayerName(playerid);
- switch(reason){
- case 0: format(message, sizeof(message), "* [%i] %s disconnected. (Lost Connection)", playerid, getCharacterName(playerid));
- case 1: format(message, sizeof(message), "* [%i] %s disconnected. (Leaving)", playerid, getCharacterName(playerid));
- case 2: format(message, sizeof(message), "* [%i] %s disconnected. (Kicked)", playerid, getCharacterName(playerid)); // Leave this in place for RCON kicks.
- }
- logger(LOGLEVEL_INFO, message); // Log event
- SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players.
- DiscordEcho(message, ECHO_CHANNEL); // Notify discord.
-
- return 1;
- }
- public OnPlayerSpawn(playerid){
- if(scriptDebug){ // Log event in case of debugging.
- new message[MAX_PLAYER_NAME + 14 + 1];
- format(message, sizeof(message), "* [%i] %s spawned.", playerid, getCharacterName(playerid));
- logger(LOGLEVEL_DEBUG, message); // Log event.
- }
- if(GetGVarInt("userlevel", playerid) == UNREGISTERED_PLAYER){ // Unregistered player.
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: To reserve your name, save your character, statistics and money, type: /register");
- }
- return 1;
- }
- public OnPlayerDeath(playerid, killerid, reason){
- new message[15 + MAX_PLAYER_NAME + 1];
- format(message, sizeof(message), "* [%d] %s died.", playerid, getCharacterName(playerid)); // TODO Add killerid & reason.
- logger(LOGLEVEL_DEBUG, message); // Log event
- DiscordEcho(message, ADMIN_ECHO_CHANNEL); // Notify Discord admin echo.
-
- //ResetPlayerMoney(playerid); TODO test if required
- //SpawnPlayer(playerid);
- return 1;
- }
- public OnVehicleSpawn(vehicleid) // TODO for 0.0a
- {
- return 1;
- }
- public OnVehicleDeath(vehicleid, killerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerText(playerid, text[]){
- new shortcut_message[128 + 1];
- strfromliteral(shortcut_message, text);
- strdel(shortcut_message, 0, 1); // Remove chat character from text
- switch(strgetfirstc(text)){
- case '`': {
- if(GetGVarInt("chatmode", playerid) == CHAT_LOCAL){
- sendToChat(playerid, CHAT_GLOBAL, shortcut_message, 0, DCC_INVALID_USER);
- }
- else if (GetGVarInt("chatmode", playerid) == CHAT_GLOBAL){
- sendToChat(playerid, CHAT_LOCAL, shortcut_message, 0, DCC_INVALID_USER);
- }
- else{
- sendToChat(playerid, CHAT_GLOBAL, shortcut_message, 0, DCC_INVALID_USER);
- }
- }
- case '~': {sendToChat(playerid, CHAT_GANG, shortcut_message, 0, DCC_INVALID_USER);}
- case '!': {sendToChat(playerid, CHAT_FACTION, shortcut_message, 0, DCC_INVALID_USER);}
- case '@': {sendToChat(playerid, CHAT_CREW, shortcut_message, 0, DCC_INVALID_USER);}
- case '#': {sendToChat(playerid, CHAT_ADMIN, shortcut_message, 0, DCC_INVALID_USER);}
- case '$': {sendToChat(playerid, CHAT_GANG_OC, shortcut_message, 0, DCC_INVALID_USER);}
- case '%': {sendToChat(playerid, CHAT_FACTION_OC, shortcut_message, 0, DCC_INVALID_USER);}
- case '^': {sendToChat(playerid, CHAT_MANAGEMENT, shortcut_message, 0, DCC_INVALID_USER);}
- //case '$': {sendToChat(playerid, CHAT_MANAGEMENT, shortcut_message[]);}
- case '&': {sendToChat(playerid, CHAT_VIP, shortcut_message, 0, DCC_INVALID_USER);}
- case '*': {sendToChat(playerid, CHAT_UNDERCOVER, shortcut_message, 0, DCC_INVALID_USER);}
- case '+': {sendToChat(playerid, CHAT_CALL, shortcut_message, 0, DCC_INVALID_USER);}
- case '-': {sendToChat(playerid, CHAT_SMS, shortcut_message, 0, DCC_INVALID_USER);}
- case '=': {sendToChat(playerid, CHAT_RADIO, shortcut_message, 0, DCC_INVALID_USER);}
- case '>': {
- new recipient_id, message[128 + 1];
- if (sscanf(shortcut_message, "u s", recipient_id, message)){
- SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: > <playerid> <message>");
- }
- else{
- sendPM(playerid, message, recipient_id);
- }
- }
- default:{
- new chatmode = GetGVarInt("chatmode", playerid), message[128 + 1];
- strmid(message, text, 0, 128);
- // message = text;
- if(!chatmode){ // Default is local chat
- sendToChat(playerid, CHAT_LOCAL, message, 0, DCC_INVALID_USER);
- }
- else{ // Send to preferred chat
- printf("chatmode: %i", chatmode);
- sendToChat(playerid, chatmode, message, 0, DCC_INVALID_USER);
- }
- }
- }
- return 0; // Return 1 for default behavior, return 0 to disable default output.
- }
- public OnPlayerCommandText(playerid, cmdtext[]){
- if(scriptDebug){ // Log event in case of debugging.
- new message[5 + 4 + MAX_PLAYER_NAME + 128 + 1]; // 128 = samp text input limit.
- format(message, sizeof(message), "[%d] %s: %s", playerid, getCharacterName(playerid), cmdtext);
- logger(LOGLEVEL_COMMAND, message); // Log event
- }
- return 0;
- }
- public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerExitVehicle(playerid, vehicleid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerStateChange(playerid, newstate, oldstate) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerEnterCheckpoint(playerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerLeaveCheckpoint(playerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerEnterRaceCheckpoint(playerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerLeaveRaceCheckpoint(playerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnRconCommand(cmd[]){ // The website and some cronjobs do RCON commands. TODO create filter not to show some commands to preven spam
- new message[8 + 128 + 1]; // Max samp message legnth = 128.
- format(message, sizeof(message), "* RCON: %s", cmd);
- logger(LOGLEVEL_NOTICE, message); // Log event
- DiscordEcho(message, MANAGEMENT_CHANNEL);
- return 1;
- }
- public OnPlayerRequestSpawn(playerid){ // After picking a skin in class selection.
- SetPlayerColor(playerid, COLOR_WHITE);
-
- new playername[MAX_PLAYER_NAME + 1], message[14 + MAX_PLAYER_NAME + 1];
- playername = getPlayerName(playerid);
- if(scriptDebug){ // Only log spawns when debuggins script.
- format(message, sizeof(message), "* [%d] %s Chose a character.", playerid, getCharacterName(playerid));
- logger(LOGLEVEL_DEBUG, message); // Log event
- }
- if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Registered player
- createCharacterRecord(playerid, getUserID(playerid)); // Save character
-
- new client_connect_username[MAX_PLAYER_NAME + 1], admin_message[25 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
- format(admin_message, sizeof(admin_message), "[%i] %s has been created by %s.", playerid, getCharacterName(playerid), client_connect_username);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- return 1;
- }
- public OnObjectMoved(objectid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerObjectMoved(playerid, objectid) // TODO for 0.0a
- {
- return 1;
- }
- //public OnPlayerPickUpPickup(playerid, pickupid){} // Replaced byOnPlayerPickUpDynamicPickup() streamer.inc
- public OnPlayerPickUpDynamicPickup(playerid, pickupid){ // Requires streamer
- new type = GetGVarInt("pickup_type", pickupid);
- // Special pickup types first, rugular in the else{} conditional statement
- if(type == PICKUP_PORTAL){
- // Do nothing if the player just used a pickup
- if(GetGVarInt("disable_pickups", playerid)){
- return 0;
- }
- new Float:x = GetGVarFloat("pickup_x", pickupid);
- new Float:y = GetGVarFloat("pickup_y", pickupid);
- new Float:z = GetGVarFloat("pickup_z", pickupid);
- new world = GetGVarInt("pickup_world", pickupid);
- new interior = GetGVarInt("pickup_interior", pickupid);
- // Don't releport when the exit is not set
- if(x == 0 && y == 0 && z == 0){
- return 0;
- }
- // Create dynamic area and temporarily disable pickups for player
- new area = CreateDynamicCircle(x, y, 1.7, world, -1, playerid);
- SetGVarInt("disable_pickups", area, playerid);
- // Teleport player
- SetPlayerPos(playerid, x, y, z);
- if(world != -1){SetPlayerVirtualWorld(playerid, world);}
- SetPlayerInterior(playerid, interior);
- }
- else{
- // Do nothing if the player just used a pickup
- if(GetGVarInt("disable_pickups", playerid)){
- return 0;
- }
-
- // Create dynamic area and temporarily disable pickups for player
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new area = CreateDynamicCircle(x, y, 1, GetPlayerVirtualWorld(playerid), -1, playerid);
- SetGVarInt("disable_pickups", area, playerid);
-
- // Regular pickup types
- switch(type){
- case PICKUP_FACTION_PD: {
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_PD, DIALOG_STYLE_MSGBOX, "Active police duty", "Go on police duty as a rookie cop?", "Yes", "No");}
- case JOB_POLICE:{ShowPlayerDialog(playerid, DIALOG_DUTY_PD, DIALOG_STYLE_MSGBOX, "Active police duty", "Go off police duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- case PICKUP_FACTION_MD:{
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_MD, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go on medic duty as a rookie paramedic?", "Yes", "No");}
- case JOB_MEDIC:{ShowPlayerDialog(playerid, DIALOG_DUTY_MD, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go off paramedic duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
- }
- }
- case PICKUP_FACTION_FD:{
- printf("jobid: %i", GetGVarInt("job", playerid));
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FD, DIALOG_STYLE_MSGBOX, "Active fire duty", "Go on fire duty as a rookie firefighter?", "Yes", "No");}
- case JOB_FIRE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FD, DIALOG_STYLE_MSGBOX, "Active firefighter duty", "Go off firefighter duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
- }
- }
- case PICKUP_FACTION_FBI:{
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FBI, DIALOG_STYLE_MSGBOX, "Active FBI duty", "Go on FBI duty as a rookie agent?", "Yes", "No");}
- case JOB_FBI:{ShowPlayerDialog(playerid, DIALOG_DUTY_FBI, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go off FBI duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
- }
- }
- case PICKUP_FACTION_DMV:{
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_DMV, DIALOG_STYLE_MSGBOX, "Active DMV duty", "Go on DMV duty as a rookie service officer?", "Yes", "No");}
- case JOB_DMV:{ShowPlayerDialog(playerid, DIALOG_DUTY_DMV, DIALOG_STYLE_MSGBOX, "Active DMV duty", "Go off DMV duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
- }
- }
- case PICKUP_FACTION_NEWS:{
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_NEWS, DIALOG_STYLE_MSGBOX, "Active broadcasting duty", "Go on network duty as a rookie reporter?", "Yes", "No");}
- case JOB_NEWS:{ShowPlayerDialog(playerid, DIALOG_DUTY_NEWS, DIALOG_STYLE_MSGBOX, "Active broadcasting duty", "Go off network duty?", "Yes", "No");}
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
- }
- }
- }
-
- }
- return 1;
- }
- public OnPlayerLeaveDynamicArea(playerid, areaid){ // Requires streamer
- // Reactivate pickup after player leaves it
- new area = GetGVarInt("disable_pickups", playerid);
- if(area == 0 && areaid != 0){ // Stop if player had not had this area disabled (With the exception of areaid 0 as GetVarInt() returns 0 on null)
- return;
- }
- else if(area == 0){ // Player has not had picks disabled
- return;
- }
- if(area == areaid){ // Player had this pickup disabled
- DestroyDynamicArea(GetGVarInt("disable_pickups", playerid));
- DeleteGVar("disable_pickups", playerid);
- }
- }
- public OnVehicleMod(playerid, vehicleid, componentid) // TODO for 0.0a
- {
- return 1;
- }
- public OnVehiclePaintjob(playerid, vehicleid, paintjobid) // TODO for 0.0a
- {
- return 1;
- }
- public OnVehicleRespray(playerid, vehicleid, color1, color2) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerSelectedMenuRow(playerid, row) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerExitedMenu(playerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) // TODO for 0.0a
- {
- return 1;
- }
- public OnRconLoginAttempt(ip[], password[], success){
- new message[30 + MAX_SQL_IP + 1];
- if(success){
- format(message, sizeof(message), "* [%s] authenticated via RCON.", ip);
- }
- else{
- format(message, sizeof(message), "* [%s] invalid RCON authentication.", ip);
- }
- logger(LOGLEVEL_NOTICE, message); // Log event
- DiscordEcho(message, MANAGEMENT_CHANNEL); // Notify Discord management.
- return 1;
- }
- public OnPlayerUpdate(playerid) // Don't use for now.
- {
- return 1;
- }
- public OnPlayerStreamIn(playerid, forplayerid){
- return 1;
- }
- public OnPlayerStreamOut(playerid, forplayerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnVehicleStreamIn(vehicleid, forplayerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnVehicleStreamOut(vehicleid, forplayerid) // TODO for 0.0a
- {
- return 1;
- }
- public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]){
- switch(dialogid){
- case DIALOG_CHANGENAME:{
- if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Registered player
- if(!response){ // User aborted
- return 0; // Allow escaping dialogm without forcing to continue
- }
- }
-
- changeName(playerid, inputtext); // Forced name check and change
- }
- case DIALOG_REGISTER:{
- if(response){ // If they clicked 'Yes' or pressed enter
- // Check password complexity
- new Regex:r = Regex_New("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[0-9!@#\\$%\\^&\\*\\(\\)\\-\\_=+[{\\]}\\\\|;:'\",<.>\\/?]).{8,}$"); // Regex password filter
- new isSecurePassword = Regex_Check(inputtext, r); // Validate name to filter
- Regex_Delete(r);
- if(!isSecurePassword){ // Insecure password
- ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Insecure password", "Enter a secure password, containg at least:\n\n * A lowercase letter (a-z)\n * A capiral letter (A-Z)\n * A number (0-9).\n * A character that is not a letter (0-9!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?).\n * 8 characters.", "Register", "Cancel"); // Show password requirements.
- }
- else { // Secure password
- // Hash password
- new buffer[MAX_SQL_HASH + 1], hash[MAX_SQL_HASH + 1];
- WP_Hash(buffer, sizeof(buffer), inputtext);
- GetGVarString("hash", hash, sizeof(hash), playerid);
- if(isempty(hash)){ // First password dialog
- SetGVarString("hash", buffer, playerid); // Save password has a GVar
- ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password confirmation", "Repeat your password to confirm.", "Register", "Cancel"); // Show password confirmation dialog
- }
- else{ // Password confirmation
- if(!isequal(hash, buffer)){ // Password does not match confirmation
- DeleteGVar("hash", playerid);
-
- SendClientMessage(playerid, COLOR_RED, "ERROR: Password does not match password confirmation.");
- ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password", "Enter the same password twice.", "Continue", "Cancel"); // Password prompt
- }
- else{ // Password matches confirmation
- DeleteGVar("hash", playerid);
-
- new client_connect_username[MAX_PLAYER_NAME + 1], playerIP[MAX_SQL_IP + 1], escaped_username[MAX_PLAYER_NAME + 1];
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
- GetPlayerIp(playerid, playerIP, sizeof(playerIP));
- sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username));
- // Create user record
- new user_query[61 + MAX_PLAYER_NAME + MAX_SQL_HASH + 1 + MAX_SQL_IP + 1];
- format(user_query, sizeof(user_query), "INSERT INTO \"user\"(name, password) VALUES('%s', '%s')", escaped_username, hash);
- /*new Result:user_result = sql_query(sqlHandle, user_query);
- //new id = sql_insert_id(user_result); // Broken, always returns 0.
- // sql_insert_id workaround*/
- sql_query(sqlHandle, user_query);
-
- new id = getUserID(playerid); // Get ID user user record
-
- SetGVarInt("userlevel", REGISTERED_PLAYER, playerid);
- // Create user_ip relation table record
- new user_ip_query[50 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1 ];
- format(user_ip_query, sizeof(user_ip_query), "INSERT INTO user_ip(id, id) VALUES(%i, %i)", getIPID(playerid), id);
- sql_query(sqlHandle, user_ip_query);
- createCharacterRecord(playerid, id); // Save character
-
- // Inform user
- new dialogMessage[135 + MAX_PLAYER_NAME + 1], message[31 + MAX_PLAYER_NAME + 1];
- format(dialogMessage, sizeof(dialogMessage), "To login as any of your characters, connect as: \nRemember your username carefully, as you have to use it to connect with SA-MP client!", client_connect_username);
- ShowPlayerDialog(playerid, DIALOG_ACCOUNT_CREATED, DIALOG_STYLE_MSGBOX, "Account created", dialogMessage, "Play", "");
- format(message, sizeof(message), "SERVER: Remember your username, %s!", client_connect_username);
- SendClientMessage(playerid, COLOR_WARNING, message);
-
- // send discord admin echo
- new admin_message[30 + 4 + MAX_PLAYER_NAME + 1];
- format(admin_message, sizeof(admin_message), "[%i] %s has registered an account.", playerid, client_connect_username);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- }
- }
- }
- else{ // Pressed ESC or clicked cancel
- DeleteGVar("hash", playerid);
- }
- }
- case DIALOG_LOGIN:{
- if(response){ // If they clicked 'Yes' or pressed enter
- // Escape username
- new client_connect_username[MAX_PLAYER_NAME + 1], escaped_username[MAX_PLAYER_NAME + 1];
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
- sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username));
- // Get account
- new user_query[82 + MAX_PLAYER_NAME + 1], hash[MAX_SQL_HASH + 1];
- format(user_query, sizeof(user_query), "SELECT id, password, level FROM \"user\" WHERE name = '%s'", escaped_username);
- new Result:user_result = sql_query(sqlHandle, user_query);
- sql_get_field_assoc_ex(user_result, 0, "password", hash, sizeof(hash));
- // Compare hashes
- new buffer[MAX_SQL_HASH + 1];
- WP_Hash(buffer, sizeof(buffer), inputtext);
- if (!isequal(buffer, hash)){ // Hashes don't match
- // Brute-force protection
- new authentication_count = GetGVarInt("authentication_count", playerid);
- authentication_count++;
- SetGVarInt("authentication_count", authentication_count, playerid);
- ShowPlayerDialog(playerid, DIALOG_LOGIN_FAILED, DIALOG_STYLE_MSGBOX, "Authenticaion failed", "Invalid password.", "Wait", "");
- switch(authentication_count){
- case 0: SetTimerEx("authenticate", 3000, false, "i", playerid); // Return to authentication workflow in 3 second.
- case 1: SetTimerEx("authenticate", 5000, false, "i", playerid); // Return to authentication workflow in 5 seconds.
- case 2: SetTimerEx("authenticate", 7000, false, "i", playerid); // Return to authentication workflow in 7 seconds.
- default: ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", ""); // After 4 failed authentication attempts
- }
- }
- else{ // Hashes match
- // Set userlevel (This has to be done before banning, else the user ban record won't save)
- new userlevel = sql_get_field_assoc_int(user_result, "level");
- printf("Setting userlevel: %i", userlevel);
- SetGVarInt("userlevel", userlevel, playerid);
-
- // Check bans
- new ban_query[76 + MAX_SQL_INTEGER + 1];
- format(ban_query, sizeof(ban_query), "SELECT user_id FROM user_ban WHERE user_id = %i AND expires > NOW()::timestamp", getUserID(playerid));
- new Result:ban_result = sql_query(sqlHandle, ban_query);
- if(sql_num_rows(ban_result) > 0){ // Banned
- new reason[121 + 1];
- format(reason, sizeof(reason), "Logged in with banned account: %i", sql_get_field_assoc_int(ban_result, "user_id"));
- banPlayer(playerid, -1, reason, 10);
- }
-
- // Get character names
- characterSelection(playerid);
- }
- }
- else{ // Pressed ESC or clicked cancel
- ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
- }
- }
- case DIALOG_CHANGE_USERNAME:{
- if(response){ // If they clicked 'Yes' or pressed enter
- new Regex:r = Regex_New("^[0-9a-zA-Z\\[\\]\\(\\)\\$@._=]{1,}$"); // Regex name filter
- new isValidName = Regex_Check(inputtext, r);
- Regex_Delete(r);
- if(isValidName){ // Valid name
- // Get user record
- new escaped_username[MAX_PLAYER_NAME + 1], user_query[36 + MAX_PLAYER_NAME + 1];
- sql_escape_string(sqlHandle, inputtext, escaped_username, sizeof(escaped_username)); // Escape player name
- format(user_query, sizeof(user_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
- //new Result:result = sqlQuery(sqlHandle, user_query); // Middleware broken.
- new Result:result = sql_query(sqlHandle, user_query);
-
- if(sql_num_rows(result) > 0){ // Username taken
- ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
- }
- else{ // Username free
- SetGVarString("client_connect_username", inputtext, playerid); // Used by register and DIALOG_LOGIN
- SetPlayerName(playerid, inputtext); // Change name in-game
- return 1; // Do nothing to let player continue class selection
- }
- }
- else{ // Invalid name
- ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Invalid name. Names may only contain numbers (0-9), letters (a-z) & (A-Z) and special characters ([]()$@._=)", "Change", "");
- }
- }
- else{ // Pick another username
- ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
- }
- }
- case DIALOG_CHARACTERS:{ // TODO set color & skin in case of job
- if(response){ // Spawn as character
- new character_array_string[MAX_CHARACTERS_PER_USER * MAX_SQL_INTEGER + 1], character_array[MAX_CHARACTERS_PER_USER + 1];
- GetGVarString("character_array_string", character_array_string, sizeof(character_array_string), playerid);
- DeleteGVar("character_array_string");
-
- strtobin(character_array, character_array_string);
-
- new character_query[124 + MAX_PLAYER_NAME + 1], name[24 + 1];
- format(character_query, sizeof(character_query), "SELECT name, skin_id, cash, armour, health, pos_x, pos_y, pos_z, rotation, world_id, interior_id FROM character WHERE id = %i", character_array[listitem]);
- new Result:character_result = sql_query(sqlHandle, character_query);
- sql_get_field_assoc(character_result, "name", name, sizeof(name));
- new skin_id = sql_get_field_assoc_int(character_result, "skin_id");
- new cash = sql_get_field_assoc_int(character_result, "cash");
- new Float:armour = sql_get_field_assoc_int(character_result, "armour");
- new Float:health = sql_get_field_assoc_int(character_result, "health");
- new Float:pos_x = sql_get_field_assoc_int(character_result, "pos_x");
- new Float:pos_y = sql_get_field_assoc_int(character_result, "pos_y");
- new Float:pos_z = sql_get_field_assoc_int(character_result, "pos_z");
- new Float:rotation = sql_get_field_assoc_int(character_result, "rotation");
- new world_id = sql_get_field_assoc_int(character_result, "world_id");
- new interior_id = sql_get_field_assoc_int(character_result, "interior_id");
-
- // Temporary bug workaround TODO find cause
- if(pos_x == 0 && pos_y == 0 && pos_z == 0){ // Sometimes this happens. Due to unreliable OnPlayerDisconnect() & OnGamemodeExit(), due to character creation, or due to (forgot the other possiblity, but had a strong hunch)?
- pos_x = -144.0328;
- pos_y = 1225.0564;
- pos_z = 19.8992;
- rotation = 175.5507;
- }
- SetSpawnInfo(playerid, 0, skin_id, pos_x, pos_y, pos_z, rotation, 0, 0, 0, 0, 0, 0);
- SetGVarInt("character_id", character_array[listitem], playerid);
-
- SetPlayerName(playerid, name); // Change name in-game
- SetPlayerColor(playerid, COLOR_WHITE);
- SpawnPlayer(playerid);
- ResetPlayerMoney(playerid);
- GivePlayerMoney(playerid, cash);
- SetPlayerHealth(playerid, health);
- SetPlayerArmour(playerid, armour);
- SetPlayerVirtualWorld(playerid, world_id);
- SetPlayerInterior(playerid, interior_id);
-
- // Notify all players
- new message[16 + 4 + MAX_PLAYER_NAME + 1];
- format(message, sizeof(message), "* [%i] %s joined.", playerid, getCharacterName(playerid));
- SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players.
- DiscordEcho(message, ECHO_CHANNEL); // Notify discord public echo
-
- }
- else{ // New character
- // character cap
- new id = getUserID(playerid);
- new character_query[60 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT id FROM character WHERE character_id = %i", id);
- new Result:character_result = sql_query(sqlHandle, character_query);
- printf("%i", sql_num_rows(character_result));
- if(sql_num_rows(character_result) >= MAX_CHARACTERS_PER_USER){ // At or over character limit
- SendClientMessage(playerid, COLOR_WARNING, "SERVER: Maximum characters reached, can not create another.");
- characterSelection(playerid);
- }
- else{
- ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Pick a name.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
- // changeName(playerid, ""); // Pick name and save character ANNOYING this forces new character creation, no way out.
- }
-
- }
- }
- case DIALOG_LOGIN_FAILED:{
- ShowPlayerDialog(playerid, DIALOG_LOGIN_FAILED, DIALOG_STYLE_MSGBOX, "Authenticaion failed", "Take some time to think about your password...", "Wait", "Longer");
- }
- case DIALOG_DELETE_CHARACTER:{
- if(response){ // Delete character
- new playername[MAX_PLAYER_NAME + 1];
- playername = getPlayerName(playerid);
-
- // Checkcharacter amount
- new id = getUserID(playerid), character_query[75 + MAX_SQL_INTEGER + MAX_CHARACTERS_PER_USER_DIGITS + 1];
- format(character_query, sizeof(character_query), "SELECT id, name FROM character WHERE user_id = %i LIMIT %i", id, MAX_CHARACTERS_PER_USER);
- new Result:character_result = sql_query(sqlHandle, character_query);
- if(sql_num_rows(character_result) < 2){ // 1 character or less
- SendClientMessage(playerid, COLOR_WARNING, "SERVER: You can not have less then one character.\nCreate another character,before deleting this one.");
-
- }
- else{ // More then 1 character
- // delete character record
- new delete_query[50 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
- format(delete_query, sizeof(delete_query), "DELETE FROM character WHERE name = '%s' AND user_id = %i", playername, getUserID(playerid));
- sql_query(sqlHandle, delete_query);
-
- // infordm admin echo
- new client_connect_username[MAX_PLAYER_NAME + 1], message[28 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
- GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
- format(message, sizeof(message), "* [%i] %s has been deleted by it's user: %s", playerid, getCharacterName(playerid), client_connect_username);
- DiscordEcho(message, ADMIN_ECHO_CHANNEL);
- sendToAdmins(COLOR_COMMAND_OUTPUT, message);
-
- // Player must not be spawned or will be able to esacpe the character menu and continue with character without dartabase record
- ForceClassSelection(playerid);
- TogglePlayerSpectating(playerid, true);
- TogglePlayerSpectating(playerid, false);
-
- characterSelection(playerid);
- }
- }
- }
- case DIALOG_GOTO:{
- if(response){
- switch(listitem){
- case GOTO_CATEGORY_INTERIOR:{
- dialogGotoInterior(playerid);
- }
- /*case GOTO_CATEGORY_PLAYER:{
- dialogGotoPlayer(playerid);
- }*/
- }
- }
- }
- case DIALOG_GOTO_INTERIOR:{
- if(response){
- switch(listitem){
- case INTERIOR_CATEGORY_247:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_247, DIALOG_STYLE_TABLIST, "24/7's", "L-shaped\tBig\tNO EXIT\nOblong\tBig\tNO EXIT\nSquare\tMedium\tCreek, LV\nSquare\tMedium\tNO EXIT\nLong\tSmall\tMulholland\nSquare\tSmall\tWhetstone", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_AVIATION:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_AVIATION, DIALOG_STYLE_TABLIST, "Aviation interiors", "Francis Intn'l Airport - Ticket sales\tStarting Cutscene\nFrancis Intn'l Airport - Baggage claim\tStarting Cutscene\nShamal cabin\tMission \"Free Fall\"\nAndromada cargo hold\tMission \"Stowaway\"\nLS Airport, Baggage Reclaim\tCutscene in \"Opening Mission\"", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_AMMUNATION:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_AMMUNATION, DIALOG_STYLE_TABLIST, "Ammunation's", "Ocean Flats\tSF\nPalomino Creek\tLV\nAngel Pine\tSF\nEl Quebrados\tLV\n2 Stories/t with Booth and Range\n Booth\n Range", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_BUGRLARY:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_BURGLARY, DIALOG_STYLE_TABLIST, "Burglary houses", "Large\t2 story\t3 bedroom clone of house 9\t\nMedium\t1 story\t1 bedroom\tEast LS\nSmall\t1 story\t1 bedroom\tCalton Heights, SF\nVery large\t2 story\t4 bedrooms\nSmall\t1 story\t2 bedrooms\tJefferson LS\nSmall\t1 story\t2 bedrooms\tEast LS\nSmall\t1 story\t 1 bedroom (NO BATHROOM!)", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_MISSION:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_MISSION, DIALOG_STYLE_TABLIST, "Mission interiors", "Atrium\tMission \"Just Business\"\tLS\nBig Smoke's Crack Palace\tMission \"End of the Line\"\nJefferson Motel\tMission \"Reuniting the Families\"\tLS\nPleasure Domes/Jizzy's\tMission \"Ice Cold Killa\"\tSF\nRC Battlefield\tMission \"New Model Army\"\nWoozies Apartment/Wu-Zi Mu's\t\tSF\n", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_MISSIONEXT:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_MISSIONEXT, DIALOG_STYLE_TABLIST, "Mission exteriors", "Dillimore Gas Station\tMission \"Tanker Commander\"\nLiberty City\tMission \"Saint Marks Bistro\"\nSan Fierro Garage\tDoherty (Locked Camera Position}", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_MISSIONHOUSE:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_MISSIONHOUSE, DIALOG_STYLE_TABLIST, "Mission houses", "Burning Desire house\t\tEast LS\nColonel Furhberger's\tMission \"Home Invasion\"\t Los Flores, LS\nRyder's house\nSweet's house\tCutscene in \"First Date\"\nCrack Den\tMission \"Cleaning The Hood\"", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_MODSHOP:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_MODDING, DIALOG_STYLE_TABLIST, "Modding shops", "Loco Low Co\tLos Santos\nWheel Arch Angels\tSan Fierro\nTransfender", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_POLICE:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_POLICE, DIALOG_STYLE_LIST, "Police departments", "Las Venturas\nLos Santos\nSan Fierro\nBarbara's love nest", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_HOUSES:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_HOUSE, DIALOG_STYLE_TABLIST, "Safe houses", "Golden Bed motel room\t\t\nHashbury house\tHashburry\tSF\nThe Johnson house\tGanton\tLS\nMadd Doggs mansion\tMulholland\tLS\nRed Bed motel Room\nVerdant Bluffs safehouse\tVerdant Bluffs\t LV\nUnused safehouse\tLarge modern safehouse", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_SHOPS:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_SHOP, DIALOG_STYLE_TABLIST, "Shops & casino's", "Tattoos\tIdlewood\tLS\nBurger Shot\tWhitewood Estates\nWell Stacked Pizza\tBlueberry\nCluckin' Bell\nCaligulas casino\tThe Strip\tLV\nCasino (Redsands West)\tThe Strip\tLV\n4 Dragons casino\tThe Strip\tLV\nRusty Brown's donuts\tMission \"Burning Desire\"\nZero's RC shop\tGarcia\tSF\nThe Welcome Pump", "Goto", "Cancel");
- }
- case INTERIOR_CATEGORY_STADIA:{
- ShowPlayerDialog(playerid, DIALOG_GOTO_STADIA, DIALOG_STYLE_TABLIST, "Stadia", "Bloodbowl stadium\nKickstart stadium\n8 Track stadium\nDirtbike stadium\n", "Goto", "Cancel");
- }
- }
- }
- else{
- ShowPlayerDialog(playerid, DIALOG_GOTO, DIALOG_STYLE_LIST, "Categories", "Interiors", "Select", "Cancel");
- }
- }
- case DIALOG_GOTO_247:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
- switch(listitem){
- case INTERIOR_247_LSHAPED:{
- x = -25.7220;
- y = -187.8216;
- z = 1003.5469;
- world = GetPlayerVirtualWorld(playerid);
- interior = 17;
- angle = 5.0760;
- name = "L-shaped ammunation";
- }
- case INTERIOR_247_OBLONG:{
- x = 6.0856;
- y = -28.8966;
- z = 1003.5494;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 5.0365;
- name = "Oblong ammunation";
- }
- case INTERIOR_247_MEDIUM:{
- x = -30.9875;
- y = -89.6806;
- z = 1003.5469;
- world = GetPlayerVirtualWorld(playerid);
- interior = 18;
- angle = 359.8401;
- name = "Medium ammunation";
- }
- case INTERIOR_247_MEDIUM_NOEXIT:{
- x = -26.1856;
- y = -140.9164;
- z = 1003.5469;
- world = GetPlayerVirtualWorld(playerid);
- interior = 16;
- angle = 2.9087;
- name = "Medium no exit ammunation";
- }
- case INTERIOR_247_LONG:{
- x = -27.844;
- y = 26.6737;
- z = 1003.5573;
- world = GetPlayerVirtualWorld(playerid);
- interior = 4;
- angle = 184.3118;
- name = "Small long ammunation";
- }
- case INTERIOR_247_SQAURE:{
- x = -26.8339,
- y = -55.5846,
- z = 1003.5469,
- world = GetPlayerVirtualWorld(playerid),
- interior = 6,
- angle = 3.9528;
- name = "Small square ammunation";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_AVIATION:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[39 + 1];
- switch(listitem){
- case INTERIOR_AVIATION_TICKET:{
- x = -1827.147338;
- y = 7.207418;
- z = 1061.143554;
- world = GetPlayerVirtualWorld(playerid);
- interior = 14;
- angle = 335.3199;
- name = "Francis Intn'l Airport - Ticket sales";
- }
- case INTERIOR_AVIATION_BAGGAGE:{
- x = -1855.568725;
- y = 41.263156;
- z = 1061.143554;
- world = GetPlayerVirtualWorld(playerid);
- interior = 14;
- angle = 335.3199;
- name = "Francis Intn'l Airport - Baggage claim";
- }
- case INTERIOR_AVIATION_SHAMAL:{
- x = 2.384830;
- y = 33.103397;
- z = 1199.849976 ;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 359.8401;
- name = "Shamal cabin";
- }
- case INTERIOR_AVIATION_ANDROMADA:{
- x = 315.856170;
- y = 1024.496459;
- z = 1949.797363;
- world = GetPlayerVirtualWorld(playerid);
- interior = 9;
- angle = 359.6368;
- name = "Andromada cargo hold";
- }
- case INTERIOR_AVIATION_LSAIRPORT:{
- x = -1870.80;
- y = 59.81;
- z = 1056.25;
- world = GetPlayerVirtualWorld(playerid);
- interior = 14;
- angle = 85.8541;
- name = "LS Airport, Baggage Reclaim";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_AMMUNATION:{ // TODO there are more ammunations that deserve a booth and range teleport
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
- switch(listitem){
- case INTERIOR_AMMU_OCEAN:{
- x = 286.148987;
- y = -40.644398 ;
- z = 1001.569946;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 0.7529;
- name = "Ocean Flats, SF";
- }
- case INTERIOR_AMMU_PALOMINO:{
- x = 286.800995;
- y = -82.547600;
- z = 1001.539978;
- world = GetPlayerVirtualWorld(playerid);
- interior = 4;
- angle = 290.2195;
- name = "Palomino Creek, LV";
- }
- case INTERIOR_AMMU_ANGEL:{
- x = 296.919983;
- y = -108.071999;
- z = 1001.569946;
- world = GetPlayerVirtualWorld(playerid);
- interior = 6;
- angle = 290.2195;
- name = "Angel Pine, SF";
- }
- case INTERIOR_AMMU_QUEBRADOS:{
- x = 316.524994;
- y = -167.706985;
- z = 999.661987;
- world = GetPlayerVirtualWorld(playerid);
- interior = 6;
- angle = 10.3031;
- name = "El Quebrados, LV";
- }
- case INTERIOR_AMMU_2STORIES:{
- x = 314.820984;
- y = -141.431992;
- z = 999.661987;
- world = GetPlayerVirtualWorld(playerid);
- interior = 7;
- angle = 20.2254;
- name = "2 Stories, with booth and range";
- }
- case INTERIOR_AMMU_BOOTH:{
- x = 302.292877;
- y = -143.139099;
- z = 1004.062500;
- world = GetPlayerVirtualWorld(playerid);
- interior = 7;
- angle = 20.2254;
- name = "Booth";
- }
- case INTERIOR_AMMU_RANGE:{
- x = 280.795104;
- y = -135.203353;
- z = 1004.062500;
- world = GetPlayerVirtualWorld(playerid);
- interior = 7;
- angle = 20.2254;
- name = "Range";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_BURGLARY:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[45 + 1];
- switch(listitem){
- case INTERIOR_BURGRLARY_LARGE:{
- x = 235.508994;
- y = 1189.169897;
- z = 1080.339966;
- world = GetPlayerVirtualWorld(playerid);
- interior = 3;
- angle = 349.4844;
- name = "Large: 2 story, 3 bedroom clone of house 9";
- }
- case INTERIOR_BURGRLARY_MEDIUM:{
- x = 225.756989;
- y = 1240.000000;
- z = 1082.149902;
- world = GetPlayerVirtualWorld(playerid);
- interior = 2;
- angle = 96.2852;
- name = "Medium: 1 story, 1 bedroom";
- }
- case INTERIOR_BURGRLARY_SMALL:{
- x = 223.043991;
- y = 1289.259888;
- z = 1082.199951;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 359.868;
- name = "Small: 1 story, 1 bedroom";
- }
- case INTERIOR_BURGRLARY_VERYLARGE:{
- x = 225.630997;
- y = 1022.479980;
- z = 1084.069946;
- world = GetPlayerVirtualWorld(playerid);
- interior = 7;
- angle = 270.2654;
- name = "VERY Large: 2 story, 4 bedrooms";
- }
- case INTERIOR_BURGRLARY_5:{
- x = 295.138977;
- y = 1474.469971;
- z = 1080.519897;
- world = GetPlayerVirtualWorld(playerid);
- interior = 15;
- angle = 0;
- name = "Small: 1 story, 2 bedrooms";
- }
- case INTERIOR_BURGRLARY_6:{
- x = 328.493988;
- y = 1480.589966;
- z = 1084.449951;
- world = GetPlayerVirtualWorld(playerid);
- interior = 15;
- angle = 0;
- name = "Small: 1 story, 2 bedrooms";
- }
- case INTERIOR_BURGRLARY_NOBATH:{
- x = 385.803986;
- y = 1471.769897;
- z = 1080.209961;
- world = GetPlayerVirtualWorld(playerid);
- interior = 15;
- angle = 0;
- name = "Small: 1 story, 1 bedroom (NO BATHROOM!)";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_MISSION:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
- switch(listitem){
- case INTERIOR_MISSION_ATRIUM:{
- x = 1726.18;
- y = -1641.00;
- z = 20.23;
- world = GetPlayerVirtualWorld(playerid);
- interior = 18;
- angle = 172.4193;
- name = "Atrium";
- }
- case INTERIOR_MISSION_BIGSMOKE:{
- x = 2567.52;
- y = -1294.59;
- z = 1063.25 ;
- world = GetPlayerVirtualWorld(playerid);
- interior = 2;
- angle = 254.9548;
- name = "Big Smoke's Crack Palace";
- }
- case INTERIOR_MISSION_JEFFERSON:{
- x = 2220.26;
- y = -1148.01;
- z = 1025.80;
- world = GetPlayerVirtualWorld(playerid);
- interior = 15;
- angle = 273.7328;
- name = "Jefferson Motel";
- }
- case INTERIOR_MISSION_JIZZY:{
- x = -2637.69;
- y = 1404.24;
- z = 906.46;
- world = GetPlayerVirtualWorld(playerid);
- interior = 3;
- angle = 94.6794;
- name = "Pleasure Domes/Jizzy's";
- }
- case INTERIOR_MISSION_RC:{
- x = -1079.99;
- y = 1061.58;
- z = 1343.04;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 274.5268;
- name = "RC Battlefield";
- }
- case INTERIOR_MISSION_WUZI:{
- x = -2158.72;
- y = 641.29;
- z = 1052.38;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 86.5402;
- name = "Woozies Apartment/Wu-Zi Mu's";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_MISSIONEXT:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
- switch(listitem){
- case INTERIOR_MISSIONEXT_GAS:{
- x = 664.19;
- y = -570.73;
- z = 16.34;
- world = GetPlayerVirtualWorld(playerid);
- interior = 0;
- angle = 264.9829;
- name = "Dillimore Gas Station";
- }
- case INTERIOR_MISSIONEXT_LIBERTY:{ // TODO Create extra interior inside the shop
- x = -750.80;
- y = 491.00;
- z = 1371.70;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 71.7782;
- name = "Liberty City";
- }
- case INTERIOR_MISSIONEXT_SFGARAGE:{ // TODO Create extra interior of area that does not capture the camera & see about the camera camera capturing (Use it for broadcast? & In other world or interior place more usable?)
- x = -2042.42;
- y = 178.59;
- z = 28.84;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 156.2153;
- name = "San Fierro Garage Interior";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_MISSIONHOUSE:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
- switch(listitem){
- case INTERIOR_MISSIONHOUSE_DESIRE:{
- x = 2338.32;
- y = -1180.61;
- z = 1027.98;
- world = GetPlayerVirtualWorld(playerid);
- interior = 5;
- angle = 99.1864;
- name = "Burning Desire House";
- }
- case INTERIOR_MISSIONHOUSE_COLONEL:{
- x = 2807.63;
- y = -1170.15;
- z = 1025.57;
- world = GetPlayerVirtualWorld(playerid);
- interior = 8;
- angle = 193.7117;
- name = "Colonel Furhberger's";
- }
- case INTERIOR_MISSIONHOUSE_RYDER:{
- x = 2451.77;
- y = -1699.80;
- z = 1013.51;
- world = GetPlayerVirtualWorld(playerid);
- interior = 2;
- angle = 314.5253;
- name = "Ryder's House";
- }
- case INTERIOR_MISSIONHOUSE_SWEET:{
- x = 2535.83;
- y = -1674.32;
- z = 1015.50;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 260.9709;
- name = "Sweet's House";
- }
- case INTERIOR_MISSIONHOUSE_CRACK:{
- x = 318.565;
- y = 1115.210;
- z = 1082.98;
- world = GetPlayerVirtualWorld(playerid);
- interior = 5;
- angle = 267.459;
- name = "Crack den";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_MODDING:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
- switch(listitem){
- case INTERIOR_MOD_LOCO:{
- x = 616.7820;
- y = -74.8151;
- z = 997.6350;
- world = GetPlayerVirtualWorld(playerid);
- interior = 2;
- angle = 320.9263;
- name = "Loco Low Co";
- }
- case INTERIOR_MOD_WHEEL:{
- x = 615.2851;
- y = -124.2390;
- z = 997.6350;
- world = GetPlayerVirtualWorld(playerid);
- interior = 3;
- angle = 266.5704;
- name = "Wheel Arch Angels";
- }
- case INTERIOR_MOD_TRANSFENDER:{
- x = 617.5380;
- y = -1.9900;
- z = 1000.6829;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 15.6789;
- name = "Transfender";
- }
- }
-
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_POLICE:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
- switch(listitem){
- case INTERIOR_PD_LV:{
- x = 288.4723;
- y = 170.0647;
- z = 1007.1794;
- world = GetPlayerVirtualWorld(playerid);
- interior = 3;
- angle = 22.0477;
- name = "Las Venturas police deparment";
- }
- case INTERIOR_PD_LS:{
- x = 246.6695;
- y = 65.8039;
- z = 1003.6406;
- world = GetPlayerVirtualWorld(playerid);
- interior = 6;
- angle = 7.9562;
- name = "Los Santos police deparment";
- }
- case INTERIOR_PD_SF:{
- x = 246.0688;
- y = 108.9703;
- z = 1003.2188;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 0.2922;
- name = "San Fierro police deparment";
- }
- case INTERIOR_PD_BARBARA:{
- x = 322.5014;
- y = 303.6906;
- z = 999.1484;
- world = GetPlayerVirtualWorld(playerid);
- interior = 5;
- angle = 8.1747;
- name = "Barbara's Love nest";
- }
- }
-
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_HOUSE:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
- switch(listitem){
- case INTERIOR_HOUSE_GOLDEN:{
- x = 2251.85;
- y = -1138.16;
- z = 1050.63;
- world = GetPlayerVirtualWorld(playerid);
- interior = 9;
- angle = 167.3959;
- name = "Golden Bed motel room";
- }
- case INTERIOR_HOUSE_HASHBURY:{
- x = 2260.76;
- y = -1210.45;
- z = 1049.02;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 266.88;
- name = "Hashbury house";
- }
- case INTERIOR_HOUSE_JOHNSON:{
- x = 2496.65;
- y = -1696.55;
- z = 1014.74;
- world = GetPlayerVirtualWorld(playerid);
- interior = 3;
- angle = 179.2174;
- name = "The Johnson house";
- }
- case INTERIOR_HOUSE_MADDDOGG:{
- x = 1299.14;
- y = -794.77;
- z = 1084.00;
- world = GetPlayerVirtualWorld(playerid);
- interior = 5;
- angle = 231.3418;
- name = "Madd Doggs mansion";
- }
- case INTERIOR_HOUSE_RED:{
- x = 2262.83;
- y = -1137.71;
- z = 1050.63;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 266.88;
- name = "Red Bed motel room";
- }
- case INTERIOR_HOUSE_VERDANT:{
- x = 2365.42;
- y = -1131.85;
- z = 1050.88;
- world = GetPlayerVirtualWorld(playerid);
- interior = 8;
- angle = 177.3947;
- name = "Verdant Bluffs safehouse";
- }
- case INTERIOR_HOUSE_UNUSED:{
- x = 2324.33;
- y = -1144.79;
- z = 1050.71;
- world = GetPlayerVirtualWorld(playerid);
- interior = 12;
- angle = 269.0954;
- name = "Unused safe house";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_SHOP:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
- switch(listitem){
- case INTERIOR_SHOP_TATTOO:{
- x = -203.0764;
- y = -24.1658;
- z = 1002.2734;
- world = GetPlayerVirtualWorld(playerid);
- interior = 16;
- angle = 252.8154;
- name = "Tattoos";
- }
- case INTERIOR_SHOP_BURGER:{
- x = 366.0248;
- y = -73.3478;
- z = 1001.5078;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 292.0084;
- name = "Burger Shot";
- }
- case INTERIOR_SHOP_PIZZA:{
- x = 372.3520;
- y = -131.6510;
- z = 1001.4922;
- world = GetPlayerVirtualWorld(playerid);
- interior = 5;
- angle = 354.2285;
- name = "Well Stacked Pizza";
- }
- case INTERIOR_SHOP_CLUCKIN:{
- x = 365.7158;
- y = -9.8873;
- z = 1001.8516;
- world = GetPlayerVirtualWorld(playerid);
- interior = 9;
- angle = 160.528;
- name = "Cluckin' Bell";
- }
- case INTERIOR_SHOP_CALIGULAS:{
- x = 2233.8032;
- y = 1712.2303;
- z = 1011.7632;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 184.3891;
- name = "Caligulas Casino";
- }
- case INTERIOR_SHOP_CASINO:{
- x = 1118.8878;
- y = -10.2737;
- z = 1002.0859;
- world = GetPlayerVirtualWorld(playerid);
- interior = 12;
- angle = 165.8482;
- name = "Casino (Redsands West)";
- }
- case INTERIOR_SHOP_4DRAGONS:{
- x = 2016.2699;
- y = 1017.7790;
- z = 996.8750;
- world = GetPlayerVirtualWorld(playerid);
- interior = 10;
- angle = 88.0055;
- name = "4 Dragons Casino";
- }
- case INTERIOR_SHOP_DONUTS:{
- x = 376.99;
- y = -191.21;
- z = 1000.63;
- world = GetPlayerVirtualWorld(playerid);
- interior = 17;
- angle = 141.0245;
- name = "Rusty Brown's donuts";
- }
- case INTERIOR_SHOP_RC:{
- x = -2240.00;
- y = 131.00;
- z = 1035.40;
- world = GetPlayerVirtualWorld(playerid);
- interior = 6;
- angle = 269.0954;
- name = "Zero's RC shop";
- }
- case INTERIOR_SHOP_PUMP:{
- x = 681.66;
- y = -453.32;
- z = -25.61;
- world = GetPlayerVirtualWorld(playerid);
- interior = 1;
- angle = 166.166;
- name = "The Welcome Pump";
- }
- }
-
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
- case DIALOG_GOTO_STADIA:{
- if(response){
- new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
- switch(listitem){
- case INTERIOR_STADIUM_BLOODBOWL:{
- x = -1394.20;
- y = 987.62;
- z = 1023.96;
- world = GetPlayerVirtualWorld(playerid);
- interior = 15;
- angle = 0.7013;
- name = "Bloodbowl Stadium";
- }
- case INTERIOR_STADIUM_KICKSTART:{
- x = -1410.72;
- y = 1591.16;
- z = 1052.53;
- world = GetPlayerVirtualWorld(playerid);
- interior = 14;
- angle = 159.1255;
- name = "Kickstart Stadium";
- }
- case INTERIOR_STADIUM_8TRACK:{
- x = -1395.958;
- y = -208.197;
- z = 1051.170;
- world = GetPlayerVirtualWorld(playerid);
- interior = 7;
- angle = 355.8576;
- name = "8 Track Stadium";
- }
- case INTERIOR_STADIUM_DIRTBIKE:{
- x = -1424.9319;
- y = -664.5869;
- z = 1059.8585;
- world = GetPlayerVirtualWorld(playerid);
- interior = 4;
- angle = 170.9341;
- name = "Dirtbike Stadium";
- }
- }
- new target_player = GetGVarInt("goto_target", playerid);
- DeleteGVar("goto_target", playerid);
- teleportPlayer(target_player, x, y, z, world, interior, angle, name);
- }
- else{dialogGotoInterior(playerid);}
- }
-
- case DIALOG_CREATE_PICKUP:{
- if(response){
- switch(listitem){
- case 0: ShowPlayerDialog(playerid, DIALOG_CREATE_FACTION_PICKUP, DIALOG_STYLE_LIST, "Faction types", "Police\nMedic\nFire fighter\nFederal Bureau of Investigation\nDepeartment of motorvehicles\nBroadcasting", "Select", "Cancel"); }
- }
- }
- case DIALOG_CREATE_FACTION_PICKUP:{
- if(response){
- printf("Listitem: % i", listitem);
- new Float:x, Float:y, Float:z;
- GetPlayerPos(playerid, x, y, z);
- new world = GetPlayerVirtualWorld(playerid);
- new interior = GetPlayerInterior(playerid);
-
- new pickupid = createDynamicPickup(1247, x, y, z, world, interior, listitem);
- // Create pickup record
- new pickup_query[127 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
- format(pickup_query, sizeof(pickup_query), "INSERT INTO pickup(object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id, pickup_id) VALUES (1247, '%f', '%f', '%f', %i, %i, %i, %i)", x, y, z, world, interior, listitem, pickupid);
- sql_query(sqlHandle, pickup_query);
- // Get pickup record ID
- new id_query[44 + 1];
- format(id_query, sizeof(id_query), "SELECT id FROM pickup WHERE pickup_id = %i", pickupid);
- new Result:id_result = sql_query(sqlHandle, id_query);
- new pickup_id = sql_get_field_assoc_int(id_result, "id");
-
- new admin_message[21 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
-
- // Inform admins
- listitem++; // To account for FACTION_NONE
- printf("Listitem: % i", listitem);
- switch(listitem){
- case FACTION_POLICE: format(admin_message, sizeof(admin_message), "* [%i] %s created police faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_MEDIC: format(admin_message, sizeof(admin_message), "* [%i] %s created medic faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_FIRE: format(admin_message, sizeof(admin_message), "* [%i] %s created firefighter faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_SHERIFF: format(admin_message, sizeof(admin_message), "* [%i] %s created shariff faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_FBI: format(admin_message, sizeof(admin_message), "* [%i] %s created FBI faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_DMV: format(admin_message, sizeof(admin_message), "* [%i] %s created DMV faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- case FACTION_NEWS: format(admin_message, sizeof(admin_message), "* [%i] %s created broadcasting faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
- default: return 0;
- }
- sendToAdmins(COLOR_NOTICE, admin_message);
- DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
- }
- }
-
- case DIALOG_DUTY_PD:{ // TODO: Make DRY DUTY_ & _SKIN
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
-
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_POLICE_SKIN, DIALOG_STYLE_TABLIST, "Police skins", "Police Officer\tMale\tLS\nPolice Officer\tMale\tSF\nMotorbike Cop\tMale\tLS\nPolice Officer (Without gun holster)\tMale\tLS\nPolice Officer (Without gun holster)\tMale\tSF\nPolice Officer\tFemale\tLS\nPolice Officer\tFemale\tSF", "Duty", "Cancel");
- }
- case JOB_POLICE:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- ResetPlayerWeapons(playerid);
- // TODO: get weaponskill fromddatabase and set it to player.
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_POLICE_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 280;}
- case 1:{skin = 281;}
- case 2:{skin = 284;}
- case 3:{skin = 300;}
- case 4:{skin = 301;}
- case 5:{skin = 306;}
- case 6:{skin = 307;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_POLICE, playerid);
- SetPlayerColor(playerid, COLOR_POLICE);
- SetPlayerSkillLevel(playerid, WEAPONSKILL_PISTOL, 1);
- GivePlayerWeapon(playerid, 3, 1); // Baton
- GivePlayerWeapon(playerid, 17, 10); // Teargas
- GivePlayerWeapon(playerid, 22, 170); // 10 clips and a 9mm
- }
- }
- case DIALOG_DUTY_MD:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_MEDIC_SKIN, DIALOG_STYLE_TABLIST, "Paramedic skins", "Los Santos white\tMale\nLas Venturas blue\tMale\nSan Fierro green\tMale\nSan Fierro green\tFemale", "Duty", "Cancel");
- }
- case JOB_MEDIC:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_MEDIC_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 274;}
- case 1:{skin = 275;}
- case 2:{skin = 276;}
- case 3:{skin = 308;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_MEDIC, playerid);
- SetPlayerColor(playerid, COLOR_MEDIC);
- }
- }
- case DIALOG_DUTY_FD:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_FIRE_SKIN, DIALOG_STYLE_TABLIST, "Firefighter skins", "Los Santos green\tMale\nLas Venturas yellow\tMale\nSan Fierro black\tMale", "Duty", "Cancel");
- }
- case JOB_FIRE:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- ResetPlayerWeapons(playerid);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_FIRE_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 277;}
- case 1:{skin = 278;}
- case 2:{skin = 279;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_FIRE, playerid);
- SetPlayerColor(playerid, COLOR_FIRE);
- GivePlayerWeapon(playerid, 42, 1); // Fire extinguisher
- }
- }
- case DIALOG_DUTY_SD:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_SHERIFF_SKIN, DIALOG_STYLE_TABLIST, "Sheriff skins", "Officer\tMale\tLV\nCounty sheriff\tMale\tCountryside\nDesert sheriff\tMale\tDesert\nOfficer (Without gun holster)\tMale\nOfficer\tFemale\nCounty sheriff (Without hat)\tMale\nDesert sheriff\tMale", "Duty", "Cancel");
- }
- case JOB_SHERIFF:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- // TODO restore weaponskill
- ResetPlayerWeapons(playerid);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_SHERIFF_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 282;}
- case 1:{skin = 283;}
- case 2:{skin = 288;}
- case 3:{skin = 302;}
- case 4:{skin = 309;}
- case 5:{skin = 310;}
- case 6:{skin = 311;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_SHERIFF, playerid);
- SetPlayerColor(playerid, COLOR_SHERIFF);
- SetPlayerSkillLevel(playerid, WEAPONSKILL_PISTOL, 1);
- GivePlayerWeapon(playerid, 3, 1); // Baton
- GivePlayerWeapon(playerid, 17, 10); // Teargas
- GivePlayerWeapon(playerid, 22, 170); // 10 clips and a 9mm
- }
- }
- case DIALOG_DUTY_FBI:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_FBI_SKIN, DIALOG_STYLE_TABLIST, "Agent skins", "Caucasian MIB agent\tMale\nAfro-American MIB agent\tMale\nSWAT special forces\tMale\nFBI agent\tMale\nAfro-American bouncer\tMale\nCaucasian Bouncer\tMale\nOriental businesswoman\tFemale\nCaucasian businesswoman\tFemale", "Duty", "Cancel");
- }
- case JOB_FBI:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- ResetPlayerWeapons(playerid);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_FBI_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 165;}
- case 1:{skin = 166;}
- case 2:{skin = 258;}
- case 3:{skin = 286;}
- case 4:{skin = 163;}
- case 5:{skin = 164;}
- case 7:{skin = 141;}
- case 8:{skin = 150;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_FBI, playerid);
- SetPlayerColor(playerid, COLOR_FBI);
- GivePlayerWeapon(playerid, 23, 170); // 10 clips and a silenced 9mm
-
- }
- }
- case DIALOG_DUTY_DMV:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_DMV_SKIN, DIALOG_STYLE_TABLIST, "DMV skins", "Airport ground worker\tMale\nSecurity guard\tMale", "Duty", "Cancel");
- }
- case JOB_DMV:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- ResetPlayerWeapons(playerid);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_DMV_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 16;}
- case 1:{skin = 71;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_DMV, playerid);
- SetPlayerColor(playerid, COLOR_DMV);
- GivePlayerWeapon(playerid, 17, 10); // Teargas
- }
- }
- case DIALOG_DUTY_NEWS:{
- if(response){
- // TODO: Check if has passport
- switch(GetGVarInt("job", playerid)){
- case JOB_NONE:{
- // TODO: Check for crimes, warrents, etc
- ShowPlayerDialog(playerid, DIALOG_DMV_SKIN, DIALOG_STYLE_TABLIST, "Network skins", "Hispanic businesswoman\nCaucasian Businesswoman\nBusinessman\nRich woman", "Duty", "Cancel");
- }
- case JOB_NEWS:{
- // Get skin from character record
- new character_query[42 + MAX_SQL_INTEGER + 1];
- format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
- new Result:id_result = sql_query(sqlHandle, character_query);
- new skin_id = sql_get_field_assoc_int(id_result, "skin_id");
- setPlayerSkin(playerid, skin_id);
- SetGVarInt("job", JOB_NONE, playerid);
- SetPlayerColor(playerid, COLOR_WHITE);
- ResetPlayerWeapons(playerid);
- }
- default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
- }
- }
- }
- case DIALOG_NEWS_SKIN:{
- if(response){
- new skin;
- switch(listitem){
- case 0:{skin = 148;}
- case 1:{skin = 150;}
- case 2:{skin = 187;}
- case 3:{skin = 219;}
- }
- setPlayerSkin(playerid, skin);
- SetGVarInt("job", JOB_NEWS, playerid);
- SetPlayerColor(playerid, COLOR_NEWS);
- GivePlayerWeapon(playerid, 43, 1); // Camera
- }
- }
- }
-
- return 0; // MUST return 0 here, just like OnPlayerCommandText.
- }
- public OnPlayerClickPlayer(playerid, clickedplayerid, source) // TODO for 0.0a
- {
- return 1;
- }
- public OnEnterExitModShop(playerid, enterexit, interiorid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid) // TODO for 0.0a
- {
- return 1;
- }
- public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid) // TODO for 0.0a
- {
- return 1;
- }
- // discord-connector events
- public DCC_OnMessageCreate(DCC_Message:message){
- // Originating Discord channel
- new DCC_Channel:channel;
- DCC_GetMessageChannel(message, channel);
- // Originating Discord user
- new DCC_User:author;
- DCC_GetMessageAuthor(message, author);
- // Message content
- new str[128 + 1]; // Orignal was 256
- new command[32 + 1], params[128 + 1];
- DCC_GetMessageContent(message, str);
- sscanf(str, "s[32]s[128]", command, params); // This string is to small some times, and throws an error BROKEN TODO
- // Ignore bots
- new bool:isBot;
- DCC_IsUserBot(author, isBot);
- if(isBot){
- return 1;
- }
- if(!strcmp(command, "!players")){
- new players_string[14 + (2 * MAX_PLAYERS) + (MAX_PLAYER_NAME * MAX_PLAYERS) + 1] = "Online players:";
- for(new playerid, a = GetMaxPlayers(); playerid < a; playerid++){
- if(IsPlayerConnected(playerid)){
- format(players_string, sizeof(players_string), "%s %s,", players_string, getPlayerName(playerid));
- }
- }
- strdel(players_string, strlen(players_string), strlen(players_string)); // Delete trailing comma
- DiscordSendChannelMessage(channel, players_string);
- print("Should be sending players");
- }
- else if(!strcmp(command, "!ip")){
- DiscordSendChannelMessage(channel, "ecrp.h0v1n8.nl:6666");
- }
- else{
- if(channel == echoChannel){
- sendToChat(-1, CHAT_GLOBAL, str, 0, author);
- }
- }
- /*// Beyond this point, don't respond to commands on foreign guilds.
- if(guild != homeGuild){
- return 1;
- }*/
- // Beyond this point, only respond to privilaged channels.
- if(channel != adminEchoChannel && channel != adminChannel && channel != managementChannel){
- return 1;
- }
- // Test command.
- if(!strcmp(command, "!test", true)){
- DiscordSendChannelMessage(channel, "Works.");
- print("Some said !test in the echo channel.");
- }
- return 1;
- }
- // Entrypoint
- main(){
- // Credits
- print("\n*----------------------------------*");
- print(" RPFW by tBKwtWS.");
- new message[21 + 20 + 1];
- format(message, sizeof(message), " Role-play framework v%s", MODE_NAME);
- print(message);
- //printf("System load average: %f",loadavg()); // Linux only TODO: test
- print("*----------------------------------*\n");
- }
|