Create menu.lua

This commit is contained in:
blocco 2013-06-29 05:45:03 -04:00
parent 061f24db9f
commit 9bb5a6e449
1 changed files with 479 additions and 0 deletions

479
rpui/menu.lua Normal file
View File

@ -0,0 +1,479 @@
--[[
The following legacy code is created by blocco.
This code created the menu that was present on both the server and the client.
One menu. One script. Simple.
Here is where I used locally persistent data, to store the IP and Port of the
last connected to server. It saved a lot of time, and it was a nice feature.
You'll notice I had a little structure for generating the menu.
It contains many comments for documentation purposes.
It is to be used for educational purposes.
This code is from RBXPri (Blocco Edition).
This file is "menu.lua".
--]]
local uiBase = game.CoreGui.RPUI;
local btnShield = uiBase.UIShield;
function createMenu(layout, fn)
local validTypes={
Button={"string", "string", "boolean", "function", "table"};
Separator={};
InformationRow={"string", "string", "string", "boolean"};
}
local function isValidType(tbl)
for i, v in pairs(validTypes) do
if tbl[1] == i then return true; end
end
return false;
end
local function isValidEntry(tbl)
for i, v in ipairs(tbl) do
if i ~= 1 then
if type(v) ~= validTypes[tbl[1]][i-1] then return false; end
end
end
return true;
end
local function createButton(main, nam, txt, act, fn, i)
local btn = Instance.new("TextButton");
btn.AutoButtonColor=false;
btn.Name = nam or "MenuButton";
btn.Text = txt;
btn.TextTransparency = act and 0.2 or 0.5;
btn.TextColor3 = Color3.new(0, 0, 0);
btn.Font = "ArialBold";
btn.FontSize = main and "Size14" or "Size12";
btn.BackgroundTransparency = act and 0.8 or 0.6;
btn.BackgroundColor3 = act and Color3.new(1, 1, 1) or Color3.new(0.8, 0.8, 0.8);
btn.Size = UDim2.new(0, 100, 0, main and 20 or 16);--main and UDim2.new(0, 100, 0, 20) or UDim2.new(0, 120, 0, 16);
btn.BorderSizePixel = 0;
btn.Active = act;
btn.MouseEnter:connect(function()
if btn.Active then
btn.TextTransparency = 0.2
btn.BackgroundTransparency = 0;
end
end)
btn.MouseLeave:connect(function()
if btn.Active then
btn.TextTransparency = 0.2
btn.BackgroundTransparency = 0.8;
end
end)
btn.MouseButton1Down:connect(function()
if btn.Active then
btn.TextTransparency = 0
btn.BackgroundTransparency = 0;
end
end)
btn.MouseButton1Up:connect(function()
if btn.Active then
btn.TextTransparency = 0.2
btn.BackgroundTransparency = 0;
end
end)
btn.MouseButton1Click:connect(function()
if btn.Active then
fn(btn);
end
end)
btn.Changed:connect(function(p)
if p == "Active" then
btn.TextTransparency = btn.Active and 0.2 or 0.5;
btn.BackgroundTransparency = btn.Active and 0.8 or 0.6;
btn.BackgroundColor3 = btn.Active and Color3.new(1, 1, 1) or Color3.new(0.8, 0.8, 0.8);
end
end)
return btn;
end
local function createSeparator(main, i)
local sep=Instance.new("Frame");
sep.Size = UDim2.new(0, main and 1 or 96, 0, main and 16 or 1)--UDim2.new(0, main and 1 or 116, 0, main and 16 or 1);
sep.BackgroundColor3 = Color3.new(0, 0, 0);
sep.Active=true;
sep.BorderSizePixel=0;
sep.Name = "Separator";
return sep;
end
local function createInformationRow(main, nam, txt, typ, sav)
valLookup={
["string"]="";
["int"]="0";
["number"]="0";
}
local val=valLookup[typ];
local infRow = Instance.new("Frame");
infRow.Name = nam;
infRow.Size = UDim2.new(0, 100, 0, main and 20 or 16)--UDim2.new(0, 120, 0, main and 20 or 16);
infRow.BackgroundColor3 = Color3.new(1, 1, 1);
infRow.BackgroundTransparency = 0.8;
infRow.BorderSizePixel=0;
infRow.Active=true;
local function isValidEntry(typ, val)
if type(val) ~= "string" then return false end;
if typ == "string" then return true;
elseif typ == "number" then return tonumber(val) ~= nil;
elseif typ == "int" then
if not tonumber(val) then return false end
return tonumber(val)%1 == 0;
end
end
local tonumber=tonumber;
local floor=math.floor;
local function convertVal(v, t)
if t == "int" then v=floor(tonumber(v)+0.5)
elseif t == "number" then v=tonumber(v) end
return t:sub(1, 1):upper() .. t:sub(2), v
end
local lbl = Instance.new("TextLabel");
lbl.Name = "Label";
lbl.Text = txt;
lbl.TextTransparency = 0.2;
lbl.Size = UDim2.new(1, typ == "boolean" and -20 or -60, 1, 0);
lbl.Font = "ArialBold";
lbl.BackgroundTransparency=1;
lbl.TextXAlignment = "Right";
lbl.FontSize = main and "Size14" or "Size12";
lbl.TextColor3 = Color3.new(0, 0, 0)
lbl.Active = true;
lbl.Parent = infRow;
local typInd = Instance.new("StringValue");
typInd.Name = "TypeIndicator";
typInd.Value = typ;
typInd.Parent = infRow;
if typ == "boolean" then
local val=RbxData.GetValue(nam) or false;
local cbox = Instance.new("TextButton");
cbox.AutoButtonColor=false;
cbox.BackgroundColor3 = Color3.new(1, 1, 1);
cbox.BorderColor3 = Color3.new(0, 0, 0);
cbox.BackgroundTransparency = 0.6
cbox.Font = "Arial";
cbox.FontSize = "Size12"
if sav then cbox.Text = (val and "X" or "") else cbox.Text = "" end
cbox.Name = "Input";
cbox.TextColor3 = Color3.new(0, 0, 0)
cbox.Position = UDim2.new(1, -14, 1, -14);
cbox.Size = UDim2.new(0, 12, 0, 12);
cbox.MouseButton1Click:connect(function()
val = not RbxData.GetValue(nam);
cbox.Text = val and "X" or "";
if sav then RbxData.SetValue(nam, "Bool", val) end
end)
cbox.MouseEnter:connect(function() cbox.BackgroundTransparency = 0 end)
cbox.MouseLeave:connect(function() cbox.BackgroundTransparency = 0.6 end)
cbox.Parent = infRow
else
local focus=false;
local ibox = Instance.new("TextBox");
ibox.Name = "Input";
ibox.BackgroundColor3 = Color3.new(1, 1, 1);
ibox.BorderColor3 = Color3.new(0, 0, 0);
ibox.BackgroundTransparency = 0.6;
ibox.ClearTextOnFocus=false;
ibox.Font = "Arial";
ibox.FontSize = "Size12";
ibox.Text = tostring(sav and (RbxData.GetValue(nam) or val) or val)
ibox.TextColor3 = Color3.new(0, 0, 0);
ibox.Position = UDim2.new(1, -54, 1, -14);
ibox.Size = UDim2.new(0, 52, 0, 12);
ibox.TextXAlignment = "Left";
ibox.Parent = infRow;
local fakeibox=Instance.new("TextButton");
fakeibox.Size = UDim2.new(1, 0, 1, 0)
fakeibox.Name = "fakebutton";
fakeibox.BackgroundTransparency = 1;
fakeibox.TextTransparency = 1;
fakeibox.ZIndex = 2;
fakeibox.MouseButton1Click:connect(function()
ibox:CaptureFocus();
focus=true;
ibox.BackgroundTransparency = 0;
fakeibox.Visible=false;
end)
fakeibox.MouseEnter:connect(function() ibox.BackgroundTransparency = 0 end)
fakeibox.MouseLeave:connect(function() ibox.BackgroundTransparency = 0.6 end)
fakeibox.Parent = ibox;
ibox.FocusLost:connect(function() if isValidEntry(typ, ibox.Text) then val=ibox.Text; else ibox.Text=val; end if sav then RbxData.SetValue(nam, convertVal(val, typ)) end fakeibox.Visible=true; ibox.BackgroundTransparency = 0.6; end)
end
return infRow
end
local layoutFns={Button=createButton, Separator=createSeparator, InformationRow=createInformationRow}
local uiMenu = Instance.new("Frame");
uiMenu.Name = "UIMenu"
uiMenu.BackgroundTransparency = 1;
uiMenu.BackgroundColor3 = Color3.new(0, 0, 0);
uiMenu.BorderSizePixel = 0;
uiMenu.Size = UDim2.new(0, 0, 0, 0);
uiMenu.Position = UDim2.new(0, 0, 0, 0);
local validMainButtons=0;
local validMainSeps=0;
for i, v in ipairs(layout) do
if isValidType(v) and isValidEntry(v) then
if v[1] == "Button" then
validMainButtons = validMainButtons + 1;
elseif v[1] == "Separator" then
validMainSeps = validMainSeps + 1;
end
end
end
uiMenu.Size = UDim2.new(0, validMainButtons*100 + validMainSeps*3, 0, 20);
uiMenu.Position = UDim2.new(0.5, -(validMainButtons*100 + validMainSeps*3)/2, 0, 0)
local posVars={Button={[true]=100, [false]=16}, Separator={[true]=3, [false]=3}, InformationRow={[true]=120, [false]=16}}
local function createLayout(tab)
local function recurseCreateLayout(tab, obj, main)
main = main or false;
local posVar=0;
for i, v in pairs(tab) do
if isValidType(v) and isValidEntry(v) then
local ptab={};
for ii, vv in ipairs(v) do
if ii ~= 1 then
ptab[ii-1]=vv
end
end
local gobj=layoutFns[v[1]](main, unpack(ptab));
gobj.Position = UDim2.new(0, main and (v[1] == "Separator" and posVar+1 or posVar) or (v[1] == "Separator" and 2 or 0), 0, main and (v[1] == "Separator" and 2 or 0) or (v[1] == "Separator" and posVar+1 or posVar)+20)
gobj.Visible=main
gobj.Parent = obj;
local typVal = Instance.new("StringValue");
typVal.Name = "ElementType"
typVal.Value = v[1];
typVal.Parent = gobj;
posVar=posVar+posVars[v[1]][main]
if v[1] == "Button" then
gobj.MouseButton1Click:connect(
function()
if main or not gobj.Active then return end;
for i, v in pairs(uiMenu:GetChildren()) do
for ii, vv in pairs(v:children()) do
if vv:IsA("GuiObject") then vv.Visible=false; end
end
end
btnShield.Visible=false;
end
) recurseCreateLayout(v[6], gobj)
end
end
end
end
recurseCreateLayout(tab, uiMenu, true);
end
createLayout(layout);
for i, v in pairs(uiMenu:GetChildren()) do
if v.ElementType.Value == "Button" then
v.MouseEnter:connect(function()
if not v.Active then return end
for ii, vv in pairs(uiMenu:GetChildren()) do
for iii, vvv in pairs(vv:children()) do
if vvv:IsA("GuiObject") then vvv.Visible=false; end
end
end
for ii, vv in pairs(v:children()) do
if vv:IsA("GuiObject") then vv.Visible=true; end
end
btnShield.Visible=true;
end)
end
end
btnShield.MouseButton1Down:connect(function()
for i, v in pairs(uiMenu:GetChildren()) do
for ii, vv in pairs(v:children()) do
if vv:IsA("GuiObject") then vv.Visible=false; end
end
end
btnShield.Visible=false;
end)
btnShield.MouseButton2Down:connect(function()
for i, v in pairs(uiMenu:GetChildren()) do
for ii, vv in pairs(v:children()) do
if vv:IsA("GuiObject") then vv.Visible=false; end
end
end
btnShield.Visible=false;
end)
return uiMenu;
end
local CliButFn = function(btn)
if (RbxData.GetValue("IP") and RbxData.GetValue("CPort")) or RbxData.GetValue("CJoinString") or RbxData.GetValue("RPTPString") then
_G.ClientUtilities.SetCommandBarVisibility(RbxData.GetValue("IGCB"))
_G.ClientUtilities.SetGuestTalk(RbxData.GetValue("GT"))
_G.ClientUtilities.SetToolSpawn(RbxData.GetValue("TS"));
local success;
if not RbxData.GetValue("RPTPString") and not RbxData.GetValue("CJoinString") then
_G.ClientUtilities.Connect(RbxData.GetValue("PName") or "Player", RbxData.GetValue("PID") or 0, RbxData.GetValue("IP"), RbxData.GetValue("CPort"));
success = true;
elseif RbxData.GetValue("CJoinString") then
local b, ip, prt = pcall(CJoinEx.Decode, RbxData.GetValue("CJoinString"));
if not b then print("ERROR: " .. ip) else _G.ClientUtilities.Connect(RbxData.GetValue("PName") or "Player", RbxData.GetValue("PID") or 0, ip, prt) success = true end
elseif RbxData.GetValue("RPTPString") or (RbxData.GetValue("CJoinString") and not success) then
local b, ip, prt = pcall(RPTP2.Decode, RbxData.GetValue("RPTPString"));
if not b then print("ERROR: " .. ip) else _G.ClientUtilities.Connect(RbxData.GetValue("PName") or "Player", RbxData.GetValue("PID") or 0, ip, prt) success = true end
end
if not success then return end;
RbxData.AddChangeCallback(function(nam)
if nam == "IGCB" then
_G.ClientUtilities.SetCommandBarVisibility(RbxData.GetValue("IGCB"));
elseif nam == "GT" then
_G.ClientUtilities.SetGuestTalk(RbxData.GetValue("GT"));
elseif nam == "TS" then
_G.ClientUtilities.SetToolSpawn(RbxData.GetValue("TS"));
end
end)
for i, v in pairs(btn.Parent:GetChildren()) do
if v:IsA("GuiObject") then v.Visible=false end
end
btn.Parent.Active=false;
end
end
local CliButFn2 = function(btn)
if (RbxData.GetValue("IP") and RbxData.GetValue("CPort")) or RbxData.GetValue("CJoinString") or RbxData.GetValue("RPTPString") then
_G.ClientUtilities.SetCommandBarVisibility(RbxData.GetValue("IGCB"))
_G.ClientUtilities.SetGuestTalk(RbxData.GetValue("IGCB"))
_G.ClientUtilities.SetToolSpawn(RbxData.GetValue("TS"));
local success;
if not RbxData.GetValue("RPTPString") and not RbxData.GetValue("CJoinString") then
_G.ClientUtilities.ConnectAsGuest(RbxData.GetValue("IP"), RbxData.GetValue("CPort"));
success = true;
elseif RbxData.GetValue("CJoinString") then
local b, ip, prt = pcall(CJoinEx.Decode, RbxData.GetValue("CJoinString"));
if not b then print("ERROR: " .. ip) else _G.ClientUtilities.ConnectAsGuest(CJoinEx.Decode(RbxData.GetValue("CJoinString"))) success = true end
elseif RbxData.GetValue("RPTPString") or (RbxData.GetValue("CJoinString") and not success) then -- uses this if CJoinString doesn't work
local b, ip, prt = pcall(RPTP2.Decode, RbxData.GetValue("RPTPString"));
if not b then print("ERROR: " .. ip) else _G.ClientUtilities.ConnectAsGuest(RPTP2.Decode(RbxData.GetValue("RPTPString"))) success = true end
end
if not success then return end;
RbxData.AddChangeCallback(function(nam)
if nam == "IGCB" then
_G.ClientUtilities.SetCommandBarVisibility(RbxData.GetValue("IGCB"));
elseif nam == "GT" then
_G.ClientUtilities.SetGuestTalk(RbxData.GetValue("GT"));
elseif nam == "TS" then
_G.ClientUtilities.SetToolSpawn(RbxData.GetValue("TS"));
end
end)
for i, v in pairs(btn.Parent:GetChildren()) do
if v:IsA("GuiObject") then v.Visible=false end
end
btn.Parent.Active=false;
end
end
local num;
local SerButFn = function(btn)
if not RbxData.GetValue("SPort") then return end
_G.ServerUtilities.Start(RbxData.GetValue("SPort") or 53640)
math.randomseed(tick()+2)
num = num or math.random(16) - 9;
print("RPTP2:", RPTP2.Encode(RbxData.GetValue("SIP") or "127.0.0.1", RbxData.GetValue("SPort") or 53640, num));
print("CJoinEx:", CJoinEx.Encode(RbxData.GetValue("SIP") or "127.0.0.1", RbxData.GetValue("SPort") or 53640));
end
local SerStopButFn = function(btn)
_G.ServerUtilities.Stop();
end
local RdFn = function(btn)
for i, v in pairs(btn.Parent:children()) do
if v:IsA("GuiObject") and v.ElementType.Value == "InformationRow" then
RbxData.SetValue(v.Name, nil);
if v.TypeIndicator.Value == "number" or v.TypeIndicator.Value == "int" then
v.Input.Text = "0";
else
v.Input.Text = "";
end
end
end
end
local RadFn = function(btn)
for i, v in pairs(btn.Parent.Parent:children()) do
for i, v in pairs(v:children()) do
if v:IsA("GuiObject") and v.ElementType.Value == "InformationRow" then
RbxData.SetValue(v.Name, nil);
if v.TypeIndicator.Value == "number" or v.TypeIndicator.Value == "int" then
v.Input.Text = "0";
else
v.Input.Text = "";
end
end
end
end
end
local ExitFn = function(btn)
game:Shutdown();
end
local menuLayout={
{"Button", "ClientButton", "Client", false, function() end,
{
{"InformationRow", "IP", "IP", "string", true};
{"InformationRow", "CPort", "Port", "int", true};
{"InformationRow", "CJoinString", "CJoinEx", "string", true};
{"InformationRow", "RPTPString", "RPTP2", "string", true};
{"InformationRow", "PName", "Name", "string", true};
{"InformationRow", "PID", "ID", "int", true};
{"Button", "JoinButton", "Join As Guest", true, CliButFn2, {}};
{"Button", "JoinButton", "Join Game", true, CliButFn, {}};
{"Separator"};
{"Button", "RD1Button", "Reset Data", true, RdFn, {}};
};
};
{"Button", "ServerButton", "Server", false, function() end,
{
{"InformationRow", "SIP", "IP", "string", true}; -- used for creation of RPTPStrings
{"InformationRow", "SPort", "Port", "int", true};
{"Button", "StartButton", "Start Game", true, SerButFn, {}};
{"Button", "StopButton", "Stop Game", true, SerStopButFn, {}};
{"Separator"};
{"Button", "RD2Button", "Reset Data", true, RdFn, {}};
};
};
{"Button", "OptionsButton", "Options", true, function() end,
{
{"InformationRow", "GT", "Guest Talk", "boolean", true};
{"InformationRow", "IGCB", "IG Cmd Bar", "boolean", true};
{"InformationRow", "TS", "Tools Spawn", "boolean", true};
{"Separator"};
{"Button", "RD3Button", "Reset Data", true, RdFn, {}};
{"Button", "RADButton", "Reset All Data", true, RadFn, {}};
};
};
{"Separator"};
{"Button", "ExitButton", "Exit", true, ExitFn, {}};
}
local uiMenu = createMenu(menuLayout);
uiMenu.Parent = uiBase;
-- This is to make sure that the client can't access server stuff and vice versa
coroutine.resume(coroutine.create(function() repeat wait() until _G.ClientUtilities; uiMenu.ClientButton.Active=true; end))
coroutine.resume(coroutine.create(function() repeat wait() until _G.ServerUtilities; uiMenu.ServerButton.Active=true; end))