1 Star 5 Fork 2

提米吖 / MCBE-LLScriptEngine-TMEssential

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
TMEssential.js 265.54 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985
/*--------------------------------
_______ __ __ ______ _ _ _
|__ __| \/ | ____| | | (_) | |
| | | \ / | |__ ___ ___ ___ _ __ | |_ _ __ _| |
| | | |\/| | __| / __/ __|/ _ \ '_ \| __| |/ _` | |
| | | | | | |____\__ \__ \ __/ | | | |_| | (_| | |
|_| |_| |_|______|___/___/\___|_| |_|\__|_|\__,_|_|
Produced by Timiya
TMEssential is distributed under the GPLv3 License
该插件由提米吖创作
未经允许禁止擅自修改或者发售
该插件仅在[gitee,MineBBS,MCWeBBS]仓库发布
禁止二次发布插件
----------------------------------*/
//LiteLoaderScript Dev Helper
/// <reference path="c:\Users\Administrator\.vscode\extensions\moxicat.llscripthelper-2.1.5/dts/llaids/src/index.d.ts"/>
let TMET_RunPath = "./plugins/TMEssential.js";
const TMET_LogDir = "./logs/TMEssential/{1}";
const TMET_ErrorLogDir = "./logs/Error/{1}";
const TMET_CfgDir = "./plugins/Timiya/config/{1}";
const TMET_DataDir = "./plugins/Timiya/data/{1}";
const TMET_LangDir = "./plugins/Timiya/lang/{1}";
const TMET_DebugLogPath = "./logs/TMETDebug.log";
let LLMoney_ConfigPath = "./plugins/LLMoney/money.json";
let IsQuickJs = true;
let ServerIsStarted = false;
//#region Configs
let _Configs = {
"TMET": {//预释放配置文件(勿改)
"Enable": true,
"AutoUpdate": {
"Enable": true,
"AutoReload": true
},
"SelectForm": {
"Subsection": 40
},
"Language": {
"Default": "zh_CN",
"Cmd": "language"
},
"TPA": {
"Enable": true,
"ExpirationTime": 40,
"ConsumeMoney": 0
},
"WARP": {
"Enable": true,
"ConsumeMoney": 0
},
"Back": {
"Enable": true,
"MaxSave": 5,
"SaveToFile": true,
"InvincibleTime": 5,
"ConsumeMoney": 0
},
"Home": {
"Enable": true,
"MaxHome": 3,
"SaveRequiredMoney": 0,
"GoHomeRequiredMoney": 0,
"DelHomeBackOffMoney": 0
},
"Money": {
"Enable": true,
"MoneyType": "score",
"MoneyName": "money",
"PayTaxRate": 0.0,
"HistoryLength": 10,
"MaxRankingQuantity": 100,
"MoneyChangeMsg": true,
"PlayerInitialMoney": 0
},
"Notice": {
"Enable": true,
"JoinOpenNotice": true,
"NoticeTitle": "hello",
"NoticeText": "test"
},
"Shop": {
"Enable": true
},
"DynamicMotd": {
"Enable": true,
"Time": 5,
"MotdList": [
"test",
"test2"
]
},
"TPR": {
"Enable": true,
"MaxXZCoordinate": 10000,
"MinXZCoordinate": -10000,
"ConsumeMoney": 0
},
"RefreshChunk": {
"Enable": true,
"ConsumeMoney": 0
},
"FarmLandProtect": {
"Enable": true,
"Type": 0
},
"UseLog": {
"Enable": true,
"Conf": {
"API": false,
"Language": true,
"TPA": true,
"WARP": true,
"Back": true,
"Home": true,
"Money": true,
"Notice": true,
"Shop": true,
"DynamicMotd": false,
"TPR": true,
"RefreshChunk": true,
"FarmLandProtect": false
}
}
},
"SHOP": {//预释放商店实例文件(勿改)
"Buy": [
{
"name": "xx分类",
"type": "group",
"image": "textures/items/book_portfolio.png",
"data": [
{
"name": "空气",
"type": "exam",
"image": "",
"data": {
"type": "minecraft:air",
"aux": 0,
"remark": "test",
"money": 11
}
},
{
"name": "bread",
"type": "exam",
"image": "textures/items/bread.png",
"data": {
"type": "minecraft:bread",
"aux": 0,
"remark": "a bread",
"money": 2
}
}
]
},
{
"name": "air",
"type": "exam",
"data": {
"type": "minecraft:air",
"aux": 0,
"remark": "air",
"money": 11
}
}
],
"Sell": [
{
"name": "xx分类",
"type": "group",
"image": "textures/items/book_portfolio.png",
"data": [
{
"name": "空气",
"type": "exam",
"image": "",
"data": {
"type": "minecraft:air",
"aux": 0,
"remark": "111",
"money": 11
}
},
{
"name": "bread",
"type": "exam",
"image": "textures/items/bread.png",
"data": {
"type": "minecraft:bread",
"aux": 0,
"remark": "bread",
"money": 1
}
}
]
},
{
"name": "redstone",
"type": "exam",
"image": "textures/items/redstone_dust.png",
"data": {
"type": "minecraft:redstone",
"aux": 0,
"remark": "redstone",
"money": 11
}
}
]
},
"DefaultLangPack": {
"langPack.author": "提米吖",
"langPack.description": "这是一个默认中文语言包",
"error.message.title": "捕获到未处理错误: {1}",
"error.message.not.bug": "此错误不为bug!将不会收集错误信息!",
"error.message.parse.error": "错误!文件 {1} 无法反序列化为JS对象!",
"error.message.parse.error.tip": "请检查文件格式是否正确或文件编码是否为UTF8!",
"error.message.collect.success": "错误堆栈信息已输出至 {1},请将此文件发送至此插件开发者",
"config.reload.error.file.empty": "原文件 <{1}> 消失!",
"vec4.construct.param.error": "构造 \"Vector4\" 时, 所提供的 {1} 参数类型错误,该参数应该是数字类型!\n关键字: {2}",
"cmd.register.fail": "命令: {1} 注册失败!请检查此命令是否被其他插件注册!",
"select.form.label": "§l§a请输入关键词进行搜索",
"select.form.switch": "---§l§b我选好了(开启之后提交可选择完成)",
"select.form.slider.title": "§l§e请选择页码({1}/{2})",
"select.form.label.selects": "§l§b已选择: {1}",
"money.scoreboard.notfound": "检测到 <money> 记分板不存在,已自动创建",
"money.description": "经济系统",
"command.not.allow.entity": "§c实体禁止执行此命令!",
"command.not.allow.simulation.player": "§c模拟玩家禁止执行此命令!",
"command.not.allow.console.gui": "终端无法开启GUI!请输入其他命令!",
"command.not.allow.console.gui1": "§c此GUI无法在非玩家对象打开!请输入完整的命令!",
"command.not.allow.perm": "§c权限不足!无法执行!",
"command.not.allow.not.player": "§c此命令无法通过非玩家对象执行!",
"money.notfound.player.info": "§c没有找到该玩家的信息!",
"money.operation.completed": "§b操作成功!",
"money.pay.input.number.error": "§c付款金额不可为负数!",
"money.pay.success": "§b向玩家 {1} 付款成功!此次税费: {2} {3}",
"money.pay.fail": "§c付款失败!请检查选择玩家是否存在或你的余额是否足够!",
"command.target.not.player": "§c选择器内没有玩家!",
"money.notfound.player.info1": "§c未找到玩家 {1} 的信息",
"money.query.self": "§b你还剩余: §e{1} §f{2}",
"money.query.other": "§a玩家: §e{1} §b还剩余: §e{2} §f{3}",
"command.target.only.one.player": "§c此命令的玩家选择器要选择一个玩家!",
"money.main.gui.button.pay": "§l§a转账",
"money.main.gui.button.top": "§l§e查看排行榜",
"money.main.gui.button.hist": "§l§b查看流水账",
"money.main.gui.button.op.fast.mgr": "§l§dOP快捷管理",
"form.please.select": "§l§b请选择...",
"form.give.up": "§b表单已放弃",
"money.select.player.gui.step.slider.online": "§l§a在线玩家",
"money.select.player.gui.step.slider.offline": "§l§b离线玩家",
"money.select.player.gui.label": "§l§b请选择从哪选择玩家对象",
"money.select.player.gui.step.slider.title": "§l§a请划动",
"money.select.player.gui2.content": "§l§b请选择一个玩家...",
"money.select.player.gui2.select.error": "§c只能选择一个玩家!",
"money.select.player.gui2.select.error.player.info.lost": "§c无法操作数据丢失玩家!",
"money.admin.form.label": "§l§b当前选择玩家:§e {1}§b,\nTA的余额: §e {2} §f{3}",
"money.admin.form.add.mode.switch.title": "§l§a开启为添加(减少)模式,关闭为设置模式",
"money.admin.form.input.title": "§l§b请务必输入数字",
"money.form.input.error": "§c请输入数字!",
"money.pay.form.label": "§b当前选择玩家: §e{1}§b,\n你的余额: §e{2}§b,\nTA的余额: §e{3}§b,\n单位: §f{4}§b,\n转账税率: §e{5}",
"money.pay.form.input.title": "请输入转账金额",
"money.pay.form.note.input.title": "请输入转账原因",
"money.check.history.admin.form.content": "检测到OP权限!请选择执行操作:",
"money.check.history.admin.form.check.other": "查询其他人的账单信息",
"money.check.history.admin.form.check.self": "查询自己的账单信息",
"money.check.history.notfound": "§c没有相关的账单信息!",
"money.check.history.form.line.info": "{1}.§b时间: §e{2}§b, 转账人: §e{3}§b, 收款人: §e{4}§b, 值: §a{5}§b, 附加说明: §f{6}",
"money.check.history.form.select.player": "当前查询玩家: {1}",
"money.tax.sync.tip": "检测到TMET税率与LLMoney设置不相同!自动更正TMET税率为LLMoney值!",
"money.change.tip": "§b经济变动:您现在拥有: §e{1} §f{2},§b变动值: {3}",
"money.init.tip": "§b初始经济: {1} §f{2}已发放",
"tpa.cmd.description": "请求传送至他人(成功后消耗 {1} 经济)",
"tpa.ui.false": "§b请求UI已关闭",
"tpa.ui.true": "§b请求UI已开启",
"tpahere.cmd.description": "请求他人传送至自己(成功后消耗 {1} 经济)",
"tpaaccept.cmd.description": "同意传送请求",
"tpadeny.cmd.description": "拒绝传送请求",
"tpa.timeout.from.player.tip": "§c你发给玩家 §e{1} §c的TPA请求已过期",
"tpa.timeout.to.player.tip": "§c玩家 §e{1} §c发给你的TPA请求已过期",
"tpahere.timeout.from.player.tip": "§c你发给玩家 §e{1} §c的TPA请求已过期",
"tpahere.timeout.to.player.tip": "§c玩家 §e{1} §c发给你的TPA请求已过期",
"tpa.gui.type.to": "我传送过去",
"tpa.gui.type.here": "TA传送过来",
"tpa.gui.form.select.player.title": "§l§b请选择一个玩家",
"tpa.gui.form.select.tpa.type.title": "§l§a请选择TPA类型",
"tpa.gui.form.label.title": "§l§b成功后消耗 {1} 经济",
"command.notfound.player": "§c没有找到玩家对象",
"tpa.select.player.has.request.tip": "§c对方有一个未处理的TPA(Here)请求,无法发起请求",
"tpa.self.request.not.process.title": "§l§d请求未处理",
"tpa.self.request.not.process.content": "§l§b你有还有一个TPA(Here)请求没有处理,\n发起人: §e{1}§e,\n目标人: §e{2}",
"tpa.self.request.not.process.button.give.up.and.send.this.request": "放弃上一次请求并发起这一次请求",
"tpa.self.request.not.process.button.give.up.this.request.and.wait.last.request": "继续等待并放弃这次请求",
"tpa.self.request.not.process.res.wait.tip": "§b正在等待...",
"tpa.request.here.string": "Here",
"tpa.request.success": "§b你成功的向玩家 §e{1} §b发起了TPA{2}请求,/tpadeny取消请求",
"tpa.request.to.player.tip": "§b玩家 §e{1} §b向你发送了一个TPA{2}请求,/tpaaccept同意请求,/tpadeny拒绝请求",
"tpa.request.to.player.form.title": "§l§dTPA(Here)请求",
"tpa.request.to.player.form.content": "§l§b玩家 §e{1} §b向你发送了一个TPA{2}请求\n(消耗对方 {3} 经济)\n请选择:",
"tpa.request.to.player.form.button.accept": "同意请求",
"tpa.request.to.player.form.button.deny": "拒绝请求",
"tpa.process.notfound.request": "§c您还没有待处理的TPA(Here)请求",
"tpa.accept.from.player.lost": "§c玩家对象丢失!",
"tpa.accept.fail.money.to.player.tip": "§cTPA(Here)失败!原因: 对方经济不足!",
"tpa.accept.fail.money.from.player.tip": "§cTPA(Here)失败,请检查经济",
"tpa.accept.success.from.player.tip": "§b玩家 §e{1} §b接受了你的TPA请求",
"tpa.accept.success.to.player.tip": "§b你接受了玩家 §e{1} §b的TPA请求",
"tpahere.accept.success.from.player.tip": "§b玩家 §e{1} §b接受了你的TPAHere请求",
"tpahere.accept.success.to.player.tip": "§b你接受了玩家 §e{1} §b的TPAHere请求",
"tpa.deny.self.request.self.tip": "§b你已取消发起的TPA(Here)请求",
"tpa.deny.self.request.to.player.tip": "§b对方取消了发给你的TPA(Here)请求",
"tpa.deny.other.tpa.to.player.tip": "§c你拒绝了玩家 §e{1} §c的TPA请求",
"tpa.deny.other.tpa.from.player.tip": "§c玩家 §e{1} §c拒绝了你的TPA请求",
"tpa.deny.other.tpahere.to.player.tip": "§c你拒绝了玩家 §e{1} §c的TPAhere请求",
"tpa.deny.other.tpahere.from.player.tip": "§c玩家 §e{1} §c拒绝了你的TPAHere请求",
"tpa.left.to.player.tip": "§b玩家 §e{1} §b发给你的TPA(Here)请求因为对方退出游戏而被强制取消",
"tpa.left.from.player.tip": "§b你发给玩家 §e{1} §b的TPA(Here)请求因为对方退出游戏而被强制取消",
"warp.cmd.description": "WARP命令",
"warp.ls.list.empty": "§b当前没有可用传送点",
"warp.ls.msg": "§b当前传送点有: §r{1}",
"warp.add.fail.has": "§c添加失败,已经有这个传送点了!",
"warp.add.success": "§b传送点(\"{1}§r§l§b\")创建成功",
"warp.go.fail.notfound": "§c传送点(\"{1}§c\")不存在",
"warp.go.fail.money": "§c传送失败,请检查经济!",
"warp.go.success": "§b传送到传送点(\"{1}§r§l§b\")成功",
"warp.go.fail.error": "§c传送失败,原因未知!请联系管理员!",
"warp.del.fail.notfound": "§c传送点(\"{1}§r§l§c\")不存在",
"warp.del.success": "§c传送点(\"{1}§r§l§c\")删除成功",
"warp.main.gui.button.add": "§l§b添加传送点",
"warp.main.gui.button.go": "§l§a前往传送点",
"warp.main.gui.button.del": "§l§c删除传送点",
"warp.main.gui.content": "§l§b表单选项如下,请选择一个:",
"warp.go.gui.list.empty": "§c传送点列表为空",
"warp.go.gui.content": "§l§b表单选项如下,请选择一个\n§a此过程需要消耗 §e{1} §f{2} §a您还剩余 §e{3} §f{4}",
"warp.add.gui.input.title": "§l§a输入你想创建的WARP名字",
"warp.del.gui.list.empty": "§c传送点列表为空",
"warp.del.gui.content": "§l§c选择一个WARP名字进行删除",
"home.cmd.description": "Home主命令",
"homeas.cmd.description": "管理玩家的家",
"homeas.main.gui.content": "§l§b请选择一个玩家管理",
"homeas.main.gui.res.fail.only.select.one.player": "§c只能选择一个玩家!",
"home.main.gui.button.add": "§l§b添加家",
"home.main.gui.button.go": "§l§a前往家",
"home.main.gui.button.del": "§l§c删除家",
"home.main.gui.content": "§l§b请选择操作",
"home.as.main.gui.add.content": "\n当前选择玩家: §e{1}",
"home.add.fail.max.limit": "§c家数量已满 {1}个 !无法继续添加!",
"home.add.form.input.title": "§l§b输入你要创建家的名字",
"home.add.form.input.title1": "\n§a此过程需要消耗 §e{1} §f{2} §a您还剩余: §e{3} §f{4}",
"home.as.add.form.input.title": "\n当前选择玩家: §e{1}",
"home.add.fail.name.is.exists": "§c添加家失败!原因: 这个家名称已存在!",
"home.add.fail.money": "§c添加家失败!原因: 经济不足!",
"home.add.success": "§b添加家(\"{1}§r§l§b\")成功",
"home.go.list.empty": "§c这里还没有数据呢,请添加一个再来吧!",
"home.go.form.content": "§l§b请选择一个家进行传送",
"home.go.form.content1": "\n§a此过程需要消耗 §e{1} §f{2} §a您还剩余 §e{3} §f{4}",
"home.as.go.form.content": "\n当前选择玩家: §e{1}",
"home.go.fail.notfound": "§c前往家失败!原因: 这个家不存在!",
"home.go.fail.money": "§c前往家失败!原因: 经济不足!",
"home.go.success": "§b前往家(\"{1}§r§l§b\")成功",
"home.del.list.empty": "§c这里还没有数据呢,请添加一个再来吧!",
"home.del.form.content": "§l§c请选择一个家进行删除",
"home.del.form.content1": "\n§a此过程需要回退 §e{1} §f{2} §a您还剩余 §e{3} §f{4}",
"home.as.del.form.content": "\n§b当前选择玩家: §e{1}",
"home.del.fail.notfound": "§c删除家失败!原因: 这个家不存在!",
"home.del.success": "§c删除家(\"{1}§r§l§c\")成功",
"home.ls.list.empty": "§c查询失败!现在没有找到任何家!",
"home.ls.success": "§b查询成功!家列表: {1}",
"back.cmd.description": "回到上一次暴毙点(消耗 {1} 经济)",
"back.not.death.info": "§c您目前还无死亡记录",
"back.fail.money": "§c传送置暴毙点失败,请检查余额!",
"back.success": "§b返回到时间为 {1} 的暴毙点成功!",
"back.fail.error": "§c传送失败,原因未知!请联系管理员!",
"death.cmd.description": "查看死亡记录",
"death.not.death.info": "§c您目前还无死亡记录!",
"death.form.line": "{1}/{2}: 地点:{3} 时间:{4}",
"back.die.tip": "§b你暴毙了,你的暴毙点:({1},{2},{3},{4}),时间:{5} 使用/back可返回死亡地点",
"notice.cmd.description": "查看公告",
"notice.auto.display.false": "§a设置成功!下次加入游戏后将不再展示更改前的公告!",
"notice.auto.display.true": "§a设置成功!下次加入游戏后将自动展示公告!",
"notice_op.cmd.description": "修改公告",
"notice_op.is.continue.form.button.continue": "§l§b继续编辑",
"notice_op.is.continue.form.button.cancel": "§l§a退出编辑并保存修改",
"notice_op.is.continue.form.content": "{1}§r\n§l§b请选择:",
"notice_op.is.continue.form.res.cancel.tip": "§b保存成功!",
"notice_op.modify.title.form.input.title": "§l§b请更改公告标题",
"notice_op.modify.title.success": "§l§b标题修改成功!",
"notice_op.del.line.form.label": "§l§c请选择要删除的内容",
"notice_op.modify.content.form.label": "§l§b请修改...",
"notice_op.modify.content.form.add.line.switch.title": "§l§a添加一行(开启后提交不保存当前修改)",
"notice_op.modify.content.form.del.line.switch.title": "§l§b打开删除面板(开启后提交不保存当前修改)",
"notice_op.modify.content.success": "§l§b公告内容修改完成!",
"notice_op.main.gui.button.set.title": "§l§a设置标题",
"notice_op.main.gui.button.set.content": "§l§b设置内容",
"notice_op.main.gui.content": "§l§b请选择编辑内容:",
"notice.form.auto.display.switch.title": "§l§a下次公告更改前不再提醒",
"shop.cmd.description": "系统商店",
"shop.display.exam": "商品",
"shop.display.group": "分类",
"shop.main.gui.button.buy": "买入",
"shop.main.gui.button.sell": "卖出",
"shop.main.gui.content": "§l§b请选择操作方式:",
"shop.config.error": "§c商店配置错误",
"shop.form.back.last.page": "§l§d返回上一页",
"shop.buy.form.content": "§l§b请选择购买物品",
"shop.buy.form.buttons": "{1}§r\n{2}",
"shop.buy.form2.content": "§l§b详情信息:\n物品:§a{1}§b,\n特殊值:§a{2}§b,\n金额:§a{3}/一个§b,\n你的剩余金额:§a{4}§b,\n备注:{5},\nTips:请输入正数",
"shop.buy.form2.input.title": "请输入购买物品数量",
"shop.buy.form2.res.input.error": "§c请输入正数",
"shop.buy.fail.money": "§c购买失败!原因: 经济不足",
"shop.buy.success": "§b购买成功!",
"shop.buy.fail.rea": "§c购买失败!原因: {1}",
"shop.buy.error": "§c商店出现错误!请联系游戏管理员!",
"shop.sell.form.content": "§l§b请选择回收物品",
"shop.sell.form.buttons": "{1}§r\n{2}",
"shop.sell.form2.content": "§l§b详情信息:\n物品:§a{1}§b,\n特殊值:§a{2}§b,\n金额:§a{3}/一个§b,\n你的剩余金额:§a{4}§b,\n你剩余的物品数量:§a{6}§b,\n备注:{5},\nTips:请输入正数",
"shop.sell.form2.input.title": "请输入回收物品数量",
"shop.sell.form2.res.input.error": "§c请输入正数",
"shop.sell.success": "§b回收成功!",
"shop.sell.fail.count.not.enough": "物品数量不足",
"shop.sell.fail.rea": "§c回收失败!原因: {1}",
"shop.sell.error": "§c商店出现错误!请联系游戏管理员!",
"tpr.cmd.description": "随机传送(消耗 {1} 经济)",
"tpr.fail.money": "§c随机传送失败!请检查经济!",
"tpr.load.chunk.tip": "§b正在加载区块...",
"tpr.found.safe.pos.tip": "§b正在寻找安全坐标...",
"tpr.fail.notfound.safe.pos": "§c未能tpr成功!未能找到安全坐标!请重试!",
"tpr.success": "§a已将您传送置§e({1},{2},{3},{4})",
"refresh.chunk.cmd.description": "重载区块(消耗 {1} 经济)",
"refresh.chunk.fail.money": "§c刷新区块失败!原因: 经济不足",
"refresh.chunk.success": "§b刷新区块成功!",
"auto.update.has.new.version": "发现新版本: {1},正在尝试下载...",
"auto.update.download.fail.code": "下载失败!状态码: {1}",
"auto.update.download.fail.rea": "下载失败!原因: 返回值错误!",
"auto.update.download.fail.size": "下载失败!原因: 安全检测: 返回值大小小于30KB!",
"auto.update.download.success": "下载成功! 大小: {1}KB",
"auto.update.download.success.website.restart.tip": "下载站规定,此次更新必须重启!请重启更新!",
"auto.update.download.success.auto.reload.tip": "正在更新...",
"auto.update.download.success.tip": "下载成功!请重启更新!",
"write.use.log.title": "时间,维度,主体,XYZ,事件,数据",
"tmet.cmd.description": "文件操作",
"tmet.reloaddata.success": "操作成功",
"tmet.not.allow.default.lang.pack": "不可操作默认语言包!",
"tmet.load.lang.pack.fail": "加载语言包 <{1}> 失败!可能是语言包路径没此语言包,或文件名输入不完整,或是此语言包已被加载?",
"tmet.load.lang.pack.success": "语言包 <{1}> 加载成功!",
"tmet.unload.lang.pack.fail": "卸载语言包 <{1}> 失败!可能是语言包没有被加载?",
"tmet.unload.lang.pack.success": "语言包 <{1}> 卸载成功!",
"tmet.reload.lang.pack.fail": "重载语言包 <{1}> 失败!可能是语言包没有被加载?",
"tmet.reload.lang.pack.success": "语言包 <{1}> 重载成功!",
"tmet.ls.lang.pack": "语言包列表: {1}"
}
};
//#endregion
let _Version = new class {
constructor() {
this._ver = [1, 5, 6];
this._isBeta = false;
}
getVersionString() {
return this._ver.join(".") + (this._isBeta ? "(Beta)" : "");
}
getVersionNumber() {
return Number(this._ver.join(""));
}
getVersionArray() {
return [this._ver[0], this._ver[1], this._ver[2]];
}
isBeta() {
return this._isBeta;
}
}();
//#region Environment
//没错,我有病
Array.prototype.find = function (fn) {
let l = this.length, i = 0;
while (i < l) {
if (!!fn(this[i], i, this)) {
return [this[i], i];
}
i++;
}
return undefined;
};
Array.prototype.forEach = function (fn) {
let l = this.length, i = 0;
while (i < l) {
fn(this[i], i, this);
i++;
}
};
Object.prototype.forEach = function (fn) {
let keys = Object.keys(this);
keys.forEach((key) => {
fn(this[key], key, this);
});
}
Map.prototype.forEach = function (fn) {
let entries = new Map(this).entries(),
entrie = entries.next();
while (!entrie.done) {
fn(entrie.value[1], entrie.value[0], this);
entrie = entries.next();
}
};
Map.prototype.find = function (fn) {
let entries = new Map(this).entries(),
entrie = entries.next();
while (!entrie.done) {
if (!!fn(entrie.value[1], entrie.value[0], this)) {
return entrie.value;
};
entrie = entries.next();
}
return undefined;
}
Number.prototype.toFull = function (num = 0) {
let str = this.toString();
while (str.length < num) {
str = `0${str}`;
}
return str;
}
/**
* 加强版获取类型
* @param {any} any 任何类型
* @returns {("Object"|"Array"|"Number"|"String"|"Undefined"|"Null"|"Boolean"|"Map")}
*/
function typeOfEx(any) {
let type = {
"[object Object]": "Object",
"[object Array]": "Array",
"[object Number]": "Number",
"[object String]": "String",
"[object Undefined]": "Undefined",
"[object Null]": "Null",
"[object Boolean]": "Boolean",
"[object Map]": "Map"
}[Object.prototype.toString.call(any)];
return type;
}
/**
* @param {...(string|number)} args
* @returns {string}
*/
function getColor(...args) {
return "\u001b[" + args.join(";") + "m";
}
/**
* @param {string} OriText
* @param {...string} args
* @returns {string}
* @example
* AutoReplace("{2}{1},{3}",1,2,3): "21,3"
*/
function AutoReplace(OriText, ...args) {
let Index = 0;
while (args.length != 0) {
Index++;
let thisArg = args.shift();
if (thisArg != undefined) {
OriText = OriText.replace(`{${Index}}`, thisArg);
}
}
return OriText;
}
/**
* @param {Error} err
*/
function ErrorMsg(err) {
try {
let Message = err.message;
let StackStr = err.stack;
let FullStackStr = "";
if (IsQuickJs) {
Message = `${err.name}: ${Message}`;
FullStackStr = `${Message}\n${StackStr}`;
} else { FullStackStr = StackStr };
logger.error(AutoReplace(Tr(null, "error.message.title"), FullStackStr));
if (Message.indexOf("NotBug:") != -1) {
logger.error(Tr(null, "error.message.not.bug"));
return;
}
let NowInfo = {
"time": system.getTimeStr(),
"version": _Version.getVersionString(),
"stack": FullStackStr,
"fs": {},
// 2023/05/05 这段不需要了
// "langPacks": {},
"TMET": File.readFrom(TMET_RunPath),
};
let isError = true;
try {
fs.forEach((jc, name) => {
try {
NowInfo.fs[name] = JSON.parse(jc._TextCache);
} catch (e) {
throw jc._Path;
}
});
LangFs.forEach((jc, name) => {
try {
// 2023/05/05 这段不需要了
// NowInfo.langPacks[name] =
JSON.parse(jc._TextCache);
} catch (e) {
throw jc._Path;
}
});
} catch (e) {//Process: No Code Error
if (typeof (e) == "string") {
isError = false;
logger.error(AutoReplace(Tr(null, "error.message.parse.error"), e));
logger.error(Tr(null, "error.message.parse.error.tip"));
}
}
if (isError) {//Process: Code Error
let TO = system.getTimeObj();
let outputPath = AutoReplace(TMET_ErrorLogDir, `${TO.Y}-${TO.M}-${TO.D}-${TO.h}-${TO.m}-${TO.s}-${TO.ms}.TMETError`);
File.writeTo(outputPath, JSON.stringify(NowInfo));
logger.info(AutoReplace(Tr(null, "error.message.collect.success"), outputPath));
}
} catch (_) {
let _Log = (typeof (log) == "undefined" ? (a) => { console.log(a) } : log);
_Log(AutoReplace("{1}TMET无法在此环境运行!{2}", getColor(1, 31), getColor(0)));
}
}
let TMListen = new class {
constructor() {
this._Events = new Map();
this._TMETEvents = new Map();
this._NextId = 0;
}
/**
* @param {string} eventName
* @param {?("mc"|"TMET")} type
* @returns {(...args:any[])=>boolean}
*/
RegEvent(eventName, type = "mc") {
logger.debug(`EventMgr::Reg ${type} Event: ${eventName}`);
let ProcessEvent = (...args) => {
let time = Date.now();
let res = true;
(type == "mc" ? this._Events.get(eventName) : this._TMETEvents.get(eventName)).forEach((func) => {
try {
let res1 = func(...args);
if (typeof (res1) == "boolean") {
res = (!!res ? res1 : res);
}
} catch (e) {
ErrorMsg(e);
return false;
}
});
if (eventName != "onTick") {
logger.debug(`RunEvent ${eventName}(${type}) Time: ${Date.now() - time}`);
}
return res;
};
if (type == "mc") {
if (!this._Events.has(eventName)) { this._Events.set(eventName, new Map()); }
} else {
if (!this._TMETEvents.has(eventName)) { this._TMETEvents.set(eventName, new Map()); }
}
return ProcessEvent;
}
/**
* @param {string} eventName
* @param {(...args:any[])=>boolean|undefined} func
* @param {?("mc"|"TMET")} type
* @returns {string|null}
*/
listen(eventName, func, type = "mc") {
/**
* @type {Map<string,(...args:any[])=>boolean|undefined>|null}
*/
let ListenMap = (type == "mc" ? this._Events : this._TMETEvents).get(eventName);
if (ListenMap == null) {
ListenMap = new Map();
(type == "mc" ? this._Events : this._TMETEvents).set(eventName, ListenMap);
}
let id = (this._NextId++).toString();
ListenMap.set(id, func);
logger.debug(`EventMgr::Add ${type} Event: ${eventName}, ID: ${id}`);
return id;
}
/**
* @param {string} id
* @param {?("mc"|"TMET")} type
* @returns {boolean}
*/
unListen(id, type = "mc") {
let entrie = (type == "mc" ? this._Events : this._TMETEvents).find((ListenMap, eventName) => {
if (ListenMap.has(id)) {
ListenMap.delete(id);
logger.debug(`EventMgr::Del ${type} Event: ${eventName}, ID: ${id}`);
return true;
}
return false;
});
return (entrie == null ? false : true);
}
}();
let TickTask = new class {
constructor() {
this._TaskList = [];
}
_RunTask() {
let TL = this._TaskList;
this._TaskList = [];
while (TL.length != 0) {
try {
TL.shift()();
} catch (e) {
ErrorMsg(e);
}
}
}
/**
* @param {Function} func
*/
addTask(func) {
this._TaskList.push(func);
}
}();
class JsonConfigFileClass {
/**
*
* @param {string} path
* @param {string} defaultStr
*/
constructor(path, defaultStr = "{}") {
this._Path = path;
// this._TimeStamp = 0;
let fileText = File.readFrom(path);
if (fileText == null) {
fileText = defaultStr;
// this._saveData(JSON.parse(fileText));
File.writeTo(this._Path, fileText);
}
this._TextCache = fileText;
this._isTasking = false;
this._isDestroy = false;
this.IsError = false;
}
_getCache() {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::_GetCache: Illegal use of destroyed object <${this._Path}>!`); }
// let nowTime = Date.now();
// if ((nowTime - this._TimeStamp) > 500) {
// this._Cache = JSON.parse(this._TextCache);
// this._TimeStamp = nowTime;
// }
if (this._Cache == null) {
try {
this._Cache = JSON.parse(this._TextCache);
} catch (e) {
this.IsError = true;
throw e;
}
}
return this._Cache;
}
_saveData(obj) {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::_SaveData: Illegal use of destroyed object <${this._Path}>!`); }
this._Cache = obj;
if (!this._isTasking) {
this._isTasking = true;
TickTask.addTask(() => {
this._TextCache = JSON.stringify(this._Cache, null, 2);
File.writeTo(this._Path, this._TextCache);
this._isTasking = false;
});
}
return true;
}
init(key, content) {
try {
let cache = this._getCache();
let oldData = cache[key];
if (oldData == undefined) {
cache[key] = content;
this._saveData(cache);
}
return oldData;
} catch (e) {
ErrorMsg(e);
return undefined;
}
}
get(key, defaultD = null) {
try {
let cache = this._getCache();
let res = cache[key];
return (res == null ? defaultD : res);
} catch (e) {
ErrorMsg(e);
return undefined;
}
}
getKeys() {
try {
let cache = this._getCache();
return Object.keys(cache);
} catch (e) {
ErrorMsg(e);
return [];
}
}
set(key, content) {
try {
let cache = this._getCache();
cache[key] = content;
return this._saveData(cache);
} catch (e) {
ErrorMsg(e);
return false;
}
}
delete(key) {
try {
let cache = this._getCache();
if (cache[key] == undefined) { return false; }
delete cache[key];
return this._saveData(cache);
} catch (e) {
ErrorMsg(e);
return false;
}
}
reload() {
try {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::Reload: Illegal use of destroyed object <${this._Path}>!`); }
let fileText = File.readFrom(this._Path);
if (fileText == null) {
throw new Error(`NotBug: ${AutoReplace(Tr(null, "config.reload.error.file.empty"), this._Path)}`);
}
this._saveData(JSON.parse(fileText));
this.IsError = false;
// this._TextCache = fileText;
// this._TimeStamp = 0;
return true;
} catch (e) {
ErrorMsg(e);
return false;
}
}
close() {
try {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::Close: Illegal use of destroyed object <${this._Path}>!`); }
// let cache = this._getCache();
// this._isDestroy = true;
// return this._saveData(cache);
this.IsError = false;
} catch (e) {
ErrorMsg(e);
return false;
}
}
getPath() {
try {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass:GetPath: Illegal use of destroyed object <${this._Path}>!`); }
return this._Path;
} catch (e) {
ErrorMsg(e);
return undefined;
}
}
read() {
try {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::Read: Illegal use of destroyed object <${this._Path}>!`); }
// return JSON.stringify(this._getCache(), null, 2);
return this._TextCache;
} catch (e) {
ErrorMsg(e);
return "";
}
}
write(content) {
try {
if (this._isDestroy) { throw new Error(`JsonConfigFileClass::Write: Illegal use of destroyed object <${this._Path}>!`); }
this._TextCache = content;
// this._TimeStamp = 0;
File.writeTo(this._Path, content);
this._Cache = JSON.parse(content);
this.IsError = false;
// this._getCache();
return true;
} catch (e) {
ErrorMsg(e);
return false;
}
}
}
//#endregion
/**
* @type {Map<string,JsonConfigFileClass}
*/
let fs = new Map();
/**
* @type {Map<string,JsonConfigFileClass}
*/
let LangFs = new Map();
let LangEnumMgr = new class {
constructor() { this._LangPacks = []; this._Tasks = []; }
/**
*
* @param {(LangNames:string[])=>void} func
*/
addTask(func) {
func(this._LangPacks);
this._Tasks.push(func);
}
_T() {
this._Tasks.forEach((func) => {
try {
func(this._LangPacks);
} catch (e) { ErrorMsg(e); }
});
}
/**
* @param {string} LangName
*/
add(LangName) {
if (this._LangPacks.indexOf(LangName) == -1) {
this._LangPacks.push(LangName);
this._T();
return true;
} else { return false; }
}
/**
* @param {string} LangName
*/
del(LangName) {
let index = this._LangPacks.indexOf(LangName);
if (index == -1) { return false; }
this._LangPacks.splice(index, 1);
this._T();
return true;
}
};
let GlobalCache = {
"DebugMode": false,
"PlayerState": new Map(),//属于基础里的,收集玩家列表用这个
"defaultLangNotLoadIsTip": false,
"FileCache": new class {
constructor() {
this._Caches = {};
this._Path = AutoReplace(TMET_DataDir, "TMETCache");
}
get(name) {
return this._Caches[name];
}
set(name, val) {
return this._Caches[name] = val;
}
_SaveToFile() {
return File.writeTo(this._Path, JSON.stringify(this._Caches));
}
_TryReadFile() {
if (File.exists(this._Path)) {
this._Caches = JSON.parse(File.readFrom(this._Path));
return File.delete(this._Path);
} else {
return false;
}
}
}(),
"LL3ForceLoad": false
};
//#region Tools
/**
* @param {string} text
* @param {?boolean} hasColor
* @returns {string}
*/
function addLogo(text, hasColor = true) {//请不要改我的标识!
let Logos = [
"§l§6[-TMET-]",
"§l§d<TMET::DevMode>"
];
let txt = `${Logos[(GlobalCache.DebugMode ? 1 : 0)]} §f${text}`;
if (hasColor) {
return txt;
} else {
let arr = txt.split("§"), resArr = [];
arr.forEach((str) => {
resArr.push(str.substring(1));
});
return resArr.join("");
}
}
function ST(pl, text) {
if (pl == null) { return; }
pl.tell(text, 0);
}
GlobalCache.RunCmdNoOutput = {
"IsExecuting": false,
"Output": []
};
/**
* @param {string} cmd
*/
function runCmdNoOutput(cmd) {
GlobalCache.RunCmdNoOutput.IsExecuting = true;
mc.runcmd(cmd);
GlobalCache.RunCmdNoOutput.IsExecuting = false;
let out = GlobalCache.RunCmdNoOutput.Output;
GlobalCache.RunCmdNoOutput.Output = [];
return out;
}
/**
* @param {CommandOrigin} ori
* @returns {("other"|"cb"|"op"|"pl"|"notop"|"console"|"entity")}
*/
function getOriginLevel(ori) {
let res = "other";
switch (ori.typeName) {
case "MinecartCommandBlock":
case "CommandBlock": {
res = "cb";
break;
}
case "Entity": {
res = "entity"
break;
}
case "Virtual": {
res = "op";
break;
}
case "Server": {
res = "console";
break;
}
case "Player": {
if (ori.player.permLevel == 0) {
res = "notop";
} else {
res = "op";
}
break;
}
}
return res;
}
/**
* 发送选择表单
* @param {Player} pl
* @param {SelectFormData} selectFormData
*/
function sendSelectForm(pl, selectFormData) {
let nf = mc.newCustomForm();
nf.setTitle(selectFormData.title);
nf.addLabel(selectFormData.content);
nf.addInput(Tr(pl, "select.form.label"), "(String)", selectFormData.searchContent);
nf.addSlider(AutoReplace(Tr(pl, "select.form.slider.title"), selectFormData.nowPage, selectFormData.pageLength), 1, selectFormData.pageLength, 1, selectFormData.nowPage);
nf.addLabel(AutoReplace(Tr(pl, "select.form.label.selects"), selectFormData.getNowSelect().join(",")));
selectFormData.pageContent.forEach((val) => {
nf.addSwitch(val, selectFormData.buttonIsPress(val));
});
nf.addSwitch(Tr(pl, "select.form.switch"), false);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
selectFormData.callback(pl, null);
return;
}
args.shift();//content
let [search, page, isOK] = [args.shift(), (args.shift() - 1), args.pop()];
args.shift()
if (page < 0) { page = 0; }
if (page == selectFormData.pageLength) {
page -= 1;
}
let select = [];
let unSelect = [];
args.forEach((bool, i) => {
if (bool) {
select.push(i);
} else {
unSelect.push(i);
}
});
selectFormData.calculation(search, select, unSelect, page, isOK);
if (isOK) {
selectFormData.callback(pl, selectFormData.getNowSelectIds());
} else {
sendSelectForm(pl, selectFormData);
}
});
}
/**
* 选择表单数据
*/
class SelectFormData {
/**
* 切段
* @param {string[]} arr
* @param {number} num
* @returns {string[][]}
*/
static splitArr(arr, num) {
let newArr = [[]];
let i = 0, l = arr.length, i2 = 0, num1 = 0;
while (i < l) {
if (newArr[i2] == null) {
newArr[i2] = [];
}
newArr[i2].push(arr[i]);
num1 += 1;
if (num1 >= num) {
i2 += 1;
num1 = 0;
}
i += 1;
}
return newArr;
}
/**
* @param {string} title
* @param {string} content
* @param {string[]} buttons
* @param {number} pageNum
* @param {(pl:Player,nowSelect:string[]|null)=>void} cb
*/
constructor(title, content, buttons, pageNum, cb) {
this._title = title;
this._content = content;
/** 页面长度 */
this._pageNum = pageNum
/** 源数据 */
this._buttons = buttons;
/**
* 已选择数据
* @type {Set<string>}
* */
this._nowSelect = new Set();
/** 上一次搜索 */
this._lastSearch = "";
/** 显示数据 */
this._showData = SelectFormData.splitArr(buttons, pageNum);
/** 当前页面引索位置 */
this._nowPage = 0;
/** 页面总长度 */
this._pageLength = this._showData.length;
this._callback = cb;
}
get title() { return this._title; }
get content() { return this._content; }
get searchContent() { return this._lastSearch; }
get nowPage() { return (this._nowPage + 1); }
get pageContent() {
return this._showData[this._nowPage];
}
get pageLength() { return this._pageLength; }
get callback() { return this._callback; }
setTitle(title) {
this._title = title;
return true;
}
setContent(content) {
this._content = content;
return true;
}
/**
* 进行页面数据计算
* @param {string} search 搜索数据
* @param {number[]} selects 已选择数据
* @param {number[]} unSelects 取消选择数据
* @param {number} page 页面索引
* @param {boolean} isOK 是否选择完成
*/
calculation(search, selects, unSelects, page, isOK) {
selects.forEach((index) => {
let val = this._showData[this._nowPage][index];
this._nowSelect.add(val);
});
unSelects.forEach((index) => {
let val = this._showData[this._nowPage][index];
this._nowSelect.delete(val);
});
if (isOK) { return; }
search = search.trim();//去除前后空格
if (this._lastSearch != search) {
this._lastSearch = search;
this._nowPage = 0;
if (search == "") {//恢复默认
this._showData = SelectFormData.splitArr(this._buttons, pageNum);
this._pageLength = this._showData.length;
return;
}
let searchRes = {}, lowSearch = search.toLowerCase();//小写搜索
this._buttons.forEach((val, i) => {
let res = val.toLowerCase().indexOf(lowSearch);
if (res != -1) {
searchRes[val] = res;
}
});
this._showData = SelectFormData.splitArr(
Object.keys(searchRes).sort((a, b) => {
return (searchRes[a] - searchRes[b]);
}),
this._pageNum);
this._pageLength = this._showData.length;
} else {
this._nowPage = page;
}
}
/**
* 内容是否已被选定
* @param {string} data
*/
buttonIsPress(data) {
return this._nowSelect.has(data);
}
getNowSelect() {
return [...this._nowSelect];
}
getNowSelectIds() {
let ids = [];
[...this._nowSelect].forEach((v) => {
ids.push(this._buttons.indexOf(v));
});
return ids;
}
}
/**
* @param {Array<any>} _this
* @param {number} i
*/
function SafeDeleteArray(_this = [], i) {
let Link = _this[i];
TickTask.addTask(() => {
let nowIndex = _this.indexOf(Link);
_this.splice(nowIndex, 1);
});
}
class Vector4 {
/**
* @param {(FloatPos|IntPos|{"x":number."y":number,"z":number,"dimid":number})} pos
* @param {?string} keyword
*/
static PosToVec4(pos, keyword) {
return new Vector4(pos.x, pos.y, pos.z, pos.dimid, keyword);
}
/**
* @param {number} X
* @param {number} Y
* @param {number} Z
* @param {number} DIMID
* @param {?string} keyword
*/
constructor(X, Y, Z, DIMID, keyword = "U") {
if (typeof (X) != "number") {
throw new Error(`NotBug: ${AutoReplace(Tr(null, "vec4.construct.param.error"), "x", keyword)}`);
}
if (typeof (Y) != "number") {
throw new Error(`NotBug: ${AutoReplace(Tr(null, "vec4.construct.param.error"), "y", keyword)}`);
}
if (typeof (Z) != "number") {
throw new Error(`NotBug: ${AutoReplace(Tr(null, "vec4.construct.param.error"), "z", keyword)}`);
}
if (typeof (DIMID) != "number") {
throw new Error(`NotBug: ${AutoReplace(Tr(null, "vec4.construct.param.error"), "dimid", keyword)}`);
}
this._x = X; this._y = Y; this._z = Z; this._dimid = DIMID;
}
toPos() {
return new FloatPos(this._x, this._y, this._z, this._dimid);
}
toDecimalPlaces(num) {
let floor = Math.floor;
return new Vector4(floor((this._x) * (num * 10)) / (num * 10), floor((this._y) * (num * 10)) / (num * 10), floor((this._z) * (num * 10)) / (num * 10), this._dimid)
}
get x() { return this._x; }
get y() { return this._y; }
get z() { return this._z; }
get dimid() { return this._dimid; }
get dim() { return this.toPos().dim; }
set x(a) {
if (typeof (a) != "number") {
throw new Error("Failed to modify parameter x! Reason: the value provided is not a number");
}
this._x = a;
}
set y(a) {
if (typeof (a) != "number") {
throw new Error("Failed to modify parameter y! Reason: the value provided is not a number");
}
this._y = a;
}
set z(a) {
if (typeof (a) != "number") {
throw new Error("Failed to modify parameter z! Reason: the value provided is not a number");
}
this._z = a;
}
set dimid(a) {
if (typeof (a) != "number") {
throw new Error("Failed to modify parameter dimid! Reason: the value provided is not a number");
}
this._dimid = a;
}
/**
* @param {Vector4} vec4
*/
isSame(vec4) {
let str1 = vec4.toString();
let str2 = this.toString();
return (str1 == str2);
}
toString() {
return `Vector4(${this._x},${this._y},${this._z},${this._dimid})`;
}
toObject() {
return {
"x": this._x,
"y": this._y,
"z": this._z,
"dimid": this._dimid
};
}
}
let TMCmd = new class {
constructor() {
this._regTasks = [];
this._isInit = false;
}
/**
* @param {string} cmd
* @param {string} desc
* @param {(PermType|undefined)} perm
* @param {(number|undefined)} flag
* @param {((nc:Command)=>void|undefined)} func
*/
register(cmd, desc, perm = PermType.Any, flag = 0x80, func = () => { }) {
let regTask = () => {
logger.debug(`Cmd: ${cmd} register...`);
let nc = mc.newCommand(cmd, desc, perm, flag);
if (!nc) {
logger.error(AutoReplace(Tr(null, "cmd.register.fail"), cmd));
} else { func(nc); }
};
if (ServerIsStarted) {
regTask();
} else {
if (!this._isInit) {
this._isInit = true;
TMListen.listen("onServerStarted", () => {
this._regTasks.forEach((func, i) => {
func();
SafeDeleteArray(this._regTasks, i);
});
});
}
this._regTasks.push(regTask);
}
}
}();
/**
* 向玩家发送一个模式表单(修复表单冲突)
* @param {Player} pl
* @param {string} title
* @param {string} content
* @param {string} but1
* @param {string} but2
* @param {(pl: Player, result: boolean)=>void} cb
*/
function SendModalFormToPlayer(pl, title, content, but1, but2, cb) {
return pl.sendSimpleForm(title, content, [but1, but2], ["", ""], (pl, id) => {
if (id == null) { return; }
cb(pl, (id == 0));
});
}
/**
* 判断是否为模拟玩家
* @param {Player} pl
*/
function isSimulatedPlayer(pl) {
if (pl == null) { return true; }
let isSimPl = pl.isSimulatedPlayer();
if (isSimPl == null || isSimPl) {
return true;
}
return false;
}
//#endregion
//#region Lang-Pre
/**
* @param {?Player} pl
* @param {string} key
* @returns
*/
let Tr = (pl, key) => {
if (!GlobalCache.defaultLangNotLoadIsTip) {
GlobalCache.defaultLangNotLoadIsTip = true;
logger.warn("I18N is not load! Use built-in LangPack!");
}
return _Configs.DefaultLangPack[key];
};
//#endregion
let Modules = new class {
constructor() {
this._Exports = {};
this._RegExportApi("getVersion", () => {
return {
"major": _Version._ver[0],
"minor": _Version._ver[1],
"revision": _Version._ver[2],
"isBeta": _Version.isBeta()
};
});
}
/**
* @param {string} name
* @param {(...args:any[])=>any} func
* @returns {boolean}
*/
_RegExportApi(name, func) {
this._Exports[name] = func;
return true;
}
/**
* @param {string} name
* @returns {((...args:any)=>any|null)}
*/
getApi(name) {
return this._Exports[name];
}
LoadI18N() {
(() => {
let Event_SwitchLangPackExample = TMListen.RegEvent("onSwitchLangPack", "TMET");
function InitI18NSystem() {
fs.set("LangSetting", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "langsetting.json")));
/**
* @type {(pl:?Player,key:string)=>string}
*/
Tr = (pl, key) => {
let xuid = (pl != null ? pl.xuid : "");
let TMETDefault = fs.get("TMET").get("Language")["Default"];
let LangName = (!xuid ? TMETDefault : fs.get("LangSetting").get(xuid, TMETDefault));
let isError = LangFs.get(LangName).IsError;
if (!LangFs.has(LangName) || isError) {
LangName = "zh_CN";
if (!LangFs.has(LangName) || isError) {
if (!GlobalCache.defaultLangNotLoadIsTip) {
GlobalCache.defaultLangNotLoadIsTip = true;
logger.warn("Default LangPack: zh_CN not Read! Use built-in LangPack!");
}
return _Configs.DefaultLangPack[key];
}
}
return LangFs.get(LangName).get(key, key);
};
LoadAllLangPack();
RegLanguageCmd();
}
function RegLanguageCmd() {
TMCmd.register(fs.get("TMET").get("Language")["Cmd"], "switch language", PermType.Any, 0x80, (nc) => {
LangEnumMgr.addTask((LangPacks) => {
nc.setSoftEnum("LangNameEnum", LangPacks);
});
nc.mandatory("LangName", ParamType.SoftEnum, "LangNameEnum", "LangName", 1);
nc.mandatory("LangNameString", ParamType.String);
nc.overload([]);
nc.overload(["LangName"]);
nc.overload(["LangNameString"])
nc.setCallback((_cmd, ori, out, res) => {
let pl = ori.player, isPlayer = true;
if (!pl) {
isPlayer = false;
}
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (!isPlayer && ori.entity != null) {
out.error(addLogo("§cThe entity prohibits the execution of this command!", hasColor));
return;
}
if (pl != null && isSimulatedPlayer(pl)) {
out.error(addLogo("§cSimulated players are prohibited from executing this command!", hasColor));
return;
}
let LangName = (res.LangName || res.LangNameString);
if (LangName == null) {
if (!isPlayer) {
out.error(addLogo("§cConsole cannot open GUI! Please enter the complete command!", hasColor));
} else {
SwitchLangPackGui(pl);
}
return;
}
if (!LangFs.has(LangName)) {
out.error(addLogo(AutoReplace("§cLangPack not found: {1}", LangName)));
} else {
if (!Event_SwitchLangPackExample((isPlayer ? pl.xuid : ""), LangName)) {
return;
}
if (isPlayer) {
fs.get("LangSetting").set(pl.xuid, LangName);
} else {
let TMETCfg = fs.get("TMET");
let LangCfg = TMETCfg.get("Language");
LangCfg["Default"] = LangName;
TMETCfg.set("Language", LangCfg);
}
out.success(addLogo(AutoReplace("§bLangPack switched to {1}", LangName), hasColor));
}
});
nc.setup();
});
}
/**
* @param {Player} pl
*/
function SwitchLangPackGui(pl) {
let nf = mc.newCustomForm();
nf.setTitle("§l§dSelectLangPack");
let arr = [], nowSel = -1;
let xuid = pl.xuid;
let TMETDefault = fs.get("TMET").get("Language")["Default"];
let LangName = (!xuid ? TMETDefault : fs.get("LangSetting").get(xuid, TMETDefault));
if (!LangFs.has(LangName)) {
LangName = "zh_CN";
}
LangFs.forEach((_J, key) => {
if (LangName == key) {
nowSel = arr.length;
}
arr.push(key);
});
nf.addDropdown("§l§bPlease select a language pack", arr, nowSel);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo("§bForm abandoned"));
return;
}
let sel = arr[args[0]];
pl.runcmd(`/${fs.get("TMET").get("Language")["Cmd"]} ${sel}`);
});
}
function LoadAllLangPack() {
try {
let lang = new JsonConfigFileClass(AutoReplace(TMET_LangDir, "zh_CN.json"), JSON.stringify(_Configs.DefaultLangPack, null, 2));
LangFs.set("zh_CN", lang);
lang._getCache();
if (lang.get("langPack.author") == null) {
throw new Error("Old LangPack!!!");
}
} catch (e) {
if (e.message.indexOf("Old LangPack!!!") != -1) {
logger.warn("zh_CN LangPack is old data!");
} else {
logger.error("zh_CN LangPack is damaged!");
}
logger.info("Auto fix zh_CN LangPack...");
LangFs.get("zh_CN").write(JSON.stringify(_Configs.DefaultLangPack, null, 2));
}
UpdateDefaultLangPack();
PrintLangPackMsg("zh_CN");
LangEnumMgr.add("zh_CN");
logger.info("Standard LangPack zh_CN has been read!");
let files = File.getFilesList(AutoReplace(TMET_LangDir, ""));
files.forEach((name) => {
LoadLangPack(name, true);
});
}
/**
* @param {string} name 名称
* @param {string} isAutoMode 是否是自动加载模式,非自动加载模式会自动修正大小写(API不准修改此参数!)
* @returns {-1|0|1} -1表示失败0表示不是标准包1表示标准包
*/
function LoadLangPack(name, isAutoMode = false) {
name = name.trim();
if (name.toLowerCase() == "zh_cn.json") { return -1; }
let TmpArr = name.split(".");
if (TmpArr.pop() != "json") { return -1; };
let FileName = TmpArr.join(".");
if (!isAutoMode) {
let res = File.getFilesList(AutoReplace(TMET_LangDir, "")).find((FileName1) => {
if (FileName1.toLowerCase() == name.toLowerCase()) {
name = FileName1;
FileName = (() => {
let tmp = FileName1.split(".");
tmp.pop();
return tmp.join(".");
})();
return true;
} else { return false; }
});
if (!res) { return -1; }
}
let LangPath = AutoReplace(TMET_LangDir, name);
try {
let arr = [];
LangFs.forEach((_J, name) => { arr.push(name.toLowerCase()); });
if (arr.indexOf(FileName.toLowerCase()) != -1) { return -1; }
LangFs.set(FileName, new JsonConfigFileClass(LangPath));
let iss = isStandardLangPack(FileName);
if (iss) {
logger.info(`Standard LangPack: ${FileName} Read!`);
} else {
logger.warn(`Non-Standard LangPack: ${FileName} Read!`);
}
PrintLangPackMsg(FileName);
LangEnumMgr.add(FileName);
return (iss ? 1 : 0);
} catch (e) {
LangFs.delete(FileName);
logger.error("The LangPack: ", FileName, " Failed To Read");
return -1;
}
}
/**
* @param {string} name
*/
function UnloadLangPack(name) {
name = name.trim();
if (name.toLowerCase() == "zh_cn.json") { return false; }
let TmpArr = name.split(".");
if (TmpArr.pop() != "json") { return false; };
let FileName = TmpArr.join(".");
let arr = [], arr2 = [];
LangFs.forEach((_J, name) => { arr.push(name.toLowerCase()); arr2.push(name); });
let index = arr.indexOf(FileName.toLowerCase());
if (index == -1) { return false; }
let LName = arr2[index];
LangEnumMgr.del(LName);
let res = LangFs.delete(LName);
return res;
}
function PrintLangPackMsg(name) {
let LP = LangFs.get(name);
logger.info(`LangPack Name: ${name}`)
logger.info(`LangPack Author: ${LP.get("langPack.author", "Unknown")}`);
logger.info(`LangPack Description: ${LP.get("langPack.description", "Unknown")}`);
}
function isStandardLangPack(name) {
let LP = LangFs.get(name);
let Keys = LP.getKeys();
let NotHas = [];
LangFs.get("zh_CN").getKeys().forEach((key) => {
if (Keys.indexOf(key) == -1) {
NotHas.push(key);
}
});
if (NotHas.length == 0) {
return true;
} else {
logger.debug(`LangPack: ${name} missing data: \n[\n${NotHas.join(",\n")}\n]`);
return false;
}
}
function UpdateDefaultLangPack() {
let LangPack = LangFs.get("zh_CN");
/**
* @param {string} key
*/
let DEL = (key) => { LangPack.delete(key); return DEL; };
// DEL("reload.chunk.cmd.description")
// ("reload.chunk.fail.money")
// ("reload.chunk.success");
_Configs.DefaultLangPack.forEach((val, key) => {
let res = LangPack.get(key);
if (res == null || res != val) {
LangPack.set(key, val);
logger.info("LangPack: zh_CN auto repair: ", key);
}
});
}
Modules._RegExportApi("setLangPack", (xuid, LangName) => {
if (!LangFs.has(LangName)) { return false; }
if (xuid == "") {
let TMETCfg = fs.get("TMET");
let LangCfg = TMETCfg.get("Language");
LangCfg["Default"] = LangName;
TMETCfg.set("Language", LangCfg);
} else {
fs.get("LangSetting").set(xuid, LangName);
}
return true;
});
Modules._RegExportApi("getLangPackList", () => {
let arr = [];
LangFs.forEach((_J, name) => {
arr.push({
"name": name,
"author": _J.get("langPack.author"),
"description": _J.get("langPack.description")
});
});
return arr;
});
Modules._RegExportApi("loadLangPack", (name) => {
return LoadLangPack(name);
});
Modules._RegExportApi("unloadLangPack", (name) => {
return UnloadLangPack(name);
});
InitI18NSystem();
})();
return true;
}
LoadMoney() {
(() => {
let Event_MoneyChangeExample = TMListen.RegEvent("onMoneyChange", "TMET");
let Event_MoneyPayExample = TMListen.RegEvent("onMoneyPay", "TMET");
let isLLMoney = false;
function MoneyLoad() {
let MoneyCfg = fs.get("TMET").get("Money");
let MoneyType = MoneyCfg["MoneyType"];
fs.set("MoneyData", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "offlineMoney.json", "{}")));
switch (MoneyType) {
case "score": {
if (MoneyCfg["HistoryLength"] != 0) {
fs.set("History", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "history.json")));
}
TMListen.listen("onScoreChanged", function (pl, num, name, _disName) {
if (isSimulatedPlayer(pl)) { return true; }
let offData = fs.get("MoneyData");
if (offData == null || name != "money") { return true; }
let offMoney = offData.get(pl.xuid);
if (offMoney != num) {
WriteUseLog("Money-Change-Score", pl, `${offMoney}->${num}`);
setMoney(pl.realName, num, "set");
}
});
TickTask.addTask(() => {
let ScoreBoard = mc.getScoreObjective("money");
if (ScoreBoard == null) {
logger.info(Tr(null, "money.scoreboard.notfound"));
mc.newScoreObjective("money", "money");
}
});
RegMoneyCmd();
break;
}
case "llmoney": {
TMListen.listen("onPlayerCmd", (pl, cmd) => {
if (isSimulatedPlayer(pl)) { return true; }
let lower = cmd.toLowerCase();
lower = (lower[0] == "/" ? lower.substring(1) : lower);
if (lower.indexOf("money") == 0) {
switch ((lower.substring(5) || "").trim()) {
case "": {
MoneyMainGui(pl);
return false;
}
case "add":
case "reduce":
case "set": {
if (pl.permLevel != 0) {
MoneySetGui(pl);
return false;
}
}
case "pay": {
MoneyPayGui(pl);
return false;
}
}
}
});
TMListen.listen("onLLMoneyMoneyChanged", Money_onLLMoneyMoneyChanged);
// setInterval(() => {//同步在线玩家LLMoney
// GlobalCache.PlayerState.forEach((bool, xuid) => {
// if (bool) {
// let name = data.xuid2name(xuid);
// let llmoneyVal = money.get(xuid);
// let pluginVal = fs.get("MoneyData").get(xuid, 0);
// if (llmoneyVal != pluginVal) {
// WriteUseLog("Money-Change-LLMoney", mc.getPlayer(xuid), `${pluginVal}->${llmoneyVal}`);
// setMoney(name, llmoneyVal);
// }
// }
// });
// }, 2000);
fs.set("llmoneyConf", new JsonConfigFileClass(LLMoney_ConfigPath, "{}"));
isLLMoney = true;
break;
}
default: {
throw new TypeError(`NotBug: \n 未知的MoneyType:"${MoneyType}"! 它必选为"score"或者"llmoney"\n Unknown MoneyType:"${MoneyType}"! It must be selected as "score" or "llmoney"`);
}
}
TMListen.listen("onJoin", Money_onJoin);
}
function RegMoneyCmd() {
TMCmd.register("money", Tr(null, "money.description"), PermType.Any, 0x80, (nc) => {
nc.setEnum("MoneyOPEnum1", ["add", "reduce", "set"]);
nc.setEnum("MoneyOPEnum2", ["query", "hist"]);
nc.setEnum("MoneyOPEnum3", ["top", "gui"]);
nc.setEnum("MoneyOPEnum4", ["pay"]);
nc.mandatory("MoneyOP1", ParamType.Enum, "MoneyOPEnum1", "MoneyOP1", 1);
nc.mandatory("MoneyOP2", ParamType.Enum, "MoneyOPEnum2", "MoneyOP2", 1);
nc.mandatory("MoneyOP3", ParamType.Enum, "MoneyOPEnum3", "MoneyOP3", 1);
nc.mandatory("MoneyOP4", ParamType.Enum, "MoneyOPEnum4", "MoneyOP4", 1);
nc.optional("playerName", ParamType.String);
nc.optional("target", ParamType.Player);
nc.optional("num", ParamType.Int);
nc.optional("note", ParamType.Message);
nc.overload([]);
nc.overload(["MoneyOP1", "target", "num"]);
nc.overload(["MoneyOP1", "playerName", "num"]);
nc.overload(["MoneyOP2", "target"]);
nc.overload(["MoneyOP2", "playerName"]);
nc.overload(["MoneyOP3"]);
nc.overload(["MoneyOP4", "target", "num", "note"]);
nc.overload(["MoneyOP4", "playerName", "num", "note"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player, isPlayer = true;
if (!pl) {
isPlayer = false;
}
let type = (res.MoneyOP1 || res.MoneyOP2 || res.MoneyOP3 || res.MoneyOP4 || "gui");
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (!isPlayer && ori.entity != null) {
out.error(addLogo(Tr(pl, "command.not.allow.entity"), hasColor));
return;
}
if (pl != null && isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
switch (type) {
case "gui": {
if (isPlayer) {
MoneyMainGui(pl);
} else {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
}
break;
}
case "set":
case "reduce":
case "add": {
let playerNames = (res.playerName != null ? [res.playerName] : []);
if (res.target != null) {
res.target.forEach((pl) => { playerNames.push(pl.realName) });
}
let val = res.num;
if (oriLevel == "other" || oriLevel == "notop") {
out.error(addLogo(Tr(pl, "command.not.allow.perm"), hasColor));
return;
}
if (playerNames.length == 0 || val == null) {
if (isPlayer) {
MoneySetGui(pl);
} else {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
}
} else {
val = (type == "add" || type == "set" ? val : -val);
playerNames.forEach((playerName) => {
let hasMoney = getMoney(playerName);
if (hasMoney == null) {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
} else {
if (setMoney(playerName, (type != "set" ? (hasMoney + val) : val))) {
WriteUseLog(AutoReplace("Money-{1}", (type == "set" ? "Set" : "Add")), pl, `->${playerName}(${val})`);
out.success(addLogo(Tr(pl, "money.operation.completed"), hasColor));
}
}
});
}
break;
}
case "pay": {
let playerNames = (res.playerName != null ? [res.playerName] : []);
if (res.target != null) {
res.target.forEach((pl) => { playerNames.push(pl.realName) });
}
let val = res.num;
let note = (res.note || "pay");
if (playerNames.length == 0 || val == null) {
if (isPlayer) {
MoneyPayGui(pl);
} else {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
return;
}
} else {
if (val < 0) {
out.error(addLogo(Tr(pl, "money.pay.input.number.error")));
return;
}
playerNames.forEach((playerName) => {
let feeOrBool = tranMoney(pl.realName, playerName, val, note);
if (typeof (feeOrBool) == "number") {
WriteUseLog("Money-Pay", pl, `->${playerName}(${val}-${feeOrBool})`);
out.success(addLogo(AutoReplace(Tr(pl, "money.pay.success"), playerName, feeOrBool, fs.get("TMET").get("Money")["MoneyName"])));
} else {
out.error(addLogo(Tr(pl, "money.pay.fail")));
}
});
}
break;
}
case "top": {
if (isPlayer) {
MoneyTopGui(pl);
} else {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
}
break;
}
case "query": {
let playerNames = (res.playerName != null ? [res.playerName] : (isPlayer ? [pl.realName] : []));
if (res.target != null) {
res.target.forEach((pl) => { playerNames.push(pl.realName) });
}
if (playerNames.length == 0) {
out.error(addLogo(Tr(pl, "command.target.not.player"), hasColor));
return;
}
playerNames.forEach((playerName) => {
let hasVal = getMoney(playerName);
if (hasVal == null) {
out.error(addLogo(AutoReplace(Tr(pl, "money.notfound.player.info1"), playerName), hasColor));
return;
}
let txt = "", MoneyName = fs.get("TMET").get("Money")["MoneyName"];
if (isPlayer && playerName == pl.realName) {
txt = AutoReplace(Tr(pl, "money.query.self"), hasVal, MoneyName);
} else {
txt = AutoReplace(Tr(pl, "money.query.other"), playerName, hasVal, MoneyName);
}
WriteUseLog("Money-Query", pl, `->${playerName}(${hasVal})`);
out.success(addLogo(txt, hasColor));
});
break;
}
case "hist": {
let playerNames = (res.playerName != null ? [res.playerName] : []);
if (res.target != null) {
res.target.forEach((pl) => { playerNames.push(pl.realName) });
}
if (playerNames.length > 1) {
out.error(addLogo(Tr(pl, "command.target.only.one.player")));
return;
}
if (isPlayer) {
MoneyHistoryList(pl, (playerNames.length != 0 ? playerNames[0] : null), out);
} else {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui"), hasColor));
}
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
/**
* @param {Player} pl
*/
function MoneyMainGui(pl) {
let buttons = [
Tr(pl, "money.main.gui.button.pay"),
Tr(pl, "money.main.gui.button.top"),
Tr(pl, "money.main.gui.button.hist")
];
if (pl.permLevel != 0) { buttons.push(Tr(pl, "money.main.gui.button.op.fast.mgr")); }
pl.sendSimpleForm("§l§dMoneyGui", Tr(pl, "form.please.select"), buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
switch (id) {
case 0: {
pl.runcmd("/money pay");
break;
}
case 1: {
pl.runcmd("/money top");
break;
}
case 2: {
pl.runcmd("/money hist");
break;
}
case 3: {
pl.runcmd("/money set");
}
}
});
}
/**
* @param {Player} pl
* @param {string} title
* @param {(pl:Player,info:{"name":string,"loss":boolean})} cb
*/
function MoneySelectPlayer(pl, title, cb) {
let StepSliders = [
Tr(pl, "money.select.player.gui.step.slider.online"),
Tr(pl, "money.select.player.gui.step.slider.offline")
];
let nf = mc.newCustomForm();
nf.setTitle(title);
nf.addLabel(Tr(pl, "money.select.player.gui.label"));
nf.addStepSlider(Tr(pl, "money.select.player.gui.step.slider.title"), StepSliders);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
/**
* @type {Array<{"name":string,"loss":boolean}>}
*/
let list = [];
let buttons = [];
switch (args[1]) {
case 0: {
GlobalCache.PlayerState.forEach((_bool, xuid) => {
let name = data.xuid2name(xuid);
list.push({ "name": name, "loss": false });
buttons.push(name);
});
break;
}
case 1: {
let obj = JSON.parse(fs.get("MoneyData").read());
obj.forEach((_val, key) => {
let name = data.xuid2name(key);
list.push({ "name": (name || key), "loss": !name });
buttons.push((name || key));
});
break;
}
}
let sfd = new SelectFormData(title, Tr(pl, "money.select.player.gui2.content"), buttons, fs.get("TMET").get("SelectForm")["Subsection"], (pl, ids) => {
if (ids == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
if (ids.length != 1) {
ST(pl, addLogo(Tr(pl, "money.select.player.gui2.select.error")));
return;
}
let info = list[ids[0]];
if (info.loss) {
ST(pl, addLogo(Tr(pl, "money.select.player.gui2.select.error.player.info.lost")));
return;
}
cb(pl, info);
});
sendSelectForm(pl, sfd);
});
}
/**
* @param {Player} pl
*/
function MoneySetGui(pl) {
MoneySelectPlayer(pl, "§l§dMoneyAdmin", (pl, info) => {
let nf = mc.newCustomForm();
nf.setTitle("§l§dMoneyAdmin");
nf.addLabel(AutoReplace(Tr(pl, "money.admin.form.label"), info.name, getMoney(info.name), fs.get("TMET").get("Money")["MoneyName"]));
nf.addSwitch(Tr(pl, "money.admin.form.add.mode.switch.title"), false);
nf.addInput(Tr(pl, "money.admin.form.input.title"), "(String)");
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let [setMode, input] = [!args[1], args[2]];
if (!(/^-?\d+$/).test(input)) {
ST(pl, addLogo(Tr(pl, "money.form.input.error")));
return;
}
if (setMode) {
pl.runcmd(`/money set "${info.name}" ${input}`);
} else {
if (input > 0) {
pl.runcmd(`/money add "${info.name}" ${input}`);
} else {
pl.runcmd(`/money reduce "${info.name}" ${-input}`);
}
}
});
});
}
/**
* @param {Player} pl
*/
function MoneyPayGui(pl) {
MoneySelectPlayer(pl, "§l§dMoneyPay", (pl, info) => {
let nf = mc.newCustomForm();
nf.setTitle("§l§dMoneyPay");
nf.addLabel(AutoReplace(Tr(pl, "money.pay.form.label"),
info.name, getMoney(pl.realName), getMoney(info.name), fs.get("TMET").get("Money")["MoneyName"], getPayTax().toFixed(2)));
nf.addInput(Tr(pl, "money.pay.form.input.title"), "(+Number)");
if (!isLLMoney) {
nf.addInput(Tr(pl, "money.pay.form.note.input.title"), "(String)", "pay");
}
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let num = args[1];
if (!(/^-?\d+$/).test(num)) {
ST(pl, addLogo(Tr(pl, "money.form.input.error")));
return;
}
pl.runcmd(`/money pay "${info.name}" ${num}${!!args[2] ? " " + args[2] : ""}`);
});
});
}
/**
* @param {Player} pl
*/
function MoneyTopGui(pl) {
let allData = JSON.parse(fs.get("MoneyData").read());
let MoneyCfg = fs.get("TMET").get("Money");
let MaxRankingQuantity = MoneyCfg["MaxRankingQuantity"], MoneyName = MoneyCfg["MoneyName"];
/**
* @type {Array<{"name":string,"money":number,"loss":boolean}>}
*/
let list = [];
allData.forEach((_val, xuid) => {
let name = data.xuid2name(xuid);
if (!name) {
list.push({ "name": xuid, "money": _val, "loss": true });
return;
}
let HasMoney = getMoney(name);
list.push({ "name": name, "money": HasMoney, "loss": true });
});
list.sort((a, b) => { return (b.money - a.money); });
/** @type {string[]} */
let arr = [];
let i = 0;
list.find((obj) => {
if (MaxRankingQuantity < 0 || i < MaxRankingQuantity) {
arr.push(`§b${(i + 1)}.§e${obj.name} §a${obj.money} §f${MoneyName}`);
} else { return true; }
i++;
return false;
});
// let nf = mc.newCustomForm();
// nf.setTitle("§l§dMoneyRanking");
let realName = pl.realName;//防动态获取
let selfData = list.find((obj) => {
if (obj.name == realName) {
return true;
} else {
return false;
}
});
// if (selfData != null) {
// nf.addLabel(`§b${(selfData[1] + 1)}.§e${selfData[0].name} §a${selfData[0].money} §f${MoneyName}`);
// }
let sfd = new SelectFormData("§l§dMoneyRanking", `Top ${MaxRankingQuantity}:`, arr, fs.get("TMET").get("SelectForm")["Subsection"], () => { });
sendSelectForm(pl, sfd);
// nf.addLabel(arr.join("\n"));
// pl.sendForm(nf, (_p, _a) => { });
WriteUseLog("Money-LookTop", pl, "");
}
/**
* @param {Player} pl
* @param {?string} playerName
* @param {?CommandOutput} out
*/
function MoneyHistoryList(pl, playerName = null, out) {
if (pl.permLevel == 0 && playerName == null) {
playerName = pl.realName;
} else if (pl.permLevel == 0) {
out.error(addLogo(Tr(pl, "command.not.allow.perm")));
return;
}
if (playerName == null) {
pl.sendModalForm("§l§dMoneyHistory", Tr(pl, "money.check.history.admin.form.content"), Tr(pl, "money.check.history.admin.form.check.other"), Tr(pl, "money.check.history.admin.form.check.self"), (pl, bool) => {
if (bool) {
MoneySelectPlayer(pl, "§l§dMoneyHistory", (pl, info) => {
pl.runcmd(`/money hist "${info.name}"`);
});
} else {
pl.runcmd(`/money hist "${pl.realName}"`);
}
});
} else {
let xuid = data.name2xuid(playerName);
if (!xuid) {
out.error(addLogo(Tr(pl, "money.notfound.player.info")));
return;
}
let histList = getHistory(xuid);
if (histList == null || histList.length == 0) {
out.error(addLogo(Tr(pl, "money.check.history.notfound")));
return;
}
let arr = [], lineInfo = Tr(pl, "money.check.history.form.line.info");
histList.forEach((obj, i) => {
let timeObj = new Date(obj.time * 1000);
let timeStr = AutoReplace("{1}/{2}/{3} {4}:{5}:{6}",
timeObj.getFullYear(),
(timeObj.getMonth() + 1),
timeObj.getDate(),
timeObj.getHours().toFull(2),
timeObj.getMinutes().toFull(2),
timeObj.getSeconds().toFull(2)
);
arr.push(AutoReplace(lineInfo,
(i + 1),
timeStr,
(data.xuid2name(obj.from) || obj.from),
(data.xuid2name(obj.to) || obj.to),
obj.money,
obj.note
));
});
let nf = mc.newCustomForm();
// nf.setTitle("§l§dMoneyHistory");
// nf.addLabel(AutoReplace(Tr(pl, "money.check.history.form.select.player"), playerName));
// nf.addLabel(arr.join("\n"));
// pl.sendForm(nf, (_p, _a) => { });
let sfd = new SelectFormData("§l§dMoneyHistory", AutoReplace(Tr(pl, "money.check.history.form.select.player"), playerName), arr, fs.get("TMET").get("SelectForm")["Subsection"], () => { });
sendSelectForm(pl, sfd);
WriteUseLog("Money-LookHistory", pl, `->${playerName}`);
}
}
/**
* @param {string} xuid
* @param {string} toXuid
* @param {number} val
* @param {string} note
* @returns
*/
function addHistory(xuid, toXuid, val, note = "pay") {
let MoneyCfg = fs.get("TMET").get("Money");
if (MoneyCfg["MoneyType"] != "score" || MoneyCfg["HistoryLength"] == 0) {
return false;
}
let History = fs.get("History");
if (History == null) { return false; }
let HistoryData = History.get(xuid, []);
let Obj = {
"from": xuid,
"to": toXuid,
"money": val,
"time": Math.floor(Date.now() / 1000),
"note": note
}
if (typeOfEx(HistoryData) != "Array") {
HistoryData = [Obj];
} else { HistoryData.unshift(Obj); }
if (MoneyCfg["HistoryLength"] < 0) {
while (MoneyCfg["HistoryLength"] < HistoryData.length) {
HistoryData.pop();
}
}
History.set(xuid, HistoryData);
return true;
}
/**
* @param {string} xuid
* @param {?number} time
* @returns {(null|Array<{"from":string,"to":string,"money":number,"time":number,"note":string}>)}
*/
function getHistory(xuid, time = -1) {
let nowTime = Math.floor(Date.now() / 1000);
let History = fs.get("History");
if (History == null) { return null; }
/**
* @type {(null|Array<{"from":string,"to":string,"money":number,"time":number,"note":string})}
*/
let HistoryData = History.get(xuid, []);
if (typeOfEx(HistoryData) != "Array") { return null; }
if (HistoryData.length == 0) { return []; }
HistoryData.sort((a, b) => { return b.time - a.time; });
if (time <= -1) {
return HistoryData;
}
let arr = [];
HistoryData.find((o, i) => {
if ((nowTime - o.time) <= time) {
arr.push(HistoryData[i]);
} else { return true; }
return false;
});
return arr;
}
/**
* @param {string} xuid
* @returns {boolean}
*/
function clearHistory(xuid) {
let History = fs.get("History");
return History.delete(xuid);
}
/**
* @param {Player} pl
* @param {number} num
*/
function AutoFixScoreBug(pl, num) {
let ScoreBoard = mc.getScoreObjective("money");
if (ScoreBoard == null) {
mc.newScoreObjective("money", "money");
}
let out = runCmdNoOutput(`scoreboard players set "${pl.name}" money ${num}`);
logger.debug(`FixScoreBug::CmdOutput: ${out}`);
return true;
}
/**
* @returns {number}//float
*/
function getPayTax() {
let tax = 0.0;
switch (fs.get("TMET").get("Money")["MoneyType"]) {
case "score":
tax = fs.get("TMET").get("Money")["PayTaxRate"];
break;
case "llmoney":
tax = fs.get("llmoneyConf").get("pay_tax", 0.0);
let conf = fs.get("TMET").get("Money");
if (conf.PayTaxRate != tax) {
logger.warn(Tr(null, "money.tax.sync.tip"));
conf.PayTaxRate = tax;
fs.get("TMET").set("Money", conf);
}
break;
}
return +tax;
}
/**
* @param {string} realName
* @param {number} val
* @param {?("init"|"set"|"sync")} type
* @param {?boolean} isTarn
* @param {?string} note
* @returns {(boolean|null)}
*/
function setMoney(realName, val, type = "set", isTarn = false, note = "") {
try {
if (!type) { type = "set"; }
if (isTarn == null) { isTarn = false; }
if (typeof (realName) != "string" || typeof (val) != "number") {
return false;
}
let TMETCfg = fs.get("TMET");
if (!TMETCfg.get("Money")["Enable"]) {
return true;
}
let MoneyData = fs.get("MoneyData");
if (MoneyData == null) { return false; }
let MoneyType = TMETCfg.get("Money")["MoneyType"];
let PlayerXuid = data.name2xuid(realName);
if (!!PlayerXuid) {
let OldVal = MoneyData.get(PlayerXuid, null);
if (OldVal == val && type != "join") {//旧值等于新值
return true;
}
if (!isTarn) {
if (!Event_MoneyChangeExample(PlayerXuid, val, type, note) && type != "sync") {
return false;
}
}
let pl = mc.getPlayer(PlayerXuid);
if (pl != null) {//在线操作
MoneyData.set(PlayerXuid, val);
switch (MoneyType) {
case "score": {
let scoreOldVal = pl.getScore("money");
if (scoreOldVal == null) {
logger.debug(`LLSE:PlayerClass::GetScore API Error! Player: ${realName} money set to 0!`);
AutoFixScoreBug(pl, 0);
}
pl.setScore("money", val);
if (val != 0 && pl.getScore("money") != val) {
logger.debug(`LLSE:PlayerClass::SetScore API Error! Player: ${realName} money set to ${val}!`);
AutoFixScoreBug(pl, val);
}
if (TMETCfg.get("Money")["MoneyChangeMsg"]) {
switch (type) {
case "sync":
case "set": {
ST(pl, addLogo(AutoReplace(Tr(pl, "money.change.tip"), val, TMETCfg.get("Money")["MoneyName"], ((val - scoreOldVal) || val - +OldVal))));
break;
}
case "init": {
ST(pl, addLogo(AutoReplace(Tr(pl, "money.init.tip"), val, TMETCfg.get("Money")["MoneyName"])));
break;
}
}
}
if (!isTarn) {//add history
let Val = ((val - scoreOldVal) || val - +OldVal);
switch (type) {
case "set": {
addHistory(PlayerXuid, "", Val, (note || "System::Set"));
break;
}
case "init": {
addHistory(PlayerXuid, "", Val, `System::Init`);
break;
}
}
}
break;
}
case "llmoney": {
let LLMVal = money.get(PlayerXuid), DV = (val - LLMVal);
if (LLMVal != val) {
let ToMode = (DV >= 0 ? false : true);
money.trans(...(ToMode ? [PlayerXuid, ""] : ["", PlayerXuid]), (ToMode ? -DV : DV), (note || "System::Set"));
}
if (TMETCfg.get("Money")["MoneyChangeMsg"]) {
switch (type) {
case "sync":
case "set": {
ST(pl, addLogo(AutoReplace(Tr(pl, "money.change.tip"), val, TMETCfg.get("Money")["MoneyName"], (val - OldVal))));
break;
}
case "init": {
ST(pl, addLogo(AutoReplace(Tr(pl, "money.init.tip"), val, TMETCfg.get("Money")["MoneyName"])));
break;
}
}
}
break;
}
}
return true;
} else {//离线操作
switch (MoneyType) {
case "score": {
MoneyData.set(PlayerXuid, val);
if (!isTarn) {//add history
let Val = (val - OldVal);
switch (type) {
case "set": {
addHistory(PlayerXuid, "", Val, (note || "System::Set"));
break;
}
}
}
break;
}
case "llmoney": {
let LLMVal = money.get(PlayerXuid), DV = (val - LLMVal);
if (LLMVal != val) {
let ToMode = (DV >= 0 ? false : true);
money.trans(...(ToMode ? [PlayerXuid, ""] : ["", PlayerXuid]), (ToMode ? -DV : DV), (note || "System::Set"));
}
break;
}
}
return true;
}
} else {
return false;
}
return false;
} catch (e) {
ErrorMsg(e);
return null;
}
}
/**
* @param {string} realName
* @returns {(null|number)}
*/
function getMoney(realName) {
try {
if (typeof (realName) != "string") {
return null;
}
let TMETCfg = fs.get("TMET");
if (!TMETCfg.get("Money")["Enable"]) {
return 0;
}
let MoneyData = fs.get("MoneyData");
if (MoneyData == null) { return null; }
let MoneyType = TMETCfg.get("Money")["MoneyType"];
let PlayerXuid = data.name2xuid(realName);
if (!!PlayerXuid) {
let pl = mc.getPlayer(PlayerXuid);
if (pl != null) {
switch (MoneyType) {
case "score": {
let scoreVal = pl.getScore("money");
if (scoreVal == null) {
let offData = +MoneyData.get(PlayerXuid, TMETCfg.get("Money")["PlayerInitialMoney"]);
logger.debug(`LLSE:PlayerClass::GetScore API Error! Player: ${realName} money set to ${offData}!`);
AutoFixScoreBug(pl, offData);
scoreVal = offData;
}
return scoreVal;
}
case "llmoney": {
let llmoneyVal = money.get(PlayerXuid);
if (llmoneyVal == null) {
let offData = +MoneyData.get(PlayerXuid, TMETCfg.get("Money")["PlayerInitialMoney"]);
money.set(PlayerXuid, offData);
llmoneyVal = offData;
}
return llmoneyVal;
}
}
} else {
switch (MoneyType) {
case "score": {
return MoneyData.get(PlayerXuid, TMETCfg.get("Money")["PlayerInitialMoney"]);
}
case "llmoney": {
let llmoneyVal = money.get(PlayerXuid);
if (llmoneyVal == null) {
let llmoneyDef = fs.get("llmoneyConf").get("def_money", 0);
let offData = +MoneyData.get(PlayerXuid, llmoneyDef);
money.set(PlayerXuid, offData);
llmoneyVal = offData;
}
return llmoneyVal;
}
}
}
} else {
logger.debug(`Money::GetMoney Fail: The xuid of player ${realName} is not valid!`);
}
return null;
} catch (e) {
ErrorMsg(e);
return null;
}
}
/**
* @param {string} realName
* @param {string} toRealName
* @param {number} val
* @param {?string} note
* @returns {(boolean|number)}
*/
function tranMoney(realName, toRealName, val, note = "pay") {
if (typeof (realName) != "string" || typeof (toRealName) != "string" || typeof (val) != "number" || typeof (note) != "string") {
return false;
}
let TMETCfg = fs.get("TMET");
if (!TMETCfg.get("Money")["Enable"]) {
return false;
}
if ((/(^[1-9]\d*$)/).test(String(val))) {
let [pl1Xuid, pl2Xuid] = [data.name2xuid(realName), data.name2xuid(toRealName)];
if (!pl1Xuid || !pl2Xuid) {
return false;
}
let pl1HasMoney = getMoney(realName);
let pl2HasMoney = getMoney(toRealName);//只是一种安全检查
if (typeof (pl1HasMoney) == "number" && typeof (pl2HasMoney) == "number") {
if (val == 0) { return 0; }
if (pl1HasMoney >= val) {
let fee = Math.floor((val * +getPayTax()));
if (!Event_MoneyPayExample(pl1Xuid, pl2Xuid, val, fee, note)) {
return false;
}
switch (TMETCfg.get("Money")["MoneyType"]) {
case "score": {
setMoney(realName, (pl1HasMoney - val), "set", true);
setMoney(toRealName, (getMoney(toRealName) + val - fee), "set", true);
logger.debug(`Money::TarnMoney ${realName} to ${toRealName} Val:${val}-${fee}`);
addHistory(pl1Xuid, pl2Xuid, val, note);
addHistory(pl2Xuid, pl1Xuid, val, note);
break;
}
case "llmoney": {
money.trans(pl1Xuid, pl2Xuid, val, note);
if (!!fee) {
money.trans(pl2Xuid, "", fee, "money pay fee");
}
if (TMETCfg.get("Money")["MoneyChangeMsg"]) {
let [pl1, pl2] = [mc.getPlayer(pl1Xuid), mc.getPlayer(pl2Xuid)];
let MoneyName = TMETCfg.get("Money")["MoneyName"];
let changeTip = Tr(pl, "money.change.tip");
if (!!pl1) {
ST(pl1, addLogo(AutoReplace(changeTip, getMoney(realName), MoneyName, (-val))));
}
if (!!pl2) {
ST(pl2, addLogo(AutoReplace(changeTip, getMoney(toRealName), MoneyName, (val - fee))))
}
}
break;
}
}
return fee;
}
}
}
return false;
}
Modules._RegExportApi("getMoney", getMoney);
Modules._RegExportApi("setMoney", setMoney);
Modules._RegExportApi("tranMoney", tranMoney);
Modules._RegExportApi("getPayTax", getPayTax);
Modules._RegExportApi("getHistory", getHistory);
Modules._RegExportApi("clearHistory", clearHistory);
Modules._RegExportApi("getMoneyName", () => { return fs.get("TMET").get("Money")["MoneyName"]; });
Modules._RegExportApi("getMoneyType", () => { return fs.get("TMET").get("Money")["MoneyType"]; });
/**
* @param {Player} pl
*/
function Money_onJoin(pl) {
if (isSimulatedPlayer(pl)) { return true; }
let MoneyCfg = fs.get("TMET").get("Money");
let MoneyData = fs.get("MoneyData");
let offData = MoneyData.get(pl.xuid);
let InitVal = MoneyCfg["PlayerInitialMoney"];
switch (MoneyCfg["MoneyType"]) {
case "score": {
let scoreVal = pl.getScore("money");
if (scoreVal == null) {
AutoFixScoreBug(pl, 0);
}
if (typeOfEx(offData) == "Number") {//No Init
if (scoreVal != offData) {
setMoney(pl.realName, offData, "sync");
}
} else {//Init?
if (scoreVal == 0) {//Init!
setMoney(pl.realName, InitVal, "init") && WriteUseLog("Money-Init", pl, InitVal);
} else {//Soft
MoneyData.set(pl.xuid, scoreVal);
WriteUseLog("Money-Sync-Score", pl, scoreVal);
}
}
break;
}
case "llmoney": {
let llmoneyVal = money.get(pl.xuid);
if (llmoneyVal != offData) {
setMoney(pl.realName, llmoneyVal, "sync");
WriteUseLog("Money-Sync-LLMoney", pl, llmoneyVal);
}
break;
}
}
}
/**
* @param {string} xuid 玩家xuid
* @param {number} moneyVal
*/
function Money_onLLMoneyMoneyChanged(xuid, moneyVal) {
setMoney(data.xuid2name(xuid), moneyVal, "sync", false, "");
}
MoneyLoad();
})();
return true;
}
LoadTPA() {
(() => {
let Event_TPARequestExample = TMListen.RegEvent("onTPARequest", "TMET");
let Event_TPAAcceptExample = TMListen.RegEvent("onTPAAccept", "TMET");
let Event_TPADenyExample = TMListen.RegEvent("onTPADeny", "TMET");
let Event_TPATimeoutExample = TMListen.RegEvent("onTPATimeout", "TMET");
function TPALoad() {
GlobalCache.TPACache = [];
fs.set("TPASet", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "tpasetting.json"), "{}"));
RegTPACmd();
TMListen.listen("onLeft", TPA_onLeft);
setInterval(TPALoopCheck, 500);
}
function RegTPACmd() {
TMCmd.register("tpa", AutoReplace(Tr(null, "tpa.cmd.description"), fs.get("TMET").get("TPA")["ConsumeMoney"]), PermType.Any, 0x80, (nc) => {
nc.setEnum("TPA_OPEnum1", ["gui", "ui"]);
nc.setEnum("TPA_OPEnum2", ["to"]);
nc.mandatory("TPA_OP1", ParamType.Enum, "TPA_OPEnum1", "TPA_OP1", 1);
nc.mandatory("TPA_OP2", ParamType.Enum, "TPA_OPEnum2", "TPA_OP2", 1);
nc.optional("target", ParamType.Player);
nc.overload([]);
nc.overload(["TPA_OP1"]);
nc.overload(["TPA_OP2", "target"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else {
if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
let type = (res.target == null ? (res.TPA_OP1 || "gui") : "tpa");
switch (type) {
case "gui": {
TPA_Gui(pl, false);
break;
}
case "tpa": {
if (res.target.length != 1) {
out.error(addLogo(Tr(pl, "command.target.only.one.player")));
return;
}
TPA_Request(pl, res.target[0], out, false);
break;
}
case "ui": {
let TPASet = fs.get("TPASet");
let bool = TPASet.get(pl.xuid, true);
if (bool) {
TPASet.set(pl.xuid, false);
out.success(addLogo(Tr(pl, "tpa.ui.false")));
} else {
TPASet.set(pl.xuid, true);
out.success(addLogo(Tr(pl, "tpa.ui.true")));
}
WriteUseLog("TPA-UI", pl, !bool);
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("tpahere", AutoReplace(Tr(null, "tpahere.cmd.description"), fs.get("TMET").get("TPA")["ConsumeMoney"]), PermType.Any, 0x80, (nc) => {
nc.setEnum("TPAHere_OPEnum1", ["to"]);
nc.mandatory("TPAHere_OP1", ParamType.Enum, "TPAHere_OPEnum1", "TPAhere_OP1")
nc.optional("target", ParamType.Player);
nc.overload([]);
nc.overload(["TPAHere_OP1", "target"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else {
if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
let type = (res.target == null ? "gui" : "tpa");
switch (type) {
case "gui": {
TPA_Gui(pl, true);
break;
}
case "tpa": {
if (res.target.length != 1) {
out.error(addLogo(Tr(pl, "command.target.only.one.player")));
return;
}
TPA_Request(pl, res.target[0], out, true);
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("tpaaccept", Tr(null, "tpaaccept.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else {
if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
TPA_Accept(pl, out);
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("tpadeny", Tr(null, "tpadeny.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else {
if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
TPA_Deny(pl, out);
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
function TPALoopCheck() {
let nowTime = Date.now();
let ET = fs.get("TMET").get("TPA")["ExpirationTime"];
/**
* @type {Array<{"from":string,"to":string,"time":number,"isHereMode":boolean}>}
*/
let a = GlobalCache.TPACache;
a.forEach((obj, i) => {
if (((nowTime - obj.time) / 1000) > ET) {
let fromPl = mc.getPlayer(obj.from);
let toPl = mc.getPlayer(obj.to);
if (!Event_TPATimeoutExample(obj)) {
return;
}
WriteUseLog(`TPA-${(obj.isHereMode ? "Here-" : "")}Timeout`, fromPl, toPl.realName);
if (!obj.isHereMode) {
ST(fromPl, addLogo(AutoReplace(Tr(fromPl, "tpa.timeout.from.player.tip"), toPl.realName)));
ST(toPl, addLogo(AutoReplace(Tr(toPl, "tpa.timeout.to.player.tip"), fromPl.realName)));
} else {
ST(fromPl, addLogo(AutoReplace(Tr(fromPl, "tpahere.timeout.from.player.tip"), toPl.realName)));
ST(toPl, addLogo(AutoReplace(Tr(toPl, "tpahere.timeout.to.player.tip"), fromPl.realName)));
}
SafeDeleteArray(a, i);
}
});
}
/**
* @param {string} xuid
* @return {(null|[{"from":string,"to":string,"time":number,"isHereMode":boolean},number])}
*/
function getTPAData(xuid) {
/**
* @type {Array<{"from":string,"to":string,"time":number,"isHereMode":boolean}>}
*/
let a = GlobalCache.TPACache;
return a.find((obj) => {
if (obj.from == xuid || obj.to == xuid) {
return true;
}
return false;
});
}
/**
* @param {Player} pl
* @param {?boolean} isHere
*/
function TPA_Gui(pl, isHere = false) {
let pls = [], tpaType = [
Tr(pl, "tpa.gui.type.to"),
Tr(pl, "tpa.gui.type.here")
];
GlobalCache.PlayerState.forEach((bool, xuid) => {
if (bool) {
pls.push(data.xuid2name(xuid));
}
});
let nf = mc.newCustomForm();
nf.setTitle("§l§dTPAGui");
nf.addDropdown(Tr(pl, "tpa.gui.form.select.player.title"), pls, 0);
nf.addDropdown(Tr(pl, "tpa.gui.form.select.tpa.type.title"), tpaType, (+isHere));
nf.addLabel(AutoReplace(Tr(pl, "tpa.gui.form.label.title"), fs.get("TMET").get("TPA")["ConsumeMoney"]));
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let [selPlName, isHere] = [pls[args[0]], Boolean(args[1])];
if (isHere) {
pl.runcmd(`/tpahere to "${selPlName}"`);
} else {
pl.runcmd(`/tpa to "${selPlName}"`);
}
});
}
/**
* @param {Player} pl
* @param {Player} toPl
* @param {CommandOutput} out
* @param {boolean} isHere
*/
function TPA_Request(pl, toPl, out, isHere) {
if (!toPl.xuid || isSimulatedPlayer(toPl)) {
out.error(addLogo(Tr(pl, "command.notfound.player")));
return;
}
if (getTPAData(toPl.xuid) != null) {
out.error(addLogo(Tr(pl, "tpa.select.player.has.request.tip")));
return;
} else {
let cache = (getTPAData(pl.xuid) || [])[0];
if (cache != null) {
pl.sendModalForm(Tr(pl, "tpa.self.request.not.process.title"), AutoReplace(Tr(pl, "tpa.self.request.not.process.content"),
data.xuid2name(cache.from),
data.xuid2name(cache.to)
), Tr(pl, "tpa.self.request.not.process.button.give.up.and.send.this.request"), Tr(pl, "tpa.self.request.not.process.button.give.up.this.request.and.wait.last.request"), (pl, res) => {
if (res) {
pl.runcmd("/tpadeny");
pl.runcmd(AutoReplace("/tpa{1} to \"{2}\"", (isHere ? "here" : ""), toPl.realName));
} else {
ST(pl, addLogo(Tr(pl, "tpa.self.request.not.process.res.wait.tip")));
}
});
return;
}
}
if (!Event_TPARequestExample(pl.xuid, toPl.xuid, isHere)) {
return;
}
GlobalCache.TPACache.push({ "from": pl.xuid, "to": toPl.xuid, "time": Date.now(), "isHereMode": isHere });
out.success(addLogo(AutoReplace(Tr(pl, "tpa.request.success"), toPl.realName, (isHere ? Tr(pl, "tpa.request.here.string") : ""))));
ST(toPl, addLogo(AutoReplace(Tr(toPl, "tpa.request.to.player.tip"), pl.realName, (isHere ? "Here" : ""))));
if (fs.get("TPASet").get(toPl.xuid, true)) {
SendModalFormToPlayer(toPl, Tr(toPl, "tpa.request.to.player.form.title"), AutoReplace(Tr(toPl, "tpa.request.to.player.form.content"),
pl.realName, (isHere ? Tr(toPl, "tpa.request.here.string") : ""), fs.get("TMET").get("TPA")["ConsumeMoney"]
), Tr(toPl, "tpa.request.to.player.form.button.accept"), Tr(toPl, "tpa.request.to.player.form.button.deny"), (pl, res) => {
if (res) {
pl.runcmd("/tpaaccept");
} else {
pl.runcmd("/tpadeny");
}
});
}
WriteUseLog(`TPA${isHere ? "-Here" : ""}-Request`, pl, toPl.realName);
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function TPA_Accept(pl, out) {
let [cache, index] = (getTPAData(pl.xuid) || []);
if (cache == null || (cache.from == pl.xuid && cache.to != pl.xuid)) {
out.error(addLogo(Tr(pl, "tpa.process.notfound.request")));
return;
}
let fromPl = mc.getPlayer(cache.from);
if (fromPl == null) {
out.error(addLogo(Tr(pl, "tpa.accept.from.player.lost")));
return;
}
let fromName = fromPl.realName;
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let HasMoney = getMoney(fromName);
let consume = +fs.get("TMET").get("TPA")["ConsumeMoney"];
if (HasMoney >= consume) {
if (!Event_TPAAcceptExample(pl.xuid, cache)) {
return;
}
setMoney(fromName, (HasMoney - consume), "set", false, "TPAConsume");
} else {
out.error(addLogo(Tr(pl, "tpa.accept.fail.money.to.player.tip")));
ST(fromPl, addLogo(Tr(fromPl, "tpa.accept.fail.money.from.player.tip")));
return;
}
if (!cache.isHereMode) {
fromPl.teleport(pl.pos);
ST(fromPl, addLogo(AutoReplace(Tr(fromPl, "tpa.accept.success.from.player.tip"), pl.realName)))
out.success(addLogo(AutoReplace(Tr(pl, "tpa.accept.success.to.player.tip"), fromName)));
} else {
pl.teleport(fromPl.pos);
ST(fromPl, addLogo(AutoReplace(Tr(fromPl, "tpahere.accept.success.from.player.tip"), pl.realName)))
out.success(addLogo(AutoReplace(Tr(pl, "tpahere.accept.success.to.player.tip"), fromName)));
}
WriteUseLog(`TPA${cache.isHereMode ? "-Here" : ""}-AC`, pl, fromName);
GlobalCache.TPACache.splice(index, 1);
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function TPA_Deny(pl, out) {
let [cache, index] = (getTPAData(pl.xuid) || []);
if (cache == null) {
out.error(addLogo(Tr(pl, "tpa.process.notfound.request")));
return;
}
let pl2 = mc.getPlayer((cache.from == pl.xuid ? cache.to : cache.from));
let pl2Name = data.xuid2name((cache.from == pl.xuid ? cache.to : cache.from));
if (!Event_TPADenyExample(pl.xuid, cache, false)) {
return;
}
if (cache.from == pl.xuid) {
out.error(addLogo(Tr(pl, "tpa.deny.self.request.self.tip")));
if (pl2 != null) {
ST(pl2, addLogo(Tr(pl2, "tpa.deny.self.request.to.player.tip")));
}
} else if (!cache.isHereMode) {
out.error(addLogo(AutoReplace(Tr(pl, "tpa.deny.other.tpa.to.player.tip"), pl2Name)));
if (pl2 != null) {
ST(pl2, addLogo(AutoReplace(Tr(pl2, "tpa.deny.other.tpa.from.player.tip"), pl.realName)));
}
} else {
out.error(addLogo(AutoReplace(Tr(pl, "tpa.deny.other.tpahere.to.player.tip"), pl2Name)));
if (pl2 != null) {
ST(pl2, addLogo(AutoReplace(Tr(pl2, "tpa.deny.other.tpahere.from.player.tip"), pl.realName)));
}
}
WriteUseLog(`TPA${cache.isHereMode ? "-Here" : ""}-DE`, pl, pl2Name);
GlobalCache.TPACache.splice(index, 1);
}
Modules._RegExportApi("getTPAData", getTPAData);
Modules._RegExportApi("delTPAData", (xuid) => {
let [cache, index] = (getTPAData(xuid) || []);
if (cache == null) { return false; }
GlobalCache.TPACache.splice(index, 1);
return true;
});
/**
* @param {Player} pl
*/
function TPA_onLeft(pl) {
if (isSimulatedPlayer(pl)) { return true; }
let xuid = pl.xuid;
let name = pl.realName;
let [cache, index] = (getTPAData(xuid) || []);
if (cache != null) {
if (!Event_TPADenyExample(pl.xuid, cache, true)) {
if (cache.from == xuid) {
let pl2 = mc.getPlayer(cache.to);
ST(pl2, addLogo(AutoReplace(Tr(pl2, "tpa.left.to.player.tip"), name)));
WriteUseLog(`TPA${cache.isHereMode ? "-Here" : ""}-Left`, pl, pl2.realName);
} else {
let pl2 = mc.getPlayer(cache.from);
ST(pl2, addLogo(AutoReplace(Tr(pl, "tpa.left.from.player.tip"), name)));
WriteUseLog(`TPA${cache.isHereMode ? "-Here" : ""}-Left`, pl, pl2.realName);
}
}
GlobalCache.TPACache.splice(index, 1);
}
}
TPALoad();
})();
return true;
}
LoadWARP() {
(() => {
let Event_WARPAddExample = TMListen.RegEvent("onWARPAdd", "TMET");
let Event_WARPGoExample = TMListen.RegEvent("onWARPGo", "TMET");
let Event_WARPDelExample = TMListen.RegEvent("onWARPDel", "TMET");
function WARPLoad() {
fs.set("WARP", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "warplist.json")));
RegWARPCmd();
}
function RegWARPCmd() {
TMCmd.register("warp", Tr(null, "warp.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.setEnum("WARP_OPEnum1", ["gui", "ls"]);
nc.setEnum("WARP_OPEnum2", ["add", "go", "del"]);
nc.mandatory("WARP_OP1", ParamType.Enum, "WARP_OPEnum1", "WARP_OP1", 1);
nc.mandatory("WARP_OP2", ParamType.Enum, "WARP_OPEnum2", "WARP_OP2", 1);
nc.optional("WARPName", ParamType.String);
nc.overload([]);
nc.overload(["WARP_OP1"]);
nc.overload(["WARP_OP2", "WARPName"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
let type = (res.WARP_OP1 || res.WARP_OP2 || "gui");
let hasPerm = (pl != null ? pl.permLevel != 0 : (oriLevel == "console" || oriLevel == "cb" || oriLevel == "op" ? true : false));
if (type != "ls") {
if (pl == null && (type == "del" ? !hasPerm : true)) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if ((type == "del" ? !hasPerm : true) && (pl != null && isSimulatedPlayer(pl))) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
switch (type) {
case "gui": {
WARPMainGui(pl, out);
break;
}
case "ls": {
let warps = fs.get("WARP").getKeys();
if (warps.length == 0) {
out.success(addLogo(Tr(pl, "warp.ls.list.empty"), hasColor));
return;
}
out.success(addLogo(AutoReplace(Tr(pl, "warp.ls.msg"), warps.join("§r,")), hasColor));
WriteUseLog("WARP-List", pl, "");
break;
}
case "add": {
if (oriLevel == "other" || oriLevel == "notop") {
out.error(addLogo(Tr(pl, "command.not.allow.perm"), hasColor));
return;
}
let warpName = res.WARPName;
if (warpName == null) {
WARPAddGui(pl);
return;
}
let WarpData = fs.get("WARP");
if (WarpData.get(warpName) != null) {
out.error(addLogo(Tr(pl, "warp.add.fail.has"), hasColor));
return;
}
if (!Event_WARPAddExample(pl.xuid, warpName)) {
return;
}
let vec4 = Vector4.PosToVec4(ori.pos, `add WARP Name: "${warpName}"`).toDecimalPlaces(2);
WarpData.set(warpName, vec4.toObject());
out.success(addLogo(AutoReplace(Tr(pl, "warp.add.success"), warpName)));
WriteUseLog("WARP-Add", pl, warpName);
break;
}
case "go": {
let warpName = res.WARPName;
if (warpName == null) {
WARPGoGui(pl, out);
return;
}
let WarpInfo = fs.get("WARP").get(warpName);
if (WarpInfo == null) {
out.error(addLogo(AutoReplace(Tr(pl, "warp.go.fail.notfound"), warpName), hasColor));
return;
}
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let Consume = fs.get("TMET").get("WARP")["ConsumeMoney"],
HasMoney = Modules.getApi("getMoney")(pl.realName);
if (Consume > HasMoney) {
out.error(addLogo(Tr(pl, "warp.go.fail.money"), hasColor));
return;
}
if (!Event_WARPGoExample(pl.xuid, warpName)) {
return;
}
if (setMoney(pl.realName, (HasMoney - Consume), "set", false, "WARPConsume")) {
let vec4 = Vector4.PosToVec4(WarpInfo, `go WARP Name: "${warpName}"`);
pl.teleport(vec4.toPos());
out.success(addLogo(AutoReplace(Tr(pl, "warp.go.success"), warpName)));
WriteUseLog("WARP-Go", pl, warpName);
} else {
out.error(addLogo(Tr(pl, "warp.go.fail.error")));
}
break;
}
case "del": {
if (oriLevel == "other" || oriLevel == "notop") {
out.error(addLogo(Tr(pl, "command.not.allow.perm"), hasColor));
return;
}
let warpName = res.WARPName;
if (warpName == null) {
if (pl != null) {
WARPDelGui(pl, out);
} else {
out.error(Tr(pl, "command.not.allow.console.gui1"));
}
return;
}
let WarpData = fs.get("WARP");
let WarpInfo = WarpData.get(warpName);
if (WarpInfo == null) {
out.error(addLogo(AutoReplace(Tr(pl, "warp.del.fail.notfound"), warpName), hasColor));
return;
}
if (!Event_WARPDelExample((pl != null ? pl.xuid : ""), warpName)) {
return;
}
WarpData.delete(warpName);
out.success(addLogo(AutoReplace(Tr(pl, "warp.del.success"), warpName), hasColor));
WriteUseLog("WARP-Del", pl, warpName);
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function WARPMainGui(pl, out) {
if (pl.permLevel == 0) {
WARPGoGui(pl, out);
return;
}
let buttons = [
Tr(pl, "warp.main.gui.button.add"),
Tr(pl, "warp.main.gui.button.go"),
Tr(pl, "warp.main.gui.button.del")
];
pl.sendSimpleForm("§l§dWARPGui", Tr(pl, "warp.main.gui.content"), buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
switch (id) {
case 0: {//add
pl.runcmd(`/warp add`);
break;
}
case 1: {//go
pl.runcmd(`/warp go`);
break;
}
case 2: {//del
pl.runcmd(`/warp del`);
break;
}
}
});
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function WARPGoGui(pl, out) {
let warps = fs.get("WARP").getKeys();
if (warps.length == 0) {
out.error(addLogo(Tr(pl, "warp.go.gui.list.empty")));
return;
}
let TMETCfg = fs.get("TMET");
let MoneyName = TMETCfg.get("Money")["MoneyName"];
let Consume = TMETCfg.get("WARP")["ConsumeMoney"];
let HasMoney = Modules.getApi("getMoney")(pl.realName);
pl.sendSimpleForm("§l§dWARPGo", AutoReplace(Tr(pl, "warp.go.gui.content"),
Consume, MoneyName, HasMoney, MoneyName
), warps, new Array(warps.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let selWarpName = warps[id];
pl.runcmd(`/warp go "${selWarpName}"`);
});
}
/**
* @param {Player} pl
*/
function WARPAddGui(pl) {
let nf = mc.newCustomForm();
nf.setTitle("§l§dWARPAdd");
nf.addInput(Tr(pl, "warp.add.gui.input.title"), "(String)");
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let warpName = args[0];
pl.runcmd(`/warp add "${warpName}"`);
});
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function WARPDelGui(pl, out) {
let warps = fs.get("WARP").getKeys();
if (warps.length == 0) {
out.error(addLogo(Tr(pl, "warp.del.gui.list.empty")));
return;
}
pl.sendSimpleForm("§l§dWARPDel", Tr(pl, "warp.del.gui.content"), warps, new Array(warps.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let selWarpName = warps[id];
pl.runcmd(`/warp del "${selWarpName}"`);
});
}
Modules._RegExportApi("getWARPData", (warpName) => { return fs.get("WARP").get(warpName); });
Modules._RegExportApi("setWARPData", (warpName, obj) => {
let vec4 = Vector4.PosToVec4(obj, `API set WARP Name: "${warpName}"`).toDecimalPlaces(2);
return fs.get("WARP").set(warpName, vec4.toObject());
});
WARPLoad();
})();
return true;
}
LoadHome() {
(() => {
let Event_HomeAddExample = TMListen.RegEvent("onHomeAdd", "TMET");
let Event_HomeGoExample = TMListen.RegEvent("onHomeGo", "TMET");
let Event_HomeDelExample = TMListen.RegEvent("onHomeDel", "TMET");
function HomeLoad() {
fs.set("Home", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "homelist.json"), "{}"));
RegHomeCmd();
}
function RegHomeCmd() {
TMCmd.register("home", Tr(null, "home.cmd.description"), PermType.Any, 0x80, (nc) => {//home
nc.setEnum("Home_OPEnum1", ["add", "go", "del"]);
nc.setEnum("Home_OPEnum2", ["gui", "ls"]);
nc.mandatory("Home_OP1", ParamType.Enum, "Home_OPEnum1", "Home_OP1", 1);
nc.mandatory("Home_OP2", ParamType.Enum, "Home_OPEnum2", "Home_OP2", 1);
nc.optional("homeName", ParamType.String);
nc.overload([]);
nc.overload(["Home_OP1", "homeName"]);
nc.overload(["Home_OP2"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
let type = (res.Home_OP1 || res.Home_OP2 || "gui");
let homeName = res.homeName;
switch (type) {
case "gui": {
HomeMainGui(pl);
break;
}
case "add": {
HomeAdd(pl, out, homeName);
break;
}
case "go": {
HomeGo(pl, out, homeName);
break;
}
case "del": {
HomeDel(pl, out, homeName);
break;
}
case "ls": {
HomeLS(pl, out);
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("homeas", Tr(null, "homeas.cmd.description"), PermType.GameMasters, 0x80, (nc) => {//homeas
nc.setEnum("Homeas_OPEnum1", ["add", "go", "del"]);
nc.setEnum("Homeas_OPEnum2", ["gui", "ls"]);
nc.setEnum("Homeas_OPEnum3", ["gui"]);
nc.optional("Homeas_OP1", ParamType.Enum, "Homeas_OPEnum1", "Homeas_OP1", 1);
nc.optional("Homeas_OP2", ParamType.Enum, "Homeas_OPEnum2", "Homeas_OP2", 1);
nc.optional("Homeas_OP3", ParamType.Enum, "Homeas_OPEnum3", "Homeas_OP3", 1);
nc.optional("homeName", ParamType.String);
nc.optional("playerName", ParamType.String);
nc.optional("target", ParamType.Player);
nc.overload([]);
nc.overload(["Homeas_OP3"]);
nc.overload(["target", "Homeas_OP1", "homeName"]);
nc.overload(["target", "Homeas_OP2", "homeName"]);
nc.overload(["playerName", "Homeas_OP1", "homeName"]);
nc.overload(["playerName", "Homeas_OP2"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (oriLevel == "other" || oriLevel == "notop") {
out.error(addLogo(Tr(pl, "command.not.allow.perm"), hasColor));
return;
}
if (pl == null && ori.entity != null) {
out.error(addLogo(Tr(pl, "command.not.allow.entity"), hasColor));
return;
}
if (res.target != null && res.playerName == null) {
if (res.target.length != 1) {
out.error(addLogo(Tr(pl, "command.target.only.one.player"), hasColor));
return;
}
} else { res.target = null; }
let selPlayerName = (res.target != null ? res.target[0].realName : res.playerName);
let type = (res.Homeas_OP1 || res.Homeas_OP2 || "gui");
let homeName = (res.homeName);
if (selPlayerName == null) {
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui1"), hasColor));
return;
}
HomeAsMainGui(pl);
} else {
if ((pl == null && homeName == null && !(type == "ls" || type == "del")) || (type == "gui" && pl == null)) {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui1"), hasColor));
return;
}
if (pl == null && homeName == null && type == "del") {
out.error(addLogo(Tr(pl, "command.not.allow.console.gui1"), hasColor));
return;
}
switch (type) {
case "gui": {
HomeMainGui(pl, selPlayerName);
break;
}
case "add": {
HomeAdd(pl, out, homeName, selPlayerName);
break;
}
case "go": {
HomeGo(pl, out, homeName, selPlayerName);
break;
}
case "del": {
HomeDel(pl, out, homeName, selPlayerName);
break;
}
case "ls": {
HomeLS(pl, out, selPlayerName);
break;
}
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
/**
* @param {Player} pl
*/
function HomeAsMainGui(pl) {
let playersName = fs.get("Home").getKeys();
let sdf = new SelectFormData("§l§dHomeAs", Tr(pl, "homeas.main.gui.content"), playersName, fs.get("TMET").get("SelectForm")["Subsection"], (pl, ids) => {
if (ids == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
if (ids.length != 1) {
ST(pl, addLogo(Tr(pl, "homeas.main.gui.res.fail.only.select.one.player")));
return;
}
let playerName = playersName[ids[0]];
pl.runcmd(`/homeas "${playerName}"`);
});
sendSelectForm(pl, sdf);
}
/**
* @param {Player} pl
* @param {?string} asPlayerName
*/
function HomeMainGui(pl, asPlayerName) {
let buttons = [
Tr(pl, "home.main.gui.button.add"),
Tr(pl, "home.main.gui.button.go"),
Tr(pl, "home.main.gui.button.del")
];
let title = (asPlayerName == null ? "§l§dHomeGui" : "§l§dHomeAsGui");
let isAs = (asPlayerName != null);
let tipMsg = Tr(pl, "home.main.gui.content");
if (isAs) {
tipMsg += AutoReplace(Tr(pl, "home.as.main.gui.add.content"), asPlayerName);
}
pl.sendSimpleForm(title, tipMsg, buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
switch (id) {
case 0: {//add
pl.runcmd(AutoReplace("/{1} {2}",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" add` : "add")
));
break;
}
case 1: {//go
pl.runcmd(AutoReplace("/{1} {2}",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" go` : "go")
));
break;
}
case 2: {//del
pl.runcmd(AutoReplace("/{1} {2}",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" del` : "del")
));
break;
}
}
});
}
/**
* @param {Player} pl
* @param {CommandOutput} out
* @param {?string} homeName
* @param {?string} asPlayerName
*/
function HomeAdd(pl, out, homeName, asPlayerName) {
let isAs = (asPlayerName != null);
let HomeData = fs.get("Home");
/**
* @type {Object<string,{"x":number,"y":number,"z":number,"dimid":number}>}
*/
let homeList = HomeData.get((isAs ? asPlayerName : pl.realName), {});
let TMETCfg = fs.get("TMET");
let HomeCfg = TMETCfg.get("Home");
let MaxHomeLimit = +HomeCfg["MaxHome"];
if (Object.keys(homeList).length >= MaxHomeLimit) {
out.error(addLogo(AutoReplace(Tr(pl, "home.add.fail.max.limit"), MaxHomeLimit)));
return;
}
let needMoney = +HomeCfg["SaveRequiredMoney"];
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
if (homeName == null) {//Gui
let nf = mc.newCustomForm();
nf.setTitle((isAs ? "§l§dHomeAsAdd" : "§l§dHomeAdd"));
let tipMsg = Tr(pl, "home.add.form.input.title");
if (!isAs) {
let MoneyName = TMETCfg.get("Money")["MoneyName"];
tipMsg += AutoReplace(Tr(pl, "home.add.form.input.title1"),
needMoney, MoneyName, getMoney(pl.realName), MoneyName
);
} else {
tipMsg += AutoReplace(Tr(pl, "home.as.add.form.input.title"), asPlayerName);
}
nf.addInput(tipMsg, "(String)");
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
pl.runcmd(AutoReplace("/{1} {2} \"{3}\"",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" add` : "add"),
args[0]
));
});
} else {
if (homeList[homeName] != null) {
out.error(addLogo(Tr(pl, "home.add.fail.name.is.exists")));
return;
}
let vec4 = Vector4.PosToVec4(pl.pos, `"${pl.realName}" add ${(asPlayerName || "Self")} Home: "${homeName}"`);
vec4.y -= 1.6;
if (!Event_HomeAddExample(pl.xuid, homeName, isAs, (asPlayerName || pl.realName))) {
return;
}
if (!isAs) {
let HasMoney = getMoney(pl.realName);
if (needMoney > HasMoney) {
out.error(addLogo(Tr(pl, "home.add.fail.money")));
return;
} else {
setMoney(pl.realName, (HasMoney - needMoney), "set", false, "HomeAddConsume");
}
}
homeList[homeName] = vec4.toDecimalPlaces(2).toObject();
HomeData.set((isAs ? asPlayerName : pl.realName), homeList);
out.success(addLogo(AutoReplace(Tr(pl, "home.add.success"), homeName)));
WriteUseLog(`Home${isAs ? "As" : ""}-Add`, pl, (isAs ? `(as ${asPlayerName}) ` : "") + homeName);
}
}
/**
* @param {Player} pl
* @param {CommandOutput} out
* @param {?string} homeName
* @param {?string} asPlayerName
*/
function HomeGo(pl, out, homeName, asPlayerName) {
let isAs = (asPlayerName != null);
let TMETCfg = fs.get("TMET");
let HomeData = fs.get("Home");
/**
* @type {Object<string,{"x":number,"y":number,"z":number,"dimid":number}>}
*/
let homeList = HomeData.get((isAs ? asPlayerName : pl.realName), {});
if (Object.keys(homeList).length == 0) {
out.error(addLogo(Tr(pl, "home.go.list.empty")));
return;
}
let HomeCfg = TMETCfg.get("Home");
let needMoney = +HomeCfg["GoHomeRequiredMoney"];
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
if (homeName == null) {
let nf = mc.newSimpleForm();
nf.setTitle((isAs ? "§l§dHomeAsGo" : "§l§dHomeGo"));
let tipMsg = Tr(pl, "home.go.form.content");
if (!isAs) {
let MoneyName = TMETCfg.get("Money")["MoneyName"];
tipMsg += AutoReplace(Tr(pl, "home.go.form.content1"),
needMoney, MoneyName, getMoney(pl.realName), MoneyName
);
} else {
tipMsg += AutoReplace(Tr(pl, "home.as.go.form.content"), asPlayerName);
}
nf.setContent(tipMsg);
let homeArr = [];
homeList.forEach((_obj, name) => {
nf.addButton(name);
homeArr.push(name);
});
pl.sendForm(nf, (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let homeName = homeArr[id];
pl.runcmd(AutoReplace("/{1} {2} \"{3}\"",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" go` : "go"),
homeName
));
});
} else {
if (homeList[homeName] == null) {
out.error(addLogo(Tr(pl, "home.go.fail.notfound")));
return;
}
if (!Event_HomeGoExample(pl.xuid, homeName, isAs, (asPlayerName || pl.realName))) {
return;
}
if (!isAs) {
let HasMoney = getMoney(pl.realName);
if (needMoney > HasMoney) {
out.error(addLogo(Tr(pl, "home.go.fail.money")));
return;
} else {
setMoney(pl.realName, (HasMoney - needMoney), "set", false, "HomeGoConsume");
}
}
let homeVec4 = Vector4.PosToVec4(homeList[homeName], `"${pl.realName}" go ${(asPlayerName || "Self")} Home: "${homeName}"`);
pl.teleport(homeVec4.toPos());
out.success(addLogo(AutoReplace(Tr(pl, "home.go.success"), homeName), (pl != null)));
WriteUseLog(`Home${isAs ? "As" : ""}-Go`, pl, (isAs ? `(as ${asPlayerName}) ` : "") + homeName);
}
}
/**
* @param {?Player} pl
* @param {CommandOutput} out
* @param {?string} homeName
* @param {?string} asPlayerName
*/
function HomeDel(pl, out, homeName, asPlayerName) {
let isAs = (asPlayerName != null);
let TMETCfg = fs.get("TMET");
let HomeData = fs.get("Home");
/**
* @type {Object<string,{"x":number,"y":number,"z":number,"dimid":number}>}
*/
let homeList = HomeData.get((isAs ? asPlayerName : pl.realName), {});
if (Object.keys(homeList).length == 0) {
out.error(addLogo(Tr(pl, "home.del.list.empty")));
return;
}
let HomeCfg = TMETCfg.get("Home");
let backMoney = +HomeCfg["DelHomeBackOffMoney"];
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
if (homeName == null) {
let nf = mc.newSimpleForm();
nf.setTitle((isAs ? "§l§dHomeAsDel" : "§l§dHomeDel"));
let tipMsg = Tr(pl, "home.del.form.content");
if (!isAs) {
let MoneyName = TMETCfg.get("Money")["MoneyName"];
tipMsg += AutoReplace(Tr(pl, "home.del.form.content1"),
backMoney, MoneyName, getMoney(pl.realName), MoneyName
);
} else {
tipMsg += AutoReplace(Tr(pl, "home.as.del.form.content"), asPlayerName);
}
nf.setContent(tipMsg);
let homeArr = [];
homeList.forEach((_obj, name) => {
nf.addButton(name);
homeArr.push(name);
});
pl.sendForm(nf, (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
let homeName = homeArr[id];
pl.runcmd(AutoReplace("/{1} {2} \"{3}\"",
(isAs ? "homeas" : "home"),
(isAs ? `"${asPlayerName}" del` : "del"),
homeName
));
});
} else {
if (homeList[homeName] == null) {
out.error(addLogo(Tr(pl, "home.del.fail.notfound")));
return;
}
if (!Event_HomeDelExample((pl != null ? pl.xuid : ""), homeName, isAs, (asPlayerName || pl.realName))) {
return;
}
if (!isAs) {
let HasMoney = getMoney(pl.realName);
setMoney(pl.realName, (HasMoney + backMoney), "set", false, "HomeDelBackOff");
}
delete homeList[homeName];
HomeData.set((isAs ? asPlayerName : pl.realName), homeList);
out.success(addLogo(AutoReplace(Tr(pl, "home.del.success"), homeName), (pl != null)));
WriteUseLog(`Home${isAs ? "As" : ""}-Del`, pl, (isAs ? `(as ${asPlayerName}) ` : "") + homeName);
}
}
/**
* @param {Player} pl
* @param {CommandOutput} out
* @param {?string} asPlayerName
*/
function HomeLS(pl, out, asPlayerName) {
let isAs = (asPlayerName != null);
let HomeData = fs.get("Home");
/**
* @type {Object<string,{"x":number,"y":number,"z":number,"dimid":number}>}
*/
let homeList = HomeData.get((isAs ? asPlayerName : pl.realName), {});
let homeArr = Object.keys(homeList);
if (homeArr.length == 0) {
out.success(addLogo(Tr(pl, "home.ls.list.empty")));
return;
}
out.success(addLogo(AutoReplace(Tr(pl, "home.ls.success"), homeArr.join("§r,")), (pl != null)));
WriteUseLog(`Home${isAs ? "As" : ""}-List`, pl, (isAs ? `(as ${asPlayerName}) ` : ""));
}
Modules._RegExportApi("getHomeData", (playerName, homeName) => {
return fs.get("Home").get(playerName, {})[homeName];
});
Modules._RegExportApi("setHomeData", (playerName, homeName, obj) => {
let vec4 = Vector4.PosToVec4(obj, `API add ${playerName} Home: "${homeName}"`).toDecimalPlaces(2);
let homeData = fs.get("Home");
let playerData = homeData.get(playerName, {});
playerData[homeName] = vec4.toObject();
return homeData.set(playerName, playerData);
});
HomeLoad();
})();
return true;
}
LoadBack() {
(() => {
let Event_BackToDeathPosExample = TMListen.RegEvent("onBackToDeath", "TMET");
let Event_BackPlayerDie = TMListen.RegEvent("onBackPlayerDie", "TMET");
function BackLoad() {
GlobalCache.DeathTempInfo = {};
GlobalCache.RespawnInfo = {};
GlobalCache.InvincibleList = {};
if (fs.get("TMET").get("Back")["SaveToFile"]) {
fs.set("Back", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "deathlist.json"), "{}"));
GlobalCache.DeathTempInfo = JSON.parse(fs.get("Back").read());
}
RegBackCmd();
TMListen.listen("onPlayerDie", Back_onPlayerDie);
TMListen.listen("onMobHurt", Back_onMobHurt);
TMListen.listen("onRespawn", Back_onRespawn);
}
function RegBackCmd() {
TMCmd.register("back", AutoReplace(Tr(null, "back.cmd.description"), fs.get("TMET").get("Back")["ConsumeMoney"]), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
let lastDeathInfo = (GlobalCache.DeathTempInfo[pl.realName] || [])[0];
if (lastDeathInfo == null) {
out.error(addLogo(Tr(pl, "back.not.death.info"), hasColor));
return;
}
let time = lastDeathInfo.time;
let vec4 = Vector4.PosToVec4(lastDeathInfo, `"${pl.realName}" Back: "${time}"`);
let BackCfg = fs.get("TMET").get("Back");
let iTime = +BackCfg["InvincibleTime"];
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let Consume = BackCfg["ConsumeMoney"],
HasMoney = Modules.getApi("getMoney")(pl.realName);
if (Consume > HasMoney) {
out.error(addLogo(Tr(pl, "back.fail.money"), hasColor));
return;
}
if (!Event_BackToDeathPosExample(pl.xuid, time, vec4.toObject())) {
return;
}
if (setMoney(pl.realName, (HasMoney - Consume), "set", false, "BackConsume")) {
let name = pl.realName;
setTimeout(() => {
delete GlobalCache.InvincibleList[name];
}, (iTime * 1000));
pl.teleport(vec4.toPos());
GlobalCache.InvincibleList[pl.realName] = true;
out.success(addLogo(AutoReplace(Tr(pl, "back.success"), time)));
WriteUseLog("Back-Go", pl, time);
} else {
out.error(addLogo(Tr(pl, "back.fail.error")));
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("death", Tr(null, "death.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
if (GlobalCache.DeathTempInfo[pl.realName] == null) {
out.error(addLogo(Tr(pl, "death.not.death.info")));
return;
}
let BackCfg = fs.get("TMET").get("Back");
let MaxLimit = BackCfg["MaxSave"];
let nf = mc.newCustomForm();
nf.setTitle("§l§dDeathList");
let arr = [], lineTmp = Tr(pl, "death.form.line");
GlobalCache.DeathTempInfo[pl.realName].forEach((obj, i) => {
let vec4 = Vector4.PosToVec4(obj, `"${pl.realName}" DeathList: "${obj.time}"`);
arr.push(AutoReplace(lineTmp, (i + 1), MaxLimit, `(${vec4.x}, ${vec4.y}, ${vec4.z}, ${vec4.dim})`, obj.time));
});
nf.addLabel(arr.join("§r\n"));
pl.sendForm(nf, (_p, _a) => { });
WriteUseLog("Back-Check", pl, "");
});
nc.setup();
});
}
/**
* @param {Player} pl
* @param {?Entity} _source
*/
function Back_onPlayerDie(pl, _source) {
if (isSimulatedPlayer(pl)) { return true; }
let name = pl.realName, dimName = pl.pos.dim;
let dieVec4Obj = Vector4.PosToVec4(pl.pos, `"${pl.realName}" Die`).toDecimalPlaces(2).toObject();
if (!Event_BackPlayerDie(pl.xuid, dieVec4Obj)) {
return;
}
dieVec4Obj.time = system.getTimeStr();
if (GlobalCache.DeathTempInfo[name] == null) {
GlobalCache.DeathTempInfo[name] = [];
}
GlobalCache.DeathTempInfo[name].unshift(dieVec4Obj);
let BackCfg = fs.get("TMET").get("Back");
let MaxLimit = BackCfg["MaxSave"];
while (GlobalCache.DeathTempInfo[name].length > MaxLimit) {
GlobalCache.DeathTempInfo[name].pop();
}
if (BackCfg["SaveToFile"]) {
fs.get("Back").set(name, GlobalCache.DeathTempInfo[name]);
}
logger.debug(name, ",Death: ", GlobalCache.DeathTempInfo[name][0]);
GlobalCache.RespawnInfo[name] = AutoReplace(Tr(pl, "back.die.tip"),
dieVec4Obj.x, dieVec4Obj.y, dieVec4Obj.z, dimName, dieVec4Obj.time);
WriteUseLog("Back-Die", pl, "");
return true;
}
/**
* @param {Entity} mob
* @param {?Entity} _source
* @param {number} _damage
* @param {number} _cause
*/
function Back_onMobHurt(mob, _source, _damage, _cause) {
let pl = mob.toPlayer();
if (pl != null) {
if (GlobalCache.InvincibleList[pl.realName]) {
return false;
}
}
return true;
}
/**
* @param {Player} pl
*/
function Back_onRespawn(pl) {
let TipMsg = GlobalCache.RespawnInfo[pl.realName];
if (TipMsg != null) {
ST(pl, addLogo(TipMsg));
delete GlobalCache.RespawnInfo[pl.realName];
}
return true;
}
Modules._RegExportApi("getDeathData", (playerName) => {
return GlobalCache.DeathTempInfo[playerName];
});
Modules._RegExportApi("setDeathData", (playerName, info) => {
if (typeOfEx(info) != "Array") { return false; }
GlobalCache.DeathTempInfo[playerName] = info;
let BackCfg = fs.get("TMET").get("Back");
let MaxLimit = BackCfg["MaxSave"];
while (GlobalCache.DeathTempInfo[playerName].length > MaxLimit) {
GlobalCache.DeathTempInfo[playerName].pop();
}
if (BackCfg["SaveToFile"]) {
fs.get("Back").set(playerName, GlobalCache.DeathTempInfo[playerName]);
}
return true;
});
BackLoad();
})();
return true;
}
LoadNotice() {
(() => {
function NoticeLoad() {
fs.set("NoticeData", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "noticedata.json")));
RegNoticeCmd();
TMListen.listen("onJoin", (pl) => {
if (fs.get("TMET").get("Notice")["JoinOpenNotice"]) {
Notice_onJoin(pl);
}
});
}
function RegNoticeCmd() {
TMCmd.register("notice", Tr(null, "notice.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.setEnum("Notice_OPEnum1", ["autodisplay", "gui"]);
nc.mandatory("Notice_OP1", ParamType.Enum, "Notice_OPEnum1", "Notice_OP1", 1);
nc.overload([]);
nc.overload(["Notice_OP1"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
let type = (res.Notice_OP1 || "gui")
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
switch (type) {
case "gui": {
sendNotice(pl);
break;
}
case "autodisplay": {
let NoticeData = fs.get("NoticeData");
let lastData = Boolean(NoticeData.get(pl.xuid, false));
NoticeData.set(pl.xuid, !lastData);
if (!lastData) {
out.success(addLogo(Tr(pl, "notice.auto.display.false")));
} else {
out.success(addLogo(Tr(pl, "notice.auto.display.true")));
}
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
TMCmd.register("notice_op", Tr(null, "notice_op.cmd.description"), PermType.GameMasters, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
openNoticeModifyGui(pl);
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
/**
* @param {Player} pl
*/
function openNoticeModifyGui(pl) {
let TMETCfg = fs.get("TMET");
let NoticeCfg = TMETCfg.get("Notice");
let sendIsContinue = (pl, content) => {
let buttons = [
Tr(pl, "notice_op.is.continue.form.button.continue"),
Tr(pl, "notice_op.is.continue.form.button.cancel")
];
pl.sendSimpleForm("§l§dNoticeSetting", AutoReplace(Tr(pl, "notice_op.is.continue.form.content"), content), buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
if (id == 0) {
sendMainModify(pl);
} else {
TMETCfg.set("Notice", NoticeCfg);
fs.get("NoticeData").write("{}");
ST(pl, addLogo(Tr(pl, "notice_op.is.continue.form.res.cancel.tip")));
}
});
};
let modifyTitle = (pl) => {
let nf = mc.newCustomForm();
nf.setTitle("§l§dSetTitle");
nf.addInput(Tr(pl, "notice_op.modify.title.form.input.title"), "(String)", NoticeCfg["NoticeTitle"]);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
NoticeCfg["NoticeTitle"] = args[0];
sendIsContinue(pl, Tr(pl, "notice_op.modify.title.success"));
WriteUseLog("Notice-SetTitle", pl, args[0]);
});
};
let delLine = (pl) => {
let lines = String(NoticeCfg["NoticeText"]).split("#&#");
let nf = mc.newCustomForm();
nf.setTitle("§l§dDelContent");
nf.addLabel(Tr(pl, "notice_op.del.line.form.label"));
lines.forEach((str) => {
nf.addSwitch(str);
});
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
args.shift();
args.forEach((bool, i) => {
if (bool) {
SafeDeleteArray(lines, i);
TickTask.addTask(() => {
sendIsContinue(pl);
});
WriteUseLog("Notice-DelLine", pl2, lines[i]);
}
});
});
};
let modifyContent = (pl) => {
let lines = String(NoticeCfg["NoticeText"]).split("#&#");
let nf = mc.newCustomForm();
nf.setTitle("§l§dSetContent");
nf.addLabel(Tr(pl, "notice_op.modify.content.form.label"));
nf.addSwitch(Tr(pl, "notice_op.modify.content.form.add.line.switch.title"), false);
nf.addSwitch(Tr(pl, "notice_op.modify.content.form.del.line.switch.title"), false);
lines.forEach((str, i) => {
nf.addInput(`Line: ${(i + 1)}`, "(String)", str);
});
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
args.shift();
if (args.shift()) {
NoticeCfg["NoticeText"] += "#&#";
modifyContent(pl);
return;
}
if (args.shift()) {
delLine(pl);
return;
}
let NewText = args.join("#&#");
WriteUseLog("Notice-SetContent", pl, NewText);
NoticeCfg["NoticeText"] = NewText;
sendIsContinue(pl, Tr(pl, "notice_op.modify.content.success"));
});
};
let sendMainModify = (pl) => {
let buttons = [
Tr(pl, "notice_op.main.gui.button.set.title"),
Tr(pl, "notice_op.main.gui.button.set.content")
];
pl.sendSimpleForm("§l§dNoticeSetting", Tr(pl, "notice_op.main.gui.content"), buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
if (id == 0) {
modifyTitle(pl);
} else {
modifyContent(pl);
}
});
}
sendMainModify(pl);
}
/**
* @param {Player} pl
*/
function sendNotice(pl) {
let NoticeData = fs.get("NoticeData");
let nf = mc.newCustomForm();
let NoticeCfg = fs.get("TMET").get("Notice");
nf.setTitle(String(NoticeCfg["NoticeTitle"]));
nf.addLabel(String(NoticeCfg["NoticeText"]).replace(/#&#/g, "§r\n"));
let lastData = Boolean(NoticeData.get(pl.xuid, false));
nf.addSwitch(Tr(pl, "notice.form.auto.display.switch.title"), lastData);
pl.sendForm(nf, (pl, args) => {
if (args == null) { return; }
if (args[1] != lastData) {
pl.runcmd("/notice autodisplay");
}
});
WriteUseLog("Notice-Look", pl, "");
}
function Notice_onJoin(pl) {
if (!fs.get("NoticeData").get(pl.xuid, false)) {
sendNotice(pl);
}
return true;
}
Modules._RegExportApi("getNoticeData", () => {
let NoticeCfg = fs.get("TMET").get("Notice");
return {
"Title": NoticeCfg["NoticeTitle"],
"Content": NoticeCfg["NoticeText"]
};
});
Modules._RegExportApi("setNoticeData", (obj) => {
if (typeOfEx(obj) != "Object") { return false; }
let TMETCfg = fs.get("TMET");
let NoticeCfg = TMETCfg.get("Notice");
obj.forEach((val, key) => {
if (key == "Title" || key == "Content") {
if (typeOfEx(val) != "String") { return; }
NoticeCfg[key] = val;
}
});
fs.get("NoticeData").write("{}");
return TMETCfg.set("Notice", NoticeCfg);
});
NoticeLoad();
})();
return true;
}
LoadShop() {
(() => {
let Event_BeforeShopBuyExample = TMListen.RegEvent("onBeforeShopBuy", "TMET");
let Event_BeforeShopSellExample = TMListen.RegEvent("onBeforeShopSell", "TMET");
let Event_ShopBuyExample = TMListen.RegEvent("onAfterShopBuy", "TMET");
let Event_ShopSellExample = TMListen.RegEvent("onAfterShopSell", "TMET");
function ShopLoad() {
fs.set("Shop", new JsonConfigFileClass(AutoReplace(TMET_DataDir, "shopdata.json"), JSON.stringify(_Configs.SHOP, null, 2)));
RegShopCmd();
}
function RegShopCmd() {
TMCmd.register("shop", Tr(null, "shop.cmd.description"), PermType.Any, 0x80, (nc) => {
nc.setEnum("Shop_OPEnum1", ["gui", "buy", "sell"]);
nc.mandatory("Shop_OP1", ParamType.Enum, "Shop_OPEnum1", "Shop_OP1", 1);
nc.overload([]);
nc.overload(["Shop_OP1"]);
nc.setCallback((_cmd, ori, out, res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else {
if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
}
let type = (res.Shop_OP1 || "gui");
switch (type) {
case "gui": {
ShopMainGui(pl);
break;
}
case "buy": {
ShopBuyGui(pl, new ShopDir(fs.get("Shop").get("Buy", []), "Buy"));
break;
}
case "sell": {
ShopSellGui(pl, new ShopDir(fs.get("Shop").get("Sell", []), "Sell"));
break;
}
}
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
/**
* @param {Player} pl
*/
function ShopMainGui(pl) {
let buttons = [
Tr(pl, "shop.main.gui.button.buy"),
Tr(pl, "shop.main.gui.button.sell")
];
pl.sendSimpleForm("§l§dShopGui", Tr(pl, "shop.main.gui.content"), buttons, new Array(buttons.length).fill(""), (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
}
if (id == 0) {
pl.runcmd(`/shop buy`);
} else {
pl.runcmd(`/shop sell`);
}
});
}
function isRightStore(shop, name) {
let isObject = (anyInfo) => (typeOfEx(anyInfo) == "Object");
let isArray = (anyInfo) => (typeOfEx(anyInfo) == "Array");
let i = 0, type = null,
l = shop.length;
while (i < l) {
let button = shop[i];
if (!isObject(button)) {
type = 0;
break;
} else if (typeof (button.name) != "string") {
type = 1;
break;
} else if (button.type != "exam" && button.type != "group") {
type = 2;
break;
} else if (typeof (button.data) != "object") {
type = 3;
break;
}
if (typeof (button.type) == "string" && button.type == "exam") {
if (!isObject(button.data)) {
type = 4;
break;
} else {
if (typeof (button.data.type) != "string") {
type = 6;
break;
} else if (typeof (button.data.aux) != "number") {
type = 7;
break;
} else if (typeof (button.data.money) != "number") {
type = 8;
break;
}
}
} else if (typeof (button.type) == "string" && button.type == "group") {
if (!isArray(button.data)) {
type = 5;
break;
}
}
i++;
}
if (type != null) {
logger.error("Shop error in ", name);
logger.error(`In the ${i} of the array`);
switch (type) {
case 0:
logger.error("The whole is not an object");
break;
case 1:
logger.error("name is not a string");
break;
case 2:
logger.error("type is not a group or exam");
break;
case 3:
logger.error("data is not an object or array");
break;
case 4:
logger.error("exam => data is not an object");
break;
case 5:
logger.error("group => data is not an array");
break;
case 6:
logger.error("exam => data => type is not a string");
break;
case 7:
logger.error("exam => data => aux is not a number");
break;
case 8:
logger.error("exam => data => money is not a number");
break;
default:
logger.error("Unknown");
break;
}
return false;
} else {
return true;
}
}
class ShopDir {
/**
* @type {{
* "name":string,
* "type":"exam"|"group",
* "image":string|undefined,
* "data":(this[]|{
* "type":string,
* "aux":string,
* "remark":string,
* "money":number
* })
* }[]}
*/
#info = [];
/**
* @type {string[]}
*/
#indexStr = [];
#inExam = false;
#lastID = -1;
/**
* @param {{
* "name":string,
* "type":"exam"|"group",
* "image":string|undefined,
* "data":(this[]|{
* "type":string,
* "aux":string,
* "remark":string
* })
* }[]} commInfo
* @param {string} firstIndexStr
*/
constructor(commInfo, firstIndexStr) {
this.#info.push(commInfo);
}
/**
* @param {number} index
*/
next(index) {
if (this.#inExam) { return false; }
let now = this.nowData;
if (now.type == "group") {
/**
* @type {undefined|{
* "name":string,
* "type":"exam"|"group",
* "image":string|undefined,
* "data":(this[]|{
* "type":string,
* "aux":string,
* "remark":string
* })
* }}
*/
let res = now.data[index];
if (!res) { return false; }
this.#info.push(res);
now.type == "group" && this.#indexStr.push(res.name);
this.#inExam = res.type == "exam";
this.#lastID = index;
return true;
}
return false;
}
last() {
if (this.isFirst) { return false; }
this.#info.pop();
!this.#inExam && this.#indexStr.pop();
this.#inExam = false;
return true;
}
get lastData() {
if (this.#info.length < 2) { return undefined; }
return this.#info[(this.#info.length - 2)];
}
get nowData() {
if (this.isFirst) {
return {
"name": this.#indexStr[(this.#indexStr.length - 1)],
/** @type {"group"|"exam"} */
"type": "group",
"image": "",
/**
* @type {any[] | {
* type: string,
* aux: string,
* remark: string,
* money: number
* }}
*/
"data": this.#info[(this.#info.length - 1)]
};
}
return this.#info[(this.#info.length - 1)];
}
get isFirst() {
return this.#info.length == 1;
}
get indexStr() {
return this.#indexStr.join("=>");
}
get inExam() { return this.#inExam; }
get _lastId() { return this.#lastID; }
}
/**
* @param {Player} pl
* @param {ShopDir} shopDir
*/
function ShopBuyGui(pl, shopDir) {
try {
let now = shopDir.nowData;
if (!shopDir.inExam) {
/** @type {{"name":string,"type":"group"|"exam","image":string,"data":any[]}[]} */
let nowInfo = now.data;
if (!isRightStore(nowInfo, shopDir.indexStr)) {
ST(pl, addLogo(Tr(pl, "shop.config.error")));
return;
}
let nf = mc.newSimpleForm();
nf.setTitle("§l§dShopBuy");
nf.setContent(Tr(pl, "shop.buy.form.content"));
let LangTmp = Tr(pl, "shop.buy.form.buttons"),
ExamD = Tr(pl, "shop.display.exam"),
GroupD = Tr(pl, "shop.display.group"),
BackPageD = Tr(pl, "shop.form.back.last.page");
!shopDir.isFirst && nf.addButton(BackPageD, "");
nowInfo.forEach((v) => {
nf.addButton(AutoReplace(LangTmp, String(v.name), (v.type == "exam" ? ExamD : GroupD)), (v.image || ""));
});
pl.sendForm(nf, (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
} else if (!shopDir.isFirst) {
if (id == 0) {
if (!shopDir.last()) { return; }
ShopBuyGui(pl, shopDir);
return;
}
id -= 1;
}
shopDir.next(id) && ShopBuyGui(pl, shopDir);
});
return;
}
/**
* @type {{
* "type": string,
* "aux": string,
* "remark": string,
* "money":number
* }}
*/
let shopData = now.data;
/** @type {(realName:string)=>number} */
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let nf = mc.newCustomForm();
nf.setTitle("§l§dShopBuying");
nf.addLabel(AutoReplace(Tr(pl, "shop.buy.form2.content"),
shopData.type,
shopData.aux,
shopData.money,
getMoney(pl.realName),
shopData.remark
));
nf.addInput(Tr(pl, "shop.buy.form2.input.title"), "(+Number)");
nf.addSwitch(Tr(pl, "shop.form.back.last.page"), false);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
} else if (args[2]) {
shopDir.last() && ShopBuyGui(pl, shopDir);
return;
}
let num = args[1];
if (!(/(^[1-9]\d*$)/).test(num)) {
ST(pl, addLogo(Tr(pl, "shop.buy.form2.res.input.error")));
return;
} else { num = +num; }
let needMoney = (shopData.money * num);
let hasMoney = getMoney(pl.realName);
if (hasMoney < needMoney) {
ST(pl, addLogo(Tr(pl, "shop.buy.fail.money")));
return;
}
let indexStr = shopDir.indexStr + `[${shopDir._lastId}]=>${now.name}`;
logger.debug("IndexStr:", indexStr);
if (!Event_BeforeShopBuyExample(pl.xuid, indexStr, shopData, num)) {
return;
}
let cmdRes = mc.runcmdEx(`give "${pl.realName}" ${shopData.type} ${num} ${shopData.aux}`);
if (cmdRes.success) {
if (!Event_ShopBuyExample(pl.xuid, indexStr, shopData, num)) {
return;
}
setMoney(pl.realName, (hasMoney - needMoney), "set", false, "ShopBuy");
ST(pl, addLogo(Tr(pl, "shop.buy.success")));
WriteUseLog("Shop-Buy", pl, `${indexStr}*${num}`);
} else {
ST(pl, addLogo(AutoReplace(Tr(pl, "shop.buy.fail.rea"), (cmdRes.output || "None"))));
}
});
} catch (e) {
ErrorMsg(e);
ST(pl, addLogo(Tr(pl, "shop.buy.error")));
}
}
/**
* @param {Player} pl
* @param {string} type
* @param {number} aux
*/
function GetItemCount(pl, type, aux) {
let hasNum = 0;
let AllItems = pl.getInventory().getAllItems();
AllItems.forEach((it) => {
if (it.type == type && it.aux == aux) {
hasNum += it.count;
}
});
return hasNum;
}
/**
* @param {Player} pl
* @param {string} type
* @param {number} aux
* @param {number} num
* @returns {({"success":boolean,"output":string})}
*/
function TryClearItem(pl, type, aux, num) {
let hasNum = GetItemCount(pl, type, aux);
if (hasNum < num) {
return { "success": false, "output": Tr(pl, "shop.sell.fail.count.not.enough") };
} else {
return mc.runcmdEx(`clear "${pl.realName}" ${type} ${aux} ${num}`);
}
}
/**
* @param {Player} pl
* @param {ShopDir} shopDir
*/
function ShopSellGui(pl, shopDir) {
try {
let now = shopDir.nowData;
if (!shopDir.inExam) {
/** @type {{"name":string,"type":"group"|"exam","image":string,"data":any[]}[]} */
let nowInfo = now.data;
if (!isRightStore(nowInfo, shopDir.indexStr)) {
ST(pl, addLogo(Tr(pl, "shop.config.error")));
return;
}
let nf = mc.newSimpleForm();
nf.setTitle("§l§dShopSell");
nf.setContent(Tr(pl, "shop.sell.form.content"));
let LangTmp = Tr(pl, "shop.sell.form.buttons"),
ExamD = Tr(pl, "shop.display.exam"),
GroupD = Tr(pl, "shop.display.group"),
BackPageD = Tr(pl, "shop.form.back.last.page");
!shopDir.isFirst && nf.addButton(BackPageD, "");
nowInfo.forEach((v) => {
nf.addButton(AutoReplace(LangTmp, String(v.name), (v.type == "exam" ? ExamD : GroupD)), (v.image || ""));
});
pl.sendForm(nf, (pl, id) => {
if (id == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
} else if (!shopDir.isFirst) {
if (id == 0) {
shopDir.last() && ShopSellGui(pl, shopDir);
return;
}
id -= 1;
}
shopDir.next(id) && ShopSellGui(pl, shopDir);
});
return;
}
/**
* @type {{
* "type": string,
* "aux": string,
* "remark": string,
* "money":number
* }}
*/
let shopData = now.data;
/** @type {(realName:string)=>number} */
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let nf = mc.newCustomForm();
nf.setTitle("§l§dShopSelling");
nf.addLabel(AutoReplace(Tr(pl, "shop.sell.form2.content"),
shopData.type,
shopData.aux,
shopData.money,
getMoney(pl.realName),
shopData.remark,
GetItemCount(pl, shopData.type, shopData.aux)
));
nf.addInput(Tr(pl, "shop.sell.form2.input.title"), "(+Number)");
nf.addSwitch(Tr(pl, "shop.form.back.last.page"), false);
pl.sendForm(nf, (pl, args) => {
if (args == null) {
ST(pl, addLogo(Tr(pl, "form.give.up")));
return;
} else if (args[2]) {
shopDir.last() && ShopSellGui(pl, shopDir);
return;
}
let num = args[1];
if (!(/(^[1-9]\d*$)/).test(num)) {
ST(pl, addLogo(Tr(pl, "shop.sell.form2.res.input.error")));
return;
} else { num = +num; }
let giveMoney = (shopData.money * num);
let hasMoney = getMoney(pl.realName);
let indexStr = shopDir.indexStr + `[${shopDir._lastId}]=>${now.name}`;
logger.debug("IndexStr:", indexStr);
if (!Event_BeforeShopSellExample(pl.xuid, `${indexStr}`, shopData, num)) {
return;
}
let cmdRes = TryClearItem(pl, shopData.type, shopData.aux, num);
if (cmdRes.success) {
if (!Event_ShopSellExample(pl.xuid, indexStr, shopData, num)) {
return;
}
setMoney(pl.realName, (hasMoney + giveMoney), "set", false, "ShopSell");
ST(pl, addLogo(Tr(pl, "shop.sell.success")));
WriteUseLog("Shop-Sell", pl, `${indexStr}*${num}`);
} else {
ST(pl, addLogo(AutoReplace(Tr(pl, "shop.sell.fail.rea"), (cmdRes.output || "None"))));
}
});
} catch (e) {
ErrorMsg(e);
ST(pl, addLogo(Tr(pl, "shop.buy.error")));
}
}
Modules._RegExportApi("getShopData", () => {
return fs.get("Shop")._getCache();
});
Modules._RegExportApi("setShopData", (obj) => {
if (typeOfEx(obj) != "Object") { return false; }
let newData = { "Buy": [], "Sell": [] };
let buy = obj.Buy;
let sell = obj.Sell;
if (typeOfEx(buy) != "Array" || typeOfEx(sell) != "Array") { return false; }
/**
* @param {(ShopGroupInfo[]|ShopExamInfo[])} obj
* @param {(ShopGroupInfo[]|ShopExamInfo[])} opObj
* @param {string} indexStr
*/
function ForEachShopData(obj, opObj, indexStr) {
if (!isRightStore(obj, indexStr)) { return false; }
let l = obj.length, i = 0;
while (i < l) {
let _this = obj[i];
let _data = (_this.type == "exam" ?
{
"type": _this.data.type,
"aux": _this.data.aux,
"remark": _this.data.remark,
"money": _this.data.money
}
: (() => {
let arr = [];
ForEachShopData(_this.data, arr, `${indexStr}=>${_this.name}`);
return arr;
})()
);
let ob = {
"name": _this.name,
"type": _this.type,
"image": _this.image,
"data": _data
}
opObj.push(ob);
i++;
}
return true;
}
if (!ForEachShopData(buy, newData.Buy, "API-Set: Buy") || !ForEachShopData(sell, newData.Sell, "API-Set: Sell")) {
return false;
}
return fs.get("Shop").write(JSON.stringify(newData, null, 2));
});
ShopLoad();
})();
return true;
}
LoadDynamicMotd() {
(() => {
let Event_MotdChange = TMListen.RegEvent("onMotdChange", "TMET");
function DynamicMotdLoad() {
GlobalCache["DynamicMotdIndex"] = -1;
setInterval(ChangeMotd, (fs.get("TMET").get("DynamicMotd")["Time"] * 1000));
}
function ChangeMotd() {
let motdList = fs.get("TMET").get("DynamicMotd")["MotdList"];
if ((motdList.length - 1) <= GlobalCache.DynamicMotdIndex) {
GlobalCache.DynamicMotdIndex = -1;
}
let nowMotd = motdList[++GlobalCache.DynamicMotdIndex];
if (!Event_MotdChange(nowMotd)) {
return;
}
mc.setMotd(nowMotd);
WriteUseLog("DynamicMotd-Set", null, nowMotd);
}
DynamicMotdLoad();
})();
return true;
}
LoadTPR() {
(() => {
let Event_TPRTryExample = TMListen.RegEvent("onTPRTry", "TMET");
let Event_TPRFailExample = TMListen.RegEvent("onTPRFail", "TMET");
let Event_TPRSuccessExample = TMListen.RegEvent("onTPRSuccess", "TMET");
function TPRLoad() {
RegTPRCmd();
}
function RegTPRCmd() {
TMCmd.register("tpr", AutoReplace(Tr(null, "tpr.cmd.description"), fs.get("TMET").get("TPR")["ConsumeMoney"]), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
ProcessTPR(pl, out);
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译
}
});
nc.setup();
});
}
function getRandomValue(min, max) {
let rMax = (max - min);
let random = Math.floor((Math.random() * rMax) + 1);
return (random + min);
}
/**
* 在Y轴寻找空气方块
* 如果寻找到了就直接修改对象
* @param {Vector4} vec4
*/
function FindAirBlock(vec4) {
let pos = vec4.toPos();
let bl = mc.getBlock(pos);
while (bl != null && bl.type != "minecraft:air") {
if (bl.pos.y <= -1) {//超出限制
vec4.y = -65;
return;
}
pos.y -= 1;
bl = mc.getBlock(pos);
}
if (bl == null) {
vec4.y = -65;
}
vec4.y = pos.y;
}
/**
* @param {Player} pl
* @param {CommandOutput} out
*/
function ProcessTPR(pl, out) {
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let { MaxXZCoordinate, MinXZCoordinate, ConsumeMoney } = fs.get("TMET").get("TPR");
if (getMoney(pl.realName) < ConsumeMoney) {
out.error(addLogo(Tr(pl, "tpr.fail.money")));
return;
}
let realName = pl.realName, state = 0;//0~1: LoadChunk~LoadChunk(end), 2~3: FindPos~FindPos(end)
let beforeTPRVec4 = Vector4.PosToVec4(pl.pos, `"${pl.realName}" TPR_GetBeforeVec4`);
let randomVec4 = new Vector4(
getRandomValue(+MinXZCoordinate, +MaxXZCoordinate) - 0.5,
(beforeTPRVec4.dimid == 0 ? 319 : (beforeTPRVec4.dimid == 1 ? 666 : (beforeTPRVec4.dimid == 2 ? 200 : 0))),
getRandomValue(+MinXZCoordinate, +MaxXZCoordinate) - 0.5,
beforeTPRVec4.dimid,
`"${pl.realName}" TPR_Random`
);
if (!Event_TPRTryExample(pl.xuid, randomVec4.x, randomVec4.z)) {
return;
}
setMoney(pl.realName, (getMoney(pl.realName) - ConsumeMoney), "set", false, "TPRConsume");
WriteUseLog("TPR-Try", pl, `x:${randomVec4.x}-z:${randomVec4.z}`);
pl.teleport(randomVec4.toPos());
let lastVec4 = Vector4.PosToVec4(pl.pos, `"${pl.realName}" TPR_GetTPRLastVec4`);
let FakePl = { "realName": pl.realName, "pos": { "x": pl.pos.x, "y": pl.pos.y, "z": pl.pos.z, "dimid": pl.pos.dimid, "dim": pl.pos.dim } };
let xuid = pl.xuid;
let Task = () => {
let pl = mc.getPlayer(realName);
if (pl == null) {
Event_TPRFailExample(xuid, "LeftGame");
WriteUseLog("TPR-Fail", FakePl, "LeftGame");
return;
}
if (state == 0) {
ST(pl, addLogo(Tr(pl, "tpr.load.chunk.tip")));
state++;
} else if (state == 2 || state == 3) {
if (state == 2) {
ST(pl, addLogo(Tr(pl, "tpr.found.safe.pos.tip")));
state++;
}
let bl = mc.getBlock(randomVec4.toPos());
if (randomVec4.dimid == 1) {//寻找地狱基岩下面的空气方块
randomVec4.y = 127;
FindAirBlock(randomVec4);
bl = mc.getBlock(randomVec4.toPos());
}
if (bl == null) {//修复坐标问题
if (randomVec4.dimid == 0) {//修复低版本坐标问题
randomVec4.y = 255;
}//可拓展
}
while (1) {
if (bl == null || bl.pos.y <= -65 || ["minecraft:lava", "minecraft:flowing_lava"].indexOf(bl.type) != -1) {
setMoney(pl.realName, (getMoney(pl.realName) + ConsumeMoney), "set", false, "TPRFailBackOff");
ST(pl, addLogo(Tr(pl, "tpr.fail.notfound.safe.pos")));
Event_TPRFailExample(xuid, "NotFindSafePos");
pl.teleport(beforeTPRVec4.toPos());
WriteUseLog("TPR-Fail", pl, "NotFindSafePos");
return;
}
if (bl.type != "minecraft:air") {
break;
}
randomVec4.y--;
bl = mc.getBlock(randomVec4.toPos());
}
randomVec4.y++;
Event_TPRSuccessExample(xuid);
pl.teleport(randomVec4.toPos());
ST(pl, addLogo(AutoReplace(Tr(pl, "tpr.success"), randomVec4.x, randomVec4.y, randomVec4.z, randomVec4.dimid)));
WriteUseLog("TPR-Success", pl, "");
return;
} else {
if (!lastVec4.isSame(Vector4.PosToVec4(pl.pos, `"${pl.realName}" TPR_GetNowVec4`))) {
state++;
}
}
TickTask.addTask(Task);
};
TickTask.addTask(Task);
}
TPRLoad();
})();
return true;
}
LoadRefreshChunk() {
(() => {
let Event_RefreshChunkExample = TMListen.RegEvent("onRefreshChunk");
function RefreshChunkLoad() {
RegRefreshChunkCmd();
}
function RegRefreshChunkCmd() {
TMCmd.register("rc", AutoReplace(Tr(null, "refresh.chunk.cmd.description"), fs.get("TMET").get("RefreshChunk")["ConsumeMoney"]), PermType.Any, 0x80, (nc) => {
nc.overload([]);
nc.setCallback((_cmd, ori, out, _res) => {
try {
let pl = ori.player;
let oriLevel = getOriginLevel(ori);
let hasColor = (oriLevel == "console" ? false : true);
if (pl == null) {
out.error(addLogo(Tr(pl, "command.not.allow.not.player"), hasColor));
return;
} else if (isSimulatedPlayer(pl)) {
out.error(addLogo(Tr(pl, "command.not.allow.simulation.player"), hasColor));
return;
}
ProcessReloadChunk(pl, out);
} catch (e) {
ErrorMsg(e);
out.error(addLogo("错误: Command running error, please contact administrator!", false));//不需要翻译}
}
});
nc.setup();
});
}
/**
*
* @param {Player} pl
* @param {CommandOutput} out
*/
function ProcessReloadChunk(pl, out) {
let getMoney = Modules.getApi("getMoney");
/**
* @type {(realName:string,val:number,type:?("join"|"init"|"set"),isTarn:?boolean,note:?string)=>(boolean|null)}
*/
let setMoney = Modules.getApi("setMoney");
let hasMoney = getMoney(pl.realName);
let needMoney = fs.get("TMET").get("RefreshChunk")["ConsumeMoney"];
if (needMoney > hasMoney) {
out.error(addLogo(Tr(pl, "refresh.chunk.fail.money")));
return;
}
if (!Event_RefreshChunkExample(pl.xuid)) {
return;
}
setMoney(pl.realName, (hasMoney - needMoney), "set", false, "RefreshChunkConsume");
pl.refreshChunks();
out.success(addLogo(Tr(pl, "refresh.chunk.success")));
WriteUseLog("RefreshChuck", pl, "");
}
RefreshChunkLoad();
})();
return true;
}
LoadFarmLandProtect() {
(() => {
function FarmLandProtectLoad() {
TMListen.listen("onFarmLandDecay", FarmLandProtect_onFarmLandDecay);
}
/**
* @param {Pos} pos
* @param {?Entity} en
*/
function FarmLandProtect_onFarmLandDecay(_pos, en) {//(0全部拦截,1只拦截null对象造成耕地破坏,2只拦截非玩家破坏,3只拦截玩家破坏
let CfgType = +fs.get("TMET").get("FarmLandProtect")["Type"];
let res = true;
switch (CfgType) {
case 0: {
res = false;
break;
}
case 1: {
if (en == null) {
res = false;
break;
}
}
case 2: {
if (en != null && !en.isPlayer()) {
res = false;
break;
}
}
case 3: {
if (en != null && en.isPlayer()) {
res = false;
break;
}
}
}
let FakePl = {
"realName": (en != null ? en.name : "Null"),
"pos": (en != null ? en.pos : _pos)
};
WriteUseLog("FarmLandProtect", (FakePl), res);
return res;
}
FarmLandProtectLoad();
})();
return true;
}
}();
function AutoUpdate() {
if (_Version.isBeta()) {
logger.warn(`Beta Version Can't Be Use AutoUpdate!`);
return;
}
let isWorking = false;
let lastVer = _Version.getVersionNumber();
let VerWebSite = "https://gitee.com/timidine/mcbe-lite-loader-script-engine-tmessential/raw/main/Version.json";
setInterval(() => {
if (isWorking) { return; }
network.httpGet(VerWebSite, (code, res) => {
if (code != 200) { return; }
let Obj = null;
try { Obj = JSON.parse(res); } catch (_) { }
if (Obj == null || Obj["VersionNumber"] == lastVer) { return; }
if (!Obj["Website"]) { return; }
logger.info(AutoReplace(Tr(null, "auto.update.has.new.version"), Obj["VersionNumber"].toString().split("").join(".")));
isWorking = true;
network.httpGet(Obj["Website"], (code, res) => {
if (code != 200) {
logger.warn(AutoReplace(Tr(null, "auto.update.download.fail.code"), code));
isWorking = false;
return;
} else if (!res) {
logger.warn(AutoReplace(Tr(null, "auto.update.download.fail.rea")));
isWorking = false;
return;
}
let FileSize = +(res.length / 1024).toFixed(2);
if (FileSize < 30) {
logger.warn(AutoReplace(Tr(null, "auto.update.download.fail.size")));
isWorking = false;
return;
}
File.writeTo(TMET_RunPath, res);
logger.info(AutoReplace(Tr(null, "auto.update.download.success"), FileSize));
if (!Obj["CanReload"] || lastVer != Obj["LastVersion"]) {
logger.info(Tr(null, "auto.update.download.success.website.restart.tip"));
return;
}
lastVer = Obj["VersionNumber"];
if (fs.get("TMET").get("AutoUpdate")["AutoReload"]) {
logger.info(Tr(null, "auto.update.download.success.auto.reload.tip"));
setTimeout(() => {
GlobalCache.FileCache._SaveToFile();
mc.runcmdEx("ll reload TMEssential.js");
}, 1);
} else {
logger.info(Tr(null, "auto.update.download.success.tip"));
}
isWorking = false;
});
});
}, 1000 * 60 * 10);
}
/**
* 写使用日志
* @param {string} type 事件
* @param {(Player|null)} pl 玩家或者null
* @param {string} msg 信息
*/
function WriteUseLog(type, pl, msg) {
let plName = (pl != null ? pl.realName : null),
posTmp = (plName == null ? null : Vector4.PosToVec4(pl.pos, `"${plName}" UseLog_GetPos`).toDecimalPlaces(2));
TickTask.addTask(() => {
let ULConf = fs.get("TMET").get("UseLog");
if (ULConf["Enable"]) {
let Keys = Object.keys(ULConf["Conf"]),
ty = type.split("-")[0],
iOF = Keys.indexOf(ty);
if (type == "Plugin" || ULConf.Conf[Keys[iOF]]) {
File.mkdir("./logs/TMEssential");
let DTStr = system.getTimeStr(),
DateStr = DTStr.split(" ")[0],
FilePath = AutoReplace(TMET_LogDir, `UseLog-${DateStr}.csv`),
XYZ = (posTmp != null ? `[${posTmp.x}|${posTmp.y}|${posTmp.z}]` : null),
Data = `${DTStr},${(plName != null ? posTmp.dim : "")},${(plName != null ? plName : "Console")},${(XYZ != null ? XYZ : "")},${type},${msg}`;
if (!File.exists(FilePath)) {
File.writeLine(FilePath, Tr(null, "write.use.log.title"));
}
File.writeLine(FilePath, Data);
}
}
});
}
// function MoneyApiExport(type, a, b, c, d) {
// let ThisRes = (() => {
// switch (type) {
// case "getmoney": {
// WriteUseLog("API-Old-GetMoney", null, a);
// return Modules.getApi("getMoney")(a);
// }
// case "setmoney": {
// WriteUseLog("API-Old-SetMoney", null, `${a}->${b}`);
// return Modules.getApi("setMoney")(a, b, "set", false, "System::Set");
// }
// case "tranmoney": {
// WriteUseLog("API-Old-TranMoney", null, `${a}->${b}(${c})[${d}]`);
// return Modules.getApi("tranMoney")(a, b, c, d);
// }
// case "moneytype": {
// WriteUseLog("API-Old-GetMoneyType", null, "");
// return fs.get("TMET").get("Money")["MoneyType"];
// }
// case "version": {
// WriteUseLog("API-Old-GetVersion", null, "");
// return _Version.getVersionNumber();
// }
// case "moneyname": {
// WriteUseLog("API-Old-GetMoneyName", null, "");
// return fs.get("TMET").get("Money")["MoneyName"];
// }
// case "getpaytax": {
// WriteUseLog("API-Old-GetPayTax", null, "");
// return Modules.getApi("getPayTax")();
// }
// }
// return null;
// })();
// return ThisRes;
// }
function ExportAPI() {
//#region OldApiExport
// if (fs.get("TMET").get("ExportOldAPI")) {
// let ExportFunc = (type, a, b, c, d) => {
// try {
// let moneyRes = MoneyApiExport(type, a, b, c, d);
// if (moneyRes != null) {
// return moneyRes;
// }
// switch (a) {
// case "LANGUAGE": a = "LangSetting"; break;
// case "llmoneyconf": a = "llmoneyConf"; break;
// case "moneydata": a = "MoneyData"; break;
// case "tpaset": a = "TPASet"; break;
// case "HOME": a = "Home"; break;
// case "WARP": break;
// case "BACK": a = "Back"; break;
// case "SHOP": a = "Shop"; break;
// }
// let ThisRes = (() => {
// switch (type) {
// case "getdata": {
// let fsTmp = fs.get(a);
// if (fsTmp == null) { return null; }
// WriteUseLog("API-Old-GetData", null, a);
// return fsTmp.read();
// }
// case "setdata": {
// let fsTmp = fs.get(a);
// if (fsTmp == null) { return false; }
// WriteUseLog("API-Old-SetData", null, a);
// return fsTmp.write(b);
// }
// case "reloaddata": {
// let fsTmp = fs.get(a);
// if (fsTmp == null) { return false; }
// WriteUseLog("API-Old-ReloadData", null, a);
// return fsTmp.reload();
// }
// case "getkeys": {
// let arr = [];
// fs.forEach((_v, name) => { arr.push(name); });
// WriteUseLog("API-Old-GetKeys", null, a);
// return arr;
// }
// case "getlangdata": {
// let fsTmp = LangFs.get(a);
// if (fsTmp == null) { return false; }
// WriteUseLog("API-Old-GetLangData", null, a);
// return fsTmp.read();
// }
// case "setlangdata": {
// let fsTmp = LangFs.get(a);
// if (fsTmp == null) { return false; }
// WriteUseLog("API-Old-GetLangData", null, a);
// return fsTmp.write(b);
// }
// case "reloadlangdata": {
// let fsTmp = LangFs.get(a);
// if (fsTmp == null) { return false; }
// WriteUseLog("API-Old-ReloadLangData", null, a);
// return fsTmp.reload();
// }
// case "getlangkeys": {
// let arr = [];
// LangFs.forEach((_v, name) => { arr.push(name); });
// WriteUseLog("API-Old-GetLangKeys", null, a);
// return arr;
// }
// }
// })();
// return (typeof (ThisRes) != "string" ? JSON.stringify(ThisRes) : ThisRes);
// } catch (e) {
// ErrorMsg(e);
// }
// };
// if (ll.export(ExportFunc, "LLSEGlobal", "TMET")) {
// logger.info("OldAPI TMET API Export Successful");
// } else {
// logger.fatal("OldAPI TMET API Export Fatal!!!");
// }
// }
//#endregion
let ListenRemoteCall = (name, ns, nm) => {
logger.debug(`远程虚拟监听: ${name} 创建...`);
let id = TMListen.listen(name, (...args) => {
if (ll.hasExported(ns, nm)) {
return Boolean(ll.import(ns, nm)(...args));
} else {
logger.debug(`远程调用: ${ns}::${nm} 函数没有导出!自动删除远程虚拟监听!`);
TMListen.unListen(id, "TMET");
let index = rcd[name].indexOf(`${ns}::${nm}`);
rcd[name].splice(index, 1);
}
return true;
}, "TMET");
}
Modules._Exports.forEach((func, key) => {
if (ll.export((...args) => {
try {
return func(...args);
} catch (e) {
e.message = `${`Error in Export API: ${key}`}\n${e.message}`;
ErrorMsg(e);
}
}, "TMETApi", key)) {
logger.debug(`RemoteCall API: TMETApi::${key} export success!`);
} else {
logger.error(`RemoteCall API: TMETApi::${key} export fail!`);
}
});
let oldData = GlobalCache.FileCache.get("RemoteCall");
GlobalCache.FileCache.set("RemoteCall", {});
let rcd = GlobalCache.FileCache.get("RemoteCall");
if (oldData != null) {
oldData.forEach((NsAndNmList, key) => {
NsAndNmList.forEach((NsAndNm) => {
let [ns, nm] = NsAndNm.split("::");
if (ll.hasExported(ns, nm)) {
if (rcd[key] == null) { rcd[key] = []; }
if (rcd[key].indexOf(`${ns}::${nm}`) != -1) {
return false;
}
rcd[key].push(`${ns}::${nm}`);
ListenRemoteCall(key, ns, nm);
} else {
logger.debug(`远程调用: ${ns}::${nm} 函数没有导出!自动删除远程虚拟监听!`);
}
});
});
}
TMListen._TMETEvents.forEach((_map, name) => {
if (ll.export((a, b) => {
try {
if (rcd[name] == null) { rcd[name] = []; }
if (rcd[name].indexOf(`${a}::${b}`) != -1) {
return false;
}
rcd[name].push(`${a}::${b}`);
ListenRemoteCall(name, a, b);
return true;
} catch (e) {
e.message = `${`Error in Export ListenEvent: ${name}`}\n${e.message}`;
ErrorMsg(e);
}
}, "TMETListen", name)) {
logger.debug(`RemoteCall: TMETListen::${name} export!`);
} else {
logger.error(AutoReplace("Export RemoteCall Function: {1} Fail!", `TMETListen::${name}`));
}
});
}
function AutoUpdateConfig() {
try {
let NewCfg = _Configs.TMET;
let NewCfgKeys = Object.keys(NewCfg);
let OldCfg = JSON.parse(fs.get("TMET").read());
NewCfgKeys.forEach((key) => {
let Upper = key.toUpperCase();
if (OldCfg[key] == null && OldCfg[Upper] != null) {
logger.info(`Update config name: ${Upper}->${key}`);
OldCfg[key] = OldCfg[Upper];
delete OldCfg[Upper];
}
if (OldCfg[key] == null) {
logger.info("Update config: ", key);
return;
}
if (typeOfEx(NewCfg[key]) != "Object") {
NewCfg[key] = OldCfg[key];
} else {
let Cfg2Keys = Object.keys(NewCfg[key]);
Cfg2Keys.forEach((key2) => {
if (OldCfg[key][key2] == null) {
logger.info("Update config: ", key, ".", key2);
} else {
if (key == "UseLog" && key2 == "Conf") {
let Obj0 = NewCfg[key][key2], keys1 = Object.keys(Obj0);
let Obj1 = OldCfg[key][key2];
keys1.forEach((key2) => {
let Upper = key2.toUpperCase();
if (Obj1[key2] == null && Obj1[Upper] != null) {
logger.info(`Update config name: UseLog.Conf.${Upper}->${key2}`);
Obj1[key2] = Obj1[Upper];
delete Obj1[Upper];
}
if (Obj1[key2] != null) {
Obj0[key2] = Obj1[key2];
} else {
logger.info(`Update config name: UseLog.Conf.${key2}`);
}
});
} else {
NewCfg[key][key2] = OldCfg[key][key2];
}
}
});
}
});
if (OldCfg.Debug) {
NewCfg["Debug"] = true;
}
logger.info("Save new operation...");
fs.get("TMET").write(JSON.stringify(NewCfg, null, 2));
return true;
} catch (e) {
ErrorMsg(e);
return false;
}
}
function SafeCheck() {
try {
let pluginInfo = ll.getPluginInfo("TMEssential.js");
TMET_RunPath = pluginInfo.filePath.replace(/\\/g, "/");
if ((() => {
let err = new Error("TestErrorMessage"), stack = err.stack;
if (stack.indexOf(err.name) == 0 && stack.indexOf(err.message) != -1) { return true; }
return false;
})()) {
if (File.checkIsDir(TMET_RunPath)) {
TMET_RunPath += "/TMEssential.js";
}
IsQuickJs = false;
}
logger.debug(`Run Path: ${TMET_RunPath}`);
logger.debug(`Is QuickJs Environment: ${IsQuickJs}`);
if (!File.exists(TMET_RunPath)) {
throw new Error("TMEssential.js File is not exists!");
}
return true;
} catch (e) {
logger.error(`安全检查失败!原因: ${e.message}`);
return false;
}
}
function LL3SafeCheck() {
try {
if ((() => {
let err = new Error("TestErrorMessage"), stack = err.stack;
if (stack.indexOf(err.name) == 0 && stack.indexOf(err.message) != -1) { return true; }
return false;
})()) {
if (File.checkIsDir(TMET_RunPath)) {
TMET_RunPath += "/TMEssential.js";
}
IsQuickJs = false;
}
logger.debug(`Run Path: ${TMET_RunPath}`);
logger.debug(`Is QuickJs Environment: ${IsQuickJs}`);
if (!File.exists(TMET_RunPath)) {
throw new Error("TMEssential.js File is not exists!");
}
LLMoney_ConfigPath = "./plugins/LegacyMoney/money.json"
return true;
} catch (e) {
logger.error(`[LL3ForceLoad] 安全检查失败!原因: ${e.message || e}`);
return false;
}
}
function NetWorkNotice() {
network.httpGet("https://gitee.com/timidine/mcbe-lite-loader-script-engine-tmessential/raw/main/Notice.json", (code, res) => {
if (code != 200) {
logger.warn("Failed to obtain network notice!");
return;
}
try {
let arr = JSON.parse(res);
arr.forEach((str) => {
logger.info(`[NetWork] ${str}`);
});
} catch (_) {
logger.warn(`Failed to parse network notice!`);
}
});
}
function ProcessCacheData() {//重载读取数据成功(可能以后会用到)
}
function RegTMETCmd() {
TMCmd.register("tmet", Tr(null, "tmet.cmd.description"), PermType.Console, 0x80, (nc) => {
nc.setEnum("OPEnum1", ["reloaddata", "lslangpack"]);
nc.setEnum("OPEnum2", ["unloadlangpack", "reloadlangpack"]);
nc.setEnum("OPEnum3", ["loadlangpack"]);
LangEnumMgr.addTask((LangNames) => {
nc.setSoftEnum("LangPackEnum", LangNames);
});
nc.mandatory("OP1", ParamType.Enum, "OPEnum1", "OP1", 1);
nc.mandatory("OP2", ParamType.Enum, "OPEnum2", "OP2", 1);
nc.mandatory("OP3", ParamType.Enum, "OPEnum3", "OP3", 1);
nc.mandatory("Input", ParamType.String);
nc.mandatory("LangPackName", ParamType.SoftEnum, "LangPackEnum", "LangPackName", 1);
nc.overload(["OP1"]);
nc.overload(["OP2", "LangPackName"]);
nc.overload(["OP3", "Input"]);
nc.setCallback((_cmd, _ori, out, res) => {
let pl = _ori.player;
let type = (res.OP1 || res.OP2 || res.OP3);
switch (type) {
case "reloaddata": {
fs.forEach((jc, name) => {
jc.reload();
logger.debug(`Reload File: <${name}>`);
});
FilesChecker();
out.success(addLogo(Tr(null, "tmet.reloaddata.success"), false));
break;
}
case "loadlangpack": {
let LangName = res.Input;
if (LangName.toLowerCase() == "zh_cn.json") {
out.error(addLogo(Tr(pl, "tmet.not.allow.default.lang.pack"), false));
return;
}
if (Modules.getApi("loadLangPack")(LangName) == -1) {
out.error(addLogo(AutoReplace(Tr(pl, "tmet.load.lang.pack.fail"), LangName), false));
return;
}
out.success(addLogo(AutoReplace(Tr(pl, "tmet.load.lang.pack.success"), LangName), false));
break;
}
case "unloadlangpack": {
let LangName = res.LangPackName + ".json";
if (LangName.toLowerCase() == "zh_cn.json") {
out.error(addLogo(Tr(pl, "tmet.not.allow.default.lang.pack"), false));
return;
}
if (!Modules.getApi("unloadLangPack")(LangName)) {
out.error(addLogo(AutoReplace(Tr(pl, "tmet.unload.lang.pack.fail"), LangName), false));
return;
}
out.success(addLogo(AutoReplace(Tr(pl, "tmet.unload.lang.pack.success"), LangName), false));
break;
}
case "reloadlangpack": {
let LangName = res.LangPackName + ".json";
if (LangName.toLowerCase() == "zh_cn.json") {
out.error(addLogo(Tr(pl, "tmet.not.allow.default.lang.pack"), false));
return;
}
if (!Modules.getApi("unloadLangPack")(LangName) || Modules.getApi("loadLangPack")(LangName) == -1) {
out.error(addLogo(AutoReplace(Tr(pl, "tmet.reload.lang.pack.fail"), LangName), false));
return;
}
out.success(addLogo(AutoReplace(Tr(pl, "tmet.reload.lang.pack.success"), LangName), false));
break;
}
case "lslangpack": {
out.success(addLogo(AutoReplace(Tr(pl, "tmet.ls.lang.pack"), LangEnumMgr._LangPacks.join("§r,")), false));
break;
}
}
});
nc.setup();
});
}
function FilesChecker() {
fs.forEach((v) => {
v.getKeys();
});
}
/** 注册LLMoney玩家经济变动 */
function Money_RegMoneyChangeListen() {
let LLMoneyChangedExample = TMListen.RegEvent("onLLMoneyMoneyChanged", "mc");
mc.listen("onMoneyAdd", (xuid, _moneyVal) => {
if (!GlobalCache.PlayerState.has(xuid)) { return true; }
let nowMoney = money.get(xuid);
LLMoneyChangedExample(xuid, nowMoney);
return true;
});
mc.listen("onMoneyReduce", (xuid, _moneyVal) => {
if (!GlobalCache.PlayerState.has(xuid)) { return true; }
let nowMoney = money.get(xuid);
LLMoneyChangedExample(xuid, nowMoney);
return true;
});
mc.listen("onMoneySet", (xuid, _moneyVal) => {
if (!GlobalCache.PlayerState.has(xuid)) { return true; }
let nowMoney = money.get(xuid);
LLMoneyChangedExample(xuid, nowMoney);
return true;
});
mc.listen("onMoneyTrans", (fromXuid, toXuid, _moneyVal, _note) => {
if (GlobalCache.PlayerState.has(fromXuid)) {
let nowMoney = money.get(fromXuid);
LLMoneyChangedExample(fromXuid, nowMoney);
}
if (GlobalCache.PlayerState.has(toXuid)) {
let nowMoney = money.get(toXuid);
LLMoneyChangedExample(toXuid, nowMoney);
}
return true;
});
}
function TryLoadLL3ForceLoadConfig() {
let text = File.readFrom("./plugins/Timiya/config/TMET_LL3ForceLoadConfig.json");
if (text != null) {
try {
logger.info("Try to load TMEssential LL3 Config...");
let content = JSON.parse(text);
TMET_RunPath = content["TMETRunPath"];
GlobalCache.LL3ForceLoad = true;
} catch (e) {
logger.warn("TMET LL3 force load config Can't to read!!!");
logger.warn("Message: ", e.message || e);
return false;
}
return true;
}
return false;
}
function main() {
try {
logger.setLogLevel(4);
if (GlobalCache.DebugMode) {
logger.setLogLevel(5);
logger.debug(`Debug::Dev Mode is on`);
}
logger.info("Loading...");
//RegPlugin Info
(() => {
try {
let major = _Version._ver[0],
minor = _Version._ver[1], revision = _Version._ver[2],
other = {
"完整版本": _Version.getVersionString(),
"作者": "提米吖",
"开源地址": "https://gitee.com/timidine/mcbe-lite-loader-script-engine-tmessential/tree/main"
};
ll.registerPlugin("TMEssential.js", "新时代多功能基础插件",
{ "major": major, "minor": minor, "revision": revision }, other);
} catch (e) {
logger.warn(`RegisterPlugin Info Fail!`);
}
})();
logger.setTitle('TMEssential');
TryLoadLL3ForceLoadConfig();
let LoaderVersion = ll.version();
let VerInfoString = AutoReplace("LiteLoader/LeviLamina-ScriptEngine{1}.{2}.{3}{4}",
LoaderVersion.major,
LoaderVersion.minor,
LoaderVersion.revision,
(LoaderVersion.isBeta ? "Beta" : "")
);
logger.info(getColor(1, 33),
String.raw`
________ _________ __ _ __
/_ __/ |/ / ____/____________ ____ / /_(_)___ _/ /
/ / / /|_/ / __/ / ___/ ___/ _ \/ __ \/ __/ / __ '/ /
/ / / / / / /___(__ |__ ) __/ / / / /_/ / /_/ / /
/_/ /_/ /_/_____/____/____/\___/_/ /_/\__/_/\__,_/_/
`, `
${getColor(4, 33, 45)}===TMEssential is distributed under the GPLv3 License===${getColor(0)}${getColor(1)}`, `
${getColor(4, 36, 45)}=====Running in ${VerInfoString}=====${getColor(0)}${getColor(1)}`);
if (GlobalCache.LL3ForceLoad ? !LL3SafeCheck() : !SafeCheck()) {
if (File.exists("./LeviLamina.dll")) {
logger.warn("检测到您可能处于LL3Beta版本运行!请查阅以下网站进行了解:");
logger.warn("https://gitee.com/timidine/mcbe-lite-loader-script-engine-tmessential/blob/main/%E5%A6%82%E4%BD%95%E8%AE%A9%E6%8F%92%E4%BB%B6%E5%BC%BA%E5%88%B6%E8%BF%90%E8%A1%8C%E5%9C%A8LL3Beta%E7%89%88.md")
logger.warn("https://985.so/wf6z9");
}
return;
}
logger.info(`TMEssential is running in ${(IsQuickJs ? "QuickJs" : "NodeJs")} environment`);
File.mkdir(AutoReplace(TMET_CfgDir, ""));
File.mkdir(AutoReplace(TMET_DataDir, ""));
fs.set("TMET", new JsonConfigFileClass(AutoReplace(TMET_CfgDir, "TMEssential.json"), JSON.stringify(_Configs.TMET, null, 2)));
if (AutoUpdateConfig()) {
let TMETCfg = fs.get("TMET");
if (TMETCfg.get("Enable")) {
if (TMETCfg.get("Debug")) {
logger.setFile(TMET_DebugLogPath);
logger.setLogLevel(5);
logger.debug("Debug::Log Mode is on");
}
Modules.LoadI18N();
if (TMETCfg.get("Money")["Enable"]) {
logger.debug("Loading Money module...");
Modules.LoadMoney();
// if (TMETCfg.get("ExportOldAPI")) {
// if (ll.export(MoneyApiExport, "LLSEGlobal", "MONEY")) {
// logger.info("OldAPI MONEY Export successful");
// } else {
// logger.fatal("OldAPI MONEY Export FAIL");
// }
// }
} else {//防止无法找到api
Modules._RegExportApi("getMoney", () => { return 0; });
Modules._RegExportApi("setMoney", () => { return true; });
Modules._RegExportApi("tranMoney", () => { return false; });
Modules._RegExportApi("getPayTax", () => { return 0.0; });
}
if (TMETCfg.get("TPA")["Enable"]) {
logger.debug("Loading TPA module...");
Modules.LoadTPA();
}
if (TMETCfg.get("WARP")["Enable"]) {
logger.debug("Loading WARP module...");
Modules.LoadWARP();
}
if (TMETCfg.get("Home")["Enable"]) {
logger.debug("Loading Home module...");
Modules.LoadHome();
}
if (TMETCfg.get("Back")["Enable"]) {
logger.debug("Loading Back module...");
Modules.LoadBack();
}
if (TMETCfg.get("Notice")["Enable"]) {
logger.debug("Loading Notice module...");
Modules.LoadNotice();
}
if (TMETCfg.get("Shop")["Enable"]) {
logger.debug("Loading Shop module...");
Modules.LoadShop();
}
if (TMETCfg.get("DynamicMotd")["Enable"]) {
logger.debug("Loading DynamicMode module...");
Modules.LoadDynamicMotd();
}
if (TMETCfg.get("TPR")["Enable"]) {
logger.debug("Loading TPR module...");
Modules.LoadTPR();
}
if (TMETCfg.get("RefreshChunk")["Enable"]) {
logger.debug("Loading RefreshChuck module...");
Modules.LoadRefreshChunk();
}
if (TMETCfg.get("FarmLandProtect")["Enable"]) {
logger.debug("Loading FarmLandProtect module...");
Modules.LoadFarmLandProtect();
}
}
logger.debug("Listen Basic Event...");
TMListen.listen("onTick", () => {
TickTask._RunTask();
});
TMListen.listen("onPreJoin", (pl) => {
if (isSimulatedPlayer(pl)) { return true; }
GlobalCache.PlayerState.set(pl.xuid, false);
});
TMListen.listen("onJoin", (pl) => {
if (isSimulatedPlayer(pl)) { return true; }
let xuid = pl.xuid;//防动态
TickTask.addTask(() => {
GlobalCache.PlayerState.set(xuid, true);
});
});
TMListen.listen("onLeft", (pl) => {
if (isSimulatedPlayer(pl)) { return true; }
let xuid = pl.xuid;
TickTask.addTask(() => {
GlobalCache.PlayerState.delete(xuid);
});
});
TMListen.listen("onConsoleOutput", (out) => {
if (GlobalCache.RunCmdNoOutput.IsExecuting) {
GlobalCache.RunCmdNoOutput.Output.push(out);
return false;
}
return true;
});
TMListen.listen("onServerStarted", () => {
ServerIsStarted = true;
});
if (GlobalCache.DebugMode) {
mc.regConsoleCmd("writefile", "write to file", () => {
GlobalCache.FileCache._SaveToFile();
});
}
RegTMETCmd();
logger.debug("监听创建...");
mc.listen("onPreJoin", TMListen.RegEvent("onPreJoin"));
mc.listen("onJoin", TMListen.RegEvent("onJoin"));
mc.listen("onLeft", TMListen.RegEvent("onLeft"));
mc.listen("onScoreChanged", TMListen.RegEvent("onScoreChanged"));
mc.listen("onPlayerCmd", TMListen.RegEvent("onPlayerCmd"));
mc.listen("onPlayerDie", TMListen.RegEvent("onPlayerDie"));
mc.listen("onRespawn", TMListen.RegEvent("onRespawn"));
mc.listen("onMobHurt", TMListen.RegEvent("onMobHurt"));
mc.listen("onFarmLandDecay", TMListen.RegEvent("onFarmLandDecay"));
mc.listen("onConsoleOutput", TMListen.RegEvent("onConsoleOutput"));
mc.listen("onServerStarted", TMListen.RegEvent("onServerStarted"));
if (TMETCfg.get("Money")["MoneyType"] == "llmoney") {
Money_RegMoneyChangeListen();
}
(() => {
let tickExample = TMListen.RegEvent("onTick");
mc.listen("onTick", () => { tickExample(); return true; });
})();//安全考虑,不允许拦截Tick
if (_Version.isBeta()) {
logger.warn("Warning! This version is a test version. It is prohibited to use in production environment!");
logger.warn("Warning! This version is a test version. It is prohibited to use in production environment!");
logger.warn("Warning! This version is a test version. It is prohibited to use in production environment!");
}
if (TMETCfg.get("AutoUpdate")["Enable"]) {
AutoUpdate();
logger.info("AutoUpdate Turned on");
} else {
logger.info("AutoUpdate Closed");
}
if (GlobalCache.FileCache._TryReadFile()) {
ProcessCacheData();
}
ExportAPI();
FilesChecker();//文件检测
logger.info("TMEssential loaded! author by Timiya version: " + _Version.getVersionString() + "");
WriteUseLog("Plugin", null, `Initd-Version:${_Version.getVersionString()}`);
NetWorkNotice();
}
} catch (e) {
logger.error("TMET loading failed!!!");
ErrorMsg(e);
}
}
try {
if (ll.listPlugins().indexOf("TMEssential.js") != -1) {
let i = 0;
while (1) {
if (i == 10) { break; }
logger.error("Another TMET is already running! Please check the plugin list!");
i++;
}
throw new Error("NotBug: STOP");
}
main();
} catch (e) { ErrorMsg(e); }
JavaScript
1
https://gitee.com/timidine/mcbe-lite-loader-script-engine-tmessential.git
git@gitee.com:timidine/mcbe-lite-loader-script-engine-tmessential.git
timidine
mcbe-lite-loader-script-engine-tmessential
MCBE-LLScriptEngine-TMEssential
main

搜索帮助