PageRenderTime 68ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/FrameXML/ChatFrame.lua

https://bitbucket.org/Shenton/world-of-warcraft-user-interface-source
Lua | 4879 lines | 4228 code | 518 blank | 133 comment | 837 complexity | d9363641afb215a2b682230b8fec8f1d MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. MESSAGE_SCROLLBUTTON_INITIAL_DELAY = 0;
  2. MESSAGE_SCROLLBUTTON_SCROLL_DELAY = 0.05;
  3. CHAT_BUTTON_FLASH_TIME = 0.5;
  4. CHAT_TELL_ALERT_TIME = 300;
  5. NUM_CHAT_WINDOWS = 10;
  6. DEFAULT_CHAT_FRAME = ChatFrame1;
  7. NUM_REMEMBERED_TELLS = 10;
  8. MAX_WOW_CHAT_CHANNELS = 10;
  9. CHAT_TIMESTAMP_FORMAT = nil; -- gets set from Interface Options
  10. CHAT_SHOW_IME = false;
  11. MAX_CHARACTER_NAME_BYTES = 48;
  12. --DEBUG FIXME FOR TESTING
  13. CHAT_OPTIONS = {
  14. ONE_EDIT_AT_A_TIME = "old"
  15. };
  16. -- Table for event indexed chatFilters.
  17. -- Format ["CHAT_MSG_SYSTEM"] = { function1, function2, function3 }
  18. -- filter, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 = function1 (self, event, ...) if filter then return true end return false, ... end
  19. local chatFilters = {};
  20. -- These hash tables are to improve performance of common lookups
  21. -- if you change what these tables point to (ie slash command, emote, chat)
  22. -- then you need to invalidate the entry in the hash table
  23. local hash_SecureCmdList = {}
  24. --Note: These need to remain global for AddOns
  25. hash_SlashCmdList = {} --[localizedCommand] -> function
  26. hash_EmoteTokenList = {}
  27. hash_ChatTypeInfoList = {} --[localizedCommand] -> identifier (Stores all slash commands)
  28. ChatTypeInfo = { };
  29. ChatTypeInfo["SYSTEM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  30. ChatTypeInfo["SAY"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  31. ChatTypeInfo["PARTY"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  32. ChatTypeInfo["RAID"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  33. ChatTypeInfo["GUILD"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  34. ChatTypeInfo["OFFICER"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  35. ChatTypeInfo["YELL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  36. ChatTypeInfo["WHISPER"] = { sticky = 1, flashTab = true, flashTabOnGeneral = true };
  37. ChatTypeInfo["SMART_WHISPER"] = ChatTypeInfo["WHISPER"];
  38. ChatTypeInfo["WHISPER_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  39. ChatTypeInfo["REPLY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  40. ChatTypeInfo["EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  41. ChatTypeInfo["TEXT_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  42. ChatTypeInfo["MONSTER_SAY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  43. ChatTypeInfo["MONSTER_PARTY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  44. ChatTypeInfo["MONSTER_YELL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  45. ChatTypeInfo["MONSTER_WHISPER"] = { sticky = 0, flashTab = true, flashTabOnGeneral = true };
  46. ChatTypeInfo["MONSTER_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  47. ChatTypeInfo["CHANNEL"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  48. ChatTypeInfo["CHANNEL_JOIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  49. ChatTypeInfo["CHANNEL_LEAVE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  50. ChatTypeInfo["CHANNEL_LIST"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  51. ChatTypeInfo["CHANNEL_NOTICE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  52. ChatTypeInfo["CHANNEL_NOTICE_USER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  53. ChatTypeInfo["TARGETICONS"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  54. ChatTypeInfo["AFK"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  55. ChatTypeInfo["DND"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  56. ChatTypeInfo["IGNORED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  57. ChatTypeInfo["SKILL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  58. ChatTypeInfo["LOOT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  59. ChatTypeInfo["CURRENCY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  60. ChatTypeInfo["MONEY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  61. ChatTypeInfo["OPENING"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  62. ChatTypeInfo["TRADESKILLS"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  63. ChatTypeInfo["PET_INFO"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  64. ChatTypeInfo["COMBAT_MISC_INFO"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  65. ChatTypeInfo["COMBAT_XP_GAIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  66. ChatTypeInfo["COMBAT_HONOR_GAIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  67. ChatTypeInfo["COMBAT_FACTION_CHANGE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  68. ChatTypeInfo["BG_SYSTEM_NEUTRAL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  69. ChatTypeInfo["BG_SYSTEM_ALLIANCE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  70. ChatTypeInfo["BG_SYSTEM_HORDE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  71. ChatTypeInfo["RAID_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  72. ChatTypeInfo["RAID_WARNING"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  73. ChatTypeInfo["RAID_BOSS_WHISPER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  74. ChatTypeInfo["RAID_BOSS_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  75. ChatTypeInfo["QUEST_BOSS_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  76. ChatTypeInfo["FILTERED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  77. ChatTypeInfo["INSTANCE_CHAT"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  78. ChatTypeInfo["INSTANCE_CHAT_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  79. ChatTypeInfo["RESTRICTED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  80. ChatTypeInfo["CHANNEL1"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  81. ChatTypeInfo["CHANNEL2"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  82. ChatTypeInfo["CHANNEL3"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  83. ChatTypeInfo["CHANNEL4"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  84. ChatTypeInfo["CHANNEL5"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  85. ChatTypeInfo["CHANNEL6"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  86. ChatTypeInfo["CHANNEL7"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  87. ChatTypeInfo["CHANNEL8"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  88. ChatTypeInfo["CHANNEL9"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  89. ChatTypeInfo["CHANNEL10"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
  90. ChatTypeInfo["ACHIEVEMENT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  91. ChatTypeInfo["GUILD_ACHIEVEMENT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  92. ChatTypeInfo["PARTY_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  93. ChatTypeInfo["BN_WHISPER"] = { sticky = 1, flashTab = true, flashTabOnGeneral = true };
  94. ChatTypeInfo["BN_WHISPER_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  95. ChatTypeInfo["BN_CONVERSATION"] = { sticky = 1, flashTab = true, flashTabOnGeneral = false };
  96. ChatTypeInfo["BN_CONVERSATION_NOTICE"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  97. ChatTypeInfo["BN_CONVERSATION_LIST"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  98. ChatTypeInfo["BN_ALERT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  99. ChatTypeInfo["BN_BROADCAST"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  100. ChatTypeInfo["BN_BROADCAST_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  101. ChatTypeInfo["BN_INLINE_TOAST_ALERT"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  102. ChatTypeInfo["BN_INLINE_TOAST_BROADCAST"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  103. ChatTypeInfo["BN_INLINE_TOAST_BROADCAST_INFORM"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  104. ChatTypeInfo["BN_INLINE_TOAST_CONVERSATION"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
  105. ChatTypeInfo["BN_WHISPER_PLAYER_OFFLINE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  106. ChatTypeInfo["COMBAT_GUILD_XP_GAIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  107. ChatTypeInfo["PET_BATTLE_COMBAT_LOG"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  108. ChatTypeInfo["PET_BATTLE_INFO"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
  109. --NEW_CHAT_TYPE -Add the info here.
  110. ChatTypeGroup = {};
  111. ChatTypeGroup["SYSTEM"] = {
  112. "CHAT_MSG_SYSTEM",
  113. "TIME_PLAYED_MSG",
  114. "PLAYER_LEVEL_UP",
  115. "UNIT_LEVEL",
  116. "CHARACTER_POINTS_CHANGED",
  117. "CHAT_MSG_BN_WHISPER_PLAYER_OFFLINE",
  118. };
  119. ChatTypeGroup["SAY"] = {
  120. "CHAT_MSG_SAY",
  121. };
  122. ChatTypeGroup["EMOTE"] = {
  123. "CHAT_MSG_EMOTE",
  124. "CHAT_MSG_TEXT_EMOTE",
  125. };
  126. ChatTypeGroup["YELL"] = {
  127. "CHAT_MSG_YELL",
  128. };
  129. ChatTypeGroup["WHISPER"] = {
  130. "CHAT_MSG_WHISPER",
  131. "CHAT_MSG_WHISPER_INFORM",
  132. "CHAT_MSG_AFK",
  133. "CHAT_MSG_DND",
  134. };
  135. ChatTypeGroup["PARTY"] = {
  136. "CHAT_MSG_PARTY",
  137. "CHAT_MSG_MONSTER_PARTY",
  138. };
  139. ChatTypeGroup["PARTY_LEADER"] = {
  140. "CHAT_MSG_PARTY_LEADER",
  141. };
  142. ChatTypeGroup["RAID"] = {
  143. "CHAT_MSG_RAID",
  144. };
  145. ChatTypeGroup["RAID_LEADER"] = {
  146. "CHAT_MSG_RAID_LEADER",
  147. };
  148. ChatTypeGroup["RAID_WARNING"] = {
  149. "CHAT_MSG_RAID_WARNING",
  150. };
  151. ChatTypeGroup["INSTANCE_CHAT"] = {
  152. "CHAT_MSG_INSTANCE_CHAT",
  153. };
  154. ChatTypeGroup["INSTANCE_CHAT_LEADER"] = {
  155. "CHAT_MSG_INSTANCE_CHAT_LEADER",
  156. };
  157. ChatTypeGroup["GUILD"] = {
  158. "CHAT_MSG_GUILD",
  159. "GUILD_MOTD",
  160. "UNIT_GUILD_LEVEL",
  161. };
  162. ChatTypeGroup["OFFICER"] = {
  163. "CHAT_MSG_OFFICER",
  164. };
  165. ChatTypeGroup["MONSTER_SAY"] = {
  166. "CHAT_MSG_MONSTER_SAY",
  167. };
  168. ChatTypeGroup["MONSTER_YELL"] = {
  169. "CHAT_MSG_MONSTER_YELL",
  170. };
  171. ChatTypeGroup["MONSTER_EMOTE"] = {
  172. "CHAT_MSG_MONSTER_EMOTE",
  173. };
  174. ChatTypeGroup["MONSTER_WHISPER"] = {
  175. "CHAT_MSG_MONSTER_WHISPER",
  176. };
  177. ChatTypeGroup["MONSTER_BOSS_EMOTE"] = {
  178. "CHAT_MSG_RAID_BOSS_EMOTE",
  179. };
  180. ChatTypeGroup["MONSTER_BOSS_WHISPER"] = {
  181. "CHAT_MSG_RAID_BOSS_WHISPER",
  182. };
  183. ChatTypeGroup["ERRORS"] = {
  184. "CHAT_MSG_RESTRICTED",
  185. "CHAT_MSG_FILTERED",
  186. };
  187. ChatTypeGroup["AFK"] = {
  188. "CHAT_MSG_AFK",
  189. };
  190. ChatTypeGroup["DND"] = {
  191. "CHAT_MSG_DND",
  192. };
  193. ChatTypeGroup["IGNORED"] = {
  194. "CHAT_MSG_IGNORED",
  195. };
  196. ChatTypeGroup["BG_HORDE"] = {
  197. "CHAT_MSG_BG_SYSTEM_HORDE",
  198. };
  199. ChatTypeGroup["BG_ALLIANCE"] = {
  200. "CHAT_MSG_BG_SYSTEM_ALLIANCE",
  201. };
  202. ChatTypeGroup["BG_NEUTRAL"] = {
  203. "CHAT_MSG_BG_SYSTEM_NEUTRAL",
  204. };
  205. ChatTypeGroup["COMBAT_XP_GAIN"] = {
  206. "CHAT_MSG_COMBAT_XP_GAIN";
  207. }
  208. ChatTypeGroup["COMBAT_HONOR_GAIN"] = {
  209. "CHAT_MSG_COMBAT_HONOR_GAIN";
  210. }
  211. ChatTypeGroup["COMBAT_FACTION_CHANGE"] = {
  212. "CHAT_MSG_COMBAT_FACTION_CHANGE";
  213. };
  214. ChatTypeGroup["SKILL"] = {
  215. "CHAT_MSG_SKILL",
  216. };
  217. ChatTypeGroup["LOOT"] = {
  218. "CHAT_MSG_LOOT",
  219. };
  220. ChatTypeGroup["CURRENCY"] = {
  221. "CHAT_MSG_CURRENCY",
  222. };
  223. ChatTypeGroup["MONEY"] = {
  224. "CHAT_MSG_MONEY",
  225. };
  226. ChatTypeGroup["OPENING"] = {
  227. "CHAT_MSG_OPENING";
  228. };
  229. ChatTypeGroup["TRADESKILLS"] = {
  230. "CHAT_MSG_TRADESKILLS";
  231. };
  232. ChatTypeGroup["PET_INFO"] = {
  233. "CHAT_MSG_PET_INFO";
  234. };
  235. ChatTypeGroup["COMBAT_MISC_INFO"] = {
  236. "CHAT_MSG_COMBAT_MISC_INFO";
  237. };
  238. ChatTypeGroup["ACHIEVEMENT"] = {
  239. "CHAT_MSG_ACHIEVEMENT";
  240. };
  241. ChatTypeGroup["GUILD_ACHIEVEMENT"] = {
  242. "CHAT_MSG_GUILD_ACHIEVEMENT";
  243. };
  244. ChatTypeGroup["CHANNEL"] = {
  245. "CHAT_MSG_CHANNEL_JOIN",
  246. "CHAT_MSG_CHANNEL_LEAVE",
  247. "CHAT_MSG_CHANNEL_NOTICE",
  248. "CHAT_MSG_CHANNEL_NOTICE_USER",
  249. "CHAT_MSG_CHANNEL_LIST",
  250. };
  251. ChatTypeGroup["TARGETICONS"] = {
  252. "CHAT_MSG_TARGETICONS"
  253. };
  254. ChatTypeGroup["BN_WHISPER"] = {
  255. "CHAT_MSG_BN_WHISPER",
  256. "CHAT_MSG_BN_WHISPER_INFORM",
  257. };
  258. ChatTypeGroup["BN_CONVERSATION"] = {
  259. "CHAT_MSG_BN_CONVERSATION",
  260. "CHAT_MSG_BN_CONVERSATION_NOTICE",
  261. "CHAT_MSG_BN_CONVERSATION_LIST",
  262. };
  263. ChatTypeGroup["BN_INLINE_TOAST_ALERT"] = {
  264. "CHAT_MSG_BN_INLINE_TOAST_ALERT",
  265. "CHAT_MSG_BN_INLINE_TOAST_BROADCAST",
  266. "CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM",
  267. "CHAT_MSG_BN_INLINE_TOAST_CONVERSATION",
  268. };
  269. ChatTypeGroup["COMBAT_GUILD_XP_GAIN"] = {
  270. "CHAT_MSG_COMBAT_GUILD_XP_GAIN",
  271. };
  272. ChatTypeGroup["PET_BATTLE_COMBAT_LOG"] = {
  273. "CHAT_MSG_PET_BATTLE_COMBAT_LOG",
  274. };
  275. ChatTypeGroup["PET_BATTLE_INFO"] = {
  276. "CHAT_MSG_PET_BATTLE_INFO",
  277. };
  278. --NEW_CHAT_TYPE - Add the chat type above.
  279. ChatTypeGroupInverted = {};
  280. for group, values in pairs(ChatTypeGroup) do
  281. for _, value in pairs(values) do
  282. ChatTypeGroupInverted[value] = group;
  283. end
  284. end
  285. CHAT_CATEGORY_LIST = {
  286. PARTY = { "PARTY_LEADER", "PARTY_GUIDE", "MONSTER_PARTY" },
  287. RAID = { "RAID_LEADER", "RAID_WARNING" },
  288. GUILD = { "GUILD_ACHIEVEMENT" },
  289. WHISPER = { "WHISPER_INFORM", "AFK", "DND" },
  290. CHANNEL = { "CHANNEL_JOIN", "CHANNEL_LEAVE", "CHANNEL_NOTICE", "CHANNEL_USER" },
  291. INSTANCE_CHAT = { "INSTANCE_CHAT_LEADER" },
  292. BN_WHISPER = { "BN_WHISPER_INFORM" },
  293. BN_CONVERSATION = { "BN_CONVERSATION_NOTICE", "BN_CONVERSATION_LIST" },
  294. };
  295. CHAT_INVERTED_CATEGORY_LIST = {};
  296. for category, sublist in pairs(CHAT_CATEGORY_LIST) do
  297. for _, item in pairs(sublist) do
  298. CHAT_INVERTED_CATEGORY_LIST[item] = category;
  299. end
  300. end
  301. function Chat_GetChatCategory(chatType)
  302. return CHAT_INVERTED_CATEGORY_LIST[chatType] or chatType;
  303. end
  304. -- list of text emotes that we want to show on the Emote submenu (these have anims)
  305. EmoteList = {
  306. "WAVE",
  307. "BOW",
  308. "DANCE",
  309. "APPLAUD",
  310. "BEG",
  311. "CHICKEN",
  312. "CRY",
  313. "EAT",
  314. "FLEX",
  315. "KISS",
  316. "LAUGH",
  317. "POINT",
  318. "ROAR",
  319. "RUDE",
  320. "SALUTE",
  321. "SHY",
  322. "TALK",
  323. "STAND",
  324. "SIT",
  325. "SLEEP",
  326. "KNEEL",
  327. };
  328. -- list of text emotes that we want to show on the Speech submenu (these have sounds)
  329. TextEmoteSpeechList = {
  330. "HELPME",
  331. "INCOMING",
  332. "CHARGE",
  333. "FLEE",
  334. "ATTACKMYTARGET",
  335. "OOM",
  336. "FOLLOW",
  337. "WAIT",
  338. "HEALME",
  339. "CHEER",
  340. "OPENFIRE",
  341. "RASP",
  342. "HELLO",
  343. "BYE",
  344. "NOD",
  345. "NO",
  346. "THANK",
  347. "WELCOME",
  348. "CONGRATULATE",
  349. "FLIRT",
  350. "JOKE",
  351. "TRAIN",
  352. };
  353. -- These are text emote tokens - add new ones at the bottom of the list!
  354. EMOTE1_TOKEN = "AGREE";
  355. EMOTE2_TOKEN = "AMAZE";
  356. EMOTE3_TOKEN = "ANGRY";
  357. EMOTE4_TOKEN = "APOLOGIZE";
  358. EMOTE5_TOKEN = "APPLAUD";
  359. EMOTE6_TOKEN = "BASHFUL";
  360. EMOTE7_TOKEN = "BECKON";
  361. EMOTE8_TOKEN = "BEG";
  362. EMOTE9_TOKEN = "BITE";
  363. EMOTE10_TOKEN = "BLEED";
  364. EMOTE11_TOKEN = "BLINK";
  365. EMOTE12_TOKEN = "BLUSH";
  366. EMOTE13_TOKEN = "BONK";
  367. EMOTE14_TOKEN = "BORED";
  368. EMOTE15_TOKEN = "BOUNCE";
  369. EMOTE16_TOKEN = "BRB";
  370. EMOTE17_TOKEN = "BOW";
  371. EMOTE18_TOKEN = "BURP";
  372. EMOTE19_TOKEN = "BYE";
  373. EMOTE20_TOKEN = "CACKLE";
  374. EMOTE21_TOKEN = "CHEER";
  375. EMOTE22_TOKEN = "CHICKEN";
  376. EMOTE23_TOKEN = "CHUCKLE";
  377. EMOTE24_TOKEN = "CLAP";
  378. EMOTE25_TOKEN = "CONFUSED";
  379. EMOTE26_TOKEN = "CONGRATULATE";
  380. EMOTE27_TOKEN = "UNUSED";
  381. EMOTE28_TOKEN = "COUGH";
  382. EMOTE29_TOKEN = "COWER";
  383. EMOTE30_TOKEN = "CRACK";
  384. EMOTE31_TOKEN = "CRINGE";
  385. EMOTE32_TOKEN = "CRY";
  386. EMOTE33_TOKEN = "CURIOUS";
  387. EMOTE34_TOKEN = "CURTSEY";
  388. EMOTE35_TOKEN = "DANCE";
  389. EMOTE36_TOKEN = "DRINK";
  390. EMOTE37_TOKEN = "DROOL";
  391. EMOTE38_TOKEN = "EAT";
  392. EMOTE39_TOKEN = "EYE";
  393. EMOTE40_TOKEN = "FART";
  394. EMOTE41_TOKEN = "FIDGET";
  395. EMOTE42_TOKEN = "FLEX";
  396. EMOTE43_TOKEN = "FROWN";
  397. EMOTE44_TOKEN = "GASP";
  398. EMOTE45_TOKEN = "GAZE";
  399. EMOTE46_TOKEN = "GIGGLE";
  400. EMOTE47_TOKEN = "GLARE";
  401. EMOTE48_TOKEN = "GLOAT";
  402. EMOTE49_TOKEN = "GREET";
  403. EMOTE50_TOKEN = "GRIN";
  404. EMOTE51_TOKEN = "GROAN";
  405. EMOTE52_TOKEN = "GROVEL";
  406. EMOTE53_TOKEN = "GUFFAW";
  407. EMOTE54_TOKEN = "HAIL";
  408. EMOTE55_TOKEN = "HAPPY";
  409. EMOTE56_TOKEN = "HELLO";
  410. EMOTE57_TOKEN = "HUG";
  411. EMOTE58_TOKEN = "HUNGRY";
  412. EMOTE59_TOKEN = "KISS";
  413. EMOTE60_TOKEN = "KNEEL";
  414. EMOTE61_TOKEN = "LAUGH";
  415. EMOTE62_TOKEN = "LAYDOWN";
  416. EMOTE63_TOKEN = "MASSAGE";
  417. EMOTE64_TOKEN = "MOAN";
  418. EMOTE65_TOKEN = "MOON";
  419. EMOTE66_TOKEN = "MOURN";
  420. EMOTE67_TOKEN = "NO";
  421. EMOTE68_TOKEN = "NOD";
  422. EMOTE69_TOKEN = "NOSEPICK";
  423. EMOTE70_TOKEN = "PANIC";
  424. EMOTE71_TOKEN = "PEER";
  425. EMOTE72_TOKEN = "PLEAD";
  426. EMOTE73_TOKEN = "POINT";
  427. EMOTE74_TOKEN = "POKE";
  428. EMOTE75_TOKEN = "PRAY";
  429. EMOTE76_TOKEN = "ROAR";
  430. EMOTE77_TOKEN = "ROFL";
  431. EMOTE78_TOKEN = "RUDE";
  432. EMOTE79_TOKEN = "SALUTE";
  433. EMOTE80_TOKEN = "SCRATCH";
  434. EMOTE81_TOKEN = "SEXY";
  435. EMOTE82_TOKEN = "SHAKE";
  436. EMOTE83_TOKEN = "SHOUT";
  437. EMOTE84_TOKEN = "SHRUG";
  438. EMOTE85_TOKEN = "SHY";
  439. EMOTE86_TOKEN = "SIGH";
  440. EMOTE87_TOKEN = "SIT";
  441. EMOTE88_TOKEN = "SLEEP";
  442. EMOTE89_TOKEN = "SNARL";
  443. EMOTE90_TOKEN = "SPIT";
  444. EMOTE91_TOKEN = "STARE";
  445. EMOTE92_TOKEN = "SURPRISED";
  446. EMOTE93_TOKEN = "SURRENDER";
  447. EMOTE94_TOKEN = "TALK";
  448. EMOTE95_TOKEN = "TALKEX";
  449. EMOTE96_TOKEN = "TALKQ";
  450. EMOTE97_TOKEN = "TAP";
  451. EMOTE98_TOKEN = "THANK";
  452. EMOTE99_TOKEN = "THREATEN";
  453. EMOTE100_TOKEN = "TIRED";
  454. EMOTE101_TOKEN = "VICTORY";
  455. EMOTE102_TOKEN = "WAVE";
  456. EMOTE103_TOKEN = "WELCOME";
  457. EMOTE104_TOKEN = "WHINE";
  458. EMOTE105_TOKEN = "WHISTLE";
  459. EMOTE106_TOKEN = "WORK";
  460. EMOTE107_TOKEN = "YAWN";
  461. EMOTE108_TOKEN = "BOGGLE";
  462. EMOTE109_TOKEN = "CALM";
  463. EMOTE110_TOKEN = "COLD";
  464. EMOTE111_TOKEN = "COMFORT";
  465. EMOTE112_TOKEN = "CUDDLE";
  466. EMOTE113_TOKEN = "DUCK";
  467. EMOTE114_TOKEN = "INSULT";
  468. EMOTE115_TOKEN = "INTRODUCE";
  469. EMOTE116_TOKEN = "JK";
  470. EMOTE117_TOKEN = "LICK";
  471. EMOTE118_TOKEN = "LISTEN";
  472. EMOTE119_TOKEN = "LOST";
  473. EMOTE120_TOKEN = "MOCK";
  474. EMOTE121_TOKEN = "PONDER";
  475. EMOTE122_TOKEN = "POUNCE";
  476. EMOTE123_TOKEN = "PRAISE";
  477. EMOTE124_TOKEN = "PURR";
  478. EMOTE125_TOKEN = "PUZZLE";
  479. EMOTE126_TOKEN = "RAISE";
  480. EMOTE127_TOKEN = "READY";
  481. EMOTE128_TOKEN = "SHIMMY";
  482. EMOTE129_TOKEN = "SHIVER";
  483. EMOTE130_TOKEN = "SHOO";
  484. EMOTE131_TOKEN = "SLAP";
  485. EMOTE132_TOKEN = "SMIRK";
  486. EMOTE133_TOKEN = "SNIFF";
  487. EMOTE134_TOKEN = "SNUB";
  488. EMOTE135_TOKEN = "SOOTHE";
  489. EMOTE136_TOKEN = "STINK";
  490. EMOTE137_TOKEN = "TAUNT";
  491. EMOTE138_TOKEN = "TEASE";
  492. EMOTE139_TOKEN = "THIRSTY";
  493. EMOTE140_TOKEN = "VETO";
  494. EMOTE141_TOKEN = "SNICKER";
  495. EMOTE142_TOKEN = "TICKLE";
  496. EMOTE143_TOKEN = "STAND";
  497. EMOTE144_TOKEN = "VIOLIN";
  498. EMOTE145_TOKEN = "SMILE";
  499. EMOTE146_TOKEN = "RASP";
  500. EMOTE147_TOKEN = "GROWL";
  501. EMOTE148_TOKEN = "BARK";
  502. EMOTE149_TOKEN = "PITY";
  503. EMOTE150_TOKEN = "SCARED";
  504. EMOTE151_TOKEN = "FLOP";
  505. EMOTE152_TOKEN = "LOVE";
  506. EMOTE153_TOKEN = "MOO";
  507. EMOTE154_TOKEN = "COMMEND";
  508. EMOTE155_TOKEN = "TRAIN";
  509. EMOTE156_TOKEN = "HELPME";
  510. EMOTE157_TOKEN = "INCOMING";
  511. EMOTE158_TOKEN = "OPENFIRE";
  512. EMOTE159_TOKEN = "CHARGE";
  513. EMOTE160_TOKEN = "FLEE";
  514. EMOTE161_TOKEN = "ATTACKMYTARGET";
  515. EMOTE162_TOKEN = "OOM";
  516. EMOTE163_TOKEN = "FOLLOW";
  517. EMOTE164_TOKEN = "WAIT";
  518. EMOTE165_TOKEN = "FLIRT";
  519. EMOTE166_TOKEN = "HEALME";
  520. EMOTE167_TOKEN = "JOKE";
  521. EMOTE168_TOKEN = "WINK";
  522. EMOTE169_TOKEN = "PAT";
  523. EMOTE170_TOKEN = "GOLFCLAP";
  524. EMOTE171_TOKEN = "MOUNTSPECIAL";
  525. EMOTE304_TOKEN = "INCOMING";
  526. EMOTE306_TOKEN = "FLEE";
  527. EMOTE368_TOKEN = "BLAME"
  528. EMOTE369_TOKEN = "BLANK"
  529. EMOTE370_TOKEN = "BRANDISH"
  530. EMOTE371_TOKEN = "BREATH"
  531. EMOTE372_TOKEN = "DISAGREE"
  532. EMOTE373_TOKEN = "DOUBT"
  533. EMOTE374_TOKEN = "EMBARRASS"
  534. EMOTE375_TOKEN = "ENCOURAGE"
  535. EMOTE376_TOKEN = "ENEMY"
  536. EMOTE377_TOKEN = "EYEBROW"
  537. EMOTE380_TOKEN = "HIGHFIVE"
  538. EMOTE381_TOKEN = "ABSENT"
  539. EMOTE382_TOKEN = "ARM"
  540. EMOTE383_TOKEN = "AWE"
  541. EMOTE384_TOKEN = "BACKPACK"
  542. EMOTE385_TOKEN = "BADFEELING"
  543. EMOTE386_TOKEN = "CHALLENGE"
  544. EMOTE387_TOKEN = "CHUG"
  545. EMOTE389_TOKEN = "DING"
  546. EMOTE390_TOKEN = "FACEPALM"
  547. EMOTE391_TOKEN = "FAINT"
  548. EMOTE392_TOKEN = "GO"
  549. EMOTE393_TOKEN = "GOING"
  550. EMOTE394_TOKEN = "GLOWER"
  551. EMOTE395_TOKEN = "HEADACHE"
  552. EMOTE396_TOKEN = "HICCUP"
  553. EMOTE398_TOKEN = "HISS"
  554. EMOTE399_TOKEN = "HOLDHAND"
  555. EMOTE401_TOKEN = "HURRY"
  556. EMOTE402_TOKEN = "IDEA"
  557. EMOTE403_TOKEN = "JEALOUS"
  558. EMOTE404_TOKEN = "LUCK"
  559. EMOTE405_TOKEN = "MAP"
  560. EMOTE406_TOKEN = "MERCY"
  561. EMOTE407_TOKEN = "MUTTER"
  562. EMOTE408_TOKEN = "NERVOUS"
  563. EMOTE409_TOKEN = "OFFER"
  564. EMOTE410_TOKEN = "PET"
  565. EMOTE411_TOKEN = "PINCH"
  566. EMOTE413_TOKEN = "PROUD"
  567. EMOTE414_TOKEN = "PROMISE"
  568. EMOTE415_TOKEN = "PULSE"
  569. EMOTE416_TOKEN = "PUNCH"
  570. EMOTE417_TOKEN = "POUT"
  571. EMOTE418_TOKEN = "REGRET"
  572. EMOTE420_TOKEN = "REVENGE"
  573. EMOTE421_TOKEN = "ROLLEYES"
  574. EMOTE422_TOKEN = "RUFFLE"
  575. EMOTE423_TOKEN = "SAD"
  576. EMOTE424_TOKEN = "SCOFF"
  577. EMOTE425_TOKEN = "SCOLD"
  578. EMOTE426_TOKEN = "SCOWL"
  579. EMOTE427_TOKEN = "SEARCH"
  580. EMOTE428_TOKEN = "SHAKEFIST"
  581. EMOTE429_TOKEN = "SHIFTY"
  582. EMOTE430_TOKEN = "SHUDDER"
  583. EMOTE431_TOKEN = "SIGNAL"
  584. EMOTE432_TOKEN = "SILENCE"
  585. EMOTE433_TOKEN = "SING"
  586. EMOTE434_TOKEN = "SMACK"
  587. EMOTE435_TOKEN = "SNEAK"
  588. EMOTE436_TOKEN = "SNEEZE"
  589. EMOTE437_TOKEN = "SNORT"
  590. EMOTE438_TOKEN = "SQUEAL"
  591. EMOTE440_TOKEN = "SUSPICIOUS"
  592. EMOTE441_TOKEN = "THINK"
  593. EMOTE442_TOKEN = "TRUCE"
  594. EMOTE443_TOKEN = "TWIDDLE"
  595. EMOTE444_TOKEN = "WARN"
  596. EMOTE445_TOKEN = "SNAP"
  597. EMOTE446_TOKEN = "CHARM"
  598. EMOTE447_TOKEN = "COVEREARS"
  599. EMOTE448_TOKEN = "CROSSARMS"
  600. EMOTE449_TOKEN = "LOOK"
  601. EMOTE450_TOKEN = "OBJECT"
  602. EMOTE451_TOKEN = "SWEAT"
  603. EMOTE452_TOKEN = "YW"
  604. EMOTE453_TOKEN = "READ"
  605. local MAXEMOTEINDEX = 453;
  606. ICON_LIST = {
  607. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1:",
  608. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_2:",
  609. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_3:",
  610. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_4:",
  611. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_5:",
  612. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_6:",
  613. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_7:",
  614. "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_8:",
  615. }
  616. --Links tags from Global Strings to indicies for entries in ICON_LIST. This way addons can easily replace icons
  617. ICON_TAG_LIST =
  618. {
  619. [strlower(ICON_TAG_RAID_TARGET_STAR1)] = 1,
  620. [strlower(ICON_TAG_RAID_TARGET_STAR2)] = 1,
  621. [strlower(ICON_TAG_RAID_TARGET_CIRCLE1)] = 2,
  622. [strlower(ICON_TAG_RAID_TARGET_CIRCLE2)] = 2,
  623. [strlower(ICON_TAG_RAID_TARGET_DIAMOND1)] = 3,
  624. [strlower(ICON_TAG_RAID_TARGET_DIAMOND2)] = 3,
  625. [strlower(ICON_TAG_RAID_TARGET_TRIANGLE1)] = 4,
  626. [strlower(ICON_TAG_RAID_TARGET_TRIANGLE2)] = 4,
  627. [strlower(ICON_TAG_RAID_TARGET_MOON1)] = 5,
  628. [strlower(ICON_TAG_RAID_TARGET_MOON2)] = 5,
  629. [strlower(ICON_TAG_RAID_TARGET_SQUARE1)] = 6,
  630. [strlower(ICON_TAG_RAID_TARGET_SQUARE2)] = 6,
  631. [strlower(ICON_TAG_RAID_TARGET_CROSS1)] = 7,
  632. [strlower(ICON_TAG_RAID_TARGET_CROSS2)] = 7,
  633. [strlower(ICON_TAG_RAID_TARGET_SKULL1)] = 8,
  634. [strlower(ICON_TAG_RAID_TARGET_SKULL2)] = 8,
  635. [strlower(RAID_TARGET_1)] = 1,
  636. [strlower(RAID_TARGET_2)] = 2,
  637. [strlower(RAID_TARGET_3)] = 3,
  638. [strlower(RAID_TARGET_4)] = 4,
  639. [strlower(RAID_TARGET_5)] = 5,
  640. [strlower(RAID_TARGET_6)] = 6,
  641. [strlower(RAID_TARGET_7)] = 7,
  642. [strlower(RAID_TARGET_8)] = 8,
  643. }
  644. GROUP_TAG_LIST =
  645. {
  646. [strlower(GROUP1_CHAT_TAG1)] = 1,
  647. [strlower(GROUP1_CHAT_TAG2)] = 1,
  648. [strlower(GROUP2_CHAT_TAG1)] = 2,
  649. [strlower(GROUP2_CHAT_TAG2)] = 2,
  650. [strlower(GROUP3_CHAT_TAG1)] = 3,
  651. [strlower(GROUP3_CHAT_TAG2)] = 3,
  652. [strlower(GROUP4_CHAT_TAG1)] = 4,
  653. [strlower(GROUP4_CHAT_TAG2)] = 4,
  654. [strlower(GROUP5_CHAT_TAG1)] = 5,
  655. [strlower(GROUP5_CHAT_TAG2)] = 5,
  656. [strlower(GROUP6_CHAT_TAG1)] = 6,
  657. [strlower(GROUP6_CHAT_TAG2)] = 6,
  658. [strlower(GROUP7_CHAT_TAG1)] = 7,
  659. [strlower(GROUP7_CHAT_TAG2)] = 7,
  660. [strlower(GROUP8_CHAT_TAG1)] = 8,
  661. [strlower(GROUP8_CHAT_TAG2)] = 8,
  662. --Language independent:
  663. ["g1"] = 1;
  664. ["g2"] = 2;
  665. ["g3"] = 3;
  666. ["g4"] = 4;
  667. ["g5"] = 5;
  668. ["g6"] = 6;
  669. ["g7"] = 7;
  670. ["g8"] = 8;
  671. };
  672. GROUP_LANGUAGE_INDEPENDENT_STRINGS =
  673. {
  674. "g1",
  675. "g2",
  676. "g3",
  677. "g4",
  678. "g5",
  679. "g6",
  680. "g7",
  681. "g8",
  682. };
  683. -- Arena Team Helper Function
  684. function ArenaTeam_GetTeamSizeID(teamsizearg)
  685. local teamname, teamsize, id;
  686. for i=1, MAX_ARENA_TEAMS do
  687. teamname, teamsize = GetArenaTeam(i)
  688. if ( teamsizearg == teamsize ) then
  689. id = i;
  690. end
  691. end
  692. return id;
  693. end
  694. --
  695. -- CastSequence support
  696. --
  697. local CastSequenceManager;
  698. local CastSequenceTable = {};
  699. local CastSequenceFreeList = {};
  700. local function CreateCanonicalActions(entry, ...)
  701. entry.spells = {};
  702. entry.spellNames = {};
  703. entry.items = {};
  704. local count = 0;
  705. for i=1, select("#", ...) do
  706. local action = strlower(strtrim((select(i, ...))));
  707. if ( action and action ~="" ) then
  708. count = count + 1;
  709. if ( GetItemInfo(action) or select(3, SecureCmdItemParse(action)) ) then
  710. entry.items[count] = action;
  711. entry.spells[count] = strlower(GetItemSpell(action) or "");
  712. entry.spellNames[count] = entry.spells[count];
  713. else
  714. entry.spells[count] = action;
  715. entry.spellNames[count] = gsub(action, "!*(.*)", "%1");
  716. end
  717. end
  718. end
  719. end
  720. local function SetCastSequenceIndex(entry, index)
  721. entry.index = index;
  722. entry.pending = nil;
  723. end
  724. local function ResetCastSequence(sequence, entry)
  725. SetCastSequenceIndex(entry, 1);
  726. CastSequenceFreeList[sequence] = entry;
  727. CastSequenceTable[sequence] = nil;
  728. end
  729. local function SetNextCastSequence(sequence, entry)
  730. if ( entry.index == #entry.spells ) then
  731. ResetCastSequence(sequence, entry);
  732. else
  733. SetCastSequenceIndex(entry, entry.index + 1);
  734. end
  735. end
  736. local function CastSequenceManager_OnEvent(self, event, ...)
  737. -- Reset all sequences when the player dies
  738. if ( event == "PLAYER_DEAD" ) then
  739. for sequence, entry in pairs(CastSequenceTable) do
  740. ResetCastSequence(sequence, entry);
  741. end
  742. return;
  743. end
  744. -- Increment sequences for spells which succeed.
  745. if ( event == "UNIT_SPELLCAST_SENT" or
  746. event == "UNIT_SPELLCAST_SUCCEEDED" or
  747. event == "UNIT_SPELLCAST_INTERRUPTED" or
  748. event == "UNIT_SPELLCAST_FAILED" or
  749. event == "UNIT_SPELLCAST_FAILED_QUIET" ) then
  750. local unit, name, rank, castID, _;
  751. if ( event == "UNIT_SPELLCAST_SENT" ) then
  752. unit, name, rank, _, castID = ...;
  753. else
  754. unit, name, rank, castID = ...;
  755. end
  756. if ( not name ) then
  757. -- This was a server-side only spell affecting the player somehow, don't do anything with cast sequencing, just bail.
  758. return;
  759. end
  760. if ( unit == "player" or unit == "pet" ) then
  761. name, rank = strlower(name), strlower(rank);
  762. local nameplus = name.."()";
  763. local fullname = name.."("..rank..")";
  764. for sequence, entry in pairs(CastSequenceTable) do
  765. local entryName = entry.spellNames[entry.index];
  766. if ( entryName == name or entryName == nameplus or entryName == fullname ) then
  767. if ( event == "UNIT_SPELLCAST_SENT" ) then
  768. entry.pending = castID;
  769. elseif ( entry.pending == castID ) then
  770. entry.pending = nil;
  771. if ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
  772. SetNextCastSequence(sequence, entry);
  773. end
  774. end
  775. end
  776. end
  777. end
  778. return;
  779. end
  780. -- Handle reset events
  781. local reset = "";
  782. if ( event == "PLAYER_TARGET_CHANGED" ) then
  783. reset = "target";
  784. elseif ( event == "PLAYER_REGEN_ENABLED" ) then
  785. reset = "combat";
  786. end
  787. for sequence, entry in pairs(CastSequenceTable) do
  788. if ( strfind(entry.reset, reset, 1, true) ) then
  789. ResetCastSequence(sequence, entry);
  790. end
  791. end
  792. end
  793. local function CastSequenceManager_OnUpdate(self, elapsed)
  794. elapsed = self.elapsed + elapsed;
  795. if ( elapsed < 1 ) then
  796. self.elapsed = elapsed;
  797. return;
  798. end
  799. for sequence, entry in pairs(CastSequenceTable) do
  800. if ( entry.timeout ) then
  801. if ( elapsed >= entry.timeout ) then
  802. ResetCastSequence(sequence, entry);
  803. else
  804. entry.timeout = entry.timeout - elapsed;
  805. end
  806. end
  807. end
  808. self.elapsed = 0;
  809. end
  810. local function ExecuteCastSequence(sequence, target)
  811. if ( not CastSequenceManager ) then
  812. CastSequenceManager = CreateFrame("Frame");
  813. CastSequenceManager.elapsed = 0;
  814. CastSequenceManager:RegisterEvent("PLAYER_DEAD");
  815. CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_SENT");
  816. CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
  817. CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
  818. CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_FAILED");
  819. CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET");
  820. CastSequenceManager:RegisterEvent("PLAYER_TARGET_CHANGED");
  821. CastSequenceManager:RegisterEvent("PLAYER_REGEN_ENABLED");
  822. CastSequenceManager:SetScript("OnEvent", CastSequenceManager_OnEvent);
  823. CastSequenceManager:SetScript("OnUpdate", CastSequenceManager_OnUpdate);
  824. end
  825. local entry = CastSequenceTable[sequence];
  826. if ( not entry ) then
  827. entry = CastSequenceFreeList[sequence];
  828. if ( not entry ) then
  829. local reset, spells = strmatch(sequence, "^reset=([^%s]+)%s*(.*)");
  830. if ( not reset ) then
  831. spells = sequence;
  832. end
  833. entry = {};
  834. CreateCanonicalActions(entry, strsplit(",", spells));
  835. entry.reset = strlower(reset or "");
  836. end
  837. CastSequenceTable[sequence] = entry;
  838. entry.index = 1;
  839. end
  840. -- Don't do anything if this entry is still pending
  841. if ( entry.pending ) then
  842. return;
  843. end
  844. -- See if modified click restarts the sequence
  845. if ( (IsShiftKeyDown() and strfind(entry.reset, "shift", 1, true)) or
  846. (IsControlKeyDown() and strfind(entry.reset, "ctrl", 1, true)) or
  847. (IsAltKeyDown() and strfind(entry.reset, "alt", 1, true)) ) then
  848. SetCastSequenceIndex(entry, 1);
  849. end
  850. -- Reset the timeout each time the sequence is used
  851. local timeout = strmatch(entry.reset, "(%d+)");
  852. if ( timeout ) then
  853. entry.timeout = CastSequenceManager.elapsed + tonumber(timeout);
  854. end
  855. -- Execute the sequence!
  856. local item, spell = entry.items[entry.index], entry.spells[entry.index];
  857. if ( item ) then
  858. local name, bag, slot = SecureCmdItemParse(item);
  859. if ( slot ) then
  860. if ( name ) then
  861. spell = strlower(GetItemSpell(name) or "");
  862. else
  863. spell = "";
  864. end
  865. entry.spellNames[entry.index] = spell;
  866. end
  867. if ( IsEquippableItem(name) and not IsEquippedItem(name) ) then
  868. EquipItemByName(name);
  869. else
  870. SecureCmdUseItem(name, bag, slot, target);
  871. end
  872. else
  873. CastSpellByName(spell, target);
  874. end
  875. if ( spell == "" ) then
  876. SetNextCastSequence(sequence, entry);
  877. end
  878. end
  879. function QueryCastSequence(sequence)
  880. local index = 1;
  881. local item, spell;
  882. local entry = CastSequenceTable[sequence];
  883. if ( entry ) then
  884. if ( (IsShiftKeyDown() and strfind(entry.reset, "shift", 1, true)) or
  885. (IsControlKeyDown() and strfind(entry.reset, "ctrl", 1, true)) or
  886. (IsAltKeyDown() and strfind(entry.reset, "alt", 1, true)) ) then
  887. index = 1;
  888. else
  889. index = entry.index;
  890. end
  891. item, spell = entry.items[index], entry.spells[index];
  892. else
  893. entry = CastSequenceFreeList[sequence];
  894. if ( entry ) then
  895. item, spell = entry.items[index], entry.spells[index];
  896. else
  897. local reset, spells = strmatch(sequence, "^reset=([^%s]+)%s*(.*)");
  898. if ( not reset ) then
  899. spells = sequence;
  900. end
  901. local action = strlower(strtrim((strsplit(",", spells))));
  902. if ( GetItemInfo(action) or select(3, SecureCmdItemParse(action)) ) then
  903. item, spell = action, strlower(GetItemSpell(action) or "");
  904. else
  905. item, spell = nil, action;
  906. end
  907. end
  908. end
  909. if ( item ) then
  910. local name, bag, slot = SecureCmdItemParse(item);
  911. if ( slot ) then
  912. if ( name ) then
  913. spell = strlower(GetItemSpell(name) or "");
  914. else
  915. spell = "";
  916. end
  917. end
  918. end
  919. return index, item, spell;
  920. end
  921. local CastRandomManager;
  922. local CastRandomTable = {};
  923. local function CastRandomManager_OnEvent(self, event, ...)
  924. local unit, name, rank = ...;
  925. if ( not name ) then
  926. -- This was a server-side only spell affecting the player somehow, don't do anything with cast sequencing, just bail.
  927. return;
  928. end
  929. if ( unit == "player" ) then
  930. name, rank = strlower(name), strlower(rank);
  931. local nameplus = name.."()";
  932. local fullname = name.."("..rank..")";
  933. for sequence, entry in pairs(CastRandomTable) do
  934. if ( entry.pending and entry.value ) then
  935. local entryName = strlower(entry.value);
  936. if ( entryName == name or entryName == nameplus or entryName == fullname ) then
  937. entry.pending = nil;
  938. if ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
  939. entry.value = nil;
  940. end
  941. end
  942. end
  943. end
  944. end
  945. end
  946. local function ExecuteCastRandom(actions)
  947. if ( not CastRandomManager ) then
  948. CastRandomManager = CreateFrame("Frame");
  949. CastRandomManager:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
  950. CastRandomManager:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
  951. CastRandomManager:RegisterEvent("UNIT_SPELLCAST_FAILED");
  952. CastRandomManager:RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET");
  953. CastRandomManager:SetScript("OnEvent", CastRandomManager_OnEvent);
  954. end
  955. local entry = CastRandomTable[actions];
  956. if ( not entry ) then
  957. entry = {};
  958. CreateCanonicalActions(entry, strsplit(",", actions));
  959. CastRandomTable[actions] = entry;
  960. end
  961. if ( not entry.value ) then
  962. entry.value = strtrim(GetRandomArgument(strsplit(",", actions)));
  963. end
  964. entry.pending = true;
  965. return entry.value;
  966. end
  967. function GetRandomArgument(...)
  968. return (select(random(select("#", ...)), ...));
  969. end
  970. -- Slash commands that are protected from tampering
  971. local SecureCmdList = { };
  972. function IsSecureCmd(command)
  973. command = strupper(command);
  974. -- first check the hash table
  975. if ( hash_SecureCmdList[command] ) then
  976. return true;
  977. end
  978. for index, value in pairs(SecureCmdList) do
  979. local i = 1;
  980. local cmdString = _G["SLASH_"..index..i];
  981. while ( cmdString ) do
  982. cmdString = strupper(cmdString);
  983. if ( cmdString == command ) then
  984. return true;
  985. end
  986. i = i + 1;
  987. cmdString = _G["SLASH_"..index..i];
  988. end
  989. end
  990. end
  991. function SecureCmdItemParse(item)
  992. if ( not item ) then
  993. return nil, nil, nil;
  994. end
  995. local bag, slot = strmatch(item, "^(%d+)%s+(%d+)$");
  996. if ( not bag ) then
  997. slot = strmatch(item, "^(%d+)$");
  998. end
  999. if ( bag ) then
  1000. item = GetContainerItemLink(bag, slot);
  1001. elseif ( slot ) then
  1002. item = GetInventoryItemLink("player", slot);
  1003. end
  1004. return item, bag, slot;
  1005. end
  1006. function SecureCmdUseItem(name, bag, slot, target)
  1007. if ( bag ) then
  1008. UseContainerItem(bag, slot, target);
  1009. elseif ( slot ) then
  1010. UseInventoryItem(slot, target);
  1011. else
  1012. UseItemByName(name, target);
  1013. end
  1014. end
  1015. SecureCmdList["STARTATTACK"] = function(msg)
  1016. local action, target = SecureCmdOptionParse(msg);
  1017. if ( action ) then
  1018. if ( not target or target == "target" ) then
  1019. target = action;
  1020. end
  1021. StartAttack(target);
  1022. end
  1023. end
  1024. SecureCmdList["STOPATTACK"] = function(msg)
  1025. if ( SecureCmdOptionParse(msg) ) then
  1026. StopAttack();
  1027. end
  1028. end
  1029. SecureCmdList["CAST"] = function(msg)
  1030. local action, target = SecureCmdOptionParse(msg);
  1031. if ( action ) then
  1032. local name, bag, slot = SecureCmdItemParse(action);
  1033. if ( slot or GetItemInfo(name) ) then
  1034. SecureCmdUseItem(name, bag, slot, target);
  1035. else
  1036. CastSpellByName(action, target);
  1037. end
  1038. end
  1039. end
  1040. SecureCmdList["USE"] = SecureCmdList["CAST"];
  1041. SecureCmdList["CASTRANDOM"] = function(msg)
  1042. local actions, target = SecureCmdOptionParse(msg);
  1043. if ( actions ) then
  1044. local action = ExecuteCastRandom(actions);
  1045. local name, bag, slot = SecureCmdItemParse(action);
  1046. if ( slot or GetItemInfo(name) ) then
  1047. SecureCmdUseItem(name, bag, slot, target);
  1048. else
  1049. CastSpellByName(action, target);
  1050. end
  1051. end
  1052. end
  1053. SecureCmdList["USERANDOM"] = SecureCmdList["CASTRANDOM"];
  1054. SecureCmdList["CASTSEQUENCE"] = function(msg)
  1055. local sequence, target = SecureCmdOptionParse(msg);
  1056. if ( sequence and sequence ~= "" ) then
  1057. ExecuteCastSequence(sequence, target);
  1058. end
  1059. end
  1060. SecureCmdList["STOPCASTING"] = function(msg)
  1061. if ( SecureCmdOptionParse(msg) ) then
  1062. SpellStopCasting();
  1063. end
  1064. end
  1065. SecureCmdList["STOPSPELLTARGET"] = function(msg)
  1066. if ( SecureCmdOptionParse(msg) ) then
  1067. SpellStopTargeting();
  1068. end
  1069. end
  1070. SecureCmdList["CANCELAURA"] = function(msg)
  1071. local spell = SecureCmdOptionParse(msg);
  1072. if ( spell ) then
  1073. local name, rank = strmatch(spell, "([^(]+)[(]([^)]+)[)]");
  1074. if ( not name ) then
  1075. name = spell;
  1076. end
  1077. CancelUnitBuff("player", name, rank);
  1078. end
  1079. end
  1080. SecureCmdList["CANCELFORM"] = function(msg)
  1081. if ( SecureCmdOptionParse(msg) ) then
  1082. CancelShapeshiftForm();
  1083. end
  1084. end
  1085. -- Allow friendly names for glyph slots (needs to be local)
  1086. local GLYPH_SLOTS = {
  1087. minor1 = GLYPH_ID_MINOR_1;
  1088. minor2 = GLYPH_ID_MINOR_2;
  1089. minor3 = GLYPH_ID_MINOR_3;
  1090. major1 = GLYPH_ID_MAJOR_1;
  1091. major2 = GLYPH_ID_MAJOR_2;
  1092. major3 = GLYPH_ID_MAJOR_3;
  1093. -- prime1 = GLYPH_ID_PRIME_1;
  1094. -- prime2 = GLYPH_ID_PRIME_2;
  1095. -- prime3 = GLYPH_ID_PRIME_3;
  1096. };
  1097. SecureCmdList["CASTGLYPH"] = function(msg)
  1098. local action = SecureCmdOptionParse(msg);
  1099. if ( action ) then
  1100. local glyph, slot = strmatch(action, "^(%S+)%s+(%S+)$");
  1101. slot = (slot and GLYPH_SLOTS[slot]) or tonumber(slot);
  1102. local glyphID = tonumber(glyph);
  1103. if ( glyphID and slot ) then
  1104. CastGlyphByID(glyphID, slot);
  1105. elseif ( glyph and slot ) then
  1106. CastGlyphByName(glyph, slot);
  1107. end
  1108. end
  1109. end
  1110. SecureCmdList["EQUIP"] = function(msg)
  1111. local item = SecureCmdOptionParse(msg);
  1112. if ( item ) then
  1113. EquipItemByName((SecureCmdItemParse(item)));
  1114. end
  1115. end
  1116. SecureCmdList["EQUIP_TO_SLOT"] = function(msg)
  1117. local action = SecureCmdOptionParse(msg);
  1118. if ( action ) then
  1119. local slot, item = strmatch(action, "^(%d+)%s+(.*)");
  1120. if ( item ) then
  1121. if ( PaperDoll_IsEquippedSlot(slot) ) then
  1122. EquipItemByName(SecureCmdItemParse(item), slot);
  1123. else
  1124. -- user specified a bad slot number (slot that you can't equip an item to)
  1125. ChatFrame_DisplayUsageError(format(ERROR_SLASH_EQUIP_TO_SLOT, EQUIPPED_FIRST, EQUIPPED_LAST));
  1126. end
  1127. elseif ( slot ) then
  1128. -- user specified a slot but not an item
  1129. ChatFrame_DisplayUsageError(format(ERROR_SLASH_EQUIP_TO_SLOT, EQUIPPED_FIRST, EQUIPPED_LAST));
  1130. end
  1131. end
  1132. end
  1133. SecureCmdList["CHANGEACTIONBAR"] = function(msg)
  1134. local page = SecureCmdOptionParse(msg);
  1135. if ( page and page ~= "" ) then
  1136. page = tonumber(page);
  1137. if (page and page >= 1 and page <= NUM_ACTIONBAR_PAGES) then
  1138. ChangeActionBarPage(page);
  1139. else
  1140. ChatFrame_DisplayUsageError(format(ERROR_SLASH_CHANGEACTIONBAR, 1, NUM_ACTIONBAR_PAGES));
  1141. end
  1142. end
  1143. end
  1144. SecureCmdList["SWAPACTIONBAR"] = function(msg)
  1145. local action = SecureCmdOptionParse(msg);
  1146. if ( action ) then
  1147. local a, b = strmatch(action, "(%d+)%s+(%d+)");
  1148. if ( a and b ) then
  1149. a = tonumber(a);
  1150. b = tonumber(b);
  1151. if ( ( a and a >= 1 and a <= NUM_ACTIONBAR_PAGES ) and ( b and b >= 1 and b <= NUM_ACTIONBAR_PAGES ) ) then
  1152. if ( GetActionBarPage() == a ) then
  1153. ChangeActionBarPage(b);
  1154. else
  1155. ChangeActionBarPage(a);
  1156. end
  1157. else
  1158. ChatFrame_DisplayUsageError(format(ERROR_SLASH_SWAPACTIONBAR, 1, NUM_ACTIONBAR_PAGES));
  1159. end
  1160. end
  1161. end
  1162. end
  1163. SecureCmdList["TARGET"] = function(msg)
  1164. local action, target = SecureCmdOptionParse(msg);
  1165. if ( action ) then
  1166. if ( not target or target == "target" ) then
  1167. target = action;
  1168. end
  1169. TargetUnit(target);
  1170. end
  1171. end
  1172. SecureCmdList["TARGET_EXACT"] = function(msg)
  1173. local action, target = SecureCmdOptionParse(msg);
  1174. if ( action ) then
  1175. if ( not target or target == "target" ) then
  1176. target = action;
  1177. end
  1178. TargetUnit(target, 1);
  1179. end
  1180. end
  1181. SecureCmdList["TARGET_NEAREST_ENEMY"] = function(msg)
  1182. local action = SecureCmdOptionParse(msg);
  1183. if ( action ) then
  1184. TargetNearestEnemy(action);
  1185. end
  1186. end
  1187. SecureCmdList["TARGET_NEAREST_ENEMY_PLAYER"] = function(msg)
  1188. local action = SecureCmdOptionParse(msg);
  1189. if ( action ) then
  1190. TargetNearestEnemyPlayer(action);
  1191. end
  1192. end
  1193. SecureCmdList["TARGET_NEAREST_FRIEND"] = function(msg)
  1194. local action = SecureCmdOptionParse(msg);
  1195. if ( action ) then
  1196. TargetNearestFriend(action);
  1197. end
  1198. end
  1199. SecureCmdList["TARGET_NEAREST_FRIEND_PLAYER"] = function(msg)
  1200. local action = SecureCmdOptionParse(msg);
  1201. if ( action ) then
  1202. TargetNearestFriendPlayer(action);
  1203. end
  1204. end
  1205. SecureCmdList["TARGET_NEAREST_PARTY"] = function(msg)
  1206. local action = SecureCmdOptionParse(msg);
  1207. if ( action ) then
  1208. TargetNearestPartyMember(action);
  1209. end
  1210. end
  1211. SecureCmdList["TARGET_NEAREST_RAID"] = function(msg)
  1212. local action = SecureCmdOptionParse(msg);
  1213. if ( action ) then
  1214. TargetNearestRaidMember(action);
  1215. end
  1216. end
  1217. SecureCmdList["CLEARTARGET"] = function(msg)
  1218. if ( SecureCmdOptionParse(msg) ) then
  1219. ClearTarget();
  1220. end
  1221. end
  1222. SecureCmdList["TARGET_LAST_TARGET"] = function(msg)
  1223. if ( SecureCmdOptionParse(msg) ) then
  1224. TargetLastTarget();
  1225. end
  1226. end
  1227. SecureCmdList["TARGET_LAST_ENEMY"] = function(msg)
  1228. local action = SecureCmdOptionParse(msg);
  1229. if ( action ) then
  1230. TargetLastEnemy(action);
  1231. end
  1232. end
  1233. SecureCmdList["TARGET_LAST_FRIEND"] = function(msg)
  1234. local action = SecureCmdOptionParse(msg);
  1235. if ( action ) then
  1236. TargetLastFriend(action);
  1237. end
  1238. end
  1239. SecureCmdList["ASSIST"] = function(msg)
  1240. if ( msg == "" ) then
  1241. AssistUnit();
  1242. else
  1243. local action, target = SecureCmdOptionParse(msg);
  1244. if ( action ) then
  1245. if ( not target ) then
  1246. target = action;
  1247. end
  1248. AssistUnit(target);
  1249. end
  1250. end
  1251. end
  1252. SecureCmdList["FOCUS"] = function(msg)
  1253. if ( msg == "" ) then
  1254. FocusUnit();
  1255. else
  1256. local action, target = SecureCmdOptionParse(msg);
  1257. if ( action ) then
  1258. if ( not target or target == "focus" ) then
  1259. target = action;
  1260. end
  1261. FocusUnit(target);
  1262. end
  1263. end
  1264. end
  1265. SecureCmdList["CLEARFOCUS"] = function(msg)
  1266. if ( SecureCmdOptionParse(msg) ) then
  1267. ClearFocus();
  1268. end
  1269. end
  1270. SecureCmdList["MAINTANKON"] = function(msg)
  1271. local action, target = SecureCmdOptionParse(msg);
  1272. if ( action ) then
  1273. if ( not target ) then
  1274. target = action;
  1275. end
  1276. if ( target == "" ) then
  1277. target = "target";
  1278. end
  1279. SetPartyAssignment("MAINTANK", target);
  1280. end
  1281. end
  1282. SecureCmdList["MAINTANKOFF"] = function(msg)
  1283. local action, target = SecureCmdOptionParse(msg);
  1284. if ( action ) then
  1285. if ( not target ) then
  1286. target = action;
  1287. end
  1288. if ( target == "" ) then
  1289. target = "target";
  1290. end
  1291. ClearPartyAssignment("MAINTANK", target);
  1292. end
  1293. end
  1294. SecureCmdList["MAINASSISTON"] = function(msg)
  1295. local action, target = SecureCmdOptionParse(msg);
  1296. if ( action ) then
  1297. if ( not target ) then
  1298. target = action;
  1299. end
  1300. if ( target == "" ) then
  1301. target = "target";
  1302. end
  1303. SetPartyAssignment("MAINASSIST", target);
  1304. end
  1305. end
  1306. SecureCmdList["MAINASSISTOFF"] = function(msg)
  1307. local action, target = SecureCmdOptionParse(msg);
  1308. if ( action ) then
  1309. if ( not target ) then
  1310. target = action;
  1311. end
  1312. if ( target == "" ) then
  1313. target = "target";
  1314. end
  1315. ClearPartyAssignment("MAINASSIST", target);
  1316. end
  1317. end
  1318. SecureCmdList["DUEL"] = function(msg)
  1319. StartDuel(msg)
  1320. end
  1321. SecureCmdList["DUEL_CANCEL"] = function(msg)
  1322. CancelDuel()
  1323. end
  1324. SecureCmdList["PET_ATTACK"] = function(msg)
  1325. local action, target = SecureCmdOptionParse(msg);
  1326. if ( action ) then
  1327. if ( not target or target == "pettarget" ) then
  1328. target = action;
  1329. end
  1330. PetAttack(target);
  1331. end
  1332. end
  1333. SecureCmdList["PET_FOLLOW"] = function(msg)
  1334. if ( SecureCmdOptionParse(msg) ) then
  1335. PetFollow();
  1336. end
  1337. end
  1338. SecureCmdList["PET_MOVE_TO"] = function(msg)
  1339. local action, target = SecureCmdOptionParse(msg);
  1340. if ( action ) then
  1341. PetMoveTo(target);
  1342. end
  1343. end
  1344. SecureCmdList["PET_STAY"] = function(msg)
  1345. if ( SecureCmdOptionParse(msg) ) then
  1346. PetWait();
  1347. end
  1348. end
  1349. SecureCmdList["PET_PASSIVE"] = function(msg)
  1350. if ( SecureCmdOptionParse(msg) ) then
  1351. PetPassiveMode();
  1352. end
  1353. end
  1354. SecureCmdList["PET_DEFENSIVE"] = function(msg)
  1355. if ( SecureCmdOptionParse(msg) ) then
  1356. PetDefensiveMode();
  1357. end
  1358. end
  1359. SecureCmdList["PET_AGGRESSIVE"] = function(msg)
  1360. if ( SecureCmdOptionParse(msg) ) then
  1361. PetAggressiveMode();
  1362. end
  1363. end
  1364. SecureCmdList["PET_ASSIST"] = function(msg)
  1365. if ( SecureCmdOptionParse(msg) ) then
  1366. PetAssistMode();
  1367. end
  1368. end
  1369. SecureCmdList["PET_AUTOCASTON"] = function(msg)
  1370. local spell = SecureCmdOptionParse(msg);
  1371. if ( spell ) then
  1372. EnableSpellAutocast(spell);
  1373. end
  1374. end
  1375. SecureCmdList["PET_AUTOCASTOFF"] = function(msg)
  1376. local spell = SecureCmdOptionParse(msg);
  1377. if ( spell ) then
  1378. DisableSpellAutocast(spell);
  1379. end
  1380. end
  1381. SecureCmdList["PET_AUTOCASTTOGGLE"] = function(msg)
  1382. local spell = SecureCmdOptionParse(msg);
  1383. if ( spell ) then
  1384. ToggleSpellAutocast(spell);
  1385. end
  1386. end
  1387. SecureCmdList["STOPMACRO"] = function(msg)
  1388. if ( SecureCmdOptionParse(msg) ) then
  1389. StopMacro();
  1390. end
  1391. end
  1392. SecureCmdList["CANCELQUEUEDSPELL"] = function(msg)
  1393. if ( SecureCmdOptionParse(msg) ) then
  1394. SpellCancelQueuedSpell();
  1395. end
  1396. end
  1397. SecureCmdList["CLICK"] = function(msg)
  1398. local action = SecureCmdOptionParse(msg);
  1399. if ( action and action ~= "" ) then
  1400. local name, mouseButton, down = strmatch(action, "([^%s]+)%s+([^%s]+)%s*(.*)");
  1401. if ( not name ) then
  1402. name = action;
  1403. end
  1404. local button = GetClickFrame(name);
  1405. if ( button and button:IsObjectType("Button") ) then
  1406. button:Click(mouseButton, down);
  1407. end
  1408. end
  1409. end
  1410. SecureCmdList["EQUIP_SET"] = function(msg)
  1411. local set = SecureCmdOptionParse(msg);
  1412. if ( set and set ~= "" ) then
  1413. EquipmentManager_EquipSet(set);
  1414. end
  1415. end
  1416. SecureCmdList["WORLD_MARKER"] = function(msg)
  1417. local marker = SecureCmdOptionParse(msg);
  1418. if ( tonumber(marker) ) then
  1419. PlaceRaidMarker(tonumber(marker));
  1420. end
  1421. end
  1422. SecureCmdList["CLEAR_WORLD_MARKER"] = function(msg)
  1423. local marker = SecureCmdOptionParse(msg);
  1424. if ( tonumber(marker) ) then
  1425. ClearRaidMarker(tonumber(marker));
  1426. elseif ( type(marker) == "string" and strtrim(strlower(marker)) == strlower(ALL) ) then
  1427. ClearRaidMarker(nil); --Clear all world markers.
  1428. end
  1429. end
  1430. SecureCmdList["SUMMON_BATTLE_PET"] = function(msg)
  1431. local pet = SecureCmdOptionParse(msg);
  1432. if ( type(pet) == "string" ) then
  1433. local _, petID = C_PetJournal.FindPetIDByName(string.trim(pet));
  1434. if ( petID ) then
  1435. C_PetJournal.SummonPetByGUID(petID);
  1436. else
  1437. C_PetJournal.SummonPetByGUID(pet);
  1438. end
  1439. end
  1440. end
  1441. SecureCmdList["RANDOMPET"] = function(msg)
  1442. if ( SecureCmdOptionParse(msg) ) then
  1443. C_PetJournal.SummonRandomPet(true);
  1444. end
  1445. end
  1446. SecureCmdList["RANDOMFAVORITEPET"] = function(msg)
  1447. if ( SecureCmdOptionParse(msg) ) then
  1448. C_PetJournal.SummonRandomPet(false);
  1449. end
  1450. end
  1451. SecureCmdList["DISMISSBATTLEPET"] = function(msg)
  1452. if ( SecureCmdOptionParse(msg) ) then
  1453. local petID = C_PetJournal.GetSummonedPetGUID();
  1454. if ( petID ) then
  1455. C_PetJournal.SummonPetByGUID(petID);
  1456. end
  1457. end
  1458. end
  1459. -- Pre-populate the secure command hash table
  1460. for index, value in pairs(SecureCmdList) do
  1461. local i = 1;
  1462. local cmdString = _G["SLASH_"..index..i];
  1463. while ( cmdString ) do
  1464. cmdString = strupper(cmdString);
  1465. hash_SecureCmdList[cmdString] = value; -- add to hash
  1466. i = i + 1;
  1467. cmdString = _G["SLASH_"..index..i];
  1468. end
  1469. end
  1470. -- Slash commands
  1471. SlashCmdList = { };
  1472. SlashCmdList["CONSOLE"] = function(msg)
  1473. ConsoleExec(msg);
  1474. end
  1475. SlashCmdList["CHATLOG"] = function(msg)
  1476. local info = ChatTypeInfo["SYSTEM"];
  1477. if ( LoggingChat() ) then
  1478. LoggingChat(false);
  1479. DEFAULT_CHAT_FRAME:AddMessage(CHATLOGDISABLED, info.r, info.g, info.b, info.id);
  1480. else
  1481. LoggingChat(true);
  1482. DEFAULT_CHAT_FRAME:AddMessage(CHATLOGENABLED, info.r, info.g, info.b, info.id);
  1483. end
  1484. end
  1485. SlashCmdList["COMBATLOG"] = function(msg)
  1486. local info = ChatTypeInfo["SYSTEM"];
  1487. if ( LoggingCombat() ) then
  1488. LoggingCombat(false);
  1489. DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGDISABLED, info.r, info.g, info.b, info.id);
  1490. else
  1491. LoggingCombat(true);
  1492. DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGENABLED, info.r, info.g, info.b, info.id);
  1493. end
  1494. end
  1495. SlashCmdList["INVITE"] = function(msg)
  1496. if(msg == "") then
  1497. msg = UnitName("target");
  1498. end
  1499. if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
  1500. ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
  1501. return;
  1502. end
  1503. InviteToGroup(msg);
  1504. end
  1505. SlashCmdList["UNINVITE"] = function(msg)
  1506. if(msg == "") then
  1507. msg = UnitName("target");
  1508. end
  1509. UninviteUnit(msg);
  1510. end
  1511. SlashCmdList["PROMOTE"] = function(msg)
  1512. PromoteToLeader(msg);
  1513. end
  1514. SlashCmdList["REPLY"] = function(msg, editBox)
  1515. local lastTell = ChatEdit_GetLastTellTarget();
  1516. if ( lastTell ) then
  1517. msg = SubstituteChatMessageBeforeSend(msg);
  1518. SendChatMessage(msg, "WHISPER", editBox.languageID, lastTell);
  1519. else
  1520. -- error message
  1521. end
  1522. end
  1523. SlashCmdList["HELP"] = function(msg)
  1524. ChatFrame_DisplayHelpText(DEFAULT_CHAT_FRAME);
  1525. end
  1526. SlashCmdList["MACROHELP"] = function(msg)
  1527. ChatFrame_DisplayMacroHelpText(DEFAULT_CHAT_FRAME);
  1528. end
  1529. SlashCmdList["TIME"] = function(msg)
  1530. ChatFrame_DisplayGameTime(DEFAULT_CHAT_FRAME);
  1531. end
  1532. SlashCmdList["PLAYED"] = function(msg)
  1533. RequestTimePlayed();
  1534. end
  1535. SlashCmdList["FOLLOW"] = function(msg)
  1536. FollowUnit(msg);
  1537. end
  1538. SlashCmdList["TRADE"] = function(msg)
  1539. InitiateTrade("target");
  1540. end
  1541. SlashCmdList["INSPECT"] = function(msg)
  1542. InspectUnit("target");
  1543. end
  1544. SlashCmdList["LOGOUT"] = function(msg)
  1545. Logout();
  1546. end
  1547. SlashCmdList["QUIT"] = function(msg)
  1548. Quit();
  1549. end
  1550. SlashCmdList["JOIN"] = function(msg)
  1551. local name = gsub(msg, "%s*([^%s]+).*", "%1");
  1552. local password = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
  1553. if(strlen(name) <= 0) then
  1554. local joinhelp = CHAT_JOIN_HELP;
  1555. local info = ChatTypeInfo["SYSTEM"];
  1556. DEFAULT_CHAT_FRAME:AddMessage(joinhelp, info.r, info.g, info.b, info.id);
  1557. else
  1558. local zoneChannel, channelName = JoinPermanentChannel(name, password, DEFAULT_CHAT_FRAME:GetID(), 1);
  1559. if ( channelName ) then
  1560. name = channelName;
  1561. end
  1562. if ( not zoneChannel ) then
  1563. local info = ChatTypeInfo["CHANNEL"];
  1564. DEFAULT_CHAT_FRAME:AddMessage(CHAT_INVALID_NAME_NOTICE, info.r, info.g, info.b, info.id);
  1565. return;
  1566. end
  1567. local i = 1;
  1568. while ( DEFAULT_CHAT_FRAME.channelList[i] ) do
  1569. i = i + 1;
  1570. end
  1571. DEFAULT_CHAT_FRAME.channelList[i] = name;
  1572. DEFAULT_CHAT_FRAME.zoneChannelList[i] = zoneChannel;
  1573. end
  1574. end
  1575. SlashCmdList["LEAVE"] = function(msg)
  1576. local name = strmatch(msg, "%s*([^%s]+)");
  1577. if ( name ) then
  1578. local nameNum = tonumber(name);
  1579. if ( nameNum and nameNum > MAX_WOW_CHAT_CHANNELS ) then
  1580. BNLeaveConversation(nameNum - MAX_WOW_CHAT_CHANNELS);
  1581. else
  1582. LeaveChannelByName(name);
  1583. end
  1584. end
  1585. end
  1586. SlashCmdList["LIST_CHANNEL"] = function(msg)
  1587. local name = strmatch(msg, "%s*([^%s]+)");
  1588. if ( name ) then
  1589. local nameNum = tonumber(name);
  1590. if ( nameNum and nameNum > MAX_WOW_CHAT_CHANNELS ) then
  1591. BNListConversation(nameNum - MAX_WOW_CHAT_CHANNELS);
  1592. else
  1593. ListChannelByName(name);
  1594. end
  1595. else
  1596. ListChannels();
  1597. end
  1598. end
  1599. SlashCmdList["CHAT_HELP"] =
  1600. function(msg)
  1601. ChatFrame_DisplayChatHelp(DEFAULT_CHAT_FRAME)
  1602. end
  1603. SlashCmdList["CHAT_PASSWORD"] =
  1604. function(msg)
  1605. local name = gsub(msg, "%s*([^%s]+).*", "%1");
  1606. local password = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
  1607. SetChannelPassword(name, password);
  1608. end
  1609. SlashCmdList["CHAT_OWNER"] =
  1610. function(msg)
  1611. local channel = gsub(msg, "%s*([^%s]+).*", "%1");
  1612. local newOwner = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
  1613. if ( not channel or not newOwner ) then
  1614. return;
  1615. end
  1616. local newOwnerLen = strlen(newOwner);
  1617. if ( newOwnerLen > MAX_CHARACTER_NAME_BYTES ) then
  1618. ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
  1619. return;
  1620. end
  1621. if ( strlen(channel) > 0 ) then
  1622. if ( newOwnerLen > 0 ) then
  1623. SetChannelOwner(channel, n

Large files files are truncated, but you can click here to view the full file