This commit is contained in:
samuelWilliams99 2019-12-23 01:33:12 +00:00
parent 4d0503ad8c
commit aa7d729cfb
3 changed files with 139 additions and 61 deletions

View File

@ -6,4 +6,6 @@ AddCSLuaFile("cfc_disconnect_interface/client/cl_ponger.lua")
AddCSLuaFile("cfc_disconnect_interface/client/cl_api.lua") AddCSLuaFile("cfc_disconnect_interface/client/cl_api.lua")
AddCSLuaFile("cfc_disconnect_interface/client/cl_interface.lua") AddCSLuaFile("cfc_disconnect_interface/client/cl_interface.lua")
resource.AddSingleFile("materials/icons/cross.png")
include("cfc_disconnect_interface/server/sv_pinger.lua") include("cfc_disconnect_interface/server/sv_pinger.lua")

View File

@ -13,7 +13,7 @@ surface.CreateFont( "CFC_Normal",
surface.CreateFont( "CFC_Special", surface.CreateFont( "CFC_Special",
{ {
font = "coolvetica", font = "coolvetica",
size = 26, size = 30,
weight = 500 weight = 500
} }
) )
@ -33,11 +33,16 @@ local GAME_WIDTH = 1256
local interfaceDerma = false local interfaceDerma = false
local TIME_TO_RESTART = 10 local TIME_TO_RESTART = 180
local timeDown = 0 local timeDown = 0
local apiState local apiState
local previouslyShown = false local previouslyShown = false
-- Helper function
function getFrom(i, ...)
return ({...})[i]
end
-- Colors -- Colors
primaryCol = Color( 36, 41, 67 ) primaryCol = Color( 36, 41, 67 )
secondaryCol = Color( 42, 47, 74 ) secondaryCol = Color( 42, 47, 74 )
@ -84,7 +89,7 @@ end
-- Creates and populates a title bar for the frame -- Creates and populates a title bar for the frame
local function addTitleBar(frame) local function addTitleBar(frame)
local frameW, frameH = frame:GetSize() local frameW, frameH = frame:GetSize()
local titleBarHeight = 32 local titleBarHeight = 70
-- The bar itself -- The bar itself
local titleBar = vgui.Create( "DPanel", frame ) local titleBar = vgui.Create( "DPanel", frame )
@ -96,11 +101,12 @@ local function addTitleBar(frame)
end end
-- Close button, could be removed, but I personally think it should stay, allows you to save e2/sf files -- Close button, could be removed, but I personally think it should stay, allows you to save e2/sf files
local closeBtnPadding = (titleBarHeight - 16) / 2 local closeBtnSize = 32
local closeBtnPadding = (titleBarHeight - closeBtnSize) / 2
local closeBtn = vgui.Create( "DImageButton", titleBar ) local closeBtn = vgui.Create( "DImageButton", titleBar )
closeBtn:SetSize( 16, 16 ) closeBtn:SetSize( closeBtnSize, closeBtnSize )
closeBtn:SetPos( frameW - 16 - closeBtnPadding, closeBtnPadding) closeBtn:SetPos( frameW - closeBtnSize - closeBtnPadding, closeBtnPadding)
closeBtn:SetImage( "icon16/cross.png" ) closeBtn:SetImage( "icons/cross.png" )
function closeBtn:DoClick() function closeBtn:DoClick()
frame:Close() frame:Close()
end end
@ -109,10 +115,16 @@ local function addTitleBar(frame)
local titleLabelPadding = (titleBarHeight - 26) / 2 local titleLabelPadding = (titleBarHeight - 26) / 2
local titleLabel = vgui.Create( "DLabel", titleBar ) local titleLabel = vgui.Create( "DLabel", titleBar )
titleLabel:SetFont( "CFC_Special" ) titleLabel:SetFont( "CFC_Special" )
titleLabel:SetText( "Oops! Looks like the server crashed..." )
titleLabel:SizeToContents() local function setTitle(title)
titleLabel:SetPos( 0, titleLabelPadding + 2 ) titleLabel:SetText( title )
titleLabel:CenterHorizontal() titleLabel:SizeToContents()
titleLabel:SetPos( 0, titleLabelPadding + 2 )
titleLabel:CenterHorizontal()
end
setTitle("Oops! Looks like you disconnected...")
titleBar.setTitle = setTitle
return titleBar return titleBar
end end
@ -121,18 +133,21 @@ end
-- xFraction is 0-1 for how far across the button should be -- xFraction is 0-1 for how far across the button should be
-- Colours are self explan -- Colours are self explan
local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol, hoverOutlineCol, hoverFillCol) local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol, hoverOutlineCol, hoverFillCol)
-- Defaults for colours
outlineCol = outlineCol or Color( 255, 255, 255 )
fillCol = fillCol or primaryCol
hoverOutlineCol = hoverOutlineCol or Color(155,241,255)
hoverFillCol = hoverFillCol or primaryCol
local frameW, frameH = frame:GetSize() local frameW, frameH = frame:GetSize()
local btn = vgui.Create( "DButton", frame ) local btn = vgui.Create( "DButton", frame )
-- Defaults for colours
btn.outlineCol = outlineCol or Color( 255, 255, 255 )
btn.fillCol = fillCol or primaryCol
btn.hoverOutlineCol = hoverOutlineCol or Color( 255, 255, 255 )
btn.hoverFillCol = hoverFillCol or primaryCol
btn:SetText( text ) btn:SetText( text )
btn:SetTextColor( Color( 255, 255, 255 ) ) btn:SetTextColor( Color( 255, 255, 255 ) )
btn:SetFont( "CFC_Button" ) btn:SetFont( "CFC_Button" )
btn:SetSize( frameW * 0.4, frameH * 0.6 ) btn:SetSize( frameW * 0.3, frameH )
btn:CenterHorizontal( xFraction ) btn:CenterHorizontal( xFraction )
btn:CenterVertical() btn:CenterVertical()
btn.DoClick = doClick btn.DoClick = doClick
@ -141,7 +156,7 @@ local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol,
btn.fadeState = 0 btn.fadeState = 0
btn.prevTime = CurTime() btn.prevTime = CurTime()
local btnAnimSpeed = 0.05 * 60 local btnAnimSpeed = 0.1 * 60
function btn:Think() function btn:Think()
-- Make anim same speed for all framerates -- Make anim same speed for all framerates
@ -160,47 +175,99 @@ local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol,
function btn:Paint(w, h) function btn:Paint(w, h)
local lineCol local lineCol
local bgCol local bgCol
local borderWeight
if self:GetDisabled() then if self:GetDisabled() then
lineCol = Color( 74, 74, 74 ) lineCol = Color( 74, 74, 74 )
bgCol = fillCol bgCol = self.fillCol
borderWeight = btnBorderWeight
self:SetCursor( "no" ) self:SetCursor( "no" )
else else
lineCol = lerpColor(self.fadeState, outlineCol, hoverOutlineCol) lineCol = lerpColor(self.fadeState, self.outlineCol, self.hoverOutlineCol)
bgCol = lerpColor(self.fadeState, fillCol, hoverFillCol) bgCol = lerpColor(self.fadeState, self.fillCol, self.hoverFillCol)
borderWeight = 1.5 * btnBorderWeight + 1.5 * self.fadeState * btnBorderWeight
self:SetCursor( "hand" ) self:SetCursor( "hand" )
end end
self:SetTextColor( lineCol ) self:SetTextColor( lineCol )
surface.SetDrawColor( lineCol ) draw.RoundedBox(h/2, 0, 0, w, h, lineCol)
surface.DrawRect( 0, 0, w, h )
surface.SetDrawColor( bgCol ) local nw, nh = w - (borderWeight*2), h - (borderWeight*2)
surface.DrawRect( btnBorderWeight, btnBorderWeight, draw.RoundedBox(nh/2, borderWeight, borderWeight, nw, nh, bgCol)
w - (btnBorderWeight*2), h - (btnBorderWeight*2) )
end end
return btn return btn
end end
local function showMessage(msg)
if interfaceDerma and (interfaceDerma.messageLabel:GetText() ~= msg or not interfaceDerma.messageLabel:IsVisible()) then
if interfaceDerma.messageLabel:IsVisible() then
interfaceDerma.messageLabel:AlphaTo(0, 0.25)
timer.Simple(0.25, function()
interfaceDerma.messageLabel:setTextAndAlign(msg)
interfaceDerma.messageLabel:AlphaTo(255, 0.25)
end)
else
interfaceDerma.messageLabel:setTextAndAlign(msg)
interfaceDerma.messageLabel:Show()
interfaceDerma.messageLabel:AlphaTo(255, 0.5)
end
end
end
local function hideMessage(msg)
if interfaceDerma and interfaceDerma.messageLabel:IsVisible() then
interfaceDerma.messageLabel:AlphaTo(0, 0.25)
timer.Simple(0.25, function()
interfaceDerma.messageLabel:Hide()
end)
end
end
-- Create bar panel and add buttons -- Create bar panel and add buttons
local function addButtonsBar(frame) local function addButtonsBar(frame)
local frameW, frameH = frame:GetSize() local frameW, frameH = frame:GetSize()
local buttonBarHeight = 64 local buttonBarHeight = 90
local buttonBarOffset = 90
local barPanel = vgui.Create( "DPanel", frame ) local barPanel = vgui.Create( "DPanel", frame )
barPanel:SetSize( frameW, buttonBarHeight ) barPanel:SetSize( frameW, buttonBarHeight )
barPanel:SetPos( 0, frameH - buttonBarHeight ) barPanel:SetPos( 0, frameH - buttonBarHeight - buttonBarOffset )
function barPanel:Paint(w, h) barPanel.Paint = nil
surface.SetDrawColor( accentCol )
surface.DrawLine( 16, 0, w - 16, 0 )
end
-- Put buttons onto the panel as members for easy access -- Put buttons onto the panel as members for easy access
barPanel.reconBtn = makeButton(barPanel, "RECONNECT", 0.25, rejoin, barPanel.reconBtn = makeButton(barPanel, "RECONNECT", 0.25, function()
Color( 74, 251, 191 ), nil, Color( 74, 251, 191 ), Color( 64, 141, 131 )) if not barPanel.disconMode then
rejoin()
else
leave()
end
end)
--Color( 74, 251, 191 ), nil, Color( 74, 251, 191 ), Color( 64, 141, 131 ))
-- Reconnect button will usually start as disabled -- Reconnect button will usually start as disabled
barPanel.reconBtn:SetDisabled( true ) barPanel.reconBtn:SetDisabled( true )
barPanel.disconBtn = makeButton(barPanel, "DISCONNECT", 0.75, leave) barPanel.disconBtn = makeButton( barPanel, "DISCONNECT", 0.75, function(self)
if not barPanel.disconMode then
showMessage("Are you sure? Hang in there, the server will restart soon...")
barPanel.disconMode = true
barPanel.disconPrevDisabled = barPanel.reconBtn:GetDisabled()
barPanel.reconBtn:SetDisabled(false)
self:SetText("NO")
self.fadeState = 0
self.hoverOutlineCol = Color( 255, 0, 0 )
barPanel.reconBtn.hoverOutlineCol = Color( 0, 255, 0 )
barPanel.reconBtn:SetText("YES")
else
hideMessage()
barPanel.disconMode = false
self:SetText("DISCONNECT")
self.hoverOutlineCol = Color( 255, 255, 255 )
barPanel.reconBtn:SetText("RECONNECT")
barPanel.reconBtn.hoverOutlineCol = Color( 255, 255, 255 )
barPanel.reconBtn:SetDisabled(barPanel.disconPrevDisabled)
end
end)
return barPanel return barPanel
end end
@ -209,26 +276,30 @@ end
local function makeLabel(frame, text, top, col, xFraction) local function makeLabel(frame, text, top, col, xFraction)
col = col or Color( 255, 255, 255 ) col = col or Color( 255, 255, 255 )
local label = vgui.Create( "DLabel", frame ) local label = vgui.Create( "DLabel", frame )
label:SetText( text )
label:SetFont( "CFC_Special" ) label:SetFont( "CFC_Special" )
label:SizeToContents() function label:setTextAndAlign( str )
label:SetPos( 0, top ) self:SetText( str )
label:SetTextColor( col ) self:SizeToContents()
label:CenterHorizontal( xFraction ) self:SetPos( 0, top )
self:SetTextColor( col )
self:CenterHorizontal( xFraction )
end
label:setTextAndAlign(text)
return label return label
end end
-- Text for internet down on body -- Text for internet down on body
local function populateBodyInternetDown(body) local function populateBodyInternetDown(body)
local label1 = makeLabel(body, "Looks like your internet has gone down!", 20) local label1 = makeLabel(body, "Please check you're still connected to the internet.", 20)
local label2 = makeLabel(body, "Stick around for when it comes back", 64) local label2 = makeLabel(body, "In the meantime,", 80)
return "Oops, looks like you disconnected"
end end
-- Text for server down on body -- Text for server down on body
local function populateBodyServerDown(body) local function populateBodyServerDown(body)
local frameW, frameH = body:GetSize() local frameW, frameH = body:GetSize()
local restartTimeStr = "The server normally takes about " .. secondsAsTime(TIME_TO_RESTART) .. " to restart!" local restartTimeStr = "The server normally takes about " .. secondsAsTime(TIME_TO_RESTART) .. " to restart."
local restartTimeLabel = makeLabel(body, restartTimeStr, 0) local restartTimeLabel = makeLabel(body, restartTimeStr, 0)
local curTimePreLabel = makeLabel(body, "It has been down for", 32) local curTimePreLabel = makeLabel(body, "It has been down for", 32)
-- When the server comes back up, "It has been down for" => "It was down for" -- When the server comes back up, "It has been down for" => "It was down for"
@ -242,50 +313,51 @@ local function populateBodyServerDown(body)
end end
end end
-- Label for when timeDown > averageTimeDown
-- Currently on the right, change the 0.8 at the end to move it horizontally
local tooLongLabel = makeLabel(body, "Uh oh, seems it's taking a little longer than usual!", 70, Color( 251, 191, 83 ), 0.8)
tooLongLabel:SetAlpha(0)
tooLongLabel:Hide()
-- Text for downTime, update its value in Think -- Text for downTime, update its value in Think
-- If server comes back up, make it green and stop updating it -- If server comes back up, make it green and stop updating it
-- If timeDown > averageTimeDown, make it red and show the tooLongLabel -- If timeDown > averageTimeDown, make it red and show the messageLabel
local curTimeLabel = makeLabel(body, secondsAsTime(math.floor(timeDown)), 70, Color( 251, 191, 83 )) local curTimeLabel = makeLabel(body, secondsAsTime(math.floor(timeDown)), 70, Color( 251, 191, 83 ))
function curTimeLabel:Think() function curTimeLabel:Think()
if apiState ~= crashApi.SERVER_UP then if apiState ~= crashApi.SERVER_UP then
self:SetText(secondsAsTime(math.floor(timeDown))) self:SetText(secondsAsTime(math.floor(timeDown)))
if timeDown > TIME_TO_RESTART then if timeDown > TIME_TO_RESTART then
self:SetTextColor(Color(255, 0, 0)) self:SetTextColor(Color(255, 0, 0))
if not tooLongLabel:IsVisible() then if not messageLabel:IsVisible() then
tooLongLabel:Show() showMessage("Uh oh, seems it's taking a little longer than usual...")
tooLongLabel:AlphaTo(255, 1)
end end
end end
else else
self:SetTextColor(Color(0, 255, 0)) self:SetTextColor(Color(0, 255, 0))
end end
end end
return "Oops, looks like the server crashed..."
end end
-- Fill the body with elements, body created elsewhere as it's size relies on size of titleBar and buttonsBar -- Fill the body with elements, body created elsewhere as it's size relies on size of titleBar and buttonsBar
local function populateBody(body) local function populateBody(body)
body.Paint = nil body.Paint = nil
local title
local frameW, frameH = body:GetSize()
-- Warning message label
interfaceDerma.messageLabel = makeLabel(body, "", frameH - 45, Color( 255, 255, 0 ), 0.5)
interfaceDerma.messageLabel:SetAlpha(0)
interfaceDerma.messageLabel:Hide()
-- Fill top text based on crashApi state -- Fill top text based on crashApi state
if apiState == crashApi.NO_INTERNET then if apiState == crashApi.NO_INTERNET then
populateBodyInternetDown(body) title = populateBodyInternetDown(body)
else -- Server down or up via api, and down via net else -- Server down or up via api, and down via net
populateBodyServerDown(body) title = populateBodyServerDown(body)
end end
local frameW, frameH = 0.8 * ScrW(), 0.8 * ScrH()
local playGameLabel = makeLabel(body, "Why not play a game while you wait? (Press space)", 108) local playGameLabel = makeLabel(body, "Why not play a game while you wait? (Press space)", 108)
-- Game wrapper, in case we ever want to make a game that runs in lua -- Game wrapper, in case we ever want to make a game that runs in lua
local gamePanel = vgui.Create( "DPanel", body ) local gamePanel = vgui.Create( "DPanel", body )
gamePanel:SetSize( frameW - 20, frameH - 134 - 15 ) gamePanel:SetSize( frameW - 20, frameH - 134 - 15 )
gamePanel:SetPos( -6, 134 + 10 ) gamePanel:SetPos( 10, 134 )
gamePanel.Paint = nil gamePanel.Paint = nil
-- HTML element rending game at GAME_URL, constantly grabs focus -- HTML element rending game at GAME_URL, constantly grabs focus
@ -296,6 +368,8 @@ local function populateBody(body)
function gameHtml:Think() function gameHtml:Think()
if not gameHtml:HasFocus() then gameHtml:RequestFocus() end if not gameHtml:HasFocus() then gameHtml:RequestFocus() end
end end
return title
end end
-- Entry point for creating the interface -- Entry point for creating the interface
@ -328,9 +402,10 @@ local function createInterface()
-- Create body that fills the unused space -- Create body that fills the unused space
local body = vgui.Create( "DPanel", frame ) local body = vgui.Create( "DPanel", frame )
body:SetSize(frameW - 32, frameH - 32 - titlePanel:GetTall() - btnsPanel:GetTall()) body:SetSize(frameW - 32, getFrom(2, btnsPanel:GetPos()) - 32 - titlePanel:GetTall())
body:SetPos(16, titlePanel:GetTall() + 16) body:SetPos(16, titlePanel:GetTall() + 16)
populateBody(body) local title = populateBody(body)
titlePanel.setTitle( title )
-- If server fully recovers without crashing, close menu -- If server fully recovers without crashing, close menu
-- If server reboots, enabled the reconnect button -- If server reboots, enabled the reconnect button
@ -340,7 +415,6 @@ local function createInterface()
elseif apiState == crashApi.SERVER_UP then elseif apiState == crashApi.SERVER_UP then
if btnsPanel.reconBtn:GetDisabled() == true then if btnsPanel.reconBtn:GetDisabled() == true then
btnsPanel.reconBtn:SetDisabled( false ) -- Server back up btnsPanel.reconBtn:SetDisabled( false ) -- Server back up
-- Maybe show a "The server is back up, click here to reconnect?"
end end
end end
end end
@ -350,6 +424,8 @@ local function createInterface()
end end
end end
concommand.Add("cfc_interface", createInterface)
hook.Add("cfc_di_crashTick", "cfc_di_interfaceUpdate", function(isCrashing, _timeDown, _apiState) hook.Add("cfc_di_crashTick", "cfc_di_interfaceUpdate", function(isCrashing, _timeDown, _apiState)
timeDown = _timeDown or 0 timeDown = _timeDown or 0
apiState = _apiState apiState = _apiState
@ -362,7 +438,7 @@ hook.Add("cfc_di_crashTick", "cfc_di_interfaceUpdate", function(isCrashing, _tim
if not isCrashing then if not isCrashing then
previouslyShown = false previouslyShown = false
if interfaceDerma then if interfaceDerma then
interfaceDerma:Close() --interfaceDerma:Close()
end end
end end
end) end)

BIN
materials/icons/cross.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB