Advertisement
Guest User

custom chat

a guest
Apr 30th, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 52.25 KB | None | 0 0
  1. --game:GetService("StarterGui"):SetCoreGuiEnabled("Chat", false)
  2. local NameColorDependsOnChatColor = true
  3. local StrokeTransparency = 0.5 -- Number 0 to 1. Lower stroke transparency is easier to read against colorful backgrounds.
  4.  
  5. while not _G.PlayerListAPI do wait() end
  6. local PLAYERLIST_ADMINS, PLAYERLIST_CHATCOLORS, PLAYERLIST_ALIASES = _G.PlayerListAPI:GetChatData()
  7.  
  8. local PLAYERLIST_ADMINS = "Precisionly", "DelitiveMod2", "Aexeals"
  9.  
  10. local forceChatGUI = false
  11.  
  12. -- Utility functions + Globals
  13. local function WaitForChild(parent, childName)
  14. while parent:FindFirstChild(childName) == nil do
  15. parent.ChildAdded:wait(0.03)
  16. end
  17. return parent[childName]
  18. end
  19.  
  20. local function typedef(obj)
  21. return obj
  22. end
  23.  
  24. local function IsPhone()
  25. local rGui = script.Parent
  26. if rGui.AbsoluteSize.Y < 600 then
  27. return true
  28. end
  29. return false
  30. end
  31.  
  32. local export = {}
  33. export.NameColorDependsOnChatColor = NameColorDependsOnChatColor
  34.  
  35. export.SetNameColorDependsOnChatColor = function(self, b)
  36. self.NameColorDependsOnChatColor = b
  37. end
  38.  
  39. -- Users can use enough white spaces to spoof chatting as other players
  40. -- This function removes trailing and leading white spaces
  41. -- AFAIK, there is no reason for spam white spaces
  42. local function StringTrim(str)
  43. -- %S is whitespaces
  44. -- When we find the first non space character defined by ^%s
  45. -- we yank out anything in between that and the end of the string
  46. -- Everything else is replaced with %1 which is essentially nothing
  47. return (str:gsub("^%s*(.-)%s*$", "%1"))
  48. end
  49.  
  50. while Game.Players.LocalPlayer == nil do wait(0.03) end
  51.  
  52. local Player = Game.Players.LocalPlayer
  53. while Player.Character == nil do wait(0.03) end
  54. local RbxUtility = LoadLibrary('RbxUtility')
  55. local Gui = typedef(RbxUtility)
  56. local Camera = Game.Workspace.CurrentCamera
  57.  
  58. -- Services
  59. local CoreGuiService = Game:GetService('CoreGui')
  60. local PlayersService = Game:GetService('Players')
  61. local DebrisService= Game:GetService('Debris')
  62. local GuiService = Game:GetService('GuiService')
  63.  
  64. -- Lua Enums
  65. local Enums do
  66. Enums = {}
  67. local EnumName = {} -- used as unique key for enum name
  68. local enum_mt = {
  69. __call = function(self,value)
  70. return self[value] or self[tonumber(value)]
  71. end;
  72. __index = {
  73. GetEnumItems = function(self)
  74. local t = {}
  75. for i,item in pairs(self) do
  76. if type(i) == 'number' then
  77. t[#t+1] = item
  78. end
  79. end
  80. table.sort(t,function(a,b) return a.Value < b.Value end)
  81. return t
  82. end;
  83. };
  84. __tostring = function(self)
  85. return "Enum." .. self[EnumName]
  86. end;
  87. }
  88. local item_mt = {
  89. __call = function(self,value)
  90. return value == self or value == self.Name or value == self.Value
  91. end;
  92. __tostring = function(self)
  93. return "Enum." .. self[EnumName] .. "." .. self.Name
  94. end;
  95. }
  96. function CreateEnum(enumName)
  97. return function(t)
  98. local e = {[EnumName] = enumName}
  99. for i,name in pairs(t) do
  100. local item = setmetatable({Name=name,Value=i,Enum=e,[EnumName]=enumName},item_mt)
  101. e[i] = item
  102. e[name] = item
  103. e[item] = item
  104. end
  105. Enums[enumName] = e
  106. return setmetatable(e, enum_mt)
  107. end
  108. end
  109. end
  110. ---------------------------------------------------
  111. ------------------ Input class --------------------
  112. local Input = {
  113. Mouse = Player:GetMouse(),
  114. Speed = 0,
  115. Simulating = false,
  116.  
  117. Configuration = {
  118. DefaultSpeed = 1
  119. },
  120. UserIsScrolling = false
  121. }
  122.  
  123. ---------------------------------------------------
  124. ------------------ Chat class --------------------
  125. local Chat = {
  126.  
  127. ChatColors = {
  128. BrickColor.new("Bright red"),
  129. BrickColor.new("Bright blue"),
  130. BrickColor.new("Earth green"),
  131. BrickColor.new("Bright violet"),
  132. BrickColor.new("Bright orange"),
  133. BrickColor.new("Bright yellow"),
  134. BrickColor.new("Light reddish violet"),
  135. BrickColor.new("Brick yellow"),
  136. },
  137.  
  138. Gui = nil,
  139. Frame = nil,
  140. RenderFrame = nil,
  141. TapToChatLabel = nil,
  142. ClickToChatButton = nil,
  143.  
  144. ScrollingLock = false,
  145. EventListener = nil,
  146.  
  147. -- This is actually a ring buffer
  148. -- Meaning at hitting the historyLength it wraps around
  149. -- Reuses the text objects, so chat atmost uses 100 text objects
  150. MessageQueue = {},
  151.  
  152. -- Stores all the values for configuring chat
  153. Configuration = {
  154. FontSize = Enum.FontSize.Size12, -- 10 is good
  155. -- Also change this when you are changing the above, this is suboptimal but so is our interface to find FontSize
  156. NumFontSize = 12,
  157. HistoryLength = 20, -- stores up to 50 of the last chat messages for you to scroll through,
  158. Size = UDim2.new(0.38, 0, 0.20, 0),
  159. MessageColor = Color3.new(1, 1, 1),
  160. AdminMessageColor = Color3.new(1, 215/255, 0),
  161. XScale = 0.025,
  162. LifeTime = 45,
  163. Position = UDim2.new(0, 2, 0.05, 0),
  164. DefaultTweenSpeed = 0.15,
  165. },
  166.  
  167. -- This could be redone by just using the previous and next fields of the Queue
  168. -- But the iterators cause issues, will be optimized later
  169. SlotPositions_List = {},
  170. -- To precompute and store all player null strings since its an expensive process
  171. CachedSpaceStrings_List = {},
  172. MouseOnFrame = false,
  173. GotFocus = false,
  174.  
  175. Messages_List = {},
  176. MessageThread = nil,
  177.  
  178. Admins_List = PLAYERLIST_ADMINS,
  179.  
  180. SafeChat_List = {
  181. ['Use the Chat menu to talk to me.'] = {'/sc 0', true},
  182. ['I can only see menu chats.'] = {'/sc 1', true},
  183. ['Hello'] = {
  184. ['Hi'] = {'/sc 2_0', true, ['Hi there!'] = true, ['Hi everyone'] = true},
  185. ['Howdy'] = {'/sc 2_1', true, ['Howdy partner!'] = true},
  186. ['Greetings'] = {'/sc 2_2', true, ['Greetings everyone'] = true, ['Greetings Robloxians!'] = true, ['Seasons greetings!'] = true},
  187. ['Welcome'] = {'/sc 2_3', true, ['Welcome to my place'] = true, ['Welcome to my barbeque'] = true, ['Welcome to our base'] = true},
  188. ['Hey there!'] = {'/sc 2_4', true},
  189. ['What\'s up?'] = {'/sc 2_5', true, ['How are you doing?'] = true, ['How\'s it going?'] = true, ['What\'s new?'] = true},
  190. ['Good day'] = {'/sc 2_6', true, ['Good morning'] = true, ['Good evening'] = true, ['Good afternoon'] = true, ['Good night'] = true},
  191. ['Silly'] = {'/sc 2_7', true, ['Waaaaaaaz up?!'] = true, ['Hullo!'] = true, ['Behold greatness, mortals!'] = true, ['Pardon me, is this Sparta?'] = true, ['THIS IS SPARTAAAA!'] = true},
  192. ['Happy Holidays!'] = {'/sc 2_8', true, ['Happy New Year!'] = true,
  193. ['Happy Valentine\'s Day!'] = true,
  194. ['Beware the Ides of March!'] = true,
  195. ['Happy St. Patrick\'s Day!'] = true,
  196. ['Happy Easter!'] = true,
  197. ['Happy Earth Day!'] = true,
  198. ['Happy 4th of July!'] = true,
  199. ['Happy Thanksgiving!'] = true,
  200. ['Happy Halloween!'] = true,
  201. ['Happy Hanukkah!'] = true,
  202. ['Merry Christmas!'] = true,
  203. ['Happy Halloween!'] = true,
  204. ['Happy Earth Day!'] = true,
  205. ['Happy May Day!'] = true,
  206. ['Happy Towel Day!'] = true,
  207. ['Happy ROBLOX Day!'] = true,
  208. ['Happy LOL Day!'] = true },
  209.  
  210. [1] = '/sc 2'
  211. },
  212. ['Goodbye'] = {
  213. ['Good Night']= {'/sc 3_0', true,
  214. ['Sweet dreams'] = true,
  215. ['Go to sleep!'] = true,
  216. ['Lights out!'] = true,
  217. ['Bedtime'] = true,
  218. ['Going to bed now'] = true},
  219.  
  220. ['Later']= {'/sc 3_1', true,
  221. ['See ya later'] = true,
  222. ['Later gator!'] = true,
  223. ['See you tomorrow'] = true},
  224.  
  225. ['Bye'] = {'/sc 3_2', true, ['Hasta la bye bye!'] = true},
  226. ['I\'ll be right back'] = {'/sc 3_3', true},
  227. ['I have to go'] = {'/sc 3_4', true},
  228. ['Farewell'] = {'/sc 3_5', true, ['Take care'] = true, ['Have a nice day'] = true, ['Goodluck!'] = true, ['Ta-ta for now!'] = true},
  229. ['Peace'] = {'/sc 3_6', true, ['Peace out!'] = true, ['Peace dudes!'] = true, ['Rest in pieces!'] = true},
  230. ['Silly'] = {'/sc 3_7', true,
  231. ['To the batcave!'] = true,
  232. ['Over and out!'] = true,
  233. ['Happy trails!'] = true,
  234. ['I\'ve got to book it!'] = true,
  235. ['Tootles!'] = true,
  236. ['Smell you later!'] = true,
  237. ['GG!'] = true,
  238. ['My house is on fire! gtg.'] = true},
  239. [1] = '/sc 3'
  240. },
  241. ['Friend'] ={
  242. ['Wanna be friends?'] = {'/sc 4_0', true},
  243. ['Follow me'] = {'/sc 4_1', true, ['Come to my place!'] = true, ['Come to my base!'] = true, ['Follow me, team!'] = true, ['Follow me'] = true},
  244. ['Your place is cool'] = {'/sc 4_2', true, ['Your place is fun'] = true, ['Your place is awesome'] = true, ['Your place looks good'] = true, ['This place is awesome!'] = true},
  245. ['Thank you'] = {'/sc 4_3', true, ['Thanks for playing'] = true, ['Thanks for visiting'] = true, ['Thanks for everything'] = true, ['No, thank you'] = true, ['Thanx'] = true},
  246. ['No problem'] = {'/sc 4_4', true, ['Don\'t worry'] = true, ['That\'s ok'] = true, ['np'] = true},
  247. ['You are ...'] = {'/sc 4_5', true,
  248. ['You are great!'] = true,
  249. ['You are good!'] = true,
  250. ['You are cool!'] = true,
  251. ['You are funny!'] = true,
  252. ['You are silly!'] = true,
  253. ['You are awesome!'] = true,
  254. ['You are doing something I don\'t like, please stop'] = true
  255. },
  256. ['I like ...'] = {'/sc 4_6', true, ['I like your name'] = true, ['I like your shirt'] = true, ['I like your place'] = true, ['I like your style'] = true,
  257. ['I like you'] = true, ['I like items'] = true, ['I like money'] = true},
  258. ['Sorry'] = {'/sc 4_7', true, ['My bad!'] = true, ['I\'m sorry'] = true, ['Whoops!'] = true, ['Please forgive me.'] = true, ['I forgive you.'] = true,
  259. ['I didn\'t mean to do that.'] = true, ['Sorry, I\'ll stop now.'] = true},
  260. [1] = '/sc 4'
  261. },
  262. ['Questions'] = {
  263. ['Who?'] = {'/sc 5_0', true, ['Who wants to be my friend?'] = true, ['Who wants to be on my team?'] = true, ['Who made this brilliant game?'] = true},
  264. ['What?'] = {'/sc 5_1', true, ['What is your favorite animal?'] = true, ['What is your favorite game?'] = true, ['What is your favorite movie?'] = true,
  265. ['What is your favorite TV show?'] = true, ['What is your favorite music?'] = true, ['What are your hobbies?'] = true, ['LOLWUT?'] = true},
  266. ['When?'] = {'/sc 5_2', true, ['When are you online?'] = true, ['When is the new version coming out?'] = true, ['When can we play again?'] = true, ['When will your place be done?'] = true},
  267. ['Where?'] = {'/sc 5_3', true, ['Where do you want to go?'] = true, ['Where are you going?'] = true, ['Where am I?!'] = true, ['Where did you go?'] = true},
  268. ['How?'] = {'/sc 5_4', true, ['How are you today?'] = true, ['How did you make this cool place?'] = true, ['LOLHOW?'] = true},
  269. ['Can I...'] = {'/sc 5_5', true, ['Can I have a tour?'] = true, ['Can I be on your team?'] = true, ['Can I be your friend?'] = true, ['Can I try something?'] = true,
  270. ['Can I have that please?'] = true, ['Can I have that back please?'] = true, ['Can I have borrow your hat?'] = true, ['Can I have borrow your gear?'] = true},
  271. [1] = '/sc 5'
  272. },
  273. ['Answers'] = {
  274. ['You need help?'] = {'/sc 6_0', true, ['Check out the news section'] = true, ['Check out the help section'] = true, ['Read the wiki!'] = true,
  275. ['All the answers are in the wiki!'] = true, ['I will help you with this.'] = true},
  276. ['Some people ...'] = {'/sc 6_1', true, ['Me'] = true, ['Not me'] = true, ['You'] = true, ['All of us'] = true, ['Everyone but you'] = true, ['Builderman!'] = true,
  277. ['Telamon!'] = true, ['My team'] = true, ['My group'] = true, ['Mom'] = true, ['Dad'] = true, ['Sister'] = true, ['Brother'] = true, ['Cousin'] = true,
  278. ['Grandparent'] = true, ['Friend'] = true},
  279. ['Time ...'] = {'/sc 6_2', true, ['In the morning'] = true, ['In the afternoon'] = true, ['At night'] = true, ['Tomorrow'] = true, ['This week'] = true, ['This month'] = true,
  280. ['Sometime'] = true, ['Sometimes'] = true, ['Whenever you want'] = true, ['Never'] = true, ['After this'] = true, ['In 10 minutes'] = true, ['In a couple hours'] = true,
  281. ['In a couple days'] = true},
  282. ['Animals'] = {'/sc 6_3', true,
  283. ['Cats'] = {['Lion'] = true, ['Tiger'] = true, ['Leopard'] = true, ['Cheetah'] = true},
  284. ['Dogs'] = {['Wolves'] = true, ['Beagle'] = true, ['Collie'] = true, ['Dalmatian'] = true, ['Poodle'] = true, ['Spaniel'] = true,
  285. ['Shepherd'] = true, ['Terrier'] = true, ['Retriever'] = true},
  286. ['Horses'] = {['Ponies'] = true, ['Stallions'] = true, ['Pwnyz'] = true},
  287. ['Reptiles'] = {['Dinosaurs'] = true, ['Lizards'] = true, ['Snakes'] = true, ['Turtles!'] = true},
  288. ['Hamster'] = true,
  289. ['Monkey'] = true,
  290. ['Bears'] = true,
  291. ['Fish'] = {['Goldfish'] = true, ['Sharks'] = true, ['Sea Bass'] = true, ['Halibut'] = true, ['Tropical Fish'] = true},
  292. ['Birds'] = {['Eagles'] = true, ['Penguins'] = true, ['Parakeets'] = true, ['Owls'] = true, ['Hawks'] = true, ['Pidgeons'] = true},
  293. ['Elephants'] = true,
  294. ['Mythical Beasts'] = {['Dragons'] = true, ['Unicorns'] = true, ['Sea Serpents'] = true, ['Sphinx'] = true, ['Cyclops'] = true,
  295. ['Minotaurs'] = true, ['Goblins'] = true, ['Honest Politicians'] = true, ['Ghosts'] = true, ['Scylla and Charybdis'] = true}
  296. },
  297. ['Games'] = {'/sc 6_4', true,
  298. ['Action'] = true, ['Puzzle'] = true, ['Strategy'] = true, ['Racing'] = true, ['RPG'] = true, ['Obstacle Course'] = true, ['Tycoon'] = true,
  299. ['Roblox'] = { ['BrickBattle'] = true, ['Community Building'] = true, ['Roblox Minigames'] = true, ['Contest Place'] = true},
  300. ['Board games'] = { ['Chess'] = true, ['Checkers'] = true, ['Settlers of Catan'] = true, ['Tigris and Euphrates'] = true, ['El Grande'] = true,
  301. ['Stratego'] = true, ['Carcassonne'] = true}
  302. },
  303. ['Sports'] = {'/sc 6_5', true, ['Hockey'] = true, ['Soccer'] = true, ['Football'] = true, ['Baseball'] = true, ['Basketball'] = true,
  304. ['Volleyball'] = true, ['Tennis'] = true, ['Sports team practice'] = true,
  305. ['Watersports'] = { ['Surfing'] = true,['Swimming'] = true, ['Water Polo'] = true},
  306. ['Winter sports'] = { ['Skiing'] = true, ['Snowboarding'] = true, ['Sledding'] = true, ['Skating'] = true},
  307. ['Adventure'] = {['Rock climbing'] = true, ['Hiking'] = true, ['Fishing'] = true, ['Horseback riding'] = true},
  308. ['Wacky'] = {['Foosball'] = true, ['Calvinball'] = true, ['Croquet'] = true, ['Cricket'] = true, ['Dodgeball'] = true,
  309. ['Squash'] = true, ['Trampoline'] = true}
  310. },
  311. ['Movies/TV'] = {'/sc 6_6', true, ['Science Fiction'] = true, ['Animated'] = {['Anime'] = true}, ['Comedy'] = true, ['Romantic'] = true,
  312. ['Action'] = true, ['Fantasy'] = true},
  313. ['Music'] = {'/sc 6_7', true, ['Country'] = true, ['Jazz'] = true, ['Rap'] = true, ['Hip-hop'] = true, ['Techno'] = true, ['Classical'] = true,
  314. ['Pop'] = true, ['Rock'] = true},
  315. ['Hobbies'] = {'/sc 6_8', true,
  316. ['Computers'] = { ['Building computers'] = true, ['Videogames'] = true, ['Coding'] = true, ['Hacking'] = true},
  317. ['The Internet'] = { ['lol. teh internets!'] = true, ['Watching vids'] = true},
  318. ['Dance'] = true, ['Gymnastics'] = true, ['Listening to music'] = true, ['Arts and crafts'] = true,
  319. ['Martial Arts'] = {['Karate'] = true, ['Judo'] = true, ['Taikwon Do'] = true, ['Wushu'] = true, ['Street fighting'] = true},
  320. ['Music lessons'] = {['Playing in my band'] = true, ['Playing piano'] = true, ['Playing guitar'] = true,
  321. ['Playing violin'] = true, ['Playing drums'] = true, ['Playing a weird instrument'] = true}
  322. },
  323. ['Location'] = {'/sc 6_9', true,
  324. ['USA'] = {
  325. ['West'] = { ['Alaska'] = true, ['Arizona'] = true, ['California'] = true, ['Colorado'] = true, ['Hawaii'] = true,
  326. ['Idaho'] = true, ['Montana'] = true, ['Nevada'] = true, ['New Mexico'] = true, ['Oregon'] = true,
  327. ['Utah'] = true, ['Washington'] = true, ['Wyoming'] = true
  328. },
  329. ['South'] = { ['Alabama'] = true, ['Arkansas'] = true, ['Florida'] = true, ['Georgia'] = true, ['Kentucky'] = true,
  330. ['Louisiana'] = true, ['Mississippi'] = true, ['North Carolina'] = true, ['Oklahoma'] = true,
  331. ['South Carolina'] = true, ['Tennessee'] = true, ['Texas'] = true, ['Virginia'] = true, ['West Virginia'] = true
  332. },
  333. ['Northeast'] = {['Connecticut'] = true, ['Delaware'] = true, ['Maine'] = true, ['Maryland'] = true, ['Massachusetts'] = true,
  334. ['New Hampshire'] = true, ['New Jersey'] = true, ['New York'] = true, ['Pennsylvania'] = true, ['Rhode Island'] = true,
  335. ['Vermont'] = true
  336. },
  337. ['Midwest'] = {['Illinois'] = true, ['Indiana'] = true, ['Iowa'] = true, ['Kansas'] = true, ['Michigan'] = true, ['Minnesota'] = true,
  338. ['Missouri'] = true, ['Nebraska'] = true, ['North Dakota'] = true, ['Ohio'] = true, ['South Dakota'] = true, ['Wisconsin'] = true}
  339. },
  340. ['Canada'] = {['Alberta'] = true, ['British Columbia'] = true, ['Manitoba'] = true, ['New Brunswick'] = true, ['Newfoundland'] = true,
  341. ['Northwest Territories'] = true, ['Nova Scotia'] = true, ['Nunavut'] = true, ['Ontario'] = true, ['Prince Edward Island'] = true,
  342. ['Quebec'] = true, ['Saskatchewan'] = true, ['Yukon'] = true},
  343. ['Mexico'] = true,
  344. ['Central America'] = true,
  345. ['Europe'] = {['France'] = true, ['Germany'] = true, ['Spain'] = true, ['Italy'] = true, ['Poland'] = true, ['Switzerland'] = true,
  346. ['Greece'] = true, ['Romania'] = true, ['Netherlands'] = true,
  347. ['Great Britain'] = {['England'] = true, ['Scotland'] = true, ['Wales'] = true, ['Northern Ireland'] = true}
  348. },
  349. ['Asia'] = { ['China'] = true, ['India'] = true, ['Japan'] = true, ['Korea'] = true, ['Russia'] = true, ['Vietnam'] = true},
  350. ['South America'] = { ['Argentina'] = true, ['Brazil'] = true},
  351. ['Africa'] = { ['Eygpt'] = true, ['Swaziland'] = true},
  352. ['Australia'] = true, ['Middle East'] = true, ['Antarctica'] = true, ['New Zealand'] = true
  353. },
  354. ['Age'] = {'/sc 6_10', true, ['Rugrat'] = true, ['Kid'] = true, ['Tween'] = true, ['Teen'] = true, ['Twenties'] = true,
  355. ['Old'] = true, ['Ancient'] = true, ['Mesozoic'] = true, ['I don\'t want to say my age. Don\'t ask.'] = true},
  356. ['Mood'] = {'/sc 6_11', true, ['Good'] = true, ['Great!'] = true, ['Not bad'] = true, ['Sad'] = true, ['Hyper'] = true,
  357. ['Chill'] = true, ['Happy'] = true, ['Kind of mad'] = true},
  358. ['Boy'] = {'/sc 6_12', true},
  359. ['Girl'] = {'/sc 6_13', true},
  360. ['I don\'t want to say boy or girl. Don\'t ask.'] = {'/sc 6_14', true},
  361. [1] = '/sc 6'
  362. },
  363. ['Game'] = {
  364. ['Let\'s build'] = {'/sc 7_0', true},
  365. ['Let\'s battle'] = {'/sc 7_1', true},
  366. ['Nice one!'] = {'/sc 7_2', true},
  367. ['So far so good'] = {'/sc 7_3', true},
  368. ['Lucky shot!'] = {'/sc 7_4', true},
  369. ['Oh man!'] = {'/sc 7_5', true},
  370. ['I challenge you to a fight!'] = {'/sc 7_6', true},
  371. ['Help me with this'] = {'/sc 7_7', true},
  372. ['Let\'s go to your game'] = {'/sc 7_8', true},
  373. ['Can you show me how do to that?'] = {'/sc 7_9', true},
  374. ['Backflip!'] = {'/sc 7_10', true},
  375. ['Frontflip!'] = {'/sc 7_11', true},
  376. ['Dance!'] = {'/sc 7_12', true},
  377. ['I\'m on your side!'] = {'/sc 7_13', true},
  378. ['Game Commands'] = {'/sc 7_14', true, ['regen'] = true, ['reset'] = true, ['go'] = true, ['fix'] = true, ['respawn'] = true},
  379. [1] = '/sc 7'
  380. };
  381. ['Silly'] = {
  382. ['Muahahahaha!'] = true,
  383. ['all your base are belong to me!'] = true,
  384. ['GET OFF MAH LAWN'] = true,
  385. ['TEH EPIK DUCK IS COMING!!!'] = true,
  386. ['ROFL'] = true,
  387. ['1337'] = {true, ['i r teh pwnz0r!'] = true, ['w00t!'] = true, ['z0mg h4x!'] = true, ['ub3rR0xXorzage!'] = true}
  388. },
  389. ['Yes'] = {
  390. ['Absolutely!'] = true,
  391. ['Rock on!'] = true,
  392. ['Totally!'] = true,
  393. ['Juice!'] = true,
  394. ['Yay!'] = true,
  395. ['Yesh'] = true
  396. },
  397. ['No'] = {
  398. ['Ummm. No.'] = true,
  399. ['...'] = true,
  400. ['Stop!'] = true,
  401. ['Go away!'] = true,
  402. ['Don\'t do that'] = true,
  403. ['Stop breaking the rules'] = true,
  404. ['I don\'t want to'] = true
  405. },
  406. ['Ok'] = {
  407. ['Well... ok'] = true,
  408. ['Sure'] = true
  409. },
  410. ['Uncertain'] = {
  411. ['Maybe'] = true,
  412. ['I don\'t know'] = true,
  413. ['idk'] = true,
  414. ['I can\'t decide'] = true,
  415. ['Hmm...'] = true
  416. },
  417. [':-)'] = {
  418. [':-('] = true,
  419. [':D'] = true,
  420. [':-O'] = true,
  421. ['lol'] = true,
  422. ['=D'] = true,
  423. ['D='] = true,
  424. ['XD'] = true,
  425. [';D'] = true,
  426. [';)'] = true,
  427. ['O_O'] = true,
  428. ['=)'] = true,
  429. ['@_@'] = true,
  430. ['&gt;_&lt;'] = true,
  431. ['T_T'] = true,
  432. ['^_^'] = true,
  433. ['<(0_0<) <(0_0)> (>0_0)> KIRBY DANCE'] = true,
  434. [')\';'] = true,
  435. [':3'] = true
  436. },
  437. ['Ratings'] = {
  438. ['Rate it!'] = true,
  439. ['I give it a 1 out of 10'] = true,
  440. ['I give it a 2 out of 10'] = true,
  441. ['I give it a 3 out of 10'] = true,
  442. ['I give it a 4 out of 10'] = true,
  443. ['I give it a 5 out of 10'] = true,
  444. ['I give it a 6 out of 10'] = true,
  445. ['I give it a 7 out of 10'] = true,
  446. ['I give it a 8 out of 10'] = true,
  447. ['I give it a 9 out of 10'] = true,
  448. ['I give it a 10 out of 10!'] = true,
  449. }
  450. },
  451. CreateEnum('SafeChat'){'Level1', 'Level2', 'Level3'},
  452. SafeChatTree = {},
  453. TempSpaceLabel = nil
  454. }
  455. ---------------------------------------------------
  456.  
  457. local function GetNameValue(pName)
  458. local value = 0
  459. for index = 1, #pName do
  460. local cValue = string.byte(string.sub(pName, index, index))
  461. local reverseIndex = #pName - index + 1
  462. if #pName%2 == 1 then
  463. reverseIndex = reverseIndex - 1
  464. end
  465. if reverseIndex%4 >= 2 then
  466. cValue = -cValue
  467. end
  468. value = value + cValue
  469. end
  470. return value%8
  471. end
  472.  
  473. function Chat:ComputeChatColor(pName)
  474. if export.NameColorDependsOnChatColor then
  475. return PLAYERLIST_CHATCOLORS[pName:lower()] or self.ChatColors[GetNameValue(pName) + 1].Color
  476. else
  477. return self.ChatColors[GetNameValue(pName) + 1].Color
  478. end
  479. end
  480.  
  481. -- This is context based scrolling
  482. function Chat:EnableScrolling(toggle)
  483. -- Genius idea gone to fail, if we switch the camera type we can effectively lock the
  484. -- camera and do no click scrolling
  485. self.MouseOnFrame = false
  486. if self.RenderFrame then
  487. self.RenderFrame.MouseEnter:connect(function()
  488. local character = Player.Character
  489. local torso = WaitForChild(character, 'Torso')
  490. local humanoid = WaitForChild(character, 'Humanoid')
  491. local head = WaitForChild(character, 'Head')
  492. if toggle then
  493. self.MouseOnFrame = true
  494. Camera.CameraType = 'Scriptable'
  495. -- Get relative position of camera and keep to it
  496. Spawn(function()
  497. local currentRelativePos = Camera.CoordinateFrame.p - torso.Position
  498. while Chat.MouseOnFrame do
  499. Camera.CoordinateFrame = CFrame.new(torso.Position + currentRelativePos, head.Position)
  500. wait(0.015)
  501. end
  502. end)
  503. end
  504. end)
  505.  
  506. self.RenderFrame.MouseLeave:connect(function()
  507. Camera.CameraType = 'Custom'
  508. self.MouseOnFrame = false
  509. end)
  510. end
  511. end
  512.  
  513. -- TODO: Scrolling using Mouse wheel
  514. function Chat:OnScroll(speed)
  515. if self.MouseOnFrame then
  516. --
  517. end
  518. end
  519.  
  520. -- Check if we are running on a touch device
  521. function Chat:IsTouchDevice()
  522. local touchEnabled = false
  523. pcall(function() touchEnabled = Game:GetService('UserInputService').TouchEnabled end)
  524. return touchEnabled
  525. end
  526.  
  527. -- Scrolling
  528. function Chat:ScrollQueue(value)
  529. --[[for i = 1, #self.MessageQueue do
  530. if self.MessageQueue[i] then
  531. for _, label in pairs(self.MessageQueue[i]) do
  532. local next = self.MessageQueue[i].Next
  533. local previous = self.MessageQueue[i].Previous
  534. if label and label:IsA('TextLabel') or label:IsA('TextButton') then
  535. if value > 0 and previous and previous['Message'] then
  536. label.Position = previous['Message'].Position
  537. elseif value < 1 and next['Message'] then
  538. label.Position = previous['Message'].Position
  539. end
  540. end
  541. end
  542. end
  543. end ]]
  544. end
  545.  
  546. -- Handles the rendering of the text objects in their appropriate places
  547. function Chat:UpdateQueue(field, diff)
  548. -- Have to do some sort of correction here
  549. for i = #self.MessageQueue, 1, -1 do
  550. if self.MessageQueue[i] then
  551. for _, label in pairs(self.MessageQueue[i]) do
  552. if label and type(label) ~= 'table' and type(label) ~= 'number' then
  553. if label:IsA('TextLabel') or label:IsA('TextButton') then
  554. if diff then
  555. label.Position = label.Position - UDim2.new(0, 0, diff, 0)
  556. else
  557. if field == self.MessageQueue[i] then
  558. label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field['Message'].Size.Y.Scale , 0)
  559. -- Just to show up popping effect for the latest message in chat
  560. coroutine.resume(coroutine.create(function()
  561. wait(0.05)
  562.  
  563. local t = 0.1
  564. local start = tick()
  565.  
  566. while tick() - start < t do
  567. local alpha = (tick() - start) / t
  568.  
  569. label.TextTransparency = 1-alpha
  570. wait()
  571. end
  572. label.TextTransparency = 0
  573.  
  574. if label == field['Message'] then
  575. label.TextStrokeTransparency = StrokeTransparency
  576. else
  577. label.TextStrokeTransparency = StrokeTransparency
  578. end
  579. end))
  580. else
  581. label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field['Message'].Size.Y.Scale, 0)
  582. end
  583. if label.Position.Y.Scale < -0.01 then
  584. -- NOTE: Remove this fix when Textbounds is fixed
  585. label.Visible = false
  586. label:Destroy()
  587. end
  588. end
  589. end
  590. end
  591. end
  592. end
  593. end
  594. end
  595.  
  596. function Chat:CreateScrollBar()
  597. -- Code for scrolling is in here, partially, but scroll bar drawing isn't drawn
  598. -- TODO: Implement
  599. end
  600.  
  601. -- For scrolling, to see if we hit the bounds so that we can stop it from scrolling anymore
  602. function Chat:CheckIfInBounds(value)
  603. if #Chat.MessageQueue < 3 then
  604. return true
  605. end
  606.  
  607. if value > 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1]['Player'] and Chat.MessageQueue[1]['Player'].Position.Y.Scale == 0 then
  608. return true
  609. elseif value < 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1]['Player'] and Chat.MessageQueue[1]['Player'].Position.Y.Scale < 0 then
  610. return true
  611. else
  612. return false
  613. end
  614. return false
  615. end
  616.  
  617. -- This is to precompute all playerName space strings
  618. -- This is used to offset the message by exactly this + 2 spacestrings
  619. function Chat:ComputeSpaceString(pLabel)
  620. local nString = " "
  621. if not self.TempSpaceLabel then
  622. self.TempSpaceLabel = Gui.Create'TextButton'
  623. {
  624. Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y);
  625. FontSize = self.Configuration.FontSize;
  626. Parent = self.RenderFrame;
  627. BackgroundTransparency = 1.0;
  628. Text = nString;
  629. Name = 'SpaceButton'
  630. };
  631. else
  632. self.TempSpaceLabel.Text = nString
  633. end
  634.  
  635. while self.TempSpaceLabel.TextBounds.X < pLabel.TextBounds.X do
  636. nString = nString .. " "
  637. self.TempSpaceLabel.Text = nString
  638. end
  639. nString = nString .. " "
  640. self.CachedSpaceStrings_List[pLabel.Text] = nString
  641. self.TempSpaceLabel.Text = ""
  642. return nString
  643. end
  644.  
  645. -- When the playerChatted event fires
  646. -- The message is what the player chatted
  647. function Chat:UpdateChat(cPlayer, message)
  648. local messageField = {
  649. ['Player'] = cPlayer,
  650. ['Message'] = message
  651. }
  652. if Chat.MessageThread == nil or coroutine.status(Chat.MessageThread) == 'dead' then
  653. --Chat.Messages_List = {}
  654. table.insert(Chat.Messages_List, messageField)
  655. Chat.MessageThread = coroutine.create(function()
  656. for i = 1, #Chat.Messages_List do
  657. local field = Chat.Messages_List[i]
  658. Chat:CreateMessage(field['Player'], field['Message'])
  659. end
  660. Chat.Messages_List = {}
  661. end)
  662. coroutine.resume(Chat.MessageThread)
  663. else
  664. table.insert(Chat.Messages_List, messageField)
  665. end
  666. end
  667.  
  668. function Chat:RecalculateSpacing()
  669. --[[for i = 1, #self.MessageQueue do
  670. local pLabel = self.MessageQueue[i]['Player']
  671. local mLabel = self.MessageQueue[i]['Message']
  672.  
  673. local prevYScale = mLabel.Size.Y.Scale
  674. local prevText = mLabel.Text
  675. mLabel.Text = prevText
  676.  
  677. local heightField = mLabel.TextBounds.Y
  678.  
  679. mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)
  680. pLabel.Size = mLabel.Size
  681.  
  682. local diff = mLabel.Size.Y.Scale - prevYScale
  683.  
  684. Chat:UpdateQueue(self.MessageQueue[i], diff)
  685. end ]]
  686. end
  687.  
  688. function Chat:ApplyFilter(str)
  689. --[[for _, word in pair(self.Filter_List) do
  690. if string.find(str, word) then
  691. str:gsub(word, '@#$^')
  692. end
  693. end ]]
  694. end
  695.  
  696. export.SendChat = function(self, name, message, custom_color, do_not_add_to_history)
  697. local old_color = PLAYERLIST_CHATCOLORS[name:lower()]
  698. if custom_color ~= nil then
  699. PLAYERLIST_CHATCOLORS[name:lower()] = custom_color
  700. end
  701. print(old_color, PLAYERLIST_CHATCOLORS[name:lower()])
  702.  
  703. local player = game.Players:FindFirstChild(name) or {
  704. Name = name,
  705. Neutral = true,
  706. TeamColor = Color3.new(1,1,1)
  707. }
  708.  
  709. Chat:CreateMessage(player, message, do_not_add_to_history)
  710. -- if do_not_add_to_history ~= true then
  711. -- AddToChatHistory(player, message)
  712. -- end
  713.  
  714. wait()
  715. PLAYERLIST_CHATCOLORS[name:lower()] = old_color or nil
  716. end
  717.  
  718. -- NOTE: Temporarily disabled ring buffer to allow for chat to always wrap around
  719. function Chat:CreateMessage(cPlayer, message, do_not_add_to_history)
  720. if do_not_add_to_history ~= true then
  721. AddToChatHistory(cPlayer, message)
  722. end
  723.  
  724. local pName
  725. if not cPlayer then
  726. pName = ''
  727. else
  728. pName = cPlayer.Name
  729. end
  730. message = StringTrim(message)
  731. local pLabel
  732. local mLabel
  733. -- Our history stores upto 50 messages that is 100 textlabels
  734. -- If we ever hit the mark, which would be in every popular game btw
  735. -- we wrap around and reuse the labels
  736. if #self.MessageQueue > self.Configuration.HistoryLength then
  737. --[[pLabel = self.MessageQueue[#self.MessageQueue]['Player']
  738. mLabel = self.MessageQueue[#self.MessageQueue]['Message']
  739.  
  740. pLabel.Text = pName .. ':'
  741. pLabel.Name = pName
  742.  
  743. local pColor
  744. if cPlayer.Neutral then
  745. pLabel.TextColor3 = Chat:ComputeChatColor(pName)
  746. else
  747. pLabel.TextColor3 = cPlayer.TeamColor.Color
  748. end
  749.  
  750. local nString
  751.  
  752. if not self.CachedSpaceStrings_List[pName] then
  753. nString = Chat:ComputeSpaceString(pLabel)
  754. else
  755. nString = self.CachedSpaceStrings_List[pName]
  756. end
  757.  
  758. mLabel.Text = ""
  759. mLabel.Name = pName .. " - message"
  760. mLabel.Text = nString .. message;
  761.  
  762. mLabel.Parent = nil
  763. mLabel.Parent = self.RenderFrame
  764.  
  765. mLabel.Position = UDim2.new(0, 0, 1, 0);
  766. pLabel.Position = UDim2.new(0, 0, 1, 0);]]
  767.  
  768. -- Reinserted at the beginning, ring buffer
  769. self.MessageQueue[#self.MessageQueue] = nil
  770. end
  771. --else
  772. -- Haven't hit the mark yet, so keep creating
  773. pLabel = Gui.Create'TextLabel'
  774. {
  775. Name = pName;
  776. Text = (PLAYERLIST_ALIASES[pName:lower()] or pName) .. ":";
  777. TextColor3 = PLAYERLIST_CHATCOLORS[pName:lower()] or pColor;
  778. FontSize = Chat.Configuration.FontSize;
  779. TextXAlignment = Enum.TextXAlignment.Left;
  780. TextYAlignment = Enum.TextYAlignment.Top;
  781. Parent = self.RenderFrame;
  782. TextWrapped = false;
  783. Size = UDim2.new(1, 0, 0.1, 0);
  784. BackgroundTransparency = 1.0;
  785. TextTransparency = 1.0;
  786. Position = UDim2.new(0, 0, 1, 0);
  787. BorderSizePixel = 0.0;
  788. TextStrokeColor3 = Color3.new(0, 0, 0);
  789. TextStrokeTransparency = StrokeTransparency;
  790. --Active = false;
  791. };
  792. local pColor
  793. if cPlayer.Neutral then
  794. pLabel.TextColor3 = Chat:ComputeChatColor(pName)
  795. else
  796. pLabel.TextColor3 = cPlayer.TeamColor.Color
  797. end
  798.  
  799. local nString
  800.  
  801. if not self.CachedSpaceStrings_List[pName] then
  802. nString = Chat:ComputeSpaceString(pLabel)
  803. else
  804. nString = self.CachedSpaceStrings_List[pName]
  805. end
  806.  
  807. mLabel = Gui.Create'TextLabel'
  808. {
  809. Name = pName .. ' - message';
  810. -- Max is 3 lines
  811. Size = UDim2.new(1, 0, 0.5, 0);
  812. TextColor3 = Chat.Configuration.MessageColor;
  813. FontSize = Chat.Configuration.FontSize;
  814. TextXAlignment = Enum.TextXAlignment.Left;
  815. TextYAlignment = Enum.TextYAlignment.Top;
  816. Text = ""; -- this is to stop when the engine reverts the swear words to default, which is button, ugh
  817. Parent = self.RenderFrame;
  818. TextWrapped = true;
  819. BackgroundTransparency = 1.0;
  820. TextTransparency = 1.0;
  821. Position = UDim2.new(0, 0, 1, 0);
  822. BorderSizePixel = 0.0;
  823. TextStrokeColor3 = Color3.new(0, 0, 0);
  824. --TextStrokeTransparency = 0.8;
  825. --Active = false;
  826. };
  827. mLabel.Text = nString .. message;
  828.  
  829. if not pName then
  830. pLabel.Text = ''
  831. mLabel.TextColor3 = Color3.new(0, 0.4, 1.0)
  832. end
  833. --end
  834.  
  835. if self.Admins_List[pName:lower()] then
  836. mLabel.TextColor3 = PLAYERLIST_CHATCOLORS[pName:lower()] or self.Configuration.AdminMessageColor
  837. end
  838.  
  839. pLabel.Visible = true
  840. mLabel.Visible = true
  841.  
  842. -- This will give beautiful multilines as well
  843. local heightField = mLabel.TextBounds.Y
  844.  
  845. mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)
  846. pLabel.Size = mLabel.Size
  847.  
  848. local yPixels = self.RenderFrame.AbsoluteSize.Y
  849. local yFieldSize = mLabel.TextBounds.Y
  850.  
  851. local queueField = {}
  852. queueField['Player'] = pLabel
  853. queueField['Message'] = mLabel
  854. queueField['SpawnTime'] = tick() -- Used for identifying when to make the message invisible
  855.  
  856. table.insert(self.MessageQueue, 1, queueField)
  857. Chat:UpdateQueue(queueField)
  858. end
  859.  
  860. function Chat:ScreenSizeChanged()
  861. wait()
  862. while self.Frame.AbsoluteSize.Y > 120 do
  863. self.Frame.Size = self.Frame.Size - UDim2.new(0, 0, 0.005, 0)
  864. end
  865. Chat:RecalculateSpacing()
  866. end
  867.  
  868.  
  869. function Chat:FindButtonTree(scButton, rootList)
  870. local list = {}
  871. rootList = rootList or self.SafeChatTree
  872. for button, _ in pairs(rootList) do
  873. if button == scButton then
  874. list = rootList[button]
  875. elseif type(rootList[button]) == 'table' then
  876. list = Chat:FindButtonTree(scButton, rootList[button])
  877. end
  878. end
  879. return list
  880. end
  881.  
  882. function Chat:ToggleSafeChatMenu(scButton)
  883. local list = Chat:FindButtonTree(scButton, self.SafeChatTree)
  884. if list then
  885. for button, _ in pairs(list) do
  886. if button:IsA('TextButton') or button:IsA('ImageButton') then
  887. button.Visible = not button.Visible
  888. end
  889. end
  890. return true
  891. end
  892. return false
  893. end
  894.  
  895. function Chat:CreateSafeChatOptions(list, rootButton)
  896. local text_List = {}
  897. level = level or 0
  898. local count = 0
  899. text_List[rootButton] = {}
  900. text_List[rootButton][1] = list[1]
  901. rootButton = rootButton or self.SafeChatButton
  902. for msg, _ in pairs(list) do
  903. if type(msg) == 'string' then
  904. local chatText = Gui.Create'TextButton'
  905. {
  906. Name = msg;
  907. Text = msg;
  908. Size = UDim2.new(0, 100, 0, 20);
  909. TextXAlignment = Enum.TextXAlignment.Center;
  910. TextColor3 = Color3.new(0.2, 0.1, 0.1);
  911. BackgroundTransparency = 0.5;
  912. BackgroundColor3 = Color3.new(1, 1, 1);
  913. Parent = self.SafeChatFrame;
  914. Visible = false;
  915. Position = UDim2.new(0, rootButton.Position.X.Scale + 105, 0, rootButton.Position.Y.Scale - ((count - 3) * 100));
  916. };
  917.  
  918. count = count + 1
  919.  
  920. if type(list[msg]) == 'table' then
  921. text_List[rootButton][chatText] = Chat:CreateSafeChatOptions(list[msg], chatText)
  922. else
  923. --table.insert(text_List[chatText], true)
  924. end
  925. chatText.MouseEnter:connect(function()
  926. Chat:ToggleSafeChatMenu(chatText)
  927. end)
  928.  
  929. chatText.MouseLeave:connect(function()
  930. Chat:ToggleSafeChatMenu(chatText)
  931. end)
  932.  
  933. chatText.MouseButton1Click:connect(function()
  934. local lList = Chat:FindButtonTree(chatText)
  935. if lList then
  936. for i, v in pairs(lList) do
  937. end
  938. else
  939. end
  940. pcall(function() PlayersService:Chat(lList[1]) end)
  941. end)
  942. end
  943. end
  944. return text_List
  945. end
  946.  
  947. function Chat:CreateSafeChatGui()
  948. self.SafeChatFrame = Gui.Create'Frame'
  949. {
  950. Name = 'SafeChatFrame';
  951. Size = UDim2.new(1, 0, 1, 0);
  952. Parent = self.Gui;
  953. BackgroundTransparency = 1.0;
  954.  
  955. Gui.Create'ImageButton'
  956. {
  957. Name = 'SafeChatButton';
  958. Size = UDim2.new(0, 44, 0, 31);
  959. Position = UDim2.new(0, 1, 0.35, 0);
  960. BackgroundTransparency = 1.0;
  961. Image = 'http://www.roblox.com/asset/?id=97080365';
  962. };
  963. }
  964.  
  965. self.SafeChatButton = self.SafeChatFrame.SafeChatButton
  966. -- safe chat button is the root of this tree
  967. self.SafeChatTree[self.SafeChatButton] = Chat:CreateSafeChatOptions(self.SafeChat_List, self.SafeChatButton)
  968.  
  969. self.SafeChatButton.MouseButton1Click:connect(function()
  970. Chat:ToggleSafeChatMenu(self.SafeChatButton)
  971. end)
  972. end
  973.  
  974.  
  975. function Chat:FocusOnChatBar()
  976. if self.ClickToChatButton then
  977. self.ClickToChatButton.Visible = false
  978. end
  979.  
  980. self.GotFocus = true
  981. if self.Frame['Background'] then
  982. self.Frame.Background.Visible = false
  983. end
  984. self.ChatBar:CaptureFocus()
  985. end
  986.  
  987. -- For touch devices we create a button instead
  988. function Chat:CreateTouchButton()
  989. self.ChatTouchFrame = Gui.Create'Frame'
  990. {
  991. Name = 'ChatTouchFrame';
  992. Size = UDim2.new(0, 128, 0, 32);
  993. Position = UDim2.new(0, 88, 0, 0);
  994. BackgroundTransparency = 1.0;
  995. Parent = self.Gui;
  996.  
  997. Gui.Create'ImageButton'
  998. {
  999. Name = 'ChatLabel';
  1000. Size = UDim2.new(0, 74, 0, 28);
  1001. Position = UDim2.new(0, 0, 0, 0);
  1002. BackgroundTransparency = 1.0;
  1003. ZIndex = 2.0;
  1004. };
  1005. Gui.Create'ImageLabel'
  1006. {
  1007. Name = 'Background';
  1008. Size = UDim2.new(1, 0, 1, 0);
  1009. Position = UDim2.new(0, 0, 0, 0);
  1010. BackgroundTransparency = 1.0;
  1011. Image = 'http://www.roblox.com/asset/?id=97078724'
  1012. };
  1013.  
  1014. }
  1015. self.TapToChatLabel = self.ChatTouchFrame.ChatLabel
  1016. self.TouchLabelBackground = self.ChatTouchFrame.Background
  1017.  
  1018. self.ChatBar = Gui.Create'TextBox'
  1019. {
  1020. Name = 'ChatBar';
  1021. Size = UDim2.new(1, 0, 0.2, 0);
  1022. Position = UDim2.new(0, 0, 0.8, 800);
  1023. Text = "";
  1024. ZIndex = 1.0;
  1025. BackgroundTransparency = 1.0;
  1026. Parent = self.Frame;
  1027. TextXAlignment = Enum.TextXAlignment.Left;
  1028. TextColor3 = Color3.new(1, 1, 1);
  1029. ClearTextOnFocus = false;
  1030. };
  1031.  
  1032. self.TapToChatLabel.MouseButton1Click:connect(function()
  1033. self.TapToChatLabel.Visible = false
  1034. --self.ChatBar.Visible = true
  1035. --self.Frame.Background.Visible = true
  1036. self.ChatBar:CaptureFocus()
  1037. self.GotFocus = true
  1038. if self.TouchLabelBackground then
  1039. self.TouchLabelBackground.Visible = false
  1040. end
  1041. end)
  1042. end
  1043.  
  1044. -- Non touch devices, create the bottom chat bar
  1045. function Chat:CreateChatBar()
  1046. -- okay now we do
  1047. -- local status, result = pcall(function() return GuiService.UseLuaChat end)
  1048. -- if forceChatGUI or (status and result) then
  1049. -- self.ClickToChatButton = Gui.Create'TextButton'
  1050. -- {
  1051. -- Name = 'ClickToChat';
  1052. -- Size = UDim2.new(1, 0, 0, 20);
  1053. -- BackgroundTransparency = 1.0;
  1054. -- ZIndex = 2.0;
  1055. -- Parent = self.Gui;
  1056. -- Text = "To chat click here or press \"/\" key";
  1057. -- TextColor3 = Color3.new(1, 1, 0.9);
  1058. -- Position = UDim2.new(0, 0, 1, 0);
  1059. -- TextXAlignment = Enum.TextXAlignment.Left;
  1060. -- FontSize = Enum.FontSize.Size12;
  1061. -- }
  1062. --
  1063. -- self.ChatBar = Gui.Create'TextBox'
  1064. -- {
  1065. -- Name = 'ChatBar';
  1066. -- Size = UDim2.new(1, 0, 0, 20);
  1067. -- Position = UDim2.new(0, 0, 1, 0);
  1068. -- Text = "";
  1069. -- ZIndex = 1.0;
  1070. -- BackgroundColor3 = Color3.new(0, 0, 0);
  1071. -- BackgroundTransparency = 0.25;
  1072. -- Parent = self.Gui;
  1073. -- TextXAlignment = Enum.TextXAlignment.Left;
  1074. -- TextColor3 = Color3.new(1, 1, 1);
  1075. -- FontSize = Enum.FontSize.Size12;
  1076. -- ClearTextOnFocus = false;
  1077. -- Text = '';
  1078. -- };
  1079. --
  1080. -- -- Engine has code to offset the entire world, so if we do it by -20 pixels nothing gets in our chat's way
  1081. -- --GuiService:SetGlobalSizeOffsetPixel(0, -20)
  1082. -- local success, error = pcall(function() GuiService:SetGlobalGuiInset(0, 0, 0, 20) end)
  1083. -- if not success then
  1084. -- GuiService:SetGlobalSizeOffsetPixel(0, -20)
  1085. -- end
  1086. -- -- CHatHotKey is '/'
  1087. -- GuiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
  1088. -- GuiService.SpecialKeyPressed:connect(function(key)
  1089. -- if key == Enum.SpecialKey.ChatHotkey then
  1090. -- Chat:FocusOnChatBar()
  1091. -- end
  1092. -- end)
  1093. --
  1094. -- self.ClickToChatButton.MouseButton1Click:connect(function()
  1095. -- Chat:FocusOnChatBar()
  1096. -- end)
  1097. -- end
  1098. end
  1099.  
  1100. -- Create the initial Chat stuff
  1101. -- Done only once
  1102. function Chat:CreateGui()
  1103. self.Gui = script.Parent
  1104. self.Frame = Gui.Create'Frame'
  1105. {
  1106. Name = 'ChatFrame';
  1107. --Size = self.Configuration.Size;
  1108. Size = UDim2.new(0, 500, 0, 120);
  1109. Position = UDim2.new(0, 0, 0, 5);
  1110. BackgroundTransparency = 1.0;
  1111. --ClipsDescendants = true;
  1112. ZIndex = 0.0;
  1113. Parent = self.Gui;
  1114. Active = false;
  1115.  
  1116. Gui.Create'ImageLabel'
  1117. {
  1118. Name = 'Background';
  1119. Image = 'http://www.roblox.com/asset/?id=97120937'; --96551212';
  1120. Size = UDim2.new(1.3, 0, 1.64, 0);
  1121. Position = UDim2.new(0, 0, 0, 0);
  1122. BackgroundTransparency = 1.0;
  1123. ZIndex = 0.0;
  1124. Visible = false
  1125. };
  1126.  
  1127. Gui.Create'Frame'
  1128. {
  1129. Name = 'Border';
  1130. Size = UDim2.new(1, 0, 0, 1);
  1131. Position = UDim2.new(0, 0, 0.8, 0);
  1132. BackgroundTransparency = 0.0;
  1133. BackgroundColor3 = Color3.new(236/255, 236/255, 236/255);
  1134. BorderSizePixel = 0.0;
  1135. Visible = false;
  1136. };
  1137.  
  1138. Gui.Create'Frame'
  1139. {
  1140. Name = 'ChatRenderFrame';
  1141. Size = UDim2.new(1.02, 0, 1.01, 0);
  1142. Position = UDim2.new(0, 0, 0, 0);
  1143. BackgroundTransparency = 1.0;
  1144. --ClipsDescendants = true;
  1145. ZIndex = 0.0;
  1146. Active = false;
  1147.  
  1148. };
  1149. };
  1150.  
  1151. Spawn(function()
  1152. wait(0.5)
  1153. if IsPhone() then
  1154. self.Frame.Size = UDim2.new(0, 280, 0, 120)
  1155. end
  1156. end)
  1157.  
  1158. self.RenderFrame = self.Frame.ChatRenderFrame
  1159. if Chat:IsTouchDevice() then
  1160. self.Frame.Position = self.Configuration.Position;
  1161. self.RenderFrame.Size = UDim2.new(1, 0, 1, 0)
  1162. elseif self.Frame.AbsoluteSize.Y > 120 then
  1163. Chat:ScreenSizeChanged()
  1164. self.Gui.Changed:connect(function(property)
  1165. if property == 'AbsoluteSize' then
  1166. Chat:ScreenSizeChanged()
  1167. end
  1168. end)
  1169. end
  1170.  
  1171. if forceChatGUI or true then
  1172. if Chat:IsTouchDevice() then
  1173. Chat:CreateTouchButton()
  1174. else
  1175. Chat:CreateChatBar()
  1176. --Chat:CreateSafeChatGui()
  1177. end
  1178.  
  1179. if self.ChatBar then
  1180. self.ChatBar.FocusLost:connect(function(enterPressed)
  1181. Chat.GotFocus = false
  1182. if Chat:IsTouchDevice() then
  1183. self.ChatBar.Visible = false
  1184. self.TapToChatLabel.Visible = true
  1185.  
  1186. if self.TouchLabelBackground then
  1187. self.TouchLabelBackground.Visible = true
  1188. end
  1189. end
  1190. if enterPressed and self.ChatBar.Text ~= "" then
  1191.  
  1192. local cText = self.ChatBar.Text
  1193. if string.sub(self.ChatBar.Text, 1, 1) == '%' then
  1194. cText = '(TEAM) ' .. string.sub(cText, 2, #cText)
  1195. pcall(function() PlayersService:TeamChat(cText) end)
  1196. else
  1197. pcall(function() PlayersService:Chat(cText) end)
  1198. end
  1199.  
  1200. if self.ClickToChatButton then
  1201. self.ClickToChatButton.Visible = true
  1202. end
  1203. self.ChatBar.Text = ""
  1204. end
  1205. Spawn(function()
  1206. wait(5.0)
  1207. if not Chat.GotFocus then
  1208. Chat.Frame.Background.Visible = false
  1209. end
  1210. end)
  1211. end)
  1212. end
  1213. end
  1214. end
  1215.  
  1216. -- Scrolling function
  1217. -- Applies a speed(velocity) to have nice scrolling effect
  1218. function Input:OnMouseScroll()
  1219. Spawn(function()
  1220. -- How long should the speed last?
  1221. while Input.Speed ~=0 do
  1222. if Input.Speed > 1 then
  1223. while Input.Speed > 0 do
  1224. Input.Speed = Input.Speed - 1
  1225. wait(0.25)
  1226. end
  1227. elseif Input.Speed < 0 then
  1228. while Input.Speed < 0 do
  1229. Input.Speed = Input.Speed + 1
  1230. wait(0.25)
  1231. end
  1232. end
  1233. wait(0.03)
  1234. end
  1235. end)
  1236. if Chat:CheckIfInBounds(Input.Speed) then
  1237. return
  1238. end
  1239. Chat:ScrollQueue()
  1240. end
  1241.  
  1242. function Input:ApplySpeed(value)
  1243. Input.Speed = Input.Speed + value
  1244. if not self.Simulating then
  1245. Input:OnMouseScroll()
  1246. end
  1247. end
  1248.  
  1249. function Input:Initialize()
  1250. self.Mouse.WheelBackward:connect(function()
  1251. Input:ApplySpeed(self.Configuration.DefaultSpeed)
  1252. end)
  1253.  
  1254. self.Mouse.WheelForward:connect(function()
  1255. Input:ApplySpeed(self.Configuration.DefaultSpeed)
  1256. end)
  1257. end
  1258.  
  1259. function Chat:FindMessageInSafeChat(message, list)
  1260. local foundMessage = false
  1261. for msg, _ in pairs(list) do
  1262. if msg == message then
  1263. return true
  1264. end
  1265. if type(list[msg]) == 'table' then
  1266. foundMessage = Chat:FindMessageInSafeChat(message, list[msg])
  1267. if foundMessage then
  1268. return true
  1269. end
  1270. end
  1271. end
  1272. return foundMessage
  1273. end
  1274.  
  1275. -- Just a wrapper around our PlayerChatted event
  1276. function Chat:PlayerChatted(...)
  1277. local args = {...}
  1278. local argCount = select('#', ...)
  1279. local player
  1280. local message
  1281. -- This doesn't look very good, but what else to do?
  1282. if args[2] then
  1283. player = args[2]
  1284. end
  1285. if args[3] then
  1286. message = args[3]
  1287. if string.sub(message, 1, 1) == '%' then
  1288. message = '(TEAM) ' .. string.sub(message, 2, #message)
  1289. end
  1290. end
  1291.  
  1292. -- if PlayersService.ClassicChat then
  1293. if string.sub(message, 1, 3) == '/e ' or string.sub(message, 1, 7) == '/emote ' then
  1294. -- don't do anything right now
  1295. elseif forceChatGUI or true then
  1296. Chat:UpdateChat(player, message)
  1297. elseif true and string.sub(message, 1, 3) == '/sc' then
  1298. Chat:UpdateChat(player, message)
  1299. else
  1300. if Chat:FindMessageInSafeChat(message, self.SafeChat_List) then
  1301. Chat:UpdateChat(player, message)
  1302. end
  1303. end
  1304. -- end
  1305. end
  1306.  
  1307. -- After Chat.Configuration.Lifetime seconds of existence, the labels become invisible
  1308. -- Runs only every 5 seconds and has to loop through 50 values
  1309. -- Shouldn't be too expensive
  1310. function Chat:CullThread()
  1311. while true do
  1312. if #self.MessageQueue > 0 then
  1313. for _, field in pairs(self.MessageQueue) do
  1314. if field['SpawnTime'] and field['Player'] and field['Message'] and tick() - field['SpawnTime'] > self.Configuration.LifeTime then
  1315. field['Player'].Visible = false
  1316. field['Message'].Visible = false
  1317. end
  1318. end
  1319. end
  1320. wait(5.0)
  1321. end
  1322. end
  1323.  
  1324. -- RobloxLock everything so users can't delete them(?)
  1325. function Chat:LockAllFields(gui)
  1326. local children = gui:GetChildren()
  1327. for i = 1, #children do
  1328. children[i].RobloxLocked = true
  1329. if #children[i]:GetChildren() > 0 then
  1330. Chat:LockAllFields(children[i])
  1331. end
  1332. end
  1333. end
  1334.  
  1335. function Chat:CoreGuiChanged(coreGuiType,enabled)
  1336. if coreGuiType == Enum.CoreGuiType.Chat or coreGuiType == Enum.CoreGuiType.All then
  1337. if self.Frame then self.Frame.Visible = enabled end
  1338.  
  1339. if not Chat:IsTouchDevice() and self.ChatBar then
  1340. self.ChatBar.Visible = enabled
  1341. if enabled then
  1342. GuiService:SetGlobalGuiInset(0, 0, 0, 20)
  1343. else
  1344. GuiService:SetGlobalGuiInset(0, 0, 0, 0)
  1345. end
  1346. end
  1347. end
  1348. end
  1349.  
  1350. _G.ChatHistory = _G.ChatHistory or {}
  1351. function RunChatHistory(max)
  1352. for i=#_G.ChatHistory-max, #_G.ChatHistory do
  1353. local player, message = unpack(_G.ChatHistory[i] or {})
  1354.  
  1355. if player ~= nil and message ~= nil then
  1356. export:SendChat(player.Name, message, nil, true)
  1357. end
  1358.  
  1359. end
  1360. end
  1361.  
  1362. function AddToChatHistory(player, message)
  1363. table.insert(_G.ChatHistory, {player, message})
  1364. end
  1365.  
  1366. -- Constructor
  1367. -- This function initializes everything
  1368. function Chat:Initialize()
  1369.  
  1370. Chat:CreateGui()
  1371.  
  1372. function PlayerChatted(...)
  1373. Chat:PlayerChatted(...)
  1374. end
  1375.  
  1376. function OnPlayer(p)
  1377. if p:IsA 'Player' then
  1378. p.Chatted:connect(function(chat)
  1379. PlayerChatted(
  1380. Enum.PlayerChatType.All,
  1381. p,
  1382. chat,
  1383. nil
  1384. )
  1385. end)
  1386. end
  1387. end
  1388.  
  1389. for _,p in pairs(game.Players:GetPlayers()) do
  1390. OnPlayer(p)
  1391. end
  1392.  
  1393. game.Players.ChildAdded:connect(OnPlayer)
  1394.  
  1395. self.EventListener = script.ChildAdded:connect(function(...)
  1396. -- This event has 4 callback arguments
  1397. -- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
  1398. -- Chat:PlayerChatted(...)
  1399.  
  1400. end)
  1401.  
  1402. -- Initialize input for us
  1403. -- Input:Initialize()
  1404. -- Eww, everytime a player is added, you have to redo the connection
  1405. -- Seems this is not automatic
  1406. -- -- NOTE: PlayerAdded only fires on the server, hence ChildAdded is used here
  1407. -- PlayersService.ChildAdded:connect(function()
  1408. -- Chat.EventListener:disconnect()
  1409. -- self.EventListener = PlayersService.PlayerChatted:connect(function(...)
  1410. -- -- This event has 4 callback arguments
  1411. -- -- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
  1412. -- Chat:PlayerChatted(...)
  1413. -- end)
  1414. -- end)
  1415.  
  1416. Spawn(function()
  1417. Chat:CullThread()
  1418. end)
  1419.  
  1420. -- Chat:LockAllFields(self.Frame)
  1421. -- self.Frame.DescendantAdded:connect(function(descendant)
  1422. ---- Chat:LockAllFields(descendant)
  1423. -- end)
  1424. end
  1425.  
  1426. Chat:Initialize()
  1427.  
  1428. RunChatHistory(10)
  1429.  
  1430. _G.ChatAPI = export
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement