├── package.json ├── module.json ├── lib ├── data │ ├── miscData.json │ ├── userSpawns.json │ ├── abnormalities.json │ └── skillString.json ├── setting_migration.js └── index.js ├── README.md └── manifest.json /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "lib", 3 | "name": "fps-utils", 4 | "author": "Risenio", 5 | "description": "A free script filled with features dedicated to improve your fps.", 6 | "version": "19", 7 | "homepage": "https://github.com/Risenio/fps-utils/wiki", 8 | "supportUrl": "https://github.com/Risenio/fps-utils/issues", 9 | "keywords": ["tera", "fps", "tera-fps", "tera-proxy", "tera-toolbox", "tera-online", "fps-utils", "optimization"], 10 | "contributors": ["Saegusae", "codeagon", "SerenTera", "Kyoukaya", "SaltyMonkey", "Leyki"], 11 | "conflicts": ["hide-players","fps-utils-lite","fps-manager"], 12 | "repository": { "type": "git", "url": "git+https://github.com/Risenio/fps-utils.git" } 13 | } -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "disableAutoUpdate": false, 3 | "name": "fps-utils", 4 | "author": "Risenio", 5 | "homepage": "https://github.com/Risenio/fps-utils/wiki", 6 | "supportUrl": "https://github.com/Risenio/fps-utils/issues", 7 | "readmePath": "./README.md", 8 | "description": "A free script filled with features dedicated to improve your fps.", 9 | "contributors": ["Saegusae","codeagon","SerenTera","Kyoukaya","SaltyMonkey","Leyki"], 10 | "conflicts": ["hide-players","fps-utils-lite","fps-manager"], 11 | "version": "19", 12 | "options": { 13 | "cliName": "FPS", 14 | "guiName": "Fps Utils", 15 | "settingsVersion": 19, 16 | "settingsFile": "config.json", 17 | "settingsMigrator": "./lib/setting_migration.js" 18 | }, 19 | "servers": ["https://raw.githubusercontent.com/Risenio/fps-utils/master/"] 20 | } -------------------------------------------------------------------------------- /lib/data/miscData.json: -------------------------------------------------------------------------------- 1 | {"Alphabet":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","PClasses":["warrior","lancer","slayer","berserker","sorcerer","archer","priest","mystic","reaper","gunner","brawler","ninja","valkyrie"],"PRoles":["dps","healer","tank","ranged"],"InvalidVoiceId":249,"InvisibleNpcs":{"8":[6011],"12":[1],"23":[201,202],"34":[8000],"61":[9901],"62":[9001,9002,9003,9004,9901],"83":[9901],"207":[9901],"223":[9901],"230":[9901],"2010":[9901],"2011":[9901],"2012":[9901],"2013":[9901],"2014":[9901],"2015":[9901]},"ImportantActionScripts":[40000,40001,40002,426002],"MountToReplaceId":16,"SpamAchIds":[3,6,14,15,17,18,51,166,358,377,391,466,467,468,469,470,471,472,473,476,611,1002,1003,1004,1005,1308,1309,1310,1311,1312,1313,1314,1315,1408,1420,1744,1745,1769,1770,1771,1942,1943,1952,1992,2032,2033,2036,2037,2038,2057,2062,2071,2078,2081,2082,2083,2084,2088,2089,2095,6005,9817,20605,20607,20608,28723,28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,28736,510005,510012,510019,510026,510027,510033,510034,510035,510036,510037,510038,510039,510040,510041,520029,520030,520032,520033,520034,520035,520048,520049,520050,520051,525000,525001,525002,525003,525004,525005,525006,525007,525008,525009,525010,525011,525012,525013,525014,525015,525016,525017,525018,525019,525020,525021,525022,525023,525024,525025,5010000],"StarterWeaponIds":[10001,10002,10003,10004,10005,10006,10007,10008,80396,55005,82005,58171,59053],"HexColors":{"BnzC":"#BC8F8F","SlvC":"#9A9A9A","GldC":"#DAA520","PnkC":"#FFB7C5","HPkC":"#FF69B4","CPkC":"#ED5D92","RedC":"#FE6F5E","GrnC":"#4DE19C","LPrC":"#E0B0FF","PrpC":"#9966CC","LBlC":"#4DDCE1","BluC":"#436EEE","DBlC":"#5BC0BE","HBlC":"#08B3E5","GryC":"#778899","YlwC":"#C0B94D"}} -------------------------------------------------------------------------------- /lib/data/userSpawns.json: -------------------------------------------------------------------------------- 1 | {"FireWorks":[60016000,80037000],"MoteIds":[8008,8009,8010,8011,8012,8013,8014,8015,8016,8017,8018,8019,8020,8021,8022,8023],"SmokeBombId":{"12":9},"DivineWrathId":{"11":3},"TrapsIds":[30120,30220,30320,90220,90320,90420,90520,90620,90720,90820,90920,100120,100220,100320,100420,100520,120220,120320,120420,120520,120620,120720,120820,120920,150120,150220,150320,150420,150520,150620,150720,170120,170220,170320,170420,170520,170620,170720,170820,170920,230120,230220,230320,250120,250220,250320,250420,250520,250620,250720,250820,250920,251020],"UserNpcsHzId":1023,"UserNpcs":[12345,1100100,1100101,1023000,1023001,1023002,1023003,1023004,1023005,1023006,1023007,1023008,1023009,1023010,1023011,1023012,1023013,1023014,1023200,1023201,1023202,1023203,1023204,1023205,1023206,1023207,1023208,1023209,1023210,1023211,1023300,1023301,1023302,1023303,1023304,1023305,1023306,1023307,1023308,1023309,1023310,1023311,1023312,1023400,1023401,1023402,1023403,1023404,1023405,1024000,1024001,1024100,1024200,1024300,2100100,2100101,10235001,10235002,10235003,10235004,10235005,10235006,10235007,10235008,10235009,10235010,10235011,10235012,10235013,10235014,10235015,10235016,10235017,10235100,10236001,10236002,10236003,10236004,10236005,10236006,10236007,10236008,10236009,10236010,10236011,10236012,10236013,10236014,10236015,10236100,10237001,10237002,10237003,10237004,10237005,10237006,10237007,10237008,10237009,10237010,10237011,10237012,10237013,10237014,10237015,10237100,10238001,10238002,10238003,10238004,10238005,10238006,10238007,10238008,10238100,10239003,30301001,30301002,30301003,30301004,30301005,30302001,30302002,30302003,30302004,30302005,30302006,30302007,30303001,30303002,30303003,30303004,30303005,30303006,30303007]} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fps Utils 2 | Written for tera-proxy, a free script filled with features dedicated to improve your fps, in the open world, in dungeons and in battlegrounds. 3 | 4 | ## How to use. 5 | * Put the script folder "fps-utils" into the `mods` folder. 6 | * Log the game using the proxy. 7 | * Get access to the built-in GUI via typing `/!fps g` into the chat. 8 | 9 | ## Capability. 10 | * Should work on any proxy. ([Tera-Proxy](https://github.com/tera-proxy/tera-proxy) & [Tera-Toolbox](https://github.com/tera-toolbox/tera-toolbox), *as long as its up-to-date*) 11 | * No dependencies. 12 | 13 | ## List of commands can be found in [this Wiki](https://github.com/Risenio/fps-utils/wiki/Commands). 14 | 15 | ## Suggestions/Issues/Reports are welcome. 16 | * If you have suggestions, need help, or want to comment on my coding, dm me on discord `@Risenio#6997` or leave an issue report. 17 | 18 | ## Credits 19 | Direct Contributers: 20 | - [Saegusae](https://github.com/Saegusae) - [Original developer](https://github.com/Saegusae/fps-utils) (No longer maintained). 21 | - [Pentagon](https://github.com/codeagon) - [Fps-utils's fork](https://github.com/codeagon/fps-utils) (No longer maintained). 22 | - [SerenTera](https://github.com/SerenTera) 23 | - [Kyoukaya](https://github.com/kyoukaya) 24 | - [SaltyMonkey](https://github.com/SaltyMonkey) - Current [Tera-Toolbox (Tera-proxy's fork)](https://github.com/tera-toolbox/tera-toolbox) developer. 25 | - [Leyki](https://github.com/Leyki) 26 | 27 | --- 28 | 29 | In-direct Contributers: 30 | - [Kasea](https://github.com/Kasea) 31 | - [Caali](https://github.com/caali-hackerman) - Original [Tera-Toolbox (Tera-proxy's fork)](https://github.com/tera-toolbox/tera-toolbox) developer. 32 | - [Bernkastel](https://github.com/Bernkastel-0) - Original idea/ZFPS alternative script. 33 | - [Pinkie Pie](https://github.com/pinkipi) - Original idea/~~Current maintained~~ [Tera-proxy's fork](https://github.com/tera-proxy/tera-proxy) developer (No longer maintained). 34 | - [Meishu](https://github.com/meishuu) - Original developer of [Tera-proxy](https://github.com/meishuu/tera-proxy) (No longer maintained & DMCA'd by EME). 35 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "README.md": "f5c50ef82e8ba86477c3f97f92bf5e8b466b6742e84297b72d3f357f02ad26cb", 4 | "lib/data/abnormalities.json": "54727de2123584eb0ff38ffca5e86601e3faf05e8dc3379c9a0fd6e5ede1ca0c", 5 | "lib/data/miscData.json": "7d71d166aaa8bd39f40d9ddd8cbbccea6af7d8facae42b7d77046f2ea8cd143b", 6 | "lib/data/npcData.json": "bcd1876e4266f71299a298221b2594e45bf87f143f276a62c60dd8a35b75acd7", 7 | "lib/data/skillString.json": "8668b91e8165287eb43935cf9d2d85ffa6f1b6873d452857d8138a720d862fa9", 8 | "lib/data/userSpawns.json": "e82a593b3e5aa970542d8330dfe690049abad98691e8b90210f46cdc281b17a3", 9 | "lib/index.js": "ee36df541ecb128665494f122b80fde74e56535843645f74cbd33b366f3ee0b8", 10 | "lib/setting_migration.js": "1821fbb5ed37672bd9a8daa54f8ab392e35aa6c38b1602c560865b3bf6a7c6a2", 11 | "module.json": "f6c096f624a92587583d9b0f66a21bcbaefaf9d81c684f035a3ecada3712579c", 12 | "package.json": "05c87cd1ccd2c23ba209b7a58d7fe10c5ed04e52c6fbecac8c3b0f368eeb7742" 13 | }, 14 | "defs": { 15 | "C_ADMIN": 1, 16 | "C_CONFIRM_UPDATE_NOTIFICATION": "raw", 17 | "C_DISMISS_PARTY": 1, 18 | "C_LEAVE_PARTY": 1, 19 | "C_REQUEST_CONTRACT": 1, 20 | "C_RESET_ALL_DUNGEON": 1, 21 | "C_RETURN_TO_LOBBY": 1, 22 | "C_SET_VISIBLE_RANGE": 1, 23 | "S_ABNORMALITY_BEGIN": 5, 24 | "S_ABNORMALITY_DAMAGE_ABSORB": 1, 25 | "S_ABNORMALITY_END": 1, 26 | "S_ABNORMALITY_FAIL": 2, 27 | "S_ABNORMALITY_REFRESH": 2, 28 | "S_ABNORMALITY_RESIST": 1, 29 | "S_ABNORMALITY_SCALE_UP": 2, 30 | "S_ACTION_END": 5, 31 | "S_ACTION_STAGE": 9, 32 | "S_ANNOUNCE_UPDATE_NOTIFICATION": 1, 33 | "S_APPLY_TITLE": 3, 34 | "S_CREATURE_CHANGE_HP": 6, 35 | "S_CREATURE_LIFE": 3, 36 | "S_CREATURE_ROTATE": 2, 37 | "S_DEAD_LOCATION": 2, 38 | "S_DESPAWN_DROPITEM": 4, 39 | "S_DESPAWN_EVENT_SEED": 1, 40 | "S_DESPAWN_NPC": 3, 41 | "S_DESPAWN_PROJECTILE": 2, 42 | "S_DESPAWN_USER": 3, 43 | "S_EACH_SKILL_RESULT": 15, 44 | "S_END_USER_PROJECTILE": 4, 45 | "S_EXIT": 3, 46 | "S_FEARMOVE_END": 2, 47 | "S_FEARMOVE_STAGE": 2, 48 | "S_FIELD_EVENT_ON_ENTER": "raw", 49 | "S_FIELD_EVENT_ON_LEAVE": "raw", 50 | "S_FONT_SWAP_INFO": "raw", 51 | "S_GUILD_NAME": 2, 52 | "S_IMAGE_DATA": "raw", 53 | "S_INSTANCE_ARROW": 4, 54 | "S_ITEM_CUSTOM_STRING": 2, 55 | "S_ITEM_EXPLOSION_RESULT": 2, 56 | "S_LEAVE_PARTY": "raw", 57 | "S_LEAVE_PARTY_MEMBER": 2, 58 | "S_LOADING_SCREEN_CONTROL_INFO": "raw", 59 | "S_LOAD_TOPO": "raw", 60 | "S_LOGIN": 14, 61 | "S_MOUNT_VEHICLE": 2, 62 | "S_NPC_LOCATION": 3, 63 | "S_NPC_MENU_SELECT": 1, 64 | "S_PARTY_MEMBER_LIST": 9, 65 | "S_PLAYER_CHANGE_MP": 1, 66 | "S_QUEST_BALLOON": 1, 67 | "S_REQUEST_DESPAWN_SERVANT": 1, 68 | "S_REQUEST_SPAWN_SERVANT": 4, 69 | "S_RESULT_EVENT_SEED": 2, 70 | "S_SOCIAL": 1, 71 | "S_SPAWN_DROPITEM": 9, 72 | "S_SPAWN_EVENT_SEED": 2, 73 | "S_SPAWN_NPC": 12, 74 | "S_SPAWN_PROJECTILE": 6, 75 | "S_SPAWN_USER": 17, 76 | "S_START_ACTION_SCRIPT": 3, 77 | "S_START_COOLTIME_ITEM": 1, 78 | "S_START_USER_PROJECTILE": 9, 79 | "S_UNICAST_TRANSFORM_DATA": 6, 80 | "S_UNMOUNT_VEHICLE": 2, 81 | "S_UPDATE_ACHIEVEMENT_PROGRESS": 1, 82 | "S_UPDATE_EVENT_SEED_STATE": 4, 83 | "S_USER_APPEARANCE_CHANGE": 1, 84 | "S_USER_CHANGE_FACE_CUSTOM": 2, 85 | "S_USER_EXTERNAL_CHANGE": 7, 86 | "S_USER_LOCATION": 6, 87 | "S_USER_MOVETYPE": 1, 88 | "S_USER_STATUS": 4 89 | } 90 | } -------------------------------------------------------------------------------- /lib/data/abnormalities.json: -------------------------------------------------------------------------------- 1 | {"AbnNoEffectInvisibleNpcSpamId":9943049,"ReplaceAbnIds":{"90442103":47702000,"90442107":47702000},"BlockedAbns":[201,202,902,903,908,910,911,912,913,916,917,920,921,922,1130,1131,1133,1461,1462,1490,1491,1495,1510,1511,1512,1610,1630,1800,2040,2041,2042,2057,2058,2059,2060,2066,2067,2068,2081,2755,2756,2757,2758,2759,2760,2761,4401,4600,4610,4611,4612,4613,4614,4615,4616,4850,4950,5060,6005,6006,6007,6009,6016,10400,10401,10402,10403,10404,10405,10501,10502,10503,10504,10505,10506,10510,10511,10512,10513,10514,10515,10516,10520,10521,10522,10523,10524,10525,10600,10601,10602,10603,10604,10605,10606,10610,10611,10612,10613,10614,10615,10616,10620,10621,10622,10623,10624,10625,10625,10700,10701,10702,10703,10704,10705,10706,10710,10711,10712,10713,10714,10715,10716,10720,10721,10722,10723,10724,10725,10800,10801,10802,10803,10804,10805,10806,12230,12240,27050,40175,40176,48732,48733,48734,48735,48736,48737,48738,48739,60005,60018,60026,70214,70221,70222,70223,70224,70225,70226,70227,70228,70231,70232,70233,70234,70235,70241,70242,70243,70244,70245,70251,70252,70253,70254,70255,70256,70261,70262,70263,70264,70465,70271,70272,70273,70274,70275,70281,70282,70283,70284,70285,70286,70287,70288,70289,70290,70300,70301,70302,70303,70304,70305,70310,70311,70312,70313,70314,70315,70321,70322,70323,70324,70325,70330,70331,70332,70333,70334,70335,70336,70337,70338,70341,70342,70343,70344,70345,70346,70347,70348,70351,70352,70353,70354,70355,70356,70357,70358,70359,70360,70361,70362,70363,70364,70365,70366,70367,70368,70369,70370,70462,88611,88612,100200,100201,100202,100203,100294,100295,100296,100297,100298,100299,100800,100801,101801,101900,102600,103100,103102,103104,103130,103131,200200,200201,200202,200230,200231,200232,200500,200900,200901,200930,200931,201200,201300,201301,201302,201303,201304,201305,201700,201807,201808,201811,201812,201830,201831,300300,300301,400100,400101,400102,400103,400104,400105,401705,401706,401710,401711,401721,401722,401723,401724,401727,401728,457017,457052,476615,476616,476617,476618,476806,500200,500500,500600,500601,500602,500700,500701,500702,500703,500704,500705,500706,500707,500720,500721,500722,500723,500724,500725,500726,500727,501000,501001,501002,501003,501004,501005,501006,501020,501021,501022,501023,501024,501025,501026,501400,501402,600900,600901,600902,600903,600904,600905,600906,600907,600908,600920,600921,600922,600923,600924,600925,600926,600927,600928,601450,620000,620001,621000,622001,622002,630201,630202,630411,630511,631002,631003,631201,631202,700200,700201,700202,700203,700230,700231,700232,700233,700300,700400,700401,700402,700403,700404,700405,700406,700407,700408,700409,700600,700601,700602,700603,700630,700631,700700,700701,700730,700731,701001,701002,701003,701004,701005,701006,701007,701008,701009,701010,701011,701012,701511,701540,701541,701542,701543,701544,701545,701546,701547,701548,701549,701550,701551,701560,701561,701562,701563,701564,701565,701566,701567,701568,701569,701570,701571,701604,701605,701606,701607,701800,701801,701802,701803,701804,701805,701806,701807,701808,701820,701821,701822,701823,701824,701825,701826,701827,701828,701900,702000,702001,702002,702003,702005,702012,757002,757003,757004,757005,757006,757007,757008,757009,757016,757017,757018,757029,757031,757032,757033,757049,757052,757054,760009,760015,760031,760032,776017,776021,776022,776023,776024,776025,776026,776028,776029,800100,800101,800102,800103,800104,800105,800106,800107,800108,800300,800301,800302,800303,800304,801000,801001,801100,801101,801400,801401,806001,806002,806020,806021,806022,806023,806028,811061,821101,830004,905434,905656,905657,905932,999996,4510004,4510005,4510006,4510007,4510008,4510009,4510010,4510011,4510012,4510013,4510014,4510015,5000000,5000003,5020003,5020006,5020007,5020008,5020010,5020011,5030004,5030005,5690001,7102001,7691000,7691007,9691000,9691007,9691011,9943049,10152050,10152096,10154030,10154054,10155550,14400002,14400003,44300066,44300073,44300078,44300079,45000011,45000012,47630300,47650400,47660100,47660200,47660300,47660400,47660500,47660600,47660700,47660800,47660900,47661000,47662300,47662800,47680400,74300078,74300081,75000016,76600024,77600017,77702400,77703433,77703437,78200379,78200383,80401500,81121101,81121102,81121103,81121104,81121105,81121201,81121202,81121203,81121204,81121205,90341010,90442101,91600019,93503301,93503302,93503303,93503401,93503402,98200379,98200383,98850027,98850030,98850035,98850036,99000900,99000910,99000920,99000930,99000940,99000950,99000960,99000970,99001000,99001010,99001020,99001030,99001040,99001050,99001060,99001070,99001200,99001210,99001220,99001230,99001240,99001250,99001260,99001270,99001300,99001301,99001302,99001303,99001310,99001320,99001330,99001340,99001350,99001360,99001370,99001400,99001410,99001420,99001430,99001440,99001450,99001460,99001470,99001700,99001710,99001720,99001730,99001740,99001750,99001760,99001770,99002300,99002310,99002320,99002330,99002340,99002350,99002360,99002370,99003200,99003400,99003500,99003600,99003700,99020000,99020010,99020020,99070011,99070021,99070023,99070025,99070027,99070028,99070029,99070030,99070031,99070032,999001001,999001002,999001003,999001004,999001005,999001006,999001007,999001008,999001011,999001018,999001019,999001020,999001021,999009820,999010000],"ImportantAbns":[31040001,32040001,32040007,90440009,90442106,90442110,90442111,90442112,90442113,90442114,90442400,90442401,90442402,90442403,90442404,90442405,90442406,90442407,90442408,90442502,78200123,78200126,78200130,78200131,78200161,78200162,78200203,78200204,78200205,78200209,78200234,78200235,78200236]} -------------------------------------------------------------------------------- /lib/data/skillString.json: -------------------------------------------------------------------------------- 1 | {"warrior":{"Combo Attack":1,"Evasive Roll":2,"Torrent of Blows":3,"Rain of Blows":4,"Battle Cry":5,"Assault Stance":8,"Defensive Stance":9,"Death From Above":10,"Poison Blade":11,"Leaping Strike":12,"Retaliate":13,"Charging Slash":16,"Vortex Slash":17,"Combative Strike":18,"Rising Fury":19,"Deadly Gamble":20,"Cascade of Stuns":21,"Smoke Aggressor":24,"Command: Attack":25,"Command: Follow":26,"Traverse Cut":28,"Blade Draw":29,"Scythe":30,"Reaping Slash":31,"Cross Parry":32,"Binding Sword":34,"Infuriate":35,"Rain of Blows (Deadly Gamble)":36,"Blade Draw (Deadly Gamble)":37,"Scythe (Deadly Gamble)":38,"Traverse Cut (Defensive Stance)":39,"Blade Waltz":40,"Aerial Scythe":41,"Blade Frenzy":42},"lancer":{"Combo Attack":1,"Stand Fast":2,"Onslaught":3,"Challenging Shout":4,"Shield Bash":5,"Guardian Shout":7,"Shield Counter":8,"Leash":9,"Debilitate":10,"Retaliate":11,"Infuriate":12,"Spring Attack":13,"Charging Lunge":15,"Second Wind":16,"Adrenaline Rush":17,"Shield Barrage":18,"Pledge of Protection":19,"Lockdown Blow":21,"Iron Will":22,"Master's Leash":23,"Chained Leash":24,"Wallop":25,"Backstep":26,"Rallying Cry":27,"Super Leap":28,"Guardian's Barrier":29,"Divine Protection":30},"slayer":{"Combo Attack":1,"Knockdown Strike":2,"Whirlwind":3,"Evasive Roll":4,"Dash":5,"Backstab":6,"Overhand Strike":8,"Leaping Strike":9,"Retaliate":10,"Heart Thrust":12,"Stunning Backhand":13,"Distant Blade":14,"Startling Kick":15,"Fury Strike":16,"Headlong Rush":17,"Overpower":18,"Tenacity":19,"In Cold Blood":20,"Measured Slice":23,"Eviscerate":24,"Ultimate Overhand Strike":25,"Punishing Blow":26,"Savage Strike":27,"Unsheathe":28,"Rotation Combo":30,"Jump Smash":31},"berserker":{"Combo Attack":1,"Axe Block":2,"Thunder Strike":3,"Flatten":4,"Dash":5,"Sweeping Strike":6,"Fiery Rage":8,"Cyclone":10,"Leaping Strike":11,"Retaliate":13,"Vampiric Blow":15,"Fearsome Shout":16,"Lethal Strike":18,"Triumphant Shout":19,"Inescapable Doom":20,"Bloodlust":21,"Evasive Smash":24,"Raze":25,"Tackle":26,"Unbreakable":27,"Intimiation":28,"Evasive Roll":29,"Axe Counter":30,"Overwhelm":31,"Punishing Strike":32,"Unleash":33,"Unleash: Dexter":34,"Unleash: Sinister":35,"Unleash: Rampage":36,"Unleash: Beast Fury":37},"sorcerer":{"Fireball":1,"Frost Sphere":2,"Lightning Trap":3,"Arcane Pulse":4,"Mana Infusion":5,"Meteor Strike":6,"Backstep":7,"Flame Pillar":8,"Mana Barrier":10,"Lightning Strike":11,"Void Pulse":12,"Mindblast":13,"Retaliate":14,"Painblast":16,"Painful Trap":17,"Glacial Retreat":18,"Mana Siphon":19,"Flaming Barrage":20,"Nerve Exhaustion":21,"Burning Breath":22,"Mana Volley":23,"Time Gyre":25,"Teleport Jaunt":26,"Hailstorm":27,"Nova":30,"Warp Barrier":31,"Meteor Strike (Mana Boost)":32,"Arcane Pulse (Mana Boost)":33,"Mana Boost":34,"Fusion":36,"Implosion":39},"archer":{"Arrow":1,"Arrow Volley":2,"Radiant Arrow":3,"Penetrating Arrow":4,"Rain of Arrows":5,"Backstep":6,"Feign Death":7,"Rapid Fire":8,"Slow Trap":9,"Stunning Trap":10,"Velik's Mark":12,"Retaliate":14,"Incendiary Trap":15,"Breakaway Bolt":16,"Web Arrow":17,"Close Quarters":18,"Poison Arrow":19,"Restraining Arrow":20,"Sequential Fire":22,"Incendiary Trap Arrow":25,"Thunderbolt":29,"Tenacity":31,"Find Weakness":32,"Chase":33,"Wind Walk":24,"Windsong":35,"Gust Arrow":36,"Illusion Arrow":37,"Illusion Explosion":38},"priest":{"Divine Radiance":1,"Regeneration Circle":2,"Healing Circle":3,"Blessing of Shakan":5,"Arise":6,"Mana Infusion":8,"Purifying Circle":10,"Metamorphic Blast":11,"Resurrect":12,"Summon: Group":14,"Shocking Implosion":16,"Heal Thyself":18,"Focus Heal":19,"Kaia's Shield":22,"Retaliate":25,"Fiery Escape":26,"Final Reprisal":27,"Mana Charge / Divine Charge":28,"Triple Nemesis":29,"Plague of Exhaustion":30,"Guardian Sanctuary":31,"Divine Prayer":32,"Ishara's Lulliby":33,"Restorative Burst":34,"Energy Stars":35,"Healing Immersion":37,"Backstep":38,"Grace of Resurrection":39,"Zenobia's Vortex":40,"Divine Intervention / Mass Divine Intervention":41,"Holy Burst":42,"Edict of Judgement":43},"mystic":{"Sharan Bolt":1,"Corruption Ring":2,"Titanic Favor":5,"Shara's Lash":6,"Metamorphic Blast":8,"Arun's Cleansing":9,"Resurrect":10,"Summon: Group":11,"Vow of Rebirth":12,"Aura of the Merciless":13,"Aura of the Swift":14,"Aura of the Unyielding":15,"Aura of the Tenacious":16,"Teleport Jaunt":17,"Arun's Vitae":18,"Retaliate":21,"Arun's Tears":22,"Metmorphic Smite":23,"Volley of Curses":24,"Thrall of Protection":25,"Thrall of Life":27,"Sonorous Dreams":28,"Regression":29,"Curse of Exhaustion":30,"Curse of Confusion":31,"Mire":32,"Thrall of Vengeance":33,"Thrall of Wrath":34,"Command: Attack":35,"Command: Follow":36,"Warding Totem":37,"Contagion":41,"Boomerang Pulse":42,"Unsummon Thrall":43,"Mass Teleport":44,"Thrall Augmentation":45,"Arunic Release":47,"Thrall Lord":48},"reaper":{"Spiral Barrage":1,"Double Shear":3,"Sundering Strike":4,"Grim Strike":5,"Death Spiral":6,"Whipsaw":8,"Smite":9,"Pendulum Strike":10,"Shadow Lash":11,"Shadow Burst":12,"Retaliate":14,"Retribution":15,"Shadow Reaping":16,"Dark Harvest":19,"Cable Step":20,"Recall Scythes":21,"Binding Scythes":23,"Shadow Step":40},"gunner":{"Blast":1,"Bombardment":2,"Scattershot":3,"Point Blank":4,"Burst Fire / Targeted Burst Fire":5,"Time Bomb":6,"Arcane Barrage":7,"Mana Missiles":9,"Arc Bomb":10,"Rocket Jump":11,"Balder's Vengeance":13,"Replenishment":15,"HB":18,"ST":19,"Retaliate":20,"Rolling Reload / Dashing Reload":40,"Modular Weapon System":41,"Detonate":42,"Remote Trigger":43,"Obliteration":47},"brawler":{"Punch":1,"Counter":2,"Divine Wrath":3,"Ground Pound":4,"Bullrush":5,"Haymaker":6,"Roundhouse Kick":7,"Piledriver":8,"Jackhammer":9,"Counterpunch":10,"Retaliate":12,"Provoke":13,"Infuriate":14,"Flip Kick":16,"Mounting Rage":21,"Flying Kick":22,"One-Inch Punch":24,"Rythmic Blows":26,"Quick Dash":40},"ninja":{"Combo Attack":1,"Shadow Jump":2,"Leaves on the Wind":3,"Jagged Path":4,"Impact Bomb":5,"One Thousand Cuts":6,"Decoy Jutsu":7,"Fire Avalanche":8,"Smoke Bomb":9,"Retaliate":10,"Focus":11,"Skyfall":12,"Circle of Steel":13,"Double Cut":14,"Burning Heart":15,"Death Blossom":16,"Attunement":17,"Bladestorm":18,"Chakra Thrust":19,"Clone Jutsu":20,"Boomerang Shuriken":21,"Quick Attack":22,"Inner Harmony":23},"valkyrie":{"Slash":1,"Overhead Slash":2,"Glaive Strike":3,"Charge":4,"Maelstorm":5,"Leaping Strike":6,"Spinning Death":7,"Titansbane":8,"Ground Bash":9,"Dream Slash":10,"Shining Crescent":11,"Ragnarok":12,"Bloodflower":13,"Evasion":14,"Windslash":15,"Runeburst":16,"Balder's Tears":17,"Retaliate":18,"Reclamation":19,"Backstab":20,"Dark Herald":21,"Gungir's Bite":23,"Twilight Waltz":24,"Godsfall":25}} -------------------------------------------------------------------------------- /lib/setting_migration.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const DefaultSettings = { 4 | _version: 19, 5 | Mode: 0, 6 | StreamMode: false, 7 | OnlyParty: false, 8 | RaidAutoChange: false, 9 | GuardianAutoChange: false, 10 | ShowStyle: false, 11 | ActionScripts: false, 12 | PvpTraps: false, 13 | Hit_Me: false, 14 | Hit_Other: false, 15 | Hit_Damage: false, 16 | Hit_All: false, 17 | HideFireworks: true, 18 | HideServantBalloons: false, 19 | Hideguildlogos: false, 20 | HideMonsterDeathAnimation: false, 21 | HideHpNumbers: false, 22 | HideMpNumbers: false, 23 | HideMySummons: false, 24 | HideOthersSummons: false, 25 | HideMyServants: false, 26 | HideOthersServants: false, 27 | MuteOthersVoice: false, 28 | HideAllAbnormalities: false, 29 | HideAllProjectiles: false, 30 | HideOwnBlacklistedAbns: false, 31 | HideBlacklistedAbnormalities: false, 32 | HideBlacklistedProjectiles: false, 33 | HideBlacklistedNpcs: false, 34 | HideBlacklistedSkills: false, 35 | HideBlacklistedDrop: false, 36 | OwnAbnormalsBlacklist: [4850, 48732, 48733, 48734, 48735, 48736, 48737, 48738, 48739, 70251, 70252, 70253, 70254, 70255, 70256, 776021, 905434, 47660800, 47660900, 47661000, 47662300, 99006000, 99007200, 999001011], 37 | AbnormalitiesBlacklist: [], 38 | ProjectilesBlacklist: [270120, 270220, 270320, 270420, 270520, 270620, 270720, 270820, 270920, 271020], 39 | PlayersBlacklist: [], 40 | ClassesBlacklist: [], 41 | RolesBlacklist: [], 42 | NpcsBlacklist: [], 43 | DropBlacklist: [8000, 8001, 8002, 8005, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 8020, 8021, 8022, 8023], 44 | ClassesData: { 45 | 1: { name: "warrior", model: 1, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false }, 46 | 2: { name: "lancer", model: 2, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["tank"], isHidden: false }, 47 | 3: { name: "slayer", model: 3, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false }, 48 | 4: { name: "berserker", model: 4, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false }, 49 | 5: { name: "sorcerer", model: 5, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps", "ranged"], isHidden: false }, 50 | 6: { name: "archer", model: 6, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps", "ranged"], isHidden: false }, 51 | 7: { name: "priest", model: 7, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["healer"], isHidden: false }, 52 | 8: { name: "mystic", model: 8, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["healer"], isHidden: false }, 53 | 9: { name: "reaper", model: 9, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false }, 54 | 10: { name: "gunner", model: 10, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps", "ranged"], isHidden: false }, 55 | 11: { name: "brawler", model: 11, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["tank"], isHidden: false }, 56 | 12: { name: "ninja", model: 12, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false }, 57 | 13: { name: "valkyrie", model: 13, CD_SkillsBlacklist: [], CD_HideBlacklistedSkills: false, role: ["dps"], isHidden: false } 58 | } 59 | }; 60 | 61 | function MigrateSettings(from_ver, to_ver, settings) { 62 | if (from_ver === undefined) return Object.assign(Object.assign({}, DefaultSettings), settings); 63 | else if (from_ver === null) return DefaultSettings; 64 | else { 65 | if (from_ver + 1 < to_ver) { 66 | settings = MigrateSettings(from_ver, from_ver + 1, settings); 67 | return MigrateSettings(from_ver + 1, to_ver, settings); 68 | } 69 | 70 | switch (to_ver) { 71 | case 3: 72 | settings._version = 3; 73 | settings.HideBlacklistedAbnormalities = DefaultSettings.HideBlacklistedAbnormalities; 74 | settings.HideBlacklistedProjectiles = DefaultSettings.HideBlacklistedProjectiles; 75 | break; 76 | case 4: 77 | settings._version = 4; 78 | delete settings.NoZoomingToNpc; 79 | settings.ActionScripts = DefaultSettings.ActionScripts; 80 | settings.HideMonsterDeathAnimation = DefaultSettings.HideMonsterDeathAnimation; 81 | break; 82 | case 5: 83 | settings._version = 5; 84 | settings.HideOwnBlacklistedAbns = DefaultSettings.HideOwnBlacklistedAbns; 85 | settings.OwnAbnormalsBlacklist = DefaultSettings.OwnAbnormalsBlacklist; 86 | break; 87 | case 6: 88 | settings._version = 6; 89 | settings.OwnAbnormalsBlacklist = DefaultSettings.OwnAbnormalsBlacklist; 90 | settings.AbnormalitiesBlacklist = DefaultSettings.AbnormalitiesBlacklist; 91 | break; 92 | case 7: 93 | settings._version = 7; 94 | settings.AbnormalitiesBlacklist = DefaultSettings.AbnormalitiesBlacklist; 95 | settings.Fishing = DefaultSettings.Fishing; 96 | break; 97 | case 8: 98 | settings._version = 8; 99 | delete settings.ProjDebug; 100 | delete settings.AbnDebug; 101 | settings.PvpTraps = DefaultSettings.PvpTraps; 102 | break; 103 | case 9: 104 | settings._version = 9; 105 | settings.Hit_All = DefaultSettings.Hit_All; 106 | break; 107 | case 10: 108 | settings._version = 10; 109 | settings.HideHpMpNumbers = DefaultSettings.HideHpMpNumbers; 110 | break; 111 | case 11: 112 | settings._version = 11; 113 | delete settings.Fishing; 114 | settings.HideHpNumbers = DefaultSettings.HideHpNumbers; 115 | settings.HideMpNumbers = settings.HideHpMpNumbers; 116 | delete settings.HideHpMpNumbers; 117 | break; 118 | case 12: 119 | settings._version = 12; 120 | settings.AbnormalitiesBlacklist = DefaultSettings.AbnormalitiesBlacklist; 121 | break; 122 | case 13: 123 | settings._version = 13; 124 | settings.AbnormalitiesBlacklist = DefaultSettings.AbnormalitiesBlacklist; 125 | break; 126 | case 14: 127 | settings._version = 14; 128 | settings.AbnormalitiesBlacklist = []; 129 | break; 130 | case 15: 131 | settings._version = 15; 132 | settings.HideMyServants = DefaultSettings.HideMyServants; 133 | settings.HideOthersServants = DefaultSettings.HideOthersServants; 134 | break; 135 | case 16: 136 | settings._version = 16; 137 | delete settings.ClassesNames; 138 | delete settings.RolesNames; 139 | break; 140 | case 17: 141 | settings._version = 17; 142 | settings.StreamMode = DefaultSettings.StreamMode; 143 | settings.GuardianAutoChange = DefaultSettings.GuardianAutoChange; 144 | break; 145 | case 18: 146 | settings._version = 18; 147 | settings.MuteOthersVoice = DefaultSettings.MuteOthersVoice; 148 | break; 149 | case 19: 150 | settings._version = 19; 151 | settings.HideServantBalloons = DefaultSettings.HideServantBalloons; 152 | break; 153 | default: 154 | console.log(`\x1b[94mINFO\x1b[34m [FPS-UTILS]\x1b[39m - Your \x1b[31 ["config.json" (caali's Toolbox) OR "settings/fps-utils.json" (pinkie's Proxy)]\x1b[39m seems to be outdated.\x1b[32m Re-created new one.\x1b[39m\x1b[0m`); 155 | Object.keys(settings).forEach(key => delete settings[key]); 156 | settings = JSON.parse(JSON.stringify(DefaultSettings)); 157 | break; 158 | } 159 | return settings; 160 | } 161 | } 162 | 163 | module.exports = MigrateSettings; -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // ~~~ * Data * ~~~ \\ 4 | 5 | const NpcData = require('./data/npcData.json'), 6 | SkillData = require('./data/skillString.json'), 7 | { ImportantAbns, BlockedAbns, ReplaceAbnIds, AbnNoEffectInvisibleNpcSpamId } = require('./data/abnormalities.json'), 8 | { UserNpcs, TrapsIds, FireWorks, UserNpcsHzId, SmokeBombId, DivineWrathId, MoteIds } = require('./data/userSpawns.json'), 9 | ImportantProjectiles = { ...SmokeBombId, ...DivineWrathId }, 10 | { InvisibleNpcs, SpamAchIds, PClasses, PRoles, HexColors, Alphabet, StarterWeaponIds, InvalidVoiceId, MountToReplaceId, ImportantActionScripts } = require('./data/miscData.json'), 11 | { BnzC, SlvC, GldC, PnkC, HPkC, CPkC, RedC, GrnC, LPrC, PrpC, LBlC, BluC, DBlC, HBlC, GryC, YlwC } = HexColors; 12 | 13 | const LastHook = { order: 100010 }, 14 | LastHookfn = { order: 100010, filter: { fake: null, silenced: false, modified: null } }; 15 | 16 | module.exports = function FpsUtils(mod) { 17 | 18 | // ~~~ * Constants * ~~~ \\ 19 | 20 | const Cfg = mod.settings, 21 | Cmd = mod.command, 22 | NotCP = typeof mod.compileProto !== 'undefined'; 23 | 24 | // ~~~ * Variables * ~~~ \\ 25 | 26 | let MyName = '', 27 | MyGameId = -1n, 28 | AllowedAchUps = 0, 29 | LastVrange = 0, 30 | LastFState = null, 31 | LastGState = null, 32 | SwitchCd = false, 33 | ProjDebug = false, 34 | AbnDebug = false, 35 | TmpData = [], 36 | PMembers = new Set(), 37 | BProjectiles = new Set(), 38 | SUsers = {}, 39 | HUsers = {}, 40 | SNpcs = {}, 41 | HNpcs = {}, 42 | SPets = {}, 43 | HPets = {}, 44 | HSeedBoxes = new Set(); 45 | 46 | // ~~~ * Gui Parser * ~~~ \\ 47 | 48 | const Xmap = new WeakMap(); 49 | 50 | if (!Xmap.has(mod.dispatch || mod)) { 51 | Xmap.set(mod.dispatch || mod, {}); 52 | 53 | mod.hook('C_CONFIRM_UPDATE_NOTIFICATION', 'raw', LastHook, () => false); 54 | 55 | mod.hook('C_ADMIN', 1, LastHookfn, (event) => { 56 | const commands = event.command.split(";"); 57 | for (const cmd of commands) 58 | try { Cmd.exec(cmd); } catch (err) { continue; } 59 | return false; 60 | }); 61 | } 62 | 63 | const gui = { 64 | parse(Xarray, title, body = '') { 65 | for (const data of Xarray) { 66 | if (body.length >= 16E3) { 67 | body += 'Gui data limit exceeded, some values may be missing.'; 68 | break; 69 | } 70 | if (data.command) body += `${data.text}`; 71 | else if (!data.command) body += `${data.text}`; 72 | else continue; 73 | } 74 | mod.toClient('S_ANNOUNCE_UPDATE_NOTIFICATION', 1, { id: 0, title, body }); 75 | } 76 | }; 77 | 78 | // ~~~ * Gui Handler * ~~~ \\ 79 | 80 | function GuiHandler(page, arg) { 81 | switch (page) { 82 | case "searchnpc": case "npcsearch": 83 | NpcJsonSearch("search", arg); 84 | break; 85 | case "npc": 86 | NpcJsonSearch("starts", arg); 87 | break; 88 | case "npclist": 89 | TmpData.push( 90 | { text: `

MAIN MENU



`, command: "fps gui" }, 91 | { text: `

[Main NPC page]


`, command: "fps gui npcmain" }, 92 | { text: `Click a NPC ID to remove it from the blacklist:
` } 93 | ); 94 | for (const blNpc of Cfg.NpcsBlacklist) TmpData.push({ text: `${blNpc.zone}, ${blNpc.templateId}
`, command: `fps npc hide ${blNpc.zone} ${blNpc.templateId};fps gui npclist` }); 95 | gui.parse(TmpData, `[FPS] Options - NPCs (Blacklist)`); 96 | break; 97 | case "npcmain": 98 | TmpData.push( 99 | { text: `

MAIN MENU



`, command: "fps gui" }, 100 | { text: `

[Blacklisted NPCs list]


`, command: "fps gui npclist" }, 101 | { text: `Click a letter to view all NPCs starting with that letter:

` } 102 | ); 103 | for (const i of Alphabet.split('')) TmpData.push({ text: `${i}`, command: `fps gui npc ${i}` }, { text: "  " }); 104 | TmpData.push( 105 | { text: `

(Command "fps gui searchnpc <name>" to search for a specific NPCs names, Case sensitive)` }, 106 | { text: `

(Command "fps gui npc <letters>" to search for NPCs names that starts with that 'letters', Case sensitive)` }, 107 | { text: `

If you want to search for npc with space between it's name, you've to add the whole name inside quotations, e.g. fps gui npcsearch "Bay Kamara"\`` } 108 | ); 109 | gui.parse(TmpData, `[FPS] Options - NPCs (Main)`); 110 | break; 111 | case "show": 112 | TmpData.push( 113 | { text: `

MAIN MENU


`, command: "fps gui" }, 114 | { text: `

[Refresh]


`, command: "fps gui show" }, 115 | { text: `Red = Shown, Green = Hidden
` }, 116 | { text: `(Command "fps hide <name>" to hide someone that does not appear here)

` }, 117 | { text: `Click on Red to hide & add to blacklist.
Click on Green to show & remove from blacklist

` } 118 | ); 119 | for (const sUser in SUsers) TmpData.push({ text: `${SUsers[sUser].name}
`, command: Cfg.PlayersBlacklist.indexOf(SUsers[sUser].name.toLowerCase()) !== -1 ? `fps show ${SUsers[sUser].name};fps gui show` : `fps hide ${SUsers[sUser].name};fps gui show` }); 120 | gui.parse(TmpData, `[FPS] Options - Players (In-distance)`); 121 | break; 122 | case "hide": 123 | TmpData.push( 124 | { text: `

MAIN MENU



`, command: "fps gui" }, 125 | { text: `Click to show & remove from blacklist.
` } 126 | ); 127 | Cfg.PlayersBlacklist.forEach(el => TmpData.push({ text: `${el}
`, command: `fps show ${el};fps gui hide` })); 128 | gui.parse(TmpData, `[FPS] Options - Players (Hidden)`); 129 | break; 130 | case "skills": 131 | gui.parse([ 132 | { text: `

MAIN MENU


`, command: "fps gui" }, 133 | { text: `Tankers:` }, { text: " " }, 134 | { text: `(Lancer)`, command: "fps gui class lancer" }, { text: "  " }, 135 | { text: `(Brawler)

`, command: "fps gui class brawler" }, 136 | { text: `Healers:` }, { text: " " }, 137 | { text: `(Priest)`, command: "fps gui class priest" }, { text: "  " }, 138 | { text: `(Mystic)

`, command: "fps gui class mystic" }, 139 | { text: `Dpsers(melee):` }, { text: " " }, 140 | { text: `(Warrior)`, command: "fps gui class warrior" }, { text: "  " }, 141 | { text: `(Slayer)`, command: "fps gui class slayer" }, { text: "  " }, 142 | { text: `(Berserker)`, command: "fps gui class berserker" }, { text: "  " }, 143 | { text: `(Ninja)`, command: "fps gui class ninja" }, { text: "  " }, 144 | { text: `(Valkyrie)`, command: "fps gui class valkyrie" }, { text: "  " }, 145 | { text: `(Reaper)

`, command: "fps gui class reaper" }, 146 | { text: `Dpsers(ranged):` }, { text: " " }, 147 | { text: `(Sorcerer)`, command: "fps gui class sorcerer" }, { text: "  " }, 148 | { text: `(Archer)`, command: "fps gui class archer" }, { text: "  " }, 149 | { text: `(Gunner)`, command: "fps gui class gunner" } 150 | ], `[FPS] Options - Skills (Choose class)`); 151 | break; 152 | case "class": 153 | gui.parse(SkillJsonSearch(arg), `[FPS] Options - Skill list for '${arg}'`); 154 | break; 155 | case "role": 156 | gui.parse([ 157 | { text: `

MAIN MENU



`, command: "fps gui" }, 158 | { text: `By Roles:` }, { text: " " }, 159 | { text: `[Tankers]`, command: `fps ${Cfg.RolesBlacklist.includes('tank') ? "show" : "hide"} tank;fps gui role` }, { text: "  " }, 160 | { text: `[Healers]`, command: `fps ${Cfg.RolesBlacklist.includes('healer') ? "show" : "hide"} healer;fps gui role` }, { text: "  " }, 161 | { text: `[Dps-All]`, command: `fps ${Cfg.RolesBlacklist.includes('dps') ? "show" : "hide"} dps;fps gui role` }, { text: "  " }, 162 | { text: `[Dps-Ranged]



`, command: `fps ${Cfg.RolesBlacklist.includes('ranged') ? "show" : "hide"} ranged;fps gui role` }, 163 | { text: `By Classes

` }, 164 | { text: `Tankers:` }, { text: " " }, 165 | { text: `[Lancer]`, command: `fps ${Cfg.ClassesBlacklist.includes('lancer') ? "show" : "hide"} lancer;fps gui role` }, { text: "  " }, 166 | { text: `[Brawler]

`, command: `fps ${Cfg.ClassesBlacklist.includes('brawler') ? "show" : "hide"} brawler;fps gui role` }, 167 | { text: `Healers:` }, { text: " " }, 168 | { text: `[Priest]`, command: `fps ${Cfg.ClassesBlacklist.includes('priest') ? "show" : "hide"} priest;fps gui role` }, { text: "  " }, 169 | { text: `[Mystic]

`, command: `fps ${Cfg.ClassesBlacklist.includes('mystic') ? "show" : "hide"} mystic;fps gui role` }, 170 | { text: `Dpsers(melee):` }, { text: " " }, 171 | { text: `[Warrior]`, command: `fps ${Cfg.ClassesBlacklist.includes('warrior') ? "show" : "hide"} warrior;fps gui role` }, { text: "  " }, 172 | { text: `[Slayer]`, command: `fps ${Cfg.ClassesBlacklist.includes('slayer') ? "show" : "hide"} slayer;fps gui role` }, { text: "  " }, 173 | { text: `[Berserker]`, command: `fps ${Cfg.ClassesBlacklist.includes('berserker') ? "show" : "hide"} berserker;fps gui role` }, { text: "  " }, 174 | { text: `[Ninja]`, command: `fps ${Cfg.ClassesBlacklist.includes('ninja') ? "show" : "hide"} ninja;fps gui role` }, { text: "  " }, 175 | { text: `[Valkyrie]`, command: `fps ${Cfg.ClassesBlacklist.includes('valkyrie') ? "show" : "hide"} valkyrie;fps gui role` }, { text: "  " }, 176 | { text: `[Reaper]

`, command: `fps ${Cfg.ClassesBlacklist.includes('reaper') ? "show" : "hide"} reaper;fps gui role` }, 177 | { text: `Dpsers(ranged):` }, { text: " " }, 178 | { text: `[Sorcerer]`, command: `fps ${Cfg.ClassesBlacklist.includes('sorcerer') ? "show" : "hide"} sorcerer;fps gui role` }, { text: "  " }, 179 | { text: `[Archer]`, command: `fps ${Cfg.ClassesBlacklist.includes('archer') ? "show" : "hide"} archer;fps gui role` }, { text: "  " }, 180 | { text: `[Gunner]`, command: `fps ${Cfg.ClassesBlacklist.includes('gunner') ? "show" : "hide"} gunner;fps gui role` } 181 | ], `[FPS] Options - Roles/Classes`); 182 | break; 183 | case "abn": 184 | TmpData.push( 185 | { text: `

MAIN MENU


`, command: "fps gui" }, 186 | { text: `

Debug


`, command: "fps abn log;fps gui abn" }, 187 | { text: `Blacklist: Click to remove from the blacklist.
` } 188 | ); 189 | Cfg.AbnormalitiesBlacklist.forEach(el => TmpData.push({ text: `${el}
`, command: `fps abn blacklist remv ${el};fps gui abn` })); 190 | gui.parse(TmpData, `[FPS] Options - Abnormalities`); 191 | break; 192 | case "proj": 193 | TmpData.push( 194 | { text: `

MAIN MENU


`, command: "fps gui" }, 195 | { text: `

Debug


`, command: "fps proj log;fps gui proj" }, 196 | { text: `Blacklist: Click to remove from the blacklist.
` } 197 | ); 198 | Cfg.ProjectilesBlacklist.forEach(el => TmpData.push({ text: `${el}
`, command: `fps proj blacklist remv ${el};fps gui proj` })); 199 | gui.parse(TmpData, `[FPS] Options - Projectiles`); 200 | break; 201 | case "help": 202 | gui.parse([ 203 | { text: `

MAIN MENU


`, command: "fps gui" }, 204 | { text: `Command Arg(s) Example
` }, 205 | { text: `gui ^ g N/A !fps gui
` }, 206 | { text: ` N/A N/A !fps-util
` }, 207 | { text: `0 ^ 1 ^ 2 ^ 3 N/A !0 ^ !1 ^ !2 ^ !3
` }, 208 | { text: `mode 0 ^ 1 ^ 2 ^ 3 !fps mode 2
` }, 209 | { text: `hide^show Player^Class^Role !fps hide mie
` }, 210 | { text: `party N/A !fps party
` }, 211 | { text: `raid N/A !fps raid
` }, 212 | { text: `list N/A !fps list
` }, 213 | { text: `sums other ^ me !fps sums me
` }, 214 | { text: `skill blacklist !fps skill blacklist
` }, 215 | { text: `npc N/A ^ hide !fps npc
` }, 216 | { text: `hit me^other^damage !fps hit me
` }, 217 | { text: `firework N/A !fps firework
` }, 218 | { text: `abn all ^ blacklist !fps abn blacklist
` }, 219 | { text: `proj all ^ blacklist !fps proj all
` }, 220 | { text: `guildlogo N/A !fps guildlogo
` }, 221 | { text: `style N/A !fps style
` }, 222 | { text: `gui npcsearch "target" !fps gui npcsearch E
` }, 223 | { text: `npczoom N/A !fps npczoom
` }, 224 | { text: `dropitem N/A ^ hide !fps dropitem
` }, 225 | { text: `monsterdeathani N/A !fps monsterdeathani
` }, 226 | { text: `screenabns N/A ^ hide !fps screenabns
` }, 227 | { text: `hpnumbers N/A !fps hpnumbers
` }, 228 | { text: `mpnumbers N/A !fps mpnumbers
` }, 229 | { text: `pet N/A !fps raid
` }, 230 | { text: `guardian N/A !fps guardian
` }, 231 | { text: `muteothers N/A !fps muteothers
` }, 232 | { text: `stream N/A !fps stream

` }, 233 | ], `[FPS] HELP`); 234 | break; 235 | default: 236 | gui.parse([ 237 | { text: `

REFRESH


`, command: "fps gui" }, 238 | { text: `Modes:` }, { text: " " }, 239 | { text: `[Mode 0]`, command: "fps mode 0;fps gui" }, { text: "    " }, 240 | { text: `[Mode 1]`, command: "fps mode 1;fps gui" }, { text: "    " }, 241 | { text: `[Mode 2]`, command: "fps mode 2;fps gui" }, { text: "    " }, 242 | { text: `[Mode 3]

`, command: "fps mode 3;fps gui" }, 243 | { text: `Hit:` }, { text: " " }, 244 | { text: `[Players]`, command: "fps hit other;fps gui" }, { text: "  " }, 245 | { text: `[Own]`, command: "fps hit me;fps gui" }, { text: "  " }, 246 | { text: `[Dmg/heal numbers]`, command: "fps hit damage;fps gui" }, { text: "  " }, 247 | { text: `[ALL]

`, command: "fps hit all;fps gui" }, 248 | { text: `Hide:` }, { text: " " }, 249 | { text: `[Classes/Roles]`, command: "fps gui role" }, { text: "   " }, 250 | { text: `[Style]`, command: "fps style;fps gui" }, { text: "  " }, 251 | { text: `[Guild Logos]`, command: "fps guildlogo;fps gui" }, { text: "  " }, 252 | { text: `[Firework]`, command: "fps fireworks;fps gui" }, { text: "  " }, 253 | { text: `[Pets Popup]

`, command: "fps petspopup;fps gui" }, 254 | { text: `Self(own):` }, { text: " " }, 255 | { text: `[HP Nums]`, command: "fps hpnumbers;fps gui" }, { text: "   " }, 256 | { text: `[MP Nums]`, command: "fps mpnumbers;fps gui" }, { text: "   " }, 257 | { text: `[Own summons]`, command: "fps summons me;fps gui" }, { text: "   " }, 258 | { text: `[Pets]`, command: "fps pet me;fps gui" }, { text: "   " }, 259 | { text: `[Blur/dizzy]
`, command: "fps screenabns;fps gui" }, 260 | { text: `Players:` }, { text: " " }, 261 | { text: `[Spawned list]`, command: "fps gui show" }, { text: "    " }, 262 | { text: `[Hidden list]`, command: "fps gui hide" }, { text: "    " }, 263 | { text: `[Players summons]`, command: "fps summons;fps gui" }, { text: "   " }, 264 | { text: `[Pets]
`, command: "fps pet;fps gui" }, 265 | { text: `NPCs:` }, { text: " " }, 266 | { text: `[Menu]`, command: "fps gui npcmain" }, { text: "  " }, 267 | { text: `[Hide Death Ani]`, command: "fps monsterdeathani;fps gui" }, { text: "  " }, 268 | { text: `[Zoom-ins]`, command: "fps npczoom;fps gui" }, { text: "  " }, 269 | { text: `[Hide Blacklisted]

`, command: "fps npc;fps gui" }, 270 | { text: `Skills:` }, { text: " " }, 271 | { text: `[Hide individually]`, command: "fps gui skills" }, { text: "   " }, 272 | { text: `[Hide Blacklisted]
`, command: "fps skill blacklist;fps gui" }, 273 | { text: `Abnormal:` }, { text: " " }, 274 | { text: `[Hide ALL]`, command: "fps abn all;fps gui" }, { text: "   " }, 275 | { text: `[Hide Blacklisted]`, command: "fps abn blacklist;fps gui" }, { text: "   " }, 276 | { text: `[Black List]
`, command: "fps gui abn" }, 277 | { text: `Projectile:` }, { text: " " }, 278 | { text: `[Hide ALL]`, command: "fps proj all;fps gui" }, { text: "   " }, 279 | { text: `[Hide Blacklisted]`, command: "fps proj blacklist;fps gui" }, { text: "   " }, 280 | { text: `[Black List]

`, command: "fps gui proj" }, 281 | { text: `Misc.` }, { text: " " }, 282 | { text: `[Raid auto state]`, command: "fps raid;fps gui" }, { text: "  " }, 283 | { text: `[Only Party]`, command: "fps party;fps gui" }, { text: "  " }, 284 | { text: `[Drops BList]`, command: "fps dropitem;fps gui" }, { text: "  " }, 285 | { text: `[Show Traps]
`, command: "fps pvptraps;fps gui" }, { text: " " }, 286 | { text: `[Guardian auto state]`, command: "fps guardian;fps gui" }, { text: "  " }, 287 | { text: `[Mute others voice]`, command: "fps muteothers;fps gui" }, { text: "  " }, 288 | { text: `[Stream]

`, command: "fps stream;fps gui" }, 289 | { text: `Quick Links:
` }, 290 | { text: `UI:` }, { text: " " }, 291 | { text: `[Mail]`, command: "fps quicklink parcel" }, { text: "   " }, 292 | { text: `[Broker]`, command: "fps quicklink broker" }, { text: "    " }, 293 | { text: `[Talent]`, command: "fps quicklink talents" }, { text: "    " }, 294 | { text: `[Dress]`, command: "fps quicklink dressingroom" }, { text: "   " }, 295 | { text: `[Hat Style]
`, command: "fps quicklink hatrestyle" }, 296 | { text: `Party:` }, { text: " " }, 297 | { text: `[Reset]`, command: "fps quicklink reset" }, { text: "    " }, 298 | { text: `[Leave]`, command: "fps quicklink drop" }, { text: "    " }, 299 | { text: `[Disband]
`, command: "fps quicklink disband" }, 300 | { text: `System:` }, { text: " " }, 301 | { text: `[Character Selection]`, command: "fps quicklink lobby" }, { text: " " }, 302 | { text: `[! Instant Exit !]
`, command: "fps quicklink instantexit" } 303 | ], `[FPS] Options | Red = disabled, Green = enabled`); 304 | break; 305 | } 306 | TmpData = []; 307 | } 308 | 309 | // ~~~ * Gui Functions * ~~~ \\ 310 | 311 | function SkillJsonSearch(value) { 312 | let keys = [], 313 | skilldata = [], 314 | skillIds = []; 315 | skilldata.push( 316 | { text: `

MAIN MENU


`, command: "fps gui" }, 317 | { text: `

[Blacklisted skills are ${Cfg.HideBlacklistedSkills ? 'Hidden' : 'Shown'}]


`, command: `fps skill blacklist;fps gui class ${value}` }, 318 | { text: `Click skill to blacklist it.
` } 319 | ); 320 | for (const key in SkillData[value]) keys.push(key); 321 | skillIds.push(Object.values(SkillData[value])); 322 | for (let i = 0; i < keys.length; i++) 323 | skilldata.push({ command: `fps skill class ${value} ${skillIds[0][i]};fps gui class ${value}`, text: `[${keys[i]}]
` }); 324 | return skilldata; 325 | } 326 | 327 | function NpcJsonSearch(type, arg) { 328 | TmpData.push({ text: `

MAIN MENU



`, command: "fps gui" }); 329 | for (const data of NpcData) 330 | if (type === 'starts' && data.Nm.startsWith(arg) || type === 'search' && data.Nm.includes(arg)) 331 | TmpData.push({ command: `fps npc hide ${data.Hz} ${data.Ti};fps gui ${type === 'starts' ? 'npc' : 'npcsearch'} ${arg}`, text: `${data.Nm}
` }); 332 | gui.parse(TmpData, `[FPS] Options - NPCs | Search results for '${arg}'.`); 333 | TmpData = []; 334 | } 335 | 336 | function ClassNameFromID(name) { 337 | for (const cData of Object.keys(Cfg.ClassesData)) if (Cfg.ClassesData[cData].name === name) return cData; 338 | } 339 | 340 | // ~~~ * Command Functions * ~~~ \\ 341 | 342 | function Msg(msg) { 343 | if (Cfg.StreamMode) return; 344 | Cmd.message(`${NotCP ? '[FPS] ' : ''}${msg}`); 345 | } 346 | 347 | function RemoveEntity(arr, elem) { 348 | if (elem.length) 349 | for (const [index, value] of arr.entries()) 350 | if (value.toLowerCase() === elem.toLowerCase()) arr.splice(index, 1); 351 | return arr; 352 | } 353 | 354 | function ScaleUpEntity(gameId, scale) { 355 | mod.toClient('S_ABNORMALITY_SCALE_UP', 2, { gameId, scale, duration: 0 }); 356 | } 357 | 358 | function HideSpecificPlayerByName(name) { 359 | for (const sUser in SUsers) { 360 | if (SUsers[sUser].name.toString().toLowerCase() === name.toLowerCase()) { 361 | mod.toClient('S_DESPAWN_USER', 3, { gameId: SUsers[sUser].gameId, type: 1 }); 362 | HUsers[SUsers[sUser].gameId] = SUsers[sUser]; 363 | break; 364 | } 365 | } 366 | } 367 | 368 | function HideSpecificNpcByHzTi(hz, ti) { 369 | for (const sNpc in SNpcs) { 370 | if (SNpcs[sNpc].huntingZoneId === hz && SNpcs[sNpc].templateId === ti) { 371 | mod.toClient('S_DESPAWN_NPC', 3, { gameId: SNpcs[sNpc].gameId, loc: SNpcs[sNpc].loc, type: 1, unk: 0 }); 372 | HNpcs[SNpcs[sNpc].gameId] = SNpcs[sNpc]; 373 | HNpcs[SNpcs[sNpc].gameId].spawnType = 1; 374 | HNpcs[SNpcs[sNpc].gameId].spawnScript = 0; 375 | break; 376 | } 377 | } 378 | } 379 | 380 | function HideSpecificNpcByGid(gameId) { 381 | mod.toClient('S_DESPAWN_NPC', 3, { gameId, loc: SNpcs[gameId].loc, type: 1, unk: 0 }); 382 | HNpcs[gameId] = SNpcs[gameId]; 383 | HNpcs[gameId].spawnType = 1; 384 | HNpcs[gameId].spawnScript = 0; 385 | } 386 | 387 | function HideNpcs(type, whose) { 388 | switch (type) { 389 | case 'own': 390 | case 'others': 391 | for (const sNpc in SNpcs) 392 | if ((type === 'own' && EqGid(SNpcs[sNpc].owner) || type === 'others' && !EqGid(SNpcs[sNpc].owner)) && UserNpcs.includes(SNpcs[sNpc].templateId) && SNpcs[sNpc].huntingZoneId === UserNpcsHzId) HideSpecificNpcByGid(SNpcs[sNpc].gameId); 393 | break; 394 | case 'bl': 395 | for (const sNpc in SNpcs) 396 | for (const blNpc of Cfg.NpcsBlacklist) 397 | if (SNpcs[sNpc].huntingZoneId === Number(blNpc.zone) && SNpcs[sNpc].templateId === Number(blNpc.templateId)) HideSpecificNpcByGid(SNpcs[sNpc].gameId); 398 | break; 399 | case 'pet': 400 | for (const sPet in SPets) { 401 | if (EqGid(SPets[sPet].ownerId) && whose === 'own') { 402 | UpdateNpcLoc(SPets[sPet], -1E2); 403 | ScaleUpEntity(SPets[sPet].gameId, 1E-3); 404 | } 405 | if (!EqGid(SPets[sPet].ownerId) && whose === 'others') 406 | mod.toClient('S_REQUEST_DESPAWN_SERVANT', 1, { gameId: SPets[sPet].gameId, despawnType: 1 }); 407 | HPets[SPets[sPet].gameId] = SPets[sPet]; 408 | } 409 | break; 410 | default: break; 411 | } 412 | } 413 | 414 | function HideAllPlayers() { 415 | if (Cfg.OnlyParty) return undefined; 416 | for (const sUser in SUsers) { 417 | mod.toClient('S_DESPAWN_USER', 3, { gameId: SUsers[sUser].gameId, type: 1 }); 418 | HUsers[SUsers[sUser].gameId] = SUsers[sUser]; 419 | HUsers[SUsers[sUser].gameId].spawnFx = 1; 420 | } 421 | } 422 | 423 | function ShowSpecificPlayerByName(name) { 424 | for (const hUser in HUsers) { 425 | if (HUsers[hUser].name.toString().toLowerCase() === name.toLowerCase()) { 426 | ModifyUserAppearance(HUsers[hUser]); 427 | mod.toClient('S_SPAWN_USER', 17, HUsers[hUser]); 428 | delete HUsers[hUser]; 429 | break; 430 | } 431 | } 432 | } 433 | 434 | function ShowSpecificNpcByHzTi(hz, ti) { 435 | for (const hNpc in HNpcs) { 436 | if (HNpcs[hNpc].huntingZoneId === hz && HNpcs[hNpc].templateId === ti) { 437 | mod.toClient('S_SPAWN_NPC', 12, HNpcs[hNpc]); 438 | delete HNpcs[hNpc]; 439 | break; 440 | } 441 | } 442 | } 443 | 444 | function ShowSpecificNpcByGid(gameId) { 445 | mod.toClient('S_SPAWN_NPC', 12, HNpcs[gameId]); 446 | delete HNpcs[gameId]; 447 | } 448 | 449 | function ShowNpcs(type, whose) { 450 | switch (type) { 451 | case 'own': 452 | case 'others': 453 | for (const hNpc in HNpcs) 454 | if (type === 'own' && EqGid(HNpcs[hNpc].owner || type === 'others' && !EqGid(HNpcs[hNpc].owner)) && UserNpcs.includes(HNpcs[hNpc].templateId) && HNpcs[hNpc].huntingZoneId === UserNpcsHzId) ShowSpecificNpcByGid(HNpcs[hNpc].gameId); 455 | break; 456 | case 'bl': 457 | for (const hNpc in HNpcs) 458 | for (const blNpc of Cfg.NpcsBlacklist) 459 | if (HNpcs[hNpc].huntingZoneId === Number(blNpc.zone) && HNpcs[hNpc].templateId === Number(blNpc.templateId)) ShowSpecificNpcByGid(HNpcs[hNpc].gameId); 460 | break; 461 | case 'pet': 462 | for (const hPet in HPets) { 463 | if (EqGid(HPets[hPet].ownerId) && whose === 'own') { 464 | UpdateNpcLoc(HPets[hPet]); 465 | ScaleUpEntity(HPets[hPet].gameId, 1); 466 | } 467 | else if (!EqGid(HPets[hPet].ownerId) && whose === 'others') 468 | mod.toClient('S_REQUEST_SPAWN_SERVANT', 4, HPets[hPet]); 469 | delete HPets[hPet]; 470 | } 471 | break; 472 | default: break; 473 | } 474 | } 475 | 476 | function ShowAllPlayers() { 477 | for (const hUser in HUsers) { 478 | ModifyUserAppearance(HUsers[hUser]); 479 | mod.toClient('S_SPAWN_USER', 17, HUsers[hUser]); 480 | delete HUsers[hUser]; 481 | } 482 | } 483 | 484 | // ~~~ * Core Functions * ~~~ \\ 485 | 486 | function ModifyUserAppearance(event) { 487 | let modified = undefined; 488 | 489 | if (Cfg.ShowStyle) { 490 | event.weapon = StarterWeaponIds[event.templateId % 1E2 - 1]; 491 | event.body = event.hand = event.feet = event.underwear = event.head = event.face = 0; 492 | if (event.mount) event.mount = MountToReplaceId; 493 | event.title = 0; 494 | event.weaponDye = event.bodyDye = event.handDye = event.feetDye = event.weaponEnchant = 0; 495 | event.showFace = false; 496 | event.styleHead = event.styleFace = event.styleBack = event.styleWeapon = event.styleBody = 0; 497 | event.underwearDye = event.styleBackDye = event.styleHeadDye = event.styleFaceDye = 0; 498 | event.showStyle = false; 499 | event.styleFootprint = event.styleHeadScale = event.styleFaceScale = event.styleBackScale = 0; 500 | event.usedStyleHeadTransform = false; 501 | event.styleBodyDye = 0; 502 | event.icons = []; 503 | 504 | modified = true; 505 | } 506 | 507 | if (Cfg.Hideguildlogos) { 508 | event.guildLogo = ''; 509 | event.guildLogoId = 0; 510 | 511 | modified = true; 512 | } 513 | 514 | if (Cfg.MuteOthersVoice) { 515 | event.appearance.voice = InvalidVoiceId; 516 | 517 | modified = true; 518 | } 519 | 520 | return modified; 521 | } 522 | 523 | function ModifyAbnormalities(event, end) { 524 | if (ImportantAbns.indexOf(event.id) !== -1) return undefined; 525 | 526 | if (ReplaceAbnIds[event.id]) { 527 | event.id = ReplaceAbnIds[event.id]; 528 | 529 | return true; 530 | } 531 | 532 | if (!end) { 533 | if (typeof event.target === 'undefined') event.target = event.gameId 534 | 535 | if (EqGid(event.target)) { 536 | if (Cfg.HideOwnBlacklistedAbns && Cfg.OwnAbnormalsBlacklist.indexOf(event.id) !== -1) return false; 537 | 538 | return undefined; 539 | } 540 | 541 | if (HUsers[event.target] || HNpcs[event.target] || event.id === AbnNoEffectInvisibleNpcSpamId) return false; 542 | if (Cfg.HideBlacklistedAbnormalities && (Cfg.AbnormalitiesBlacklist.indexOf(event.id) !== -1 || BlockedAbns.indexOf(event.id) !== -1)) return false; 543 | if (Cfg.HideAllAbnormalities && (SUsers[event.target] || Cfg.AbnormalitiesBlacklist.indexOf(event.id) !== -1 || BlockedAbns.indexOf(event.id) !== -1)) return false; 544 | } 545 | } 546 | 547 | function ActionHCheck(event, end) { 548 | if (event.skill.npc) return; 549 | let hidden = false; 550 | 551 | if (EqGid(event.gameId) || !SUsers[event.gameId]) return undefined; 552 | 553 | if (Cfg.Mode >= 2 || HUsers[event.gameId] || Cfg.ClassesData[ClassID(event.templateId)].CD_HideBlacklistedSkills) hidden = true; 554 | if (Cfg.HideBlacklistedSkills && Cfg.ClassesData[ClassID(event.templateId)].CD_SkillsBlacklist.includes(Math.floor(event.skill.id / 1E4).toString())) hidden = true; 555 | 556 | if (hidden) UpdateUserLoc(event); 557 | 558 | if (HNpcs[event.gameId]) { 559 | HNpcs[event.gameId].loc = event.loc; 560 | 561 | hidden = true; 562 | } 563 | 564 | if (BProjectiles.has(event.id) && (Cfg.Mode >= 2 || Cfg.HideAllProjectiles)) hidden = true; 565 | 566 | return !end && hidden ? false : undefined; 567 | } 568 | 569 | function ProjectileBCheck(event) { 570 | if (event.skill.npc) return; 571 | if (typeof event.id === 'undefined') event.id = event.actionId; 572 | 573 | if (typeof event.skill !== 'undefined') { 574 | if (ImportantProjectiles[ClassID(event.templateId)] && ImportantProjectiles[ClassID(event.templateId)] === Math.floor(event.skill.id / 1E4) || (Cfg.PvpTraps && TrapsIds.includes(event.skill.id))) return undefined; 575 | if ((Cfg.HideBlacklistedProjectiles || Cfg.HideAllProjectiles) && Cfg.ProjectilesBlacklist.includes(event.skill.id)) BProjectiles.add(event.id); 576 | } 577 | 578 | if (typeof event.gameId !== 'undefined') 579 | if (!EqGid(event.gameId) && SUsers[event.gameId] && (HUsers[event.gameId] || Cfg.Mode >= 2 || Cfg.HideAllProjectiles)) BProjectiles.add(event.id); 580 | 581 | return BProjectiles.has(event.id) ? false : undefined; 582 | } 583 | 584 | function ModifySkillResult(event) { 585 | if (event.skill.npc) return; 586 | let returnValue = undefined; 587 | 588 | if (Cfg.Hit_Me && (EqGid(event.source) || EqGid(event.owner))) { 589 | event.templateId = 0; 590 | event.skill.id = 0; 591 | event.time = event.type = event.noctEffect = 0; 592 | event.crit = event.stackExplode = event.superArmor = false; 593 | event.superArmorId = event.hitCylinderId = 0; 594 | 595 | returnValue = true; 596 | } 597 | 598 | if (Cfg.Hit_Other && !EqGid(event.target) && !EqGid(event.source) && !EqGid(event.owner) && (SUsers[event.owner] || SUsers[event.source])) { 599 | event.templateId = 0; 600 | event.skill.id = 0; 601 | event.time = event.type = event.noctEffect = 0; 602 | event.crit = event.stackExplode = event.superArmor = false; 603 | event.superArmorId = event.hitCylinderId = 0; 604 | 605 | returnValue = true; 606 | } 607 | 608 | if (Cfg.Hit_Damage && (EqGid(event.source) || EqGid(event.owner) || EqGid(event.target) || UserNpcs.includes(event.templateId) && event.skill.huntingZoneId === UserNpcsHzId)) { 609 | event.value = 0n; 610 | 611 | returnValue = true; 612 | } 613 | 614 | if (Cfg.Hit_All) { 615 | event.templateId = 0; 616 | event.skill.id = 0; 617 | event.time = event.type = event.noctEffect = 0; 618 | event.value = 0n; 619 | event.crit = event.stackExplode = event.superArmor = false; 620 | event.superArmorId = event.hitCylinderId = 0; 621 | 622 | returnValue = true; 623 | } 624 | 625 | if (BProjectiles.has(event.id) && (Cfg.Mode >= 2 || Cfg.HideAllProjectiles)) returnValue = false; 626 | 627 | return returnValue; 628 | } 629 | 630 | const UserBCheck = user => { for (const plBlist of Cfg.PlayersBlacklist) if (plBlist.toLowerCase() === user.toLowerCase()) return true; }; 631 | 632 | function NpcBCheck(event) { 633 | let blocked = false; 634 | 635 | if (Cfg.HideBlacklistedNpcs) { 636 | for (const blNpc of Cfg.NpcsBlacklist) { 637 | if (event.huntingZoneId === Number(blNpc.zone) && event.templateId === Number(blNpc.templateId)) { 638 | HNpcs[event.gameId] = event; 639 | HNpcs[event.gameId].spawnType = 1; 640 | HNpcs[event.gameId].spawnScript = 0; 641 | blocked = true; 642 | break; 643 | } 644 | } 645 | } 646 | 647 | if (InvisibleNpcs[event.huntingZoneId] && InvisibleNpcs[event.huntingZoneId].includes(event.templateId)) { 648 | HNpcs[event.gameId] = event; 649 | blocked = true; 650 | } 651 | 652 | if (Cfg.HideFireworks && event.huntingZoneId === UserNpcsHzId && FireWorks.includes(event.templateId)) { 653 | HNpcs[event.gameId] = event; 654 | blocked = true; 655 | } 656 | 657 | if (UserNpcs.includes(event.templateId) && event.huntingZoneId === UserNpcsHzId) { 658 | if (EqGid(event.owner) && Cfg.HideMySummons) { 659 | HNpcs[event.gameId] = event; 660 | HNpcs[event.gameId].spawnType = 1; 661 | HNpcs[event.gameId].spawnScript = 0; 662 | blocked = true; 663 | 664 | } else if (!EqGid(event.owner) && Cfg.HideOthersSummons) { 665 | HNpcs[event.gameId] = event; 666 | HNpcs[event.gameId].spawnType = 1; 667 | HNpcs[event.gameId].spawnScript = 0; 668 | blocked = true; 669 | } 670 | } 671 | 672 | return blocked ? false : undefined; 673 | } 674 | 675 | function updatePartySpawns(raid) { 676 | if (!Cfg.OnlyParty || !Cfg.RaidAutoChange) return 677 | 678 | if (Cfg.OnlyParty) 679 | for (const sUser in SUsers) { 680 | if (!PMembers.has(SUsers[sUser].name)) HideSpecificPlayerByName(SUsers[sUser].name); 681 | else if (HUsers[SUsers[sUser].gameId]) ShowSpecificPlayerByName(SUsers[sUser].name); 682 | } 683 | 684 | if (Cfg.RaidAutoChange && typeof raid !== 'undefined') { 685 | if (raid) { 686 | if (Cfg.Mode >= 2 || (LastFState === null && Cfg.Mode === 2)) return; 687 | LastFState = Cfg.Mode; 688 | Cmd.exec("fps state 2"); 689 | } else { 690 | if (LastFState === null || Cfg.Mode !== 2) { 691 | LastFState = null; 692 | return; 693 | } 694 | Cmd.exec(`fps state ${LastFState}`); 695 | LastFState = null; 696 | } 697 | } 698 | } 699 | 700 | function EqGid(xG) { 701 | return (xG === MyGameId); 702 | } 703 | 704 | function ClassID(m) { 705 | return (m % 1E2); 706 | } 707 | 708 | function log(name, type, from, target, id) { 709 | console.log(`[\x1b[37m${new Date().toJSON().slice(11)}\x1b[39m] \x1b[91m->\x1b[39m \x1b[36m${name}\x1b[39m \x1b[35m${type}\x1b[39m \x1b[97m${from}\x1b[39m \x1b[32m'${target}'\x1b[39m: \x1b[94m\ID\x1b[39m "\x1b[31m${id}\x1b[39m\x1b[49m\x1b[0m"`); 710 | } 711 | 712 | function UpdateUserLoc(event) { 713 | mod.toClient('S_USER_LOCATION', 6, { gameId: event.gameId, loc: event.loc, w: event.w, speed: 3E2, dest: event.loc, type: 7 }); 714 | } 715 | 716 | function UpdateNpcLoc(event, zMod = 0) { 717 | mod.toClient('S_NPC_LOCATION', 3, { gameId: event.gameId, loc: { x: event.loc.x, y: event.loc.y, z: event.loc.z + zMod }, w: event.w, speed: 3E2, dest: { x: event.loc.x, y: event.loc.y, z: event.loc.z + zMod }, type: 7 }); 718 | } 719 | 720 | // ~~~ * Hook Functions * ~~~ \\ 721 | 722 | function sLogin(event) { 723 | LastFState = event.name === MyName ? LastFState : null; 724 | LastGState = null; 725 | MyGameId = event.gameId; 726 | MyName = event.name; 727 | ProjDebug = false; 728 | AbnDebug = false; 729 | PMembers.clear(); 730 | BProjectiles.clear(); 731 | HSeedBoxes.clear(); 732 | if (Cfg.StreamMode) console.log("\x1b[94mINFO\x1b[34m [FPS-UTILS]\x1b[39m - Steam Mode is enabled, No messages will be sent in-game messages until its disabled."); 733 | } 734 | 735 | function sLoadTopo() { 736 | SUsers = {}; 737 | SNpcs = {}; 738 | HUsers = {}; 739 | HNpcs = {}; 740 | AllowedAchUps = 2; 741 | if (ProjDebug) { 742 | ProjDebug = false; 743 | Msg(`Auto Disabled projectile debug, to reduce the unneeded spam.`); 744 | } 745 | if (AbnDebug) { 746 | AbnDebug = false; 747 | Msg(`Auto Disabled abnormalities debug, to reduce the unneeded spam.`); 748 | } 749 | } 750 | 751 | function sMountVehicle(event) { 752 | if (EqGid(event.gameId)) return; 753 | SUsers[event.gameId].mount = event.id; 754 | if (HUsers[event.gameId]) HUsers[event.gameId].mount = event.id; 755 | if (Cfg.ShowStyle) { 756 | event.id = MountToReplaceId; 757 | return true; 758 | } 759 | } 760 | 761 | function sUnmountVehicle(event) { 762 | if (EqGid(event.gameId)) return; 763 | SUsers[event.gameId].mount = 0; 764 | if (HUsers[event.gameId]) HUsers[event.gameId].mount = 0; 765 | } 766 | 767 | function cSetVisibleRange(event) { 768 | LastVrange = event.range; 769 | } 770 | 771 | function sStartCooltimeItem(event) { 772 | if (event.cooldown === 0) return false; 773 | } 774 | 775 | function sStartActionScript(event) { 776 | if (ImportantActionScripts.includes(event.script)) return; 777 | if (Cfg.ActionScripts) return false; 778 | } 779 | 780 | function sLoadingScreenControlInfo() { 781 | if (Cfg.Mode >= 2) return false; 782 | } 783 | 784 | function sUpdateAchievementProgress(event) { 785 | if (AllowedAchUps) { 786 | AllowedAchUps--; 787 | return; 788 | } 789 | if (Cfg.Mode < 2) return; 790 | for (const Achieve of event.achievements) if (SpamAchIds.indexOf(Achieve.id) !== -1 || !Achieve.requirements.length) return false; 791 | } 792 | 793 | function sItemCustomString(event) { 794 | if (event.customStrings.length === 0) return false; 795 | } 796 | 797 | function sSocial(event) { 798 | if (EqGid(event.target)) return; 799 | if (HUsers[event.target] || HNpcs[event.target]) return false; 800 | } 801 | 802 | function sGuildName(event) { 803 | if (Cfg.Hideguildlogos) { 804 | event.guildLogo = ''; 805 | return true; 806 | } 807 | } 808 | 809 | function sApplyTitle(event) { 810 | if (EqGid(event.gameId)) return; 811 | if (Cfg.ShowStyle) return false; 812 | } 813 | 814 | function sImageData() { 815 | if (Cfg.Hideguildlogos) return false; 816 | } 817 | 818 | function sSpawnUser(event) { 819 | SUsers[event.gameId] = event; 820 | SUsers[event.gameId].spawnFx = 1; 821 | if (Cfg.Mode === 3 || UserBCheck(event.name) || Cfg.ClassesData[ClassID(event.templateId)].isHidden || (Cfg.OnlyParty && !PMembers.has(event.name))) { 822 | HUsers[event.gameId] = event; 823 | HUsers[event.gameId].spawnFx = 1; 824 | return false; 825 | } 826 | return ModifyUserAppearance(event); 827 | } 828 | 829 | function sSpawnUserfn(event) { 830 | return ModifyUserAppearance(event); 831 | } 832 | 833 | function sDespawnUser(event) { 834 | delete HUsers[event.gameId]; 835 | delete SUsers[event.gameId]; 836 | } 837 | 838 | function sUserLocation(event) { 839 | if (SUsers[event.gameId]) { 840 | SUsers[event.gameId].loc = event.dest; 841 | SUsers[event.gameId].w = event.w; 842 | } 843 | if (HUsers[event.gameId]) { 844 | HUsers[event.gameId].loc = event.dest; 845 | HUsers[event.gameId].w = event.w; 846 | return false; 847 | } 848 | } 849 | 850 | function sUserStatus(event) { 851 | if (SUsers[event.gameId]) SUsers[event.gameId].status = event.status; 852 | if (HUsers[event.gameId]) { 853 | HUsers[event.gameId].status = event.status; 854 | return false; 855 | } 856 | } 857 | 858 | function sDeadLocation(event) { 859 | if (SUsers[event.gameId]) SUsers[event.gameId].loc = event.loc; 860 | if (HUsers[event.gameId]) HUsers[event.gameId].loc = event.loc; 861 | } 862 | 863 | function sUserMovetype(event) { 864 | if (SUsers[event.gameId]) SUsers[event.gameId].w = event.w; 865 | if (HUsers[event.gameId]) { 866 | HUsers[event.gameId].w = event.w; 867 | return false; 868 | } 869 | } 870 | 871 | function sUserAppearanceChange(event) { 872 | if (EqGid(event.id)) return; 873 | if (Cfg.ShowStyle) return false; 874 | } 875 | 876 | function sUserChangeFaceCustom(event) { 877 | if (EqGid(event.gameId)) return; 878 | 879 | if (Cfg.MuteOthersVoice) { 880 | event.appearance.voice = InvalidVoiceId; 881 | return true; 882 | } 883 | } 884 | 885 | function sUserExternalChange(event) { 886 | if (EqGid(event.gameId)) return; 887 | if (Cfg.ShowStyle) return false; 888 | } 889 | 890 | function sUnicastTransformData(event) { 891 | if (EqGid(event.gameId) || !event.gameId) return; 892 | if (Cfg.ShowStyle) return false; 893 | 894 | let modified = undefined; 895 | 896 | if (Cfg.Hideguildlogos) { 897 | event.guildLogo = ''; 898 | 899 | modified = true; 900 | } 901 | 902 | if (Cfg.MuteOthersVoice) { 903 | event.appearance.voice = InvalidVoiceId; 904 | 905 | modified = true; 906 | } 907 | 908 | return modified; 909 | } 910 | 911 | function sPartyMemberList(event) { 912 | event.members.map(value => { PMembers.add(value.name) }); 913 | updatePartySpawns(event.raid); 914 | } 915 | 916 | function sLeavePartyMember(event) { 917 | PMembers.delete(event.name); 918 | updatePartySpawns(); 919 | } 920 | 921 | function sLeaveParty() { 922 | PMembers.clear(); 923 | updatePartySpawns(false); 924 | } 925 | 926 | function sSpawnNpc(event) { 927 | SNpcs[event.gameId] = event; 928 | SNpcs[event.gameId].spawnType = 1; 929 | SNpcs[event.gameId].spawnScript = 0; 930 | return NpcBCheck(event); 931 | } 932 | 933 | function sDespawnNpc(event) { 934 | delete HNpcs[event.gameId]; 935 | delete SNpcs[event.gameId]; 936 | if (!Cfg.HideMonsterDeathAnimation || event.type !== 5) return; 937 | event.type = 1; 938 | return true; 939 | } 940 | 941 | function sNpcLocation(event) { 942 | if (SNpcs[event.gameId]) { 943 | SNpcs[event.gameId].loc = event.dest; 944 | SNpcs[event.gameId].w = event.w; 945 | } 946 | if (SPets[event.gameId]) { 947 | SPets[event.gameId].loc = event.dest; 948 | SPets[event.gameId].w = event.w; 949 | } 950 | if (HPets[event.gameId]) { 951 | HPets[event.gameId].loc = event.dest; 952 | HPets[event.gameId].w = event.w; 953 | return false; 954 | } 955 | if (HNpcs[event.gameId]) { 956 | HNpcs[event.gameId].loc = event.dest; 957 | HNpcs[event.gameId].w = event.w; 958 | return false; 959 | } 960 | } 961 | 962 | function sCreatureLife(event) { 963 | if (SNpcs[event.gameId]) { 964 | SNpcs[event.gameId].loc = event.loc; 965 | SNpcs[event.gameId].alive = event.alive; 966 | } 967 | if (HNpcs[event.gameId]) { 968 | SNpcs[event.gameId].loc = event.loc; 969 | HNpcs[event.gameId].alive = event.alive; 970 | } 971 | } 972 | 973 | function sCreatureRotate(event) { 974 | if (SNpcs[event.gameId]) SNpcs[event.gameId].w = event.w; 975 | if (HNpcs[event.gameId]) { 976 | HNpcs[event.gameId].w = event.w; 977 | return false; 978 | } 979 | } 980 | 981 | function sFearMoveStage(event) { 982 | if ((!EqGid(event.gameId) && Cfg.Mode === 3) || HUsers[event.gameId] || HNpcs[event.gameId]) return false; 983 | } 984 | 985 | function sFearMoveEnd(event) { 986 | if ((!EqGid(event.gameId) && Cfg.Mode === 3) || HUsers[event.gameId] || HNpcs[event.gameId]) return false; 987 | } 988 | 989 | function sRequestSpawnServant(event) { 990 | SPets[event.gameId] = event; 991 | if (EqGid(event.ownerId) && Cfg.HideMyServants) { 992 | HPets[event.gameId] = event; 993 | process.nextTick(() => { 994 | UpdateNpcLoc(event, -1E2); 995 | ScaleUpEntity(event.gameId, 1E-3); 996 | }); 997 | } else if (!EqGid(event.ownerId) && Cfg.HideOthersServants) { 998 | HPets[event.gameId] = event; 999 | return false; 1000 | } 1001 | } 1002 | 1003 | function sRequestDespawnServant(event) { 1004 | delete HPets[event.gameId]; 1005 | delete SPets[event.gameId]; 1006 | } 1007 | 1008 | function sQuestBalloon(event) { 1009 | if (!SPets[event.source]) return; 1010 | if (Cfg.HideServantBalloons) return false; 1011 | } 1012 | 1013 | function sAbnormalityBegin(event) { 1014 | if (AbnDebug) { 1015 | if (EqGid(event.target)) log('Abnormality', 'Applied', 'on', MyName, event.id); 1016 | if (EqGid(event.source)) log('Abnormality', 'Started', 'from', MyName, event.id); 1017 | if (SUsers[event.target]) log('Abnormality', 'Applied', 'on', SUsers[event.target].name, event.id); 1018 | if (SUsers[event.source]) log('Abnormality', 'Started', 'from', SUsers[event.source].name, event.id); 1019 | } 1020 | return ModifyAbnormalities(event); 1021 | } 1022 | 1023 | function sAbnormalityRefresh(event) { 1024 | return ModifyAbnormalities(event); 1025 | } 1026 | 1027 | function sAbnormalityResist(event) { 1028 | return ModifyAbnormalities(event); 1029 | } 1030 | 1031 | function sAbnormalityDamageAbsorb(event) { 1032 | return ModifyAbnormalities(event); 1033 | } 1034 | 1035 | function sAbnormalityFail(event) { 1036 | return ModifyAbnormalities(event); 1037 | } 1038 | 1039 | function sAbnormalityEnd(event) { 1040 | return ModifyAbnormalities(event, true); 1041 | } 1042 | 1043 | function sActionStage(event) { 1044 | return ActionHCheck(event); 1045 | } 1046 | 1047 | function sActionEnd(event) { 1048 | return ActionHCheck(event, true); 1049 | } 1050 | 1051 | function sInstanceArrow(event) { 1052 | if (ProjDebug) { 1053 | if (EqGid(event.gameId)) log('Projectile-Arrow', 'Spawned', 'from', MyName, event.skill.id); 1054 | if (SUsers[event.gameId]) log('Projectile-Arrow', 'Spawned', 'from', SUsers[event.gameId].name, event.skill.id); 1055 | } 1056 | return ProjectileBCheck(event); 1057 | } 1058 | 1059 | function sSpawnProjectile(event) { 1060 | if (ProjDebug) { 1061 | if (EqGid(event.gameId)) log('Projectile', 'Spawned', 'from', MyName, event.skill.id); 1062 | if (SUsers[event.gameId]) log('Projectile', 'Spawned', 'from', SUsers[event.gameId].name, event.skill.id); 1063 | } 1064 | return ProjectileBCheck(event); 1065 | } 1066 | 1067 | function sStartUserProjectile(event) { 1068 | if (ProjDebug) { 1069 | if (EqGid(event.gameId)) log('Projectile', 'Started', 'from', MyName, event.skill.id); 1070 | if (SUsers[event.gameId]) log('Projectile', 'Started', 'from', SUsers[event.gameId].name, event.skill.id); 1071 | } 1072 | return ProjectileBCheck(event); 1073 | } 1074 | 1075 | /*function sChangeDestposProjectile(event) { 1076 | return ProjectileBCheck(event); 1077 | }*/ 1078 | 1079 | function sEndUserProjectile(event) { 1080 | BProjectiles.delete(event.id); 1081 | } 1082 | 1083 | function sDespawnProjectile(event) { 1084 | BProjectiles.delete(event.id); 1085 | } 1086 | 1087 | function sPlayerChangeMp(event) { 1088 | if (!Cfg.HideMpNumbers || !EqGid(event.target)) return; 1089 | if (event.type !== 0) { 1090 | event.type = 0; 1091 | return true; 1092 | } 1093 | } 1094 | 1095 | function sCreatureChangeHp(event) { 1096 | if (!Cfg.HideHpNumbers || !EqGid(event.target)) return; 1097 | if (event.type !== 10) { 1098 | event.type = 10; 1099 | return true; 1100 | } 1101 | } 1102 | 1103 | function sEachSkillResult(event) { 1104 | return ModifySkillResult(event); 1105 | } 1106 | 1107 | function sItemExplosionResult(event) { 1108 | if (Cfg.Mode >= 2 || (EqGid(event.gameId) && Cfg.Hit_Me) || (!EqGid(event.gameId) && Cfg.Hit_Other) || Cfg.Hit_All || HUsers[event.gameId]) { 1109 | for (const gameId of event.items) { 1110 | if (SUsers[event.gameId] && Cfg.HideBlacklistedDrop && Cfg.DropBlacklist.some(item => MoteIds.indexOf(item) !== -1)) continue; 1111 | mod.toClient('S_DESPAWN_DROPITEM', 4, { gameId }); 1112 | } 1113 | return false; 1114 | } 1115 | } 1116 | 1117 | function sSpawnDropItem(event) { 1118 | if (EqGid(event.source)) return; 1119 | if (Cfg.HideBlacklistedDrop && Cfg.DropBlacklist.indexOf(event.item) !== -1) return false; 1120 | if (Cfg.Mode >= 2) { 1121 | event.explode = 0; 1122 | return true; 1123 | } 1124 | } 1125 | 1126 | function sFontSwapInfo() { 1127 | if (Cfg.Hit_Damage || Cfg.Hit_All) return false; 1128 | } 1129 | 1130 | function sSpawnEventSeed(event) { 1131 | if (HUsers[event.owner] || Cfg.Mode >= 2) { 1132 | HSeedBoxes.add(event.gameId); 1133 | return false; 1134 | } 1135 | } 1136 | 1137 | function sUpdateEventSeedState(event) { 1138 | if (HSeedBoxes.has(event.gameId)) return false; 1139 | } 1140 | 1141 | function sResultEventSeed(event) { 1142 | if (HSeedBoxes.has(event.gameId)) return false; 1143 | } 1144 | 1145 | function sDespawnEventSeed(event) { 1146 | HSeedBoxes.delete(event.gameId); 1147 | } 1148 | 1149 | function sFieldEventOnEnter() { 1150 | if (Cfg.GuardianAutoChange) { 1151 | if ((LastGState !== null && Cfg.Mode === 2) || Cfg.Mode >= 2) return; 1152 | LastGState = Cfg.Mode; 1153 | Cmd.exec("fps state 2"); 1154 | } 1155 | } 1156 | 1157 | function sFieldEventOnLeave() { 1158 | if (Cfg.GuardianAutoChange) { 1159 | if (LastGState === null || Cfg.Mode !== 2) { 1160 | LastGState = null; 1161 | return; 1162 | } 1163 | Cmd.exec(`fps state ${LastGState}`); 1164 | LastGState = null; 1165 | } 1166 | } 1167 | 1168 | // ~~~ * Packet Hooks * ~~~ \\ 1169 | 1170 | mod.hook('S_LOGIN', mod.majorPatchVersion < 114 ? 14 : 15, sLogin) 1171 | mod.hook('S_LOAD_TOPO', 'raw', sLoadTopo) 1172 | mod.hook('S_MOUNT_VEHICLE', 2, LastHook, sMountVehicle) 1173 | mod.hook('S_UNMOUNT_VEHICLE', 2, LastHook, sUnmountVehicle) 1174 | mod.hook('C_SET_VISIBLE_RANGE', 1, cSetVisibleRange) 1175 | mod.hook('S_START_COOLTIME_ITEM', 1, LastHook, sStartCooltimeItem) 1176 | mod.hook('S_START_ACTION_SCRIPT', 3, LastHook, sStartActionScript) 1177 | 1178 | mod.hook('S_LOADING_SCREEN_CONTROL_INFO', 'raw', LastHook, sLoadingScreenControlInfo) 1179 | mod.hook('S_UPDATE_ACHIEVEMENT_PROGRESS', 1, LastHookfn, sUpdateAchievementProgress) 1180 | mod.hook('S_ITEM_CUSTOM_STRING', 2, LastHook, sItemCustomString) 1181 | 1182 | mod.hook('S_SOCIAL', 1, LastHook, sSocial) 1183 | mod.hook('S_GUILD_NAME', 2, LastHook, sGuildName) 1184 | mod.hook('S_APPLY_TITLE', 3, LastHook, sApplyTitle) 1185 | mod.hook('S_IMAGE_DATA', 'raw', LastHook, sImageData) 1186 | 1187 | mod.hook('S_SPAWN_USER', 17, LastHook, sSpawnUser) 1188 | mod.hook('S_SPAWN_USER', 17, LastHookfn, sSpawnUserfn) 1189 | mod.hook('S_DESPAWN_USER', 3, sDespawnUser) 1190 | mod.hook('S_USER_LOCATION', 6, LastHook, sUserLocation) 1191 | mod.hook('S_USER_STATUS', 4, LastHook, sUserStatus) 1192 | mod.hook('S_DEAD_LOCATION', 2, sDeadLocation) 1193 | mod.hook('S_USER_MOVETYPE', 1, LastHook, sUserMovetype) 1194 | mod.hook('S_USER_APPEARANCE_CHANGE', 1, LastHook, sUserAppearanceChange) 1195 | mod.hook('S_USER_CHANGE_FACE_CUSTOM', 2, LastHook, sUserChangeFaceCustom) 1196 | mod.hook('S_USER_EXTERNAL_CHANGE', 7, LastHook, sUserExternalChange) 1197 | mod.hook('S_UNICAST_TRANSFORM_DATA', 6, LastHook, sUnicastTransformData) 1198 | 1199 | mod.hook('S_PARTY_MEMBER_LIST', 9, sPartyMemberList) 1200 | mod.hook('S_LEAVE_PARTY_MEMBER', 2, sLeavePartyMember) 1201 | mod.hook('S_LEAVE_PARTY', 'raw', sLeaveParty) 1202 | 1203 | mod.hook('S_SPAWN_NPC', 12, LastHook, sSpawnNpc) 1204 | mod.hook('S_DESPAWN_NPC', 3, LastHook, sDespawnNpc) 1205 | mod.hook('S_NPC_LOCATION', 3, LastHook, sNpcLocation) 1206 | mod.hook('S_CREATURE_LIFE', 3, sCreatureLife) 1207 | mod.hook('S_CREATURE_ROTATE', 2, LastHook, sCreatureRotate) 1208 | mod.hook('S_FEARMOVE_STAGE', 2, LastHook, sFearMoveStage) 1209 | mod.hook('S_FEARMOVE_END', 2, LastHook, sFearMoveEnd) 1210 | 1211 | mod.hook('S_REQUEST_SPAWN_SERVANT', 4, LastHook, sRequestSpawnServant) 1212 | mod.hook('S_REQUEST_DESPAWN_SERVANT', 1, sRequestDespawnServant) 1213 | mod.hook('S_QUEST_BALLOON', 1, LastHook, sQuestBalloon) 1214 | 1215 | mod.hook('S_ABNORMALITY_BEGIN', 5, LastHookfn, sAbnormalityBegin) 1216 | mod.hook('S_ABNORMALITY_REFRESH', 2, LastHookfn, sAbnormalityRefresh) 1217 | mod.hook('S_ABNORMALITY_RESIST', 1, LastHookfn, sAbnormalityResist) 1218 | mod.hook('S_ABNORMALITY_DAMAGE_ABSORB', 1, LastHookfn, sAbnormalityDamageAbsorb) 1219 | mod.hook('S_ABNORMALITY_FAIL', 2, LastHookfn, sAbnormalityFail) 1220 | mod.hook('S_ABNORMALITY_END', 1, LastHookfn, sAbnormalityEnd) 1221 | 1222 | mod.hook('S_ACTION_STAGE', 9, LastHook, sActionStage) 1223 | mod.hook('S_ACTION_END', 5, LastHook, sActionEnd) 1224 | mod.hook('S_INSTANCE_ARROW', 4, LastHook, sInstanceArrow) 1225 | mod.hook('S_SPAWN_PROJECTILE', 6, LastHook, sSpawnProjectile) 1226 | mod.hook('S_START_USER_PROJECTILE', 9, LastHook, sStartUserProjectile) 1227 | //mod.hook('S_CHANGE_DESTPOS_PROJECTILE', 1, LastHook, sChangeDestposProjectile) //! Awaiting public def !\\ 1228 | mod.hook('S_END_USER_PROJECTILE', 4, sEndUserProjectile) 1229 | mod.hook('S_DESPAWN_PROJECTILE', 2, sDespawnProjectile) 1230 | 1231 | mod.hook('S_PLAYER_CHANGE_MP', 1, LastHook, sPlayerChangeMp) 1232 | mod.hook('S_CREATURE_CHANGE_HP', 6, LastHook, sCreatureChangeHp) 1233 | mod.hook('S_EACH_SKILL_RESULT', 15, LastHook, sEachSkillResult) 1234 | mod.hook('S_ITEM_EXPLOSION_RESULT', 2, LastHook, sItemExplosionResult) 1235 | mod.hook('S_SPAWN_DROPITEM', 9, LastHook, sSpawnDropItem) 1236 | mod.hook('S_FONT_SWAP_INFO', 'raw', LastHookfn, sFontSwapInfo) 1237 | 1238 | mod.hook('S_SPAWN_EVENT_SEED', 2, LastHook, sSpawnEventSeed) 1239 | mod.hook('S_UPDATE_EVENT_SEED_STATE', 4, LastHook, sUpdateEventSeedState) 1240 | mod.hook('S_RESULT_EVENT_SEED', 2, LastHook, sResultEventSeed) 1241 | mod.hook('S_DESPAWN_EVENT_SEED', 1, sDespawnEventSeed) 1242 | 1243 | mod.hook('S_FIELD_EVENT_ON_ENTER', 'raw', sFieldEventOnEnter) 1244 | mod.hook('S_FIELD_EVENT_ON_LEAVE', 'raw', sFieldEventOnLeave) 1245 | 1246 | // ~~~ * Commands * ~~~ \\ 1247 | 1248 | Cmd.add('0', () => Cmd.exec('fps mode 0')); 1249 | Cmd.add('1', () => Cmd.exec('fps mode 1')); 1250 | Cmd.add('2', () => Cmd.exec('fps mode 2')); 1251 | Cmd.add('3', () => Cmd.exec('fps mode 3')); 1252 | 1253 | Cmd.add(['fps', '!fps', 'fps-utils', '!fps-utils'], (key, arg, arg2, arg3) => { 1254 | key = key ? key.toLowerCase() : key; 1255 | arg = arg ? arg.toLowerCase() : arg; 1256 | arg2 = arg2 ? arg2.toLowerCase() : arg2; 1257 | arg3 = arg3 ? arg3.toLowerCase() : arg3; 1258 | switch (key) { 1259 | case "b": Cmd.exec('fps skills blacklist'); break; 1260 | case "p": Cmd.exec('fps party'); break; 1261 | case "g": case "gui": GuiHandler(arg, arg2); break; 1262 | case "0": Cmd.exec('fps mode 0'); break; 1263 | case "1": Cmd.exec('fps mode 1'); break; 1264 | case "2": Cmd.exec('fps mode 2'); break; 1265 | case "3": Cmd.exec('fps mode 3'); break; 1266 | case "m": case "mod": case "mode": case "state": 1267 | switch (arg) { 1268 | case "0": case "off": case "zero": 1269 | if (Cfg.Mode === 3) ShowAllPlayers(); 1270 | Cfg.Mode = 0; 1271 | Cfg.HideAllAbnormalities = false; 1272 | Cfg.HideAllProjectiles = false; 1273 | if (!Cfg.Hit_All) Cfg.Hit_Other = false; 1274 | Msg(`Mode 0.`); 1275 | break; 1276 | case "1": case "one": 1277 | if (Cfg.Mode === 3) ShowAllPlayers(); 1278 | Cfg.Mode = 1; 1279 | Cfg.HideAllAbnormalities = false; 1280 | Cfg.HideAllProjectiles = true; 1281 | if (!Cfg.Hit_All) Cfg.Hit_Other = true; 1282 | Msg(`Mode 1.`); 1283 | break; 1284 | case "2": case "two": 1285 | if (Cfg.Mode === 3) ShowAllPlayers(); 1286 | Cfg.Mode = 2; 1287 | Cfg.HideAllAbnormalities = true; 1288 | Cfg.HideAllProjectiles = true; 1289 | if (!Cfg.Hit_All) Cfg.Hit_Other = true; 1290 | Msg(`Mode 2.`); 1291 | break; 1292 | case "3": case "three": 1293 | HideAllPlayers(); 1294 | Cfg.Mode = 3; 1295 | Cfg.HideAllAbnormalities = true; 1296 | Cfg.HideAllProjectiles = true; 1297 | if (!Cfg.Hit_All) Cfg.Hit_Other = true; 1298 | Cfg.OnlyParty = false; 1299 | Msg(`Mode 3.`); 1300 | break; 1301 | default: 1302 | Msg(`Invalid arg: '${arg}'.`); 1303 | Msg(`Modes: "[0, 1, 2, 3].`); 1304 | break; 1305 | } 1306 | break; 1307 | case "hide": 1308 | if (typeof arg === "string" && arg !== null) { 1309 | if (Cfg.PlayersBlacklist.includes(arg)) return Msg(`Player '${arg}' Already hidden.`); 1310 | else 1311 | if ((PClasses.includes(arg) && !Cfg.ClassesBlacklist.includes(arg)) || (PRoles.includes(arg) && !Cfg.RolesBlacklist.includes(arg))) { 1312 | for (const cData in Cfg.ClassesData) { 1313 | if ((Cfg.ClassesData[cData].name === arg || Cfg.ClassesData[cData].role.includes(arg)) && !Cfg.ClassesData[cData].isHidden) { 1314 | Cfg.ClassesData[cData].isHidden = true; 1315 | if (Cfg.ClassesData[cData].name === arg) Cfg.ClassesBlacklist.push(arg); 1316 | if (Cfg.ClassesData[cData].role.includes(arg)) Cfg.RolesBlacklist.push(arg); 1317 | let classtohide = Cfg.ClassesData[cData].model; 1318 | for (const sUser in SUsers) 1319 | if (ClassID(SUsers[sUser].templateId) === classtohide) HideSpecificPlayerByName(SUsers[sUser].name); 1320 | } 1321 | } 1322 | Msg(`Class/Role ${arg} Hidden.`); 1323 | return; 1324 | } else if (Cfg.ClassesBlacklist.includes(arg) || Cfg.RolesBlacklist.includes(arg)) return Msg(`Class/Role '${arg}' Already hidden.`); 1325 | Msg(`Player '${arg}' Hidden.`); 1326 | Cfg.PlayersBlacklist.push(arg); 1327 | HideSpecificPlayerByName(arg); 1328 | } else Msg(`Invalid arg: '${arg2}'.`); 1329 | break; 1330 | case "show": 1331 | if (typeof arg === "string" && arg !== null) { 1332 | if (Cfg.PlayersBlacklist.includes(arg)) { 1333 | ShowSpecificPlayerByName(arg); 1334 | RemoveEntity(Cfg.PlayersBlacklist, arg); 1335 | Msg(`Player '${arg}' Shown.`); 1336 | return; 1337 | } 1338 | if ((PClasses.includes(arg) && Cfg.ClassesBlacklist.includes(arg)) || (Cfg.RolesBlacklist.includes(arg) && PRoles.includes(arg))) { 1339 | for (const cData in Cfg.ClassesData) { 1340 | if (Cfg.ClassesData[cData].name === arg || Cfg.ClassesData[cData].role.includes(arg)) { 1341 | if (Cfg.ClassesData[cData].name === arg) RemoveEntity(Cfg.ClassesBlacklist, arg); 1342 | if (Cfg.ClassesData[cData].role.includes(arg)) RemoveEntity(Cfg.RolesBlacklist, arg); 1343 | Cfg.ClassesData[cData].isHidden = false; 1344 | let classToShow = Cfg.ClassesData[cData].model; 1345 | for (const hUser in HUsers) if (ClassID(HUsers[hUser].templateId) === classToShow) ShowSpecificPlayerByName(HUsers[hUser].name); 1346 | } 1347 | } 1348 | Msg(`Class '${arg}' Shown.`); 1349 | } else if (!Cfg.ClassesBlacklist.includes(arg) || !Cfg.RolesBlacklist.includes(arg)) Msg(`Class/Role '${arg}' Already shown.`); 1350 | else if (!Cfg.PlayersBlacklist.includes(arg)) Msg(`Player '${arg}' Already shown.`); 1351 | else Msg(`Invalid arg: '${arg2}'.`); 1352 | } 1353 | break; 1354 | case "party": 1355 | if (Cfg.Mode === 3) return Msg(`You've to disable mode 3 first.`); 1356 | //if(!PMembers.size) return Msg(`You must be in party in-order to enable this.`); 1357 | Cfg.OnlyParty = !Cfg.OnlyParty; 1358 | if (Cfg.OnlyParty) { 1359 | for (const sUser in SUsers) { 1360 | if (!PMembers.has(SUsers[sUser].name)) HideSpecificPlayerByName(SUsers[sUser].name); 1361 | else if (HUsers[SUsers[sUser].gameId]) ShowSpecificPlayerByName(SUsers[sUser].name); 1362 | } 1363 | } else ShowAllPlayers(); 1364 | Msg(`Everyone but party ${Cfg.OnlyParty ? `Hidden` : `Shown`}.`); 1365 | break; 1366 | case "raid": 1367 | Cfg.RaidAutoChange = !Cfg.RaidAutoChange; 1368 | Msg(`Raid auto-state ${Cfg.RaidAutoChange ? `Enabled` : `Disabled`}.`); 1369 | if (!Cfg.GuardianAutoChange) LastFState = null; 1370 | break; 1371 | case "guardian": 1372 | Cfg.GuardianAutoChange = !Cfg.GuardianAutoChange; 1373 | Msg(`Guardian auto-state ${Cfg.GuardianAutoChange ? `Enabled` : `Disabled`}.`); 1374 | if (!Cfg.GuardianAutoChange) LastGState = null; 1375 | break; 1376 | case "pvptraps": 1377 | Cfg.PvpTraps = !Cfg.PvpTraps; 1378 | Msg(`Pvp Traps are ${Cfg.PvpTraps ? `Shown(not affected by hide all projectiles)` : `Normal(affected by hide all projectiles)`}.`); 1379 | break; 1380 | case "list": 1381 | Msg(`Hidden players: ${Cfg.PlayersBlacklist.length ? Cfg.PlayersBlacklist.join(', ') : 0}.`); 1382 | Msg(`Hidden classes: ${Cfg.ClassesBlacklist.length ? Cfg.ClassesBlacklist.join(', ') : 0}.`); 1383 | Msg(`Hidden roles: ${Cfg.RolesBlacklist.length ? Cfg.RolesBlacklist.join(', ') : 0}.`); 1384 | break; 1385 | case "summons": case "sums": 1386 | switch (arg) { 1387 | case "me": case "own": 1388 | Cfg.HideMySummons = !Cfg.HideMySummons; 1389 | Cfg.HideMySummons ? HideNpcs('own') : ShowNpcs('own'); 1390 | Msg(`Own summoned NPCs are ${Cfg.HideMySummons ? `Hidden` : `Shown`}.`); 1391 | break; 1392 | default: 1393 | Cfg.HideOthersSummons = !Cfg.HideOthersSummons; 1394 | Cfg.HideOthersSummons ? HideNpcs('others') : ShowNpcs('others'); 1395 | Msg(`Others summoned NPCs are ${Cfg.HideOthersSummons ? `Hidden` : `Shown`}.`); 1396 | break; 1397 | } 1398 | break; 1399 | case "skills": case "skill": 1400 | switch (arg) { 1401 | case "blacklist": 1402 | Cfg.HideBlacklistedSkills = !Cfg.HideBlacklistedSkills; 1403 | Msg(`Blacklisted skills ${Cfg.HideBlacklistedSkills ? `Hidden` : `Shown`}.`); 1404 | break; 1405 | case "class": 1406 | if (PClasses.includes(arg2)) { 1407 | for (const cData in Cfg.ClassesData) { 1408 | if (Cfg.ClassesData[cData].name === arg2) { 1409 | if (arg3 && !isNaN(arg3) && arg3 < 50) { 1410 | if (Cfg.ClassesData[cData].CD_SkillsBlacklist.includes(arg3)) { 1411 | let index = Cfg.ClassesData[cData].CD_SkillsBlacklist.indexOf(arg3); 1412 | if (index !== -1) { 1413 | Cfg.ClassesData[cData].CD_SkillsBlacklist.splice(index, 1); 1414 | Msg(`Skill ID '${arg3}' Shown for class '${arg2}'.`); 1415 | } 1416 | return; 1417 | } else { 1418 | Cfg.ClassesData[cData].CD_SkillsBlacklist.push(arg3); 1419 | Msg(`Skill ID '${arg3}' Hidden for class '${arg2}'.`); 1420 | return; 1421 | } 1422 | } else { 1423 | Cfg.ClassesData[cData].CD_HideBlacklistedSkills = !Cfg.ClassesData[cData].CD_HideBlacklistedSkills; 1424 | Msg(`Skills for '${arg2}' class ${Cfg.ClassesData[cData].CD_HideBlacklistedSkills ? `Hidden` : `Shown`}.`); 1425 | return; 1426 | } 1427 | } 1428 | } 1429 | } else Msg(`Class ${arg2} not found.`); 1430 | break; 1431 | } 1432 | break; 1433 | case "npcs": case "npc": 1434 | if (arg === 'hide') { 1435 | if (!arg2 || !arg3) { 1436 | Cfg.HideBlacklistedNpcs = !Cfg.HideBlacklistedNpcs; 1437 | Msg(`Blacklisted NPCs ${Cfg.HideBlacklistedNpcs ? `Hidden` : `Shown`}.`); 1438 | break; 1439 | } 1440 | const found = Cfg.NpcsBlacklist.some(s => s.zone === arg2 && s.templateId === arg3); 1441 | if (found) { 1442 | if (Cfg.HideBlacklistedNpcs) ShowSpecificNpcByHzTi(Number(arg2), Number(arg3)); 1443 | Msg(`NPC HntZone '${arg2}', TmpId '${arg3}' Removed from the blacklist.`); 1444 | Cfg.NpcsBlacklist = Cfg.NpcsBlacklist.filter(obj => obj.zone !== arg2 || obj.templateId !== arg3); 1445 | } else { 1446 | if (Cfg.HideBlacklistedNpcs) HideSpecificNpcByHzTi(Number(arg2), Number(arg3)); 1447 | Msg(`NPC HntZone '${arg2}', TmpId '${arg3}' Added to the blacklist.`); 1448 | Cfg.NpcsBlacklist.push({ zone: arg2, templateId: arg3 }); 1449 | } 1450 | return; 1451 | } else { 1452 | Cfg.HideBlacklistedNpcs = !Cfg.HideBlacklistedNpcs; 1453 | Cfg.HideBlacklistedNpcs ? HideNpcs('bl') : ShowNpcs('bl'); 1454 | Msg(`Blacklisted NPCs ${Cfg.HideBlacklistedNpcs ? `Hidden` : `Shown`}.`); 1455 | } 1456 | break; 1457 | case "hit": 1458 | switch (arg) { 1459 | case "me": 1460 | if (Cfg.Hit_All) return Msg(`You've to disable hit ALL first.`); 1461 | Cfg.Hit_Me = !Cfg.Hit_Me; 1462 | Msg(`Own hits effect ${Cfg.Hit_Me ? `Hidden` : `Shown`}.`); 1463 | break; 1464 | case "other": 1465 | if (Cfg.Hit_All) return Msg(`You've to disable hit ALL first.`); 1466 | Cfg.Hit_Other = !Cfg.Hit_Other; 1467 | Msg(`Players hit effect ${Cfg.Hit_Other ? `Hidden` : `Shown`}.`); 1468 | break; 1469 | case "damage": 1470 | if (Cfg.Hit_All) return Msg(`You've to disable hit ALL first.`); 1471 | Cfg.Hit_Damage = !Cfg.Hit_Damage; 1472 | Msg(`Damage numbers ${Cfg.Hit_Damage ? `Hidden` : `Shown`}.`); 1473 | break; 1474 | case "all": 1475 | Cfg.Hit_Me = Cfg.Hit_Other = Cfg.Hit_Damage = false; 1476 | Cfg.Hit_All = !Cfg.Hit_All; 1477 | Msg(`Hit all ${Cfg.Hit_All ? `Hidden` : `Shown`}.`); 1478 | break; 1479 | default: 1480 | Msg(`Invalid hit arg: '${arg}'.`); 1481 | break; 1482 | } 1483 | break; 1484 | case "fireworks": case "firework": 1485 | Cfg.HideFireworks = !Cfg.HideFireworks; 1486 | Msg(`Fireworks ${Cfg.HideFireworks ? `Hidden` : `Shown`}.`); 1487 | break; 1488 | case "abn": case "effects": case "abnormal": case "abnormalities": 1489 | switch (arg) { 1490 | case "all": 1491 | Cfg.HideAllAbnormalities = !Cfg.HideAllAbnormalities; 1492 | Msg(`All Abnormalities ${Cfg.HideAllAbnormalities ? `Hidden` : `Shown`}.`); 1493 | break; 1494 | case "blacklist": 1495 | if (!arg2 || !arg3) { 1496 | Cfg.HideBlacklistedAbnormalities = !Cfg.HideBlacklistedAbnormalities; 1497 | Msg(`Blacklisted Abnormalities ${Cfg.HideBlacklistedAbnormalities ? `Hidden` : `Shown`}.`); 1498 | break; 1499 | } else if (arg2 && arg3) { 1500 | arg3 = Number(arg3); 1501 | if (!Cfg.AbnormalitiesBlacklist.includes(arg3)) { 1502 | if (arg2 === 'add') { 1503 | Cfg.AbnormalitiesBlacklist.push(arg3); 1504 | Msg(`Blacklisted Abnormalities added '${arg3}'.`); 1505 | return; 1506 | } else if (arg2 === 'remv') return Msg(`Blacklisted Abnormalities can't remove '${arg3}' as it's not there.`); 1507 | 1508 | } else if (Cfg.AbnormalitiesBlacklist.includes(arg3)) { 1509 | if (arg2 === 'add') return Msg(`Blacklisted Abnormalities can't add '${arg3}' as it's already there.`); 1510 | else if (arg2 === 'remv') { 1511 | let index = Cfg.AbnormalitiesBlacklist.indexOf(arg3); 1512 | if (index !== -1) { 1513 | Cfg.AbnormalitiesBlacklist.splice(index, 1); 1514 | Msg(`Blacklisted Abnormalities removed '${arg3}'.`); 1515 | return; 1516 | } 1517 | } 1518 | } else return Msg(`Invalid abnormalities Blacklist arg: '${arg}'.`); 1519 | } 1520 | break; 1521 | case "log": 1522 | case "debug": 1523 | AbnDebug = !AbnDebug; 1524 | if (AbnDebug) Msg(`Abnormalities debug started, check your proxy console for details.`) 1525 | else Msg(`Abnormalities debug stopped.`); 1526 | break; 1527 | default: 1528 | Msg(`Invalid abnormalities arg: '${arg}'.`); 1529 | break; 1530 | } 1531 | break; 1532 | case "guildlogo": 1533 | if (SwitchCd) return Msg(`Try again in 3 seconds.`); 1534 | Cfg.Hideguildlogos = !Cfg.Hideguildlogos; 1535 | mod.toServer('C_SET_VISIBLE_RANGE', 1, { range: 0 }); 1536 | mod.setTimeout(() => mod.toServer('C_SET_VISIBLE_RANGE', 1, { range: LastVrange }), 15E2); 1537 | SwitchCd = true; 1538 | mod.setTimeout(() => SwitchCd = false, 28E2); 1539 | Msg(`Guild Logos ${Cfg.Hideguildlogos ? `Hidden` : `Shown`}.`); 1540 | break; 1541 | case "costume": case "style": 1542 | if (SwitchCd) return Msg(`Try again in 3 seconds.`); 1543 | Cfg.ShowStyle = !Cfg.ShowStyle; 1544 | mod.toServer('C_SET_VISIBLE_RANGE', 1, { range: 0 }); 1545 | mod.setTimeout(() => mod.toServer('C_SET_VISIBLE_RANGE', 1, { range: LastVrange }), 15E2); 1546 | SwitchCd = true; 1547 | mod.setTimeout(() => SwitchCd = false, 28E2); 1548 | Msg(`Style of NPCs & others ${Cfg.ShowStyle ? `Hidden` : `Shown`}.`); 1549 | break; 1550 | case "proj": case "projectile": 1551 | switch (arg) { 1552 | case "all": 1553 | Cfg.HideAllProjectiles = !Cfg.HideAllProjectiles; 1554 | Msg(`Projectiles ${Cfg.HideAllProjectiles ? `Hidden` : `Shown`}.`); 1555 | break; 1556 | case "blacklist": 1557 | if (!arg2 || !arg3) { 1558 | Cfg.HideBlacklistedProjectiles = !Cfg.HideBlacklistedProjectiles; 1559 | Msg(`Blacklisted projectile ${Cfg.HideBlacklistedProjectiles ? `Hidden` : `Shown`}.`); 1560 | break; 1561 | } else if (arg2 && arg3) { 1562 | arg3 = Number(arg3); 1563 | if (!Cfg.ProjectilesBlacklist.includes(arg3)) { 1564 | if (arg2 === 'add') { 1565 | Cfg.ProjectilesBlacklist.push(arg3); 1566 | Msg(`Blacklisted projectile added '${arg3}'.`); 1567 | return; 1568 | } else if (arg2 === 'remv') return Msg(`Blacklisted projectile can't remove '${arg3}' as it's not there.`); 1569 | } else if (Cfg.ProjectilesBlacklist.includes(arg3)) { 1570 | if (arg2 === 'add') return Msg(`Blacklisted projectile can't add '${arg3}' as it's already there.`); 1571 | else if (arg2 === 'remv') { 1572 | let index = Cfg.ProjectilesBlacklist.indexOf(arg3); 1573 | if (index !== -1) { 1574 | Cfg.ProjectilesBlacklist.splice(index, 1); 1575 | Msg(`Blacklisted projectile removed '${arg3}'.`); 1576 | return; 1577 | } 1578 | } 1579 | } else return Msg(`Invalid projectile Blacklist arg: '${arg}'.`); 1580 | } 1581 | break; 1582 | case "log": case "debug": 1583 | ProjDebug = !ProjDebug; 1584 | if (ProjDebug) Msg(`Projectile debug started, check your proxy console for details.`); 1585 | else Msg(`Projectile debug stopped.`); 1586 | break; 1587 | default: 1588 | Msg(`Invalid projectile arg: '${arg}'.`); 1589 | break; 1590 | } 1591 | break; 1592 | case "quicklink": 1593 | switch (arg) { 1594 | case "mail": case "parcel": 1595 | mod.toServer('C_REQUEST_CONTRACT', 1, { type: 8 }); 1596 | break; 1597 | case "talent": case "talents": 1598 | mod.toServer('C_REQUEST_CONTRACT', 1, { type: 78 }); 1599 | break; 1600 | case "broker": 1601 | mod.toClient('S_NPC_MENU_SELECT', 1, { type: 28 }); 1602 | break; 1603 | case "dress": case "dressingroom": 1604 | mod.toServer('C_REQUEST_CONTRACT', 1, { type: 77 }); 1605 | break; 1606 | case "hat": case "hatrestyle": 1607 | mod.toServer('C_REQUEST_CONTRACT', 1, { type: 91 }); 1608 | break; 1609 | case "lobby": 1610 | mod.toServer('C_RETURN_TO_LOBBY', 1); 1611 | break; 1612 | case "exit": case "instantexit": 1613 | mod.toClient('S_EXIT', 3, { category: 0, code: 0 }); 1614 | break; 1615 | case "drop": 1616 | mod.toServer('C_LEAVE_PARTY', 1); 1617 | break; 1618 | case "disband": 1619 | mod.toServer('C_DISMISS_PARTY', 1); 1620 | break; 1621 | case "reset": 1622 | mod.toServer('C_RESET_ALL_DUNGEON', 1); 1623 | break; 1624 | default: 1625 | Msg(`Invalid quicklink '${arg}'.`); 1626 | break; 1627 | } 1628 | break; 1629 | case "npczoom": 1630 | Cfg.ActionScripts = !Cfg.ActionScripts; 1631 | Msg(`Npc zoom-ins ${Cfg.ActionScripts ? `Hidden` : `Shown`}.`); 1632 | break; 1633 | case "dropitem": case "drops": 1634 | if (arg === 'hide') { 1635 | if (!arg2) { 1636 | Cfg.HideBlacklistedDrop = !Cfg.HideBlacklistedDrop; 1637 | Msg(`Blacklisted Drops ${Cfg.HideBlacklistedDrop ? `Hidden` : `Shown`}.`); 1638 | break; 1639 | } 1640 | arg2 = Number(arg2); 1641 | const found1 = Cfg.DropBlacklist.some(s => s === arg2); 1642 | if (found1) { 1643 | Msg(`Drops id '${arg2}' Removed from the blacklist.`); 1644 | Cfg.DropBlacklist = Cfg.DropBlacklist.filter(obj => obj !== Number(arg2)); 1645 | } else { 1646 | Msg(`Drops id '${arg2}' Added to the blacklist.`); 1647 | Cfg.DropBlacklist.push(arg2); 1648 | } 1649 | return; 1650 | } else Cfg.HideBlacklistedDrop = !Cfg.HideBlacklistedDrop; 1651 | Msg(`Blacklisted Drops ${Cfg.HideBlacklistedDrop ? `Hidden` : `Shown`}.`); 1652 | break; 1653 | case "monsterdeathani": case "monstersdeathani": 1654 | Cfg.HideMonsterDeathAnimation = !Cfg.HideMonsterDeathAnimation; 1655 | Msg(`Monsters Death Animation is ${Cfg.HideMonsterDeathAnimation ? `Hidden` : `Shown`}.`); 1656 | break; 1657 | case "screenabns": case "blur": 1658 | if (arg === 'hide') { 1659 | if (!arg2) { 1660 | Cfg.HideOwnBlacklistedAbns = !Cfg.HideOwnBlacklistedAbns; 1661 | Msg(`Blacklisted ScreenAbns ${Cfg.OwnAbnormalsBlacklist ? `Hidden` : `Shown`}.`); 1662 | break; 1663 | } 1664 | arg2 = Number(arg2); 1665 | const found2 = Cfg.OwnAbnormalsBlacklist.some(m => m === arg2); 1666 | if (found2) { 1667 | Msg(`Abnormal id '${arg2}' Removed from the blacklist.`); 1668 | Cfg.OwnAbnormalsBlacklist = Cfg.OwnAbnormalsBlacklist.filter(obj => obj !== Number(arg2)); 1669 | } else { 1670 | Msg(`Abnormal id '${arg2}' Added to the blacklist.`); 1671 | Cfg.OwnAbnormalsBlacklist.push(arg2); 1672 | } 1673 | return; 1674 | } else Cfg.HideOwnBlacklistedAbns = !Cfg.HideOwnBlacklistedAbns; 1675 | Msg(`Blacklisted ScreenAbns ${Cfg.HideOwnBlacklistedAbns ? `Hidden` : `Shown`}.`); 1676 | break; 1677 | case "pet": case "pets": case "servant": case "servants": 1678 | switch (arg) { 1679 | case "me": 1680 | Cfg.HideMyServants = !Cfg.HideMyServants; 1681 | Cfg.HideMyServants ? HideNpcs('pet', 'own') : ShowNpcs('pet', 'own'); 1682 | Msg(`Own Servants are ${Cfg.HideMyServants ? `Hidden` : `Shown`}.`); 1683 | break; 1684 | default: 1685 | Cfg.HideOthersServants = !Cfg.HideOthersServants; 1686 | Cfg.HideOthersServants ? HideNpcs('pet', 'others') : ShowNpcs('pet', 'others'); 1687 | Msg(`Others summoned Servants are ${Cfg.HideOthersServants ? `Hidden` : `Shown`}.`); 1688 | break; 1689 | } 1690 | break; 1691 | case "hpnumbers": 1692 | Cfg.HideHpNumbers = !Cfg.HideHpNumbers; 1693 | Msg(`Own Hp numbers ${Cfg.HideHpNumbers ? `Hidden` : `Shown`}.`); 1694 | break; 1695 | case "mpnumbers": 1696 | Cfg.HideMpNumbers = !Cfg.HideMpNumbers; 1697 | Msg(`Own Mp numbers ${Cfg.HideMpNumbers ? `Hidden` : `Shown`}.`); 1698 | break; 1699 | case "muteothers": 1700 | Cfg.MuteOthersVoice = !Cfg.MuteOthersVoice; 1701 | Msg(`Mute others voice is ${Cfg.MuteOthersVoice ? `Enabled` : `Disabled`}.`); 1702 | break; 1703 | case "petspopup": 1704 | Cfg.HideServantBalloons = !Cfg.HideServantBalloons; 1705 | Msg(`Hide Pets Popup chat balloons is ${Cfg.HideServantBalloons ? `Enabled` : `Disabled`}.`); 1706 | break; 1707 | case "stream": 1708 | Cfg.StreamMode = !Cfg.StreamMode; 1709 | Msg(`Stream mode is ${Cfg.StreamMode ? `Enabled` : `Disabled`}.`); 1710 | if (Cfg.StreamMode) console.log("\x1b[94mINFO\x1b[34m [FPS-UTILS]\x1b[39m - Steam Mode has been enabled, No messages will be sent in-game messages until its disabled."); 1711 | else console.log("\x1b[94mINFO\x1b[34m [FPS-UTILS]\x1b[39m - Steam Mode has been disabled."); 1712 | break; 1713 | case "help": case "h": 1714 | Cmd.exec("fps gui help"); 1715 | break; 1716 | default: 1717 | //Msg(`Unknown command, check command list.`); 1718 | //Cmd.exec("fps gui help"); 1719 | Cmd.exec("fps gui"); 1720 | break; 1721 | } 1722 | if (!NotCP && typeof Cfg.ClassesData["12"] === 'undefined') mod.saveSettings(); 1723 | }) 1724 | } --------------------------------------------------------------------------------