Advertisement
V3rmLua33

Chat ?????

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