Advertisement
Arborus

NickTag-1.0.lua

Jul 28th, 2018
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.10 KB | None | 0 0
  1. --> Library NickTag is a small library for share individual nicknames and avatars.
  2.  
  3. --> Basic Functions:
  4. -- NickTag:SetNickname (name) -> set the player nick name, after set nicktag will broadcast the nick over addon guild channel.
  5. --
  6.  
  7. local major, minor = "NickTag-1.0", 10
  8. local NickTag, oldminor = LibStub:NewLibrary (major, minor)
  9.  
  10. if (not NickTag) then
  11. return
  12. end
  13.  
  14. --> fix for old nicktag version
  15. if (_G.NickTag) then
  16. if (_G.NickTag.OnEvent) then
  17. _G.NickTag:UnregisterComm ("NickTag")
  18. _G.NickTag.OnEvent = nil
  19. end
  20. end
  21.  
  22. ------------------------------------------------------------------------------------------------------------------------------------------------------
  23. --> constants
  24.  
  25. local CONST_INDEX_NICKNAME = 1
  26. local CONST_INDEX_AVATAR_PATH = 2
  27. local CONST_INDEX_AVATAR_TEXCOORD = 3
  28. local CONST_INDEX_BACKGROUND_PATH = 4
  29. local CONST_INDEX_BACKGROUND_TEXCOORD = 5
  30. local CONST_INDEX_BACKGROUND_COLOR = 6
  31. local CONST_INDEX_REVISION = 7
  32.  
  33. local CONST_COMM_FULLPERSONA = 1
  34. local CONST_COMM_LOGONREVISION = 2
  35. local CONST_COMM_REQUESTPERSONA = 3
  36.  
  37. --[[global]] NICKTAG_DEFAULT_AVATAR = [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
  38. --[[global]] NICKTAG_DEFAULT_BACKGROUND = [[Interface\PetBattles\Weather-ArcaneStorm]]
  39. --[[global]] NICKTAG_DEFAULT_BACKGROUND_CORDS = {0.129609375, 1, 1, 0}
  40.  
  41. ------------------------------------------------------------------------------------------------------------------------------------------------------
  42. --> library stuff
  43.  
  44. _G.NickTag = NickTag --> nicktag object over global container
  45.  
  46. local pool = {default = true} --> pointer to the cache pool and the default pool if no cache
  47. local queue_request = {}
  48. local queue_send = {}
  49. local last_queue = 0
  50. local is_updating = false
  51. NickTag.debug = false
  52.  
  53. local GetGuildRosterInfo = GetGuildRosterInfo
  54.  
  55. LibStub:GetLibrary ("AceComm-3.0"):Embed (NickTag)
  56. LibStub:GetLibrary ("AceSerializer-3.0"):Embed (NickTag)
  57. LibStub:GetLibrary ("AceTimer-3.0"):Embed (NickTag)
  58. local CallbackHandler = LibStub:GetLibrary ("CallbackHandler-1.0")
  59. NickTag.callbacks = NickTag.callbacks or CallbackHandler:New (NickTag)
  60.  
  61. NickTag.embeds = NickTag.embeds or {}
  62. local embed_functions = {
  63. "SetNickname",
  64. "SetNicknameAvatar",
  65. "SetNicknameBackground",
  66. "GetNickname",
  67. "GetNicknameAvatar",
  68. "GetNicknameBackground",
  69. "GetNicknameTable",
  70. "NickTagSetCache"
  71. }
  72. function NickTag:Embed (target)
  73. for k, v in pairs (embed_functions) do
  74. target[v] = self[v]
  75. end
  76. self.embeds [target] = true
  77. return target
  78. end
  79.  
  80. function NickTag:Msg (...)
  81. if (NickTag.debug) then
  82. print ("|cFFFFFF00NickTag:|r", ...)
  83. end
  84. end
  85.  
  86. local enUS = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "enUS", true)
  87. if (enUS) then
  88. enUS ["STRING_ERROR_1"] = "Your nickname is too long, max of 12 characters is allowed."
  89. enUS ["STRING_ERROR_2"] = "Only letters and two spaces are allowed."
  90. enUS ["STRING_ERROR_3"] = "You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."
  91. enUS ["STRING_ERROR_4"] = "Name isn't a valid string."
  92. enUS ["STRING_INVALID_NAME"] = "Invalid Name"
  93. end
  94.  
  95. local ptBR = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "ptBR")
  96. if (ptBR) then
  97. ptBR ["STRING_ERROR_1"] = "Seu apelido esta muito longo, o maximo permitido sao 12 caracteres."
  98. ptBR ["STRING_ERROR_2"] = "Apenas letras, numeros e espacos sao permitidos no apelido."
  99. ptBR ["STRING_ERROR_3"] = "Voce nao pode usar a mesma letra mais de 2 vezes consecutivas, dois espacos consecutivos ou mais de 2 espacos."
  100. ptBR ["STRING_ERROR_4"] = "Nome nao eh uma string valida."
  101. ptBR ["STRING_INVALID_NAME"] = "Nome Invalido"
  102. end
  103.  
  104. NickTag.background_pool = {
  105. {[[Interface\PetBattles\Weather-ArcaneStorm]], "Arcane Storm", {0.129609375, 1, 1, 0}},
  106. {[[Interface\PetBattles\Weather-Blizzard]], "Blizzard", {0.068704154, 1, 1, 0}},
  107. {[[Interface\PetBattles\Weather-BurntEarth]], "Burnt Earth", {0.087890625, 0.916015625, 1, 0}},
  108. {[[Interface\PetBattles\Weather-Darkness]], "Darkness", {0.080078125, 0.931640625, 1, 0}},
  109. {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight", {0.02765625, 0.94359375, 1, 0}},
  110. {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight (reverse)", {0.94359375, 0.02765625, 1, 0}},
  111. {[[Interface\PetBattles\Weather-Mud]], "Mud", {0.068359375, 0.94359375, 1, 0}},
  112. {[[Interface\PetBattles\Weather-Rain]], "Rain", {0.078125, 0.970703125, 1, 0}},
  113. {[[Interface\PetBattles\Weather-Sandstorm]], "Sand Storm", {0.048828125, 0.947265625, 1, 0}},
  114. {[[Interface\PetBattles\Weather-StaticField]], "Static Field", {0.1171875, 0.953125, 1, 0}},
  115. {[[Interface\PetBattles\Weather-Sunlight]], "Sun Light", {0.1772721, 0.953125, 1, 0}},
  116. {[[Interface\PetBattles\Weather-Windy]], "Windy", {0.9453125, 0.07421875, 0.8203125, 0}}
  117. }
  118.  
  119. NickTag.avatar_pool = {
  120. {[[Interface\EncounterJournal\UI-EJ-BOSS-Arcanist Doan]], "Arcanist Doan"},
  121. {[[Interface\EncounterJournal\UI-EJ-BOSS-Archbishop Benedictus]], "Archbishop Benedictus"},
  122. {[[Interface\EncounterJournal\UI-EJ-BOSS-Argent Confessor Paletress]], "Argent Confessor Paletress"},
  123. {[[Interface\EncounterJournal\UI-EJ-BOSS-Armsmaster Harlan]], "Armsmaster Harlan"},
  124. {[[Interface\EncounterJournal\UI-EJ-BOSS-Asira Dawnslayer]], "Asira Dawnslayer"},
  125. {[[Interface\EncounterJournal\UI-EJ-BOSS-Baelog]], "Baelog"},
  126. {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Ashbury]], "Baron Ashbury"},
  127. {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Silverlaine]], "Baron Silverlaine"},
  128. {[[Interface\EncounterJournal\UI-EJ-BOSS-Blood Guard Porung]], "Blood Guard Porung"},
  129. {[[Interface\EncounterJournal\UI-EJ-BOSS-Bronjahm]], "Bronjahm"},
  130. {[[Interface\EncounterJournal\UI-EJ-BOSS-Brother Korloff]], "Brother Korloff"},
  131. {[[Interface\EncounterJournal\UI-EJ-BOSS-Captain Skarloc]], "Captain Skarloc"},
  132. {[[Interface\EncounterJournal\UI-EJ-BOSS-Chief Ukorz Sandscalp]], "Chief Ukorz Sandscalp"},
  133. {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Kolurg]], "Commander Kolurg"},
  134. {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Malor]], "Commander Malor"},
  135. {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Sarannis]], "Commander Sarannis"},
  136. {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Springvale]], "Commander Springvale"},
  137. {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Stoutbeard]], "Commander Stoutbeard"},
  138. {[[Interface\EncounterJournal\UI-EJ-BOSS-Corla, Herald of Twilight]], "Corla, Herald of Twilight"},
  139. {[[Interface\EncounterJournal\UI-EJ-BOSS-Cyanigosa]], "Cyanigosa"},
  140. {[[Interface\EncounterJournal\UI-EJ-BOSS-Darkmaster Gandling]], "Darkmaster Gandling"},
  141. {[[Interface\EncounterJournal\UI-EJ-BOSS-Doctor Theolen Krastinov]], "Doctor Theolen Krastinov"},
  142. {[[Interface\EncounterJournal\UI-EJ-BOSS-DoomRel]], "DoomRel"},
  143. {[[Interface\EncounterJournal\UI-EJ-BOSS-Eadric the Pure]], "Eadric the Pure"},
  144. {[[Interface\EncounterJournal\UI-EJ-BOSS-Emperor Thaurissan]], "Emperor Thaurissan"},
  145. {[[Interface\EncounterJournal\UI-EJ-BOSS-Empyreal Queens]], "Lu'lin"},
  146. {[[Interface\EncounterJournal\UI-EJ-BOSS-Exarch Maladaar]], "Exarch Maladaar"},
  147. {[[Interface\EncounterJournal\UI-EJ-BOSS-Fineous Darkvire]], "Fineous Darkvire"},
  148. {[[Interface\EncounterJournal\UI-EJ-BOSS-Galdarah]], "Galdarah"},
  149. {[[Interface\EncounterJournal\UI-EJ-BOSS-Garajal the Spiritbinder]], "Garajal the Spiritbinder"},
  150. {[[Interface\EncounterJournal\UI-EJ-BOSS-Garrosh Hellscream]], "Garrosh Hellscream"},
  151. {[[Interface\EncounterJournal\UI-EJ-BOSS-General Nazgrim]], "General Nazgrim"},
  152. {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Alliance]], "Grand Champions-Alliance"},
  153. {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Horde]], "Grand Champions-Horde"},
  154. {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Magus Telestra]], "Grand Magus Telestra"},
  155. {[[Interface\EncounterJournal\UI-EJ-BOSS-HateRel]], "HateRel"},
  156. {[[Interface\EncounterJournal\UI-EJ-BOSS-Hazzarah]], "Hazzarah"},
  157. {[[Interface\EncounterJournal\UI-EJ-BOSS-Hearthsinger Forresten]], "Hearthsinger Forresten"},
  158. {[[Interface\EncounterJournal\UI-EJ-BOSS-Helix Gearbreaker]], "Helix Gearbreaker"},
  159. {[[Interface\EncounterJournal\UI-EJ-BOSS-High Botanist Freywinn]], "High Botanist Freywinn"},
  160. {[[Interface\EncounterJournal\UI-EJ-BOSS-High Inquisitor Whitemane]], "High Inquisitor Whitemane"},
  161. {[[Interface\EncounterJournal\UI-EJ-BOSS-High Interrogator Gerstahn]], "High Interrogator Gerstahn"},
  162. {[[Interface\EncounterJournal\UI-EJ-BOSS-High Justice Grimstone]], "High Justice Grimstone"},
  163. {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Braun]], "Houndmaster Braun"},
  164. {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Loksey]], "Houndmaster Loksey"},
  165. {[[Interface\EncounterJournal\UI-EJ-BOSS-Hydromancer Velratha]], "Hydromancer Velratha"},
  166. {[[Interface\EncounterJournal\UI-EJ-BOSS-Illyanna Ravenoak]], "Illyanna Ravenoak"},
  167. {[[Interface\EncounterJournal\UI-EJ-BOSS-Ingvar the Plunderer]], "Ingvar the Plunderer"},
  168. {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Galford]], "Instructor Galford"},
  169. {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Malicia]], "Instructor Malicia"},
  170. {[[Interface\EncounterJournal\UI-EJ-BOSS-Interrogator Vishas]], "Interrogator Vishas"},
  171. {[[Interface\EncounterJournal\UI-EJ-BOSS-Isiset]], "Isiset"},
  172. {[[Interface\EncounterJournal\UI-EJ-BOSS-JainaProudmoore]], "Jaina Proudmoore"},
  173. {[[Interface\EncounterJournal\UI-EJ-BOSS-Jandice Barov]], "Jandice Barov"},
  174. {[[Interface\EncounterJournal\UI-EJ-BOSS-Kaelthas Sunstrider]], "Kaelthas Sunstrider"},
  175. {[[Interface\EncounterJournal\UI-EJ-BOSS-Kelidan the Breaker]], "Kelidan the Breaker"},
  176. {[[Interface\EncounterJournal\UI-EJ-BOSS-Krick]], "Krick"},
  177. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Anacondra]], "Lady Anacondra"},
  178. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Illucia Barov]], "Lady Illucia Barov"},
  179. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lethtendris]], "Lethtendris"},
  180. {[[Interface\EncounterJournal\UI-EJ-BOSS-Loken]], "Loken"},
  181. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Alexei Barov]], "Lord Alexei Barov"},
  182. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Aurius Rivendare]], "Lord Aurius Rivendare"},
  183. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Cobrahn]], "Lord Cobrahn"},
  184. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Pythas]], "Lord Pythas"},
  185. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Serpentis]], "Lord Serpentis"},
  186. {[[Interface\EncounterJournal\UI-EJ-BOSS-Lorgus Jett]], "Lorgus Jett"},
  187. {[[Interface\EncounterJournal\UI-EJ-BOSS-Mage Lord Urom]], "Mage Lord Urom"},
  188. {[[Interface\EncounterJournal\UI-EJ-BOSS-Magister Kalendris]], "Magister Kalendris"},
  189. {[[Interface\EncounterJournal\UI-EJ-BOSS-Magistrate Barthilas]], "Magistrate Barthilas"},
  190. {[[Interface\EncounterJournal\UI-EJ-BOSS-Maiden of Grief]], "Maiden of Grief"},
  191. {[[Interface\EncounterJournal\UI-EJ-BOSS-Maleki the Pallid]], "Maleki the Pallid"},
  192. {[[Interface\EncounterJournal\UI-EJ-BOSS-Nethermancer Sepethrea]], "Nethermancer Sepethrea"},
  193. {[[Interface\EncounterJournal\UI-EJ-BOSS-Olaf]], "Olaf"},
  194. {[[Interface\EncounterJournal\UI-EJ-BOSS-Pathaleon the Calculator]], "Pathaleon the Calculator"},
  195. {[[Interface\EncounterJournal\UI-EJ-BOSS-Prince Tortheldrin]], "Prince Tortheldrin"},
  196. {[[Interface\EncounterJournal\UI-EJ-BOSS-Princess Moira Bronzebeard]], "Princess Moira Bronzebeard"},
  197. {[[Interface\EncounterJournal\UI-EJ-BOSS-QueenAzshara]], "Queen Azshara"},
  198. {[[Interface\EncounterJournal\UI-EJ-BOSS-Randolph Moloch]], "Randolph Moloch"},
  199. {[[Interface\EncounterJournal\UI-EJ-BOSS-Renataki]], "Renataki"},
  200. {[[Interface\EncounterJournal\UI-EJ-BOSS-Ribbly Screwspigot]], "Ribbly Screwspigot"},
  201. {[[Interface\EncounterJournal\UI-EJ-BOSS-Scarlet Commander Mograine]], "Scarlet Commander Mograine"},
  202. {[[Interface\EncounterJournal\UI-EJ-BOSS-Selin Fireheart]], "Selin Fireheart"},
  203. {[[Interface\EncounterJournal\UI-EJ-BOSS-Siegecrafter Blackfuse]], "Siegecrafter Blackfuse"},
  204. {[[Interface\EncounterJournal\UI-EJ-BOSS-Skarvald the Constructor]], "Skarvald the Constructor"},
  205. {[[Interface\EncounterJournal\UI-EJ-BOSS-Tribunal of the Ages]], "Tribunal of the Ages"},
  206. {[[Interface\EncounterJournal\UI-EJ-BOSS-TyrandeWhisperwind]], "Tyrande Whisperwind"},
  207. {[[Interface\EncounterJournal\UI-EJ-BOSS-Twilight Lord Kelris]], "Twilight Lord Kelris"},
  208. {[[Interface\EncounterJournal\UI-EJ-BOSS-Vanessa VanCleef]], "Vanessa VanCleef"},
  209. {[[Interface\EncounterJournal\UI-EJ-BOSS-Vazruden]], "Vazruden"},
  210. {[[Interface\EncounterJournal\UI-EJ-BOSS-Warchief Rend Blackhand]], "Warchief Rend Blackhand"},
  211. {[[Interface\EncounterJournal\UI-EJ-BOSS-Willey Hopebreaker]], "Willey Hopebreaker"},
  212. {[[Interface\EncounterJournal\UI-EJ-BOSS-Witch Doctor Zumrah]], "Witch Doctor Zumrah"},
  213. }
  214. ------------------------------------------------------------------------------------------------------------------------------------------------------
  215. --> send and receive functions
  216.  
  217. function NickTag:OnReceiveComm (prefix, data, channel, source)
  218.  
  219. if (not source) then
  220. return
  221. end
  222.  
  223. local _type, serial, arg3, name, realm, version = select (2, NickTag:Deserialize (data))
  224.  
  225. --> 0x1: received a full persona
  226. if (_type == CONST_COMM_FULLPERSONA) then
  227. local receivedPersona = arg3
  228. version = name
  229.  
  230. if (not receivedPersona or type (receivedPersona) ~= "table") then
  231. NickTag:Msg ("FULLPERSONA received but it's invalid ", source)
  232. return
  233. end
  234.  
  235. if (source ~= UnitName ("player") and (version and version == minor) and receivedPersona) then
  236.  
  237. local storedPersona = NickTag:GetNicknameTable (source)
  238. if (not storedPersona) then
  239. storedPersona = NickTag:Create (source)
  240. end
  241.  
  242. if (storedPersona [CONST_INDEX_REVISION] < receivedPersona [CONST_INDEX_REVISION]) then
  243. storedPersona [CONST_INDEX_REVISION] = receivedPersona [CONST_INDEX_REVISION]
  244.  
  245. --> we need to check if the received nickname fit in our rules.
  246. local allowNickName = NickTag:CheckName (receivedPersona [CONST_INDEX_NICKNAME])
  247. if (allowNickName) then
  248. storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
  249. else
  250. storedPersona [CONST_INDEX_NICKNAME] = LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]
  251. end
  252.  
  253. storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
  254.  
  255. --> update the rest
  256. --avatar path
  257. storedPersona [CONST_INDEX_AVATAR_PATH] = type (receivedPersona [CONST_INDEX_AVATAR_PATH]) == "string" and receivedPersona [CONST_INDEX_AVATAR_PATH] or ""
  258.  
  259. --avatar texcoord
  260. if (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "boolean") then
  261. storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
  262.  
  263. elseif (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "table") then
  264. storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = storedPersona [CONST_INDEX_AVATAR_TEXCOORD] or {}
  265. storedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] or 0
  266. storedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] or 1
  267. storedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] or 0
  268. storedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] or 1
  269. else
  270. storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
  271. end
  272.  
  273. --background texcoord
  274. if (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "boolean") then
  275. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
  276.  
  277. elseif (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "table") then
  278. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] or {}
  279. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] or 0
  280. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] or 1
  281. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] or 0
  282. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] or 1
  283. else
  284. storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
  285. end
  286.  
  287. --background path
  288. storedPersona [CONST_INDEX_BACKGROUND_PATH] = type (receivedPersona [CONST_INDEX_BACKGROUND_PATH]) == "string" and receivedPersona [CONST_INDEX_BACKGROUND_PATH] or ""
  289.  
  290. --background color
  291. if (type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR]) == "table") then
  292. storedPersona [CONST_INDEX_BACKGROUND_COLOR] = storedPersona [CONST_INDEX_BACKGROUND_COLOR] or {}
  293. storedPersona [CONST_INDEX_BACKGROUND_COLOR][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1] or 1
  294. storedPersona [CONST_INDEX_BACKGROUND_COLOR][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2] or 1
  295. storedPersona [CONST_INDEX_BACKGROUND_COLOR][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3] or 1
  296. else
  297. storedPersona [CONST_INDEX_BACKGROUND_COLOR] = {1, 1, 1}
  298. end
  299.  
  300. NickTag:Msg ("FULLPERSONA received and updated for character: ", source, "new nickname: ", receivedPersona [CONST_INDEX_NICKNAME])
  301. end
  302. end
  303.  
  304. --> 0x2: received a revision version from a guy which logon in the game
  305. elseif (_type == CONST_COMM_LOGONREVISION) then
  306.  
  307. if (UnitName ("player") == source) then
  308. return
  309. end
  310.  
  311. local receivedRevision = arg3
  312. local storedPersona = NickTag:GetNicknameTable (source)
  313.  
  314. NickTag:Msg ("LOGONREVISION rev: ", receivedRevision, " source: ", source)
  315.  
  316. if (type (version) ~= "number" or version ~= minor) then
  317. return
  318. end
  319.  
  320. if (not storedPersona or storedPersona [CONST_INDEX_REVISION] < receivedRevision) then
  321. --> put in queue our request for receive a updated persona
  322. NickTag:ScheduleTimer ("QueueRequest", math.random (10, 60), source)
  323.  
  324. NickTag:Msg ("LOGONREVISION from: " .. source .. " |cFFFF0000is out of date|r, queueing a request persona.")
  325. else
  326. NickTag:Msg ("LOGONREVISION from: " .. source .. " |cFF00FF00is up to date.")
  327. end
  328.  
  329. --> 0x3: someone requested my persona, so i need to send to him
  330. elseif (_type == CONST_COMM_REQUESTPERSONA) then
  331. if (type (version) ~= "number" or version ~= minor) then
  332. return
  333. end
  334.  
  335. --> queue to send our persona for requested person
  336. NickTag:Msg ("REQUESTPERSONA from: " .. source .. ", the request has been placed in queue.")
  337.  
  338. NickTag:QueueSend (source)
  339. end
  340.  
  341. end
  342.  
  343. NickTag:RegisterComm ("NickTag", "OnReceiveComm")
  344.  
  345. function NickTag:UpdateRoster()
  346. --> do not update roster if is in combat
  347. if (not UnitAffectingCombat ("player")) then
  348. GuildRoster()
  349. end
  350. end
  351.  
  352. function NickTag:IsOnline (name)
  353.  
  354. local isShownOffline = GetGuildRosterShowOffline()
  355. if (isShownOffline) then
  356. SetGuildRosterShowOffline (false)
  357. end
  358.  
  359. local _, numOnlineMembers = GetNumGuildMembers()
  360.  
  361. NickTag:Msg ("IsOnline(): " .. numOnlineMembers .. " online members.")
  362.  
  363. for i = 1, numOnlineMembers do
  364. local player_name = GetGuildRosterInfo (i)
  365. if (player_name:find (name)) then
  366. if (isShownOffline) then
  367. SetGuildRosterShowOffline (true)
  368. end
  369. return true
  370. end
  371. end
  372. if (isShownOffline) then
  373. SetGuildRosterShowOffline (true)
  374. end
  375. return false
  376. end
  377.  
  378. local event_frame = CreateFrame ("frame", nil, UIParent)
  379. event_frame:Hide()
  380. event_frame:SetScript ("OnEvent", function (_, _, local_update)
  381. if (not local_update) then
  382.  
  383. --> roster was been updated
  384. if (last_queue < time()) then
  385. last_queue = time()+11
  386. else
  387. return
  388. end
  389.  
  390. --> do not share if we are in combat
  391. if (UnitAffectingCombat ("player")) then
  392. return
  393. end
  394.  
  395. --> start with send requested personas
  396. if (#queue_send > 0) then
  397.  
  398. local name = queue_send [1]
  399. table.remove (queue_send, 1)
  400.  
  401. NickTag:Msg ("QUEUE -> ready to send persona to " .. name)
  402.  
  403. --> check if the player is online
  404. if (NickTag:IsOnline (name)) then
  405. NickTag:Msg ("QUEUE -> " .. name .. " is online, running SendPersona().")
  406. NickTag:SendPersona (name)
  407. else
  408. NickTag:Msg ("QUEUE -> " .. name .. " is offline, cant request his persona.")
  409. end
  410.  
  411. if (#queue_send == 0 and #queue_request == 0) then
  412. NickTag:StopRosterUpdates()
  413. end
  414.  
  415. elseif (#queue_request > 0) then
  416.  
  417. local name = queue_request [1]
  418. table.remove (queue_request, 1)
  419.  
  420. NickTag:Msg ("QUEUE -> ready to request the persona of " .. name)
  421.  
  422. --> check if the player is online
  423. if (NickTag:IsOnline (name)) then
  424. NickTag:Msg ("QUEUE -> " .. name .. " is online, running RequestPersona().")
  425. NickTag:RequestPersona (name)
  426. else
  427. NickTag:Msg ("QUEUE -> " .. name .. " is offline, cant request his persona.")
  428. end
  429.  
  430. if (#queue_request == 0 and #queue_request == 0) then
  431. NickTag:StopRosterUpdates()
  432. end
  433.  
  434. else
  435. NickTag:StopRosterUpdates()
  436. end
  437. end
  438. end)
  439.  
  440. function NickTag:StopRosterUpdates()
  441. NickTag:Msg ("ROSTER -> updates has been stopped")
  442. if (NickTag.UpdateRosterTimer) then
  443. NickTag:CancelTimer (NickTag.UpdateRosterTimer)
  444. end
  445. NickTag.UpdateRosterTimer = nil
  446. event_frame:UnregisterEvent ("GUILD_ROSTER_UPDATE")
  447. is_updating = false
  448. end
  449.  
  450. function NickTag:StartRosterUpdates()
  451. NickTag:Msg ("ROSTER -> updates has been actived")
  452. event_frame:RegisterEvent ("GUILD_ROSTER_UPDATE")
  453. if (not NickTag.UpdateRosterTimer) then
  454. NickTag.UpdateRosterTimer = NickTag:ScheduleRepeatingTimer ("UpdateRoster", 12)
  455. NickTag:Msg ("ROSTER -> new update thread created.")
  456. else
  457. NickTag:Msg ("ROSTER -> a update thread already exists.")
  458. end
  459. is_updating = true
  460. end
  461.  
  462. --> we queue data for roster update and also check for combat
  463. function NickTag:QueueRequest (name)
  464. table.insert (queue_request, name)
  465. if (not is_updating) then
  466. NickTag:StartRosterUpdates()
  467. end
  468. end
  469. function NickTag:QueueSend (name)
  470. table.insert (queue_send, name)
  471. if (not is_updating) then
  472. NickTag:StartRosterUpdates()
  473. end
  474. end
  475.  
  476. --> after logon, we send our revision, who needs update my persona will send 0x3 (request persona) to me and i send back 0x1 (send persona)
  477. function NickTag:SendRevision()
  478. local playerName = UnitName ("player")
  479. local myPersona = NickTag:GetNicknameTable (playerName)
  480. if (myPersona) then
  481. NickTag:Msg ("SendRevision() -> SENT")
  482. if (IsInGuild()) then
  483. NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_LOGONREVISION, 0, myPersona [CONST_INDEX_REVISION], UnitName ("player"), GetRealmName(), minor), "GUILD")
  484. end
  485. end
  486. end
  487.  
  488. --> i received 0x2 and his persona is out of date here, so i need to send 0x3 to him and him will send 0x1.
  489. function NickTag:RequestPersona (target)
  490. NickTag:Msg ("RequestPersona() -> requesting of " .. target)
  491. if (IsInGuild()) then
  492. NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_REQUESTPERSONA, 0, 0, UnitName ("player"), GetRealmName(), minor), "WHISPER", target)
  493. end
  494. end
  495.  
  496. --> this broadcast my persona to entire guild when i update my persona or send my persona to someone who doesn't have it or need to update.
  497. function NickTag:SendPersona (target)
  498. if (target) then
  499. NickTag:Msg ("SendPersona() -> sent to " .. target)
  500. else
  501. NickTag:Msg ("SendPersona() -> broadcast")
  502. end
  503.  
  504. --> auto change nickname if we have a invalid nickname
  505. if (NickTag:GetNickname (UnitName ("player")) == LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]) then
  506. local nickTable = NickTag:GetNicknameTable (UnitName ("player"))
  507. if (nickTable) then
  508. nickTable [CONST_INDEX_NICKNAME] = UnitName ("player")
  509. end
  510. end
  511.  
  512. if (target) then
  513. --> was requested
  514. if (IsInGuild()) then
  515. NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "WHISPER", target)
  516. end
  517. else
  518. --> updating my own persona
  519. NickTag.send_scheduled = false
  520. --> broadcast only happen when something has changed on the local player persona, it needs to increase the revision before sending
  521. NickTag:IncRevision()
  522. --> broadcast over guild channel
  523. if (IsInGuild()) then
  524. NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "GUILD")
  525. end
  526. end
  527. end
  528.  
  529. ------------------------------------------------------------------------------------------------------------------------------------------------------
  530. --> on logon stuff
  531.  
  532. --> reset cache
  533. function NickTag:ResetCache()
  534.  
  535. local playerName = UnitName ("player")
  536.  
  537. if (playerName) then
  538. local player = NickTag:GetNicknameTable (playerName)
  539. if (player and pool.last_version == minor) then
  540. for thisPlayerName, _ in pairs (pool) do
  541. if (thisPlayerName ~= playerName) then
  542. pool [thisPlayerName] = nil
  543. end
  544. end
  545. --vardump (pool)
  546. else
  547. table.wipe (pool)
  548. end
  549.  
  550. pool.nextreset = time() + (60*60*24*15) --> 15 days or 1296000 seconds
  551. pool.last_version = minor
  552. else
  553. --> sometimes player guid isn't available right after logon, so, just schedule until it become available.
  554. NickTag:ScheduleTimer ("ResetCache", 0.3)
  555. end
  556. end
  557.  
  558. function NickTag:NickTagSetCache (_table)
  559. if (not pool.default) then
  560. return table.wipe (_table)
  561. end
  562.  
  563. pool = _table
  564.  
  565. if (not pool.nextreset) then
  566. pool.nextreset = time() + (60*60*24*15)
  567. end
  568. if (not pool.last_version) then
  569. pool.last_version = minor
  570. end
  571. if (pool.last_version < minor) then
  572. pool.nextreset = 1
  573. end
  574. if (time() > pool.nextreset) then
  575. NickTag:ResetCache()
  576. end
  577.  
  578. NickTag:ScheduleTimer ("SendRevision", 30)
  579. end
  580.  
  581. ------------------------------------------------------------------------------------------------------------------------------------------------------
  582. --> basic functions
  583.  
  584. --> trim from from http://lua-users.org/wiki/StringTrim
  585. function trim (s)
  586. local from = s:match"^%s*()"
  587. return from > #s and "" or s:match(".*%S", from)
  588. end
  589. --
  590. local titlecase = function (first, rest)
  591. return first:upper()..rest:lower()
  592. end
  593. --
  594. local have_repeated = false
  595. local count_spaces = 0
  596. local check_repeated = function (char)
  597. if (char == " ") then
  598. have_repeated = true
  599. elseif (string.len (char) > 2) then
  600. have_repeated = true
  601. elseif (char == " ") then
  602. count_spaces = count_spaces + 1
  603. end
  604. end
  605.  
  606. --> we need to keep game smooth checking and formating nicknames.
  607. --> SetNickname and names comming from other player need to be check.
  608. function NickTag:CheckName (name)
  609.  
  610. --> as nicktag only work internally in the guild, we think that is not necessary a work filter to avoid people using bad language.
  611.  
  612. if (type (name) ~= "string") then
  613. return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_4"] --> error 4 = name isn't a valid string
  614. end
  615.  
  616. name = trim (name)
  617.  
  618. --> limit nickname to 12 characters, same as wow.
  619. local len = string.len (name)
  620. if (len > 75) then
  621. return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_1"] --> error 1 = nickname is too long, max of 12 characters.
  622. end
  623.  
  624. --> check if contain any non allowed characters, by now only accpet letters, numbers and spaces.
  625. --> by default wow do not accetp spaces, but here will allow.
  626. --> tested over lua 5.2 and this capture was okey with accents, not sure why inside wow this doesn't work.
  627. local notallow = string.find (name, "[%s]")
  628. if (notallow) then
  629. return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_2"] --> error 2 = nickname only support letters, numbers and spaces.
  630. end
  631.  
  632. --> check if there is sequencial repeated characters, like "Jasooon" were repeats 3 times the "o" character.
  633. --> got this from http://stackoverflow.com/questions/15608299/lua-pattern-matching-repeating-character
  634. have_repeated = false
  635. count_spaces = 0
  636. string.gsub (name, '.', '\0%0%0'):gsub ('(.)%z%1','%1'):gsub ('%z.([^%z]+)', check_repeated)
  637. if (count_spaces > 22) then
  638. have_repeated = false
  639. end
  640. if (have_repeated) then
  641. return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_3"] --> error 3 = cant use the same letter three times consecutively, 2 spaces consecutively or 3 or more spaces.
  642. end
  643.  
  644. return true
  645. end
  646.  
  647. --> set the "player" nickname and schedule for send updated persona
  648. function NickTag:SetNickname (name)
  649.  
  650. --> check data before
  651. assert (type (name) == "string", "NickTag 'SetNickname' expects a string on #1 argument.")
  652.  
  653. --> check if the nickname is okey to allowed to use.
  654.  
  655. --> here we format the text to match titles, e.g converts name like "JASON NICKSHOW" into "Jason Nickshow".
  656.  
  657. local playerName = UnitName ("player")
  658.  
  659. --> get the full nick table.
  660. local nickTable = NickTag:GetNicknameTable (playerName)
  661. if (not nickTable) then
  662. nickTable = NickTag:Create (playerName, true)
  663. end
  664.  
  665. --> change the nickname for the player nick table.
  666. if (nickTable [CONST_INDEX_NICKNAME] ~= name) then
  667. nickTable [CONST_INDEX_NICKNAME] = name
  668.  
  669. --> send the update for script which need it.
  670. NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_NICKNAME)
  671.  
  672. --> schedule a update for revision and broadcast full persona.
  673. --> this is a kind of protection for scripts which call SetNickname, SetColor and SetAvatar one after other, so scheduling here avoid three revisions upgrades and 3 broadcasts to the guild.
  674. if (not NickTag.send_scheduled) then
  675. NickTag.send_scheduled = true
  676. NickTag:ScheduleTimer ("SendPersona", 1)
  677. end
  678.  
  679. else
  680. NickTag:Msg ("SetNickname() name is the same on the pool ", name, nickTable [CONST_INDEX_NICKNAME])
  681. end
  682.  
  683. return true
  684. end
  685.  
  686. function NickTag:SetNicknameAvatar (texture, l, r, t, b)
  687.  
  688. if (l == nil) then
  689. l, r, t, b = 0, 1, 0, 1
  690. elseif (type (l) == "table") then
  691. l, r, t, b = unpack (l)
  692. end
  693.  
  694. --> check data before
  695. assert (texture and l and r and t and b, "NickTag 'SetNicknameAvatar' bad format. Usage NickTag:SetAvatar (texturepath [, L, R, T, B] or texturepath [, {L, R, T, B}])")
  696.  
  697. local playerName = UnitName ("player")
  698.  
  699. local nickTable = NickTag:GetNicknameTable (playerName)
  700. if (not nickTable) then
  701. nickTable = NickTag:Create (playerName, true)
  702. end
  703.  
  704. if (nickTable [CONST_INDEX_AVATAR_PATH] ~= texture) then
  705. nickTable [CONST_INDEX_AVATAR_PATH] = texture
  706.  
  707. --> by default, CONST_INDEX_AVATAR_TEXCOORD comes as boolean false
  708. if (type (nickTable [CONST_INDEX_AVATAR_TEXCOORD]) == "boolean") then
  709. nickTable [CONST_INDEX_AVATAR_TEXCOORD] = {}
  710. end
  711.  
  712. nickTable [CONST_INDEX_AVATAR_TEXCOORD][1] = l
  713. nickTable [CONST_INDEX_AVATAR_TEXCOORD][2] = r
  714. nickTable [CONST_INDEX_AVATAR_TEXCOORD][3] = t
  715. nickTable [CONST_INDEX_AVATAR_TEXCOORD][4] = b
  716.  
  717. NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_AVATAR_PATH)
  718.  
  719. if (not NickTag.send_scheduled) then
  720. NickTag.send_scheduled = true
  721. NickTag:ScheduleTimer ("SendPersona", 1)
  722. end
  723. end
  724.  
  725. return true
  726. end
  727.  
  728. --> set the background
  729. function NickTag:SetNicknameBackground (path, texcoord, color, silent)
  730.  
  731. if (not silent) then
  732. assert (type (path) == "string", "NickTag 'SetNicknameBackground' expects a string on #1 argument.")
  733. else
  734. if (type (path) ~= "string") then
  735. return
  736. end
  737. end
  738.  
  739. if (not texcoord) then
  740. texcoord = {0, 1, 0, 1}
  741. end
  742.  
  743. if (not color) then
  744. color = {1, 1, 1}
  745. end
  746.  
  747. local playerName = UnitName ("player")
  748.  
  749. local nickTable = NickTag:GetNicknameTable (playerName)
  750. if (not nickTable) then
  751. nickTable = NickTag:Create (playerName, true)
  752. end
  753.  
  754. local need_sync = false
  755. if (nickTable [CONST_INDEX_BACKGROUND_PATH] ~= path) then
  756. nickTable [CONST_INDEX_BACKGROUND_PATH] = path
  757. need_sync = true
  758. end
  759.  
  760. if (nickTable [CONST_INDEX_BACKGROUND_TEXCOORD] ~= texcoord) then
  761. nickTable [CONST_INDEX_BACKGROUND_TEXCOORD] = texcoord
  762. need_sync = true
  763. end
  764.  
  765. if (nickTable [CONST_INDEX_BACKGROUND_COLOR] ~= color) then
  766. nickTable [CONST_INDEX_BACKGROUND_COLOR] = color
  767. need_sync = true
  768. end
  769.  
  770. if (need_sync) then
  771. NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_BACKGROUND_PATH)
  772.  
  773. if (not NickTag.send_scheduled) then
  774. NickTag.send_scheduled = true
  775. NickTag:ScheduleTimer ("SendPersona", 1)
  776. end
  777. end
  778.  
  779. return true
  780. end
  781.  
  782. function NickTag:GetNickname (playerName, default, silent)
  783. if (not silent) then
  784. assert (type (playerName) == "string", "NickTag 'GetNickname' expects a string or string on #1 argument.")
  785. end
  786.  
  787. local _table = pool [playerName]
  788. if (not _table) then
  789. return default or nil
  790. end
  791. return _table [CONST_INDEX_NICKNAME] or default or nil
  792. end
  793.  
  794. --> return the avatar and the texcoord.
  795. function NickTag:GetNicknameAvatar (playerName, default, silent)
  796. if (not silent) then
  797. assert (type (playerName) == "string", "NickTag 'GetNicknameAvatar' expects a string or string on #1 argument.")
  798. end
  799.  
  800. local _table = pool [playerName]
  801.  
  802. if (not _table and default) then
  803. return default, {0, 1, 0, 1}
  804. elseif (not _table) then
  805. return "", {0, 1, 0, 1}
  806. end
  807. return _table [CONST_INDEX_AVATAR_PATH] or default or "", _table [CONST_INDEX_AVATAR_TEXCOORD] or {0, 1, 0, 1}
  808. end
  809.  
  810. function NickTag:GetNicknameBackground (playerName, default_path, default_texcoord, default_color, silent)
  811. if (not silent) then
  812. assert (type (playerName) == "string", "NickTag 'GetNicknameBackground' expects a string or string on #1 argument.")
  813. end
  814.  
  815. local _table = pool [playerName]
  816. if (not _table) then
  817. return default_path, default_texcoord, default_color
  818. end
  819. return _table [CONST_INDEX_BACKGROUND_PATH] or default_path, _table [CONST_INDEX_BACKGROUND_TEXCOORD] or default_texcoord, _table [CONST_INDEX_BACKGROUND_COLOR] or default_color
  820. end
  821.  
  822. --> get the full nicktag table
  823. function NickTag:GetNicknameTable (playerName, silent)
  824. --> check data before
  825. if (not silent) then
  826. assert (type (playerName) == "string", "NickTag 'GetNicknameTable' expects a string on #1 argument.")
  827. else
  828. if (not playerName or type (playerName) ~= "string") then
  829. return
  830. end
  831. end
  832.  
  833. return pool [playerName]
  834. end
  835.  
  836. ------------------------------------------------------------------------------------------------------------------------------------------------------
  837. --> internal functions
  838.  
  839. --> create a empty nick table for the player
  840. function NickTag:Create (playerName, isSelf)
  841. --> check data before
  842. assert (type (playerName) == "string", "NickTag 'Create' expects a string on #1 argument.")
  843.  
  844. --> check if alredy exists
  845. local alredyHave = pool [playerName]
  846. if (alredyHave) then
  847. return alredyHave
  848. end
  849.  
  850. --> create the table:
  851. local newTable = {
  852. UnitName ("player"), --[1] player nickname
  853. false, --[2] avatar texture path
  854. false, --[3] avatar texture coord
  855. false, --[4] background texture path
  856. false, --[5] background texcoord
  857. false, --[6] background color
  858. 1 --[7] revision
  859. }
  860.  
  861. --> if not my persona, set revision to 0, this make always get update after creation
  862. if (not isSelf) then
  863. newTable [CONST_INDEX_REVISION] = 0
  864. end
  865.  
  866. pool [playerName] = newTable
  867. return newTable
  868. end
  869.  
  870. --> inc the revision of the player persona after update nick or avatar
  871. function NickTag:IncRevision()
  872. local playerName = UnitName ("player")
  873. local nickTable = NickTag:GetNicknameTable (playerName)
  874. if (not nickTable) then
  875. nickTable = NickTag:Create (playerName, true)
  876. end
  877.  
  878. nickTable [CONST_INDEX_REVISION] = nickTable [CONST_INDEX_REVISION] + 1
  879.  
  880. return true
  881. end
  882.  
  883. --> convert GUID into serial number (deprecated, it uses player name - realm name)
  884. function NickTag:GetSerial (serial, silent)
  885. return 0
  886. end
  887.  
  888. --> choose avatar window
  889. do
  890. local avatar_pick_frame = CreateFrame ("frame", "AvatarPickFrame", UIParent)
  891. avatar_pick_frame:SetFrameStrata ("DIALOG")
  892. avatar_pick_frame:SetBackdrop ({bgFile = [[Interface\FrameGeneral\UI-Background-Marble]], edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], tile = true, tileSize = 256, edgeSize = 32, insets = {left = 11, right = 12, top = 12, bottom = 11}})
  893. avatar_pick_frame:SetBackdropColor (.3, .3, .3, .9)
  894. avatar_pick_frame:SetWidth (460)
  895. avatar_pick_frame:SetHeight (240)
  896.  
  897. avatar_pick_frame.selected_avatar = 1
  898. avatar_pick_frame.selected_background = 1
  899. avatar_pick_frame.selected_color = {1, 1, 1}
  900. avatar_pick_frame.selected_texcoord = {0, 1, 0, 1}
  901.  
  902. avatar_pick_frame:SetPoint ("center", UIParent, "center", 200, 0)
  903. ---
  904. local avatar_texture = avatar_pick_frame:CreateTexture ("AvatarPickFrameAvatarPreview", "overlay")
  905. avatar_texture:SetPoint ("topleft", avatar_pick_frame, "topleft", 167, -10)
  906. avatar_texture:SetTexture ([[Interface\EncounterJournal\UI-EJ-BOSS-Default]])
  907. --
  908. local background_texture = avatar_pick_frame:CreateTexture ("AvatarPickFrameBackgroundPreview", "artwork")
  909. background_texture:SetPoint ("topleft", avatar_pick_frame, "topleft", 167, 2)
  910. background_texture:SetWidth (290)
  911. background_texture:SetHeight (75)
  912. background_texture:SetTexture (NickTag.background_pool[1][1])
  913. background_texture:SetTexCoord (unpack (NickTag.background_pool[1][3]))
  914. --
  915. local name = avatar_pick_frame:CreateFontString ("AvatarPickFrameName", "overlay", "GameFontHighlightHuge")
  916. name:SetPoint ("left", avatar_texture, "right", -11, -17)
  917. name:SetText (UnitName ("player"))
  918. ---
  919.  
  920. local OnClickFunction = function (button)
  921. if (button.isAvatar) then
  922. local avatar = NickTag.avatar_pool [button.IconID]
  923. _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [1] )
  924. avatar_pick_frame.selected_avatar = avatar [1]
  925. elseif (button.isBackground) then
  926. local background = NickTag.background_pool [button.IconID]
  927. _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
  928. _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
  929. avatar_pick_frame.selected_background = background [1]
  930. avatar_pick_frame.selected_texcoord = background [3]
  931. end
  932. end
  933.  
  934. local selectedColor = function()
  935. local r, g, b = ColorPickerFrame:GetColorRGB()
  936. background_texture:SetVertexColor (r, g, b)
  937. avatar_pick_frame.selected_color[1] = r
  938. avatar_pick_frame.selected_color[2] = g
  939. avatar_pick_frame.selected_color[3] = b
  940. end
  941.  
  942. local okey = CreateFrame ("button", "AvatarPickFrameAccept", avatar_pick_frame, "OptionsButtonTemplate")
  943. okey:SetPoint ("bottomright", avatar_pick_frame, "bottomright", -37, 12)
  944. okey:SetText ("Accept")
  945. okey:SetFrameLevel (avatar_pick_frame:GetFrameLevel()+2)
  946. okey:SetScript ("OnClick", function (self)
  947. avatar_pick_frame:Hide()
  948. if (avatar_pick_frame.callback) then
  949. avatar_pick_frame.callback (avatar_pick_frame.selected_avatar, {0, 1, 0, 1}, avatar_pick_frame.selected_background, avatar_pick_frame.selected_texcoord, avatar_pick_frame.selected_color)
  950. end
  951. end)
  952. local change_color = CreateFrame ("button", "AvatarPickFrameColor", avatar_pick_frame, "OptionsButtonTemplate")
  953. change_color:SetPoint ("bottomright", avatar_pick_frame, "bottomright", -205, 12)
  954. change_color:SetText ("Color")
  955. change_color:SetFrameLevel (avatar_pick_frame:GetFrameLevel()+2)
  956.  
  957. change_color:SetScript ("OnClick", function (self)
  958. ColorPickerFrame.func = selectedColor
  959. ColorPickerFrame.hasOpacity = false
  960. ColorPickerFrame:SetParent (avatar_pick_frame)
  961. ColorPickerFrame:SetColorRGB (_G.AvatarPickFrameBackgroundPreview:GetVertexColor())
  962. ColorPickerFrame:ClearAllPoints()
  963. ColorPickerFrame:SetPoint ("left", avatar_pick_frame, "right", 0, -10)
  964. ColorPickerFrame:Show()
  965. end)
  966.  
  967. local buttons = {}
  968. for i = 0, 2 do
  969. local newbutton = CreateFrame ("button", "AvatarPickFrameAvatarScrollButton"..i+1, avatar_pick_frame)
  970. newbutton:SetScript ("OnClick", OnClickFunction)
  971. newbutton:SetWidth (128)
  972. newbutton:SetHeight (64)
  973. newbutton:SetPoint ("topleft", avatar_pick_frame, "topleft", 15, (i*70*-1) - 20)
  974. newbutton:SetID (i+1)
  975. newbutton.isAvatar = true
  976. buttons [#buttons+1] = newbutton
  977. end
  978.  
  979. local buttonsbg = {}
  980. for i = 0, 2 do
  981. local newbutton = CreateFrame ("button", "AvatarPickFrameBackgroundScrollButton"..i+1, avatar_pick_frame)
  982. newbutton:SetScript ("OnClick", OnClickFunction)
  983. newbutton:SetWidth (275)
  984. newbutton:SetHeight (60)
  985. newbutton:SetPoint ("topleft", avatar_pick_frame, "topleft", 157, (i*50*-1) - 80)
  986. newbutton:SetID (i+1)
  987. newbutton.isBackground = true
  988. buttonsbg [#buttonsbg+1] = newbutton
  989. end
  990.  
  991. local avatar_list = CreateFrame ("ScrollFrame", "AvatarPickFrameAvatarScroll", avatar_pick_frame, "ListScrollFrameTemplate")
  992. avatar_list:SetPoint ("topleft", avatar_pick_frame, "topleft", 10, -10)
  993. local background_list = CreateFrame ("ScrollFrame", "AvatarPickFrameBackgroundScroll", avatar_pick_frame, "ListScrollFrameTemplate")
  994. background_list:SetPoint ("topleft", avatar_pick_frame, "topleft", 147, -85)
  995.  
  996. avatar_list:SetWidth (128)
  997. avatar_list:SetHeight (220)
  998. background_list:SetWidth (275)
  999. background_list:SetHeight (140)
  1000.  
  1001. local avatar_scroll_update = function (self)
  1002. local numMacroIcons = #NickTag.avatar_pool
  1003. local macroPopupIcon, macroPopupButton, index, texture
  1004. local macroPopupOffset = FauxScrollFrame_GetOffset (avatar_list)
  1005.  
  1006. for i = 1, 3 do
  1007. macroPopupIcon = _G ["AvatarPickFrameAvatarScrollButton"..i]
  1008. macroPopupButton = _G ["AvatarPickFrameAvatarScrollButton"..i]
  1009. index = (macroPopupOffset * 1) + i
  1010.  
  1011. texture = NickTag.avatar_pool [index][1]
  1012. if ( index <= numMacroIcons and texture ) then
  1013. macroPopupButton:SetNormalTexture (texture)
  1014. macroPopupButton:SetPushedTexture (texture)
  1015. macroPopupButton:SetDisabledTexture (texture)
  1016. macroPopupButton:SetHighlightTexture (texture, "ADD")
  1017. macroPopupButton.IconID = index
  1018. macroPopupButton:Show()
  1019. else
  1020. macroPopupButton:Hide()
  1021. end
  1022. end
  1023. FauxScrollFrame_Update (avatar_list, numMacroIcons , 3, 64)
  1024. end
  1025. local background_scroll_update = function (self)
  1026. local numMacroIcons = #NickTag.background_pool
  1027. local macroPopupIcon, macroPopupButton, index, texture
  1028. local macroPopupOffset = FauxScrollFrame_GetOffset (background_list)
  1029.  
  1030. for i = 1, 3 do
  1031. macroPopupIcon = _G ["AvatarPickFrameBackgroundScrollButton"..i]
  1032. macroPopupButton = _G ["AvatarPickFrameBackgroundScrollButton"..i]
  1033. index = (macroPopupOffset * 1) + i
  1034.  
  1035. texture = NickTag.background_pool [index][1]
  1036. if ( index <= numMacroIcons and texture ) then
  1037. macroPopupButton:SetNormalTexture (texture)
  1038. macroPopupButton:SetPushedTexture (texture)
  1039. macroPopupButton:SetDisabledTexture (texture)
  1040. macroPopupButton:SetHighlightTexture (texture, "ADD")
  1041. macroPopupButton.IconID = index
  1042. macroPopupButton:Show()
  1043. else
  1044. macroPopupButton:Hide()
  1045. end
  1046. end
  1047. FauxScrollFrame_Update (background_list, numMacroIcons , 3, 40)
  1048. end
  1049.  
  1050. avatar_list:SetScript ("OnVerticalScroll", function (self, offset)
  1051. FauxScrollFrame_OnVerticalScroll (avatar_list, offset, 64, avatar_scroll_update)
  1052. end)
  1053. background_list:SetScript ("OnVerticalScroll", function (self, offset)
  1054. FauxScrollFrame_OnVerticalScroll (background_list, offset, 40, background_scroll_update)
  1055. end)
  1056.  
  1057. avatar_scroll_update (avatar_list)
  1058. background_scroll_update (background_list)
  1059.  
  1060. function avatar_pick_frame:SetAvatar (n)
  1061. if (type (n) ~= "number") then
  1062. n = 1
  1063. end
  1064. if (n > #NickTag.avatar_pool) then
  1065. n = 1
  1066. end
  1067. local avatar = NickTag.avatar_pool [n]
  1068. _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [1] )
  1069. avatar_pick_frame.selected_avatar = avatar [1]
  1070. end
  1071. function avatar_pick_frame:SetBackground (n)
  1072. if (type (n) ~= "number") then
  1073. n = 1
  1074. end
  1075. if (n > #NickTag.background_pool) then
  1076. n = 1
  1077. end
  1078. local background = NickTag.background_pool [n]
  1079. _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
  1080. _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
  1081. _G.AvatarPickFrameBackgroundPreview:SetVertexColor (unpack (avatar_pick_frame.selected_color))
  1082. avatar_pick_frame.selected_background = background [1]
  1083. end
  1084. function avatar_pick_frame:SetColor (r, g, b)
  1085. if (type (r) ~= "number" or r > 1) then
  1086. r = 1
  1087. end
  1088. if (type (g) ~= "number" or g > 1) then
  1089. g = 1
  1090. end
  1091. if (type (b) ~= "number" or b > 1) then
  1092. b = 1
  1093. end
  1094. _G.AvatarPickFrameBackgroundPreview:SetVertexColor (r, g, b)
  1095. avatar_pick_frame.selected_color[1] = r
  1096. avatar_pick_frame.selected_color[2] = g
  1097. avatar_pick_frame.selected_color[3] = b
  1098. end
  1099.  
  1100. local CONST_INDEX_NICKNAME = 1
  1101. local CONST_INDEX_AVATAR_PATH = 2
  1102. local CONST_INDEX_AVATAR_TEXCOORD = 3
  1103. local CONST_INDEX_BACKGROUND_PATH = 4
  1104. local CONST_INDEX_BACKGROUND_TEXCOORD = 5
  1105. local CONST_INDEX_BACKGROUND_COLOR = 6
  1106.  
  1107. avatar_pick_frame:SetScript ("OnShow", function()
  1108. --get player avatar
  1109. local avatar = NickTag:GetNicknameTable (UnitGUID ("player"))
  1110. if (avatar) then
  1111. _G.AvatarPickFrameName:SetText ( avatar [1] or UnitName ("player"))
  1112.  
  1113. _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [CONST_INDEX_AVATAR_PATH] or [[Interface\EncounterJournal\UI-EJ-BOSS-Default]] )
  1114. avatar_pick_frame.selected_avatar = avatar [CONST_INDEX_AVATAR_PATH] or [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
  1115.  
  1116. _G.AvatarPickFrameAvatarPreview:SetTexCoord ( 0, 1, 0, 1 ) --> always
  1117.  
  1118. _G.AvatarPickFrameBackgroundPreview:SetTexture ( avatar [CONST_INDEX_BACKGROUND_PATH] or [[Interface\PetBattles\Weather-ArcaneStorm]] )
  1119. avatar_pick_frame.selected_background = avatar [CONST_INDEX_BACKGROUND_PATH] or [[Interface\PetBattles\Weather-ArcaneStorm]]
  1120.  
  1121. if (avatar [CONST_INDEX_BACKGROUND_TEXCOORD]) then
  1122. _G.AvatarPickFrameBackgroundPreview:SetTexCoord ( unpack (avatar [CONST_INDEX_BACKGROUND_TEXCOORD]) )
  1123. avatar_pick_frame.selected_texcoord = avatar [CONST_INDEX_BACKGROUND_TEXCOORD]
  1124. else
  1125. _G.AvatarPickFrameBackgroundPreview:SetTexCoord ( 0.129609375, 1, 1, 0 )
  1126. avatar_pick_frame.selected_texcoord = {0.129609375, 1, 1, 0}
  1127. end
  1128.  
  1129. if (avatar [CONST_INDEX_BACKGROUND_COLOR]) then
  1130. _G.AvatarPickFrameBackgroundPreview:SetVertexColor ( unpack (avatar [CONST_INDEX_BACKGROUND_COLOR]) )
  1131. avatar_pick_frame.selected_color = avatar [CONST_INDEX_BACKGROUND_COLOR]
  1132. else
  1133. _G.AvatarPickFrameBackgroundPreview:SetVertexColor ( 1, 1, 1 )
  1134. avatar_pick_frame.selected_color = {1, 1, 1}
  1135. end
  1136. else
  1137. --> if none
  1138. _G.AvatarPickFrameAvatarPreview:SetTexture ( [[Interface\EncounterJournal\UI-EJ-BOSS-Default]] )
  1139. avatar_pick_frame.selected_avatar = [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
  1140.  
  1141. local background = NickTag.background_pool [1]
  1142.  
  1143. if (background) then
  1144. _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
  1145. avatar_pick_frame.selected_background = background [1]
  1146. _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
  1147. avatar_pick_frame.selected_texcoord = background [3]
  1148. _G.AvatarPickFrameBackgroundPreview:SetVertexColor (unpack (avatar_pick_frame.selected_color))
  1149. avatar_pick_frame.selected_color = avatar_pick_frame.selected_color
  1150. end
  1151.  
  1152. end
  1153. end)
  1154.  
  1155. avatar_pick_frame:Hide()
  1156. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement