• Print

Author Topic: Prevent players from closing MOTD for a certain amount of time (a la ASSMOD)  (Read 10986 times)

0 Members and 1 Guest are viewing this topic.

Offline RalphORama

  • Newbie
  • *
  • Posts: 17
  • Karma: 0
Hello!
In setting up my new server, I've run into an issue wherein I want a delay before players can close the MOTD, preferably a "countdown" on the button before it turns into "close". I've poked around the forums some, and found this thread, detailing how to not make the button show up for a specified amount of time. Good enough, I can hack it into what I want. Here's my code:
Code: Lua
  1. --in motdmenu.lua
  2. button = vgui.Create( "DButton", window ) --Need to create a button outside the timer function so it'll register as global, for some reason
  3. button:SetText( "Close in 5 seconds" )
  4. button:SetSize( 200, 40 ) -- little bigger to fit extra text
  5. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  6.  
  7. timer.Simple( 5, function()
  8.         button:Remove() -- get rid of that earlier button, replace it with the new "close" button
  9.  
  10.         button = vgui.Create( "DButton", window ) --TIMER
  11.         button:SetText( "Close" )
  12.         button.DoClick = function() window:Close() end
  13.         button:SetSize( 100, 40 )
  14.         button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  15.         end )

However, when I try to impliment it at first, I get the following error in console trying to open the MOTD:
Code: [Select]
[ERROR] addons/ulx/lua/ulx/modules/cl/motdmenu.lua:32: Tried to use invalid object (type Panel) (Object was NULL or not of the right type)
  1. GetWide - [C]:-1
   2. unknown - addons/ulx/lua/ulx/modules/cl/motdmenu.lua:32

This works currently, the only issues I'm having are:
  • Players can close the MOTD prematurely by using the "x" in the top right of the window
  • The error mentioned
  • I can't get the button to display a countdown, only have a static "you can close this in 5 seconds" message.

I've attached my modified MOTD for anyone who wants to use it on their server, and if/when I get the rest of these issues sorted, I'll attach the final version as well.

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
Experiencing God's grace one day at a time.

Offline Neku

  • Hero Member
  • *****
  • Posts: 549
  • Karma: 27
To disable the x button, put this below line 13.

Code: [Select]
window:ShowCloseButton( false )
Out of the Garry's Mod business.

Offline Neku

  • Hero Member
  • *****
  • Posts: 549
  • Karma: 27
Code: [Select]
local timersec = 5
loop
timer.Simple( 1, function()
       timersec = ( timersec - 1 )
        if timersec == 0 then
               break
        end
        button:Remove()
       
        button = vgui.Create( "DButton", window )
        button:SetText( "Unlock in ".. timersec .. "..." )
        button:SetSize( 100, 40 )
        button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
end )
end
button:Remove() -- get rid of that earlier button, replace it with the new "close" button
 
   button = vgui.Create( "DButton", window ) --TIMER
   button:SetText( "Close" )
   button.DoClick = function() window:Close() end
   button:SetSize( 100, 40 )
   button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )


Might not be efficient, but gets the job done.
You know, if I used the correct syntax for loops.
Out of the Garry's Mod business.

Offline RalphORama

  • Newbie
  • *
  • Posts: 17
  • Karma: 0
Code: Lua
  1. local timersec = 5
  2. loop
  3. timer.Simple( 1, function()
  4.        timersec = ( timersec - 1 )
  5.         if timersec == 0 then
  6.                break
  7.         end
  8.         button:Remove()
  9.        
  10.         button = vgui.Create( "DButton", window )
  11.         button:SetText( "Unlock in ".. timersec .. "..." )
  12.         button:SetSize( 100, 40 )
  13.         button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  14. end )
  15. end
  16.    button:Remove() -- get rid of that earlier button, replace it with the new "close" button
  17.  
  18.       button = vgui.Create( "DButton", window ) --TIMER
  19.       button:SetText( "Close" )
  20.       button.DoClick = function() window:Close() end
  21.       button:SetSize( 100, 40 )
  22.       button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )

Might not be efficient, but gets the job done.
You know, if I used the correct syntax for loops.

I'll try that out, here's what I have implemented currently:
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )  -- initialize the button
  5.  
  6. for (t = 13, t > 0, t = t - 1)  do  -- for 13 seconds (3 to "get in," 10 to display)
  7.         timer.Simple( 1, function()  -- 1 second timer for each tick in the for loop
  8.       button:SetText( "Wait - " .. t )  -- Wait t seconds
  9.    end )
  10. end
  11.  
  12. button:SetText( "Close" )
  13. button.DoClick = function() window:Close() end

However, this breaks the MOTD, but I think I see my errors, I'll impliment the following and get back on this:
Code: Lua
  1. for t = 13, 0, -1 do    -- for 13 seconds (3 to "get in," 10 to display)
  2.         timer.Simple( 1, function()    -- 1 second timer for each tick in the for loop
  3.       button:SetText( "Wait - " .. t )    -- Wait t seconds
  4.    end )
  5. end

E: This is the error that the code in "unfixed" box I posted throws back:
Code: [Select]
[ERROR] lua/includes/modules/net.lua:31: Received bad RPC, invalid function (ulx.rcvMotd)!
  1. func - [C]:-1
   2. unknown - lua/includes/modules/net.lua:31
E2: So my fix doesn't seem to work, gonna try changing it to this:
Code: Lua
  1. for t = 13, 0, -1 do
  2.    button:SetText( "Wait - " .. t )
  3.    wait(1)
  4. end
  5.  

None of this worked.I tried all of my examples above, including Neku's quoted one. Unfortunately, that gave me the following error:
Code: [Select]
[ERROR] lua/includes/modules/net.lua:31: Received bad RPC, invalid function (ulx.rcvMotd)!
  1. func - [C]:-1
   2. unknown - lua/includes/modules/net.lua:31
[ERROR] lua/includes/modules/net.lua:31: Received bad RPC, invalid function (ulx.showMotdMenu)!
  1. func - [C]:-1
   2. unknown - lua/includes/modules/net.lua:31
I tried modifying Neku's script to use repeat ... until, but that just caused massive memory consumption for some reason.
Here's my current script (lines 22 - 41):
Code: Lua
  1.    button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )
  5.  
  6. timersec = 13
  7.  
  8. loop
  9.    timer.Simple( 1, function()
  10.       timersec = ( timersec - 1 ) -- this is the line the error is supposedly on, not sure what's up with that
  11.       if timersec == 0 then
  12.          break
  13.       end
  14.  
  15.       button:SetText( "Wait - " .. timersec )
  16.    end )
  17. end
  18.  
  19. button:SetText( "Close" )
  20. button.DoClick = function() window:Close() end

The closest I've gotten is with the earlier for loop, everything worked fine with no errors, but the timer didn't count down. It just said "Wait -" for a second before changing text to "Close"
« Last Edit: January 20, 2014, 12:38:27 pm by RalphORama »

Offline RalphORama

  • Newbie
  • *
  • Posts: 17
  • Karma: 0
So it looks like the closest I've gotten is the following:
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )  -- initialize the button
  5.  
  6. for t = 13, 0, -1)  do                                  -- for 13 seconds, until t == 0, decreasing t by 1 each time
  7.         timer.Simple( 1, function()                     -- 1 second timer for each tick in the for loop
  8.                  button:SetText( "Wait - " .. t )       -- Wait t seconds
  9.         end )
  10. end
  11.  
  12. button:SetText( "Close" )
  13. button.DoClick = function() window:Close() end

This does not throw back any errors, but the text on the button does not count down. It almost immediately switches from "Wait - [with no #]" to "close."
Is there any way to call a wait for 1 second? Something like this could work:
Code: Lua
  1. for t = 13, 0, -1)  do                          -- for 13 seconds, until t == 0, decreasing t by 1 each time
  2.         button:SetText( "Wait - " .. t )        --Change the text
  3.         sleep( 1000 )                           --sleep for 1 second
  4. end

MAJOR EDIT: I (almost) GOT IT
Ok so here's my new code:
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )
  5. button:SetDisabled( true )
  6.  
  7. timersec = 13
  8.  
  9. timer.Create( "countDown", 1, 13, function()
  10.         button:SetText( "Wait - " .. timersec )
  11.         timersec = timersec - 1
  12. end)
  13.  
  14. button:SetText( "Close" )
  15. button:SetDisabled( false )
  16. button.DoClick = function() window:Close() end

The problem is that one can click the button while it's counting down and it will close the MOTD. I tried implementing the SetDisabled method as seen, but that doesn't fix it. If I add "button:SetDisabled( true )" inside the timer, it gets stuck at "Wait - 1" and you can't close the MOTD. Very perplexing, not sure how to fix it.
« Last Edit: January 20, 2014, 01:08:20 pm by RalphORama »

Offline Bytewave

  • Respected Community Member
  • Hero Member
  • *****
  • Posts: 718
  • Karma: 116
  • :)
    • My Homepage
So it looks like the closest I've gotten is the following:
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )  -- initialize the button
  5.  
  6. for t = 13, 0, -1)  do                                  -- for 13 seconds, until t == 0, decreasing t by 1 each time
  7.         timer.Simple( 1, function()                     -- 1 second timer for each tick in the for loop
  8.                  button:SetText( "Wait - " .. t )       -- Wait t seconds
  9.         end )
  10. end
  11.  
  12. button:SetText( "Close" )
  13. button.DoClick = function() window:Close() end

This does not throw back any errors, but the text on the button does not count down. It almost immediately switches from "Wait - [with no #]" to "close."
Is there any way to call a wait for 1 second? Something like this could work:
Code: Lua
  1. for t = 13, 0, -1)  do                          -- for 13 seconds, until t == 0, decreasing t by 1 each time
  2.         button:SetText( "Wait - " .. t )        --Change the text
  3.         sleep( 1000 )                           --sleep for 1 second
  4. end

MAJOR EDIT: I (almost) GOT IT
Ok so here's my new code:
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )
  5. button:SetDisabled( true )
  6.  
  7. timersec = 13
  8.  
  9. timer.Create( "countDown", 1, 13, function()
  10.         button:SetText( "Wait - " .. timersec )
  11.         timersec = timersec - 1
  12. end)
  13.  
  14. button:SetText( "Close" )
  15. button:SetDisabled( false )
  16. button.DoClick = function() window:Close() end

The problem is that one can click the button while it's counting down and it will close the MOTD. I tried implementing the SetDisabled method as seen, but that doesn't fix it. If I add "button:SetDisabled( true )" inside the timer, it gets stuck at "Wait - 1" and you can't close the MOTD. Very perplexing, not sure how to fix it.
Try adding:
Code: Lua
  1. button.OnClick = nil
inside the timer.
No idea if it'll work- just a guess, but give it a go.
bw81@ulysses-forums ~ % whoami
Homepage

Offline RalphORama

  • Newbie
  • *
  • Posts: 17
  • Karma: 0
Ok, I finally got it. Here's my finished code, a bit jury-rigged, but works nonetheless, with no errors at all!
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )
  5. button:SetDisabled( true )
  6.  
  7. timersec = 14                                                   --this is how long your motd will stay open, I reccomend
  8.                                                                 --adding about 5 to your desired value to compensate for lag
  9. timer.Create( "countDown", 1, 14, function()                    --change 14 to the same value as timersec
  10.         timersec = timersec - 1
  11.         button:SetText( "Wait - " .. timersec )
  12.         if timersec == 0 then
  13.                 button:SetText( "Close" )
  14.                 button:SetDisabled( false )
  15.                 button.DoClick = function() window:Close() end
  16.         end
  17. end)
  18.  
  19. if timersec == 0 then                                           --all this crap may be useless, I left it in because everything was working
  20.         button:SetText( "Close" )
  21.         button:SetDisabled( false )
  22.         button.DoClick = function() window:Close() end
  23. end

I've attached the final version of my modified motdmenu.lua for anyone who wants to use it, simply drop it in addons/ulx/lua/ulx/modules/cl/ and replace the old one. Setup is exactly the same.
« Last Edit: January 21, 2014, 07:28:05 am by RalphORama »

Offline ULXGmodFan

  • Newbie
  • *
  • Posts: 28
  • Karma: 0
Ok, I finally got it. Here's my finished code, a bit jury-rigged, but works nonetheless, with no errors at all!
Code: Lua
  1. button = vgui.Create( "DButton", window )
  2. button:SetSize( 100, 40 )
  3. button:SetPos( (window:GetWide() - button:GetWide()) / 2, window:GetTall() - button:GetTall() - 10 )
  4. button:SetText( "Wait - " )
  5. button:SetDisabled( true )
  6.  
  7. timersec = 14                                                   --this is how long your motd will stay open, I reccomend
  8.                                                                 --adding about 5 to your desired value to compensate for lag
  9. timer.Create( "countDown", 1, 14, function()                    --change 14 to the same value as timersec
  10.         timersec = timersec - 1
  11.         button:SetText( "Wait - " .. timersec )
  12.         if timersec == 0 then
  13.                 button:SetText( "Close" )
  14.                 button:SetDisabled( false )
  15.                 button.DoClick = function() window:Close() end
  16.         end
  17. end)
  18.  
  19. if timersec == 0 then                                           --all this crap may be useless, I left it in because everything was working
  20.         button:SetText( "Close" )
  21.         button:SetDisabled( false )
  22.         button.DoClick = function() window:Close() end
  23. end

I've attached the final version of my modified motdmenu.lua for anyone who wants to use it, simply drop it in addons/ulx/lua/ulx/modules/cl/ and replace the old one. Setup is exactly the same.

Thanks, i've been needing this too :)

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
We strongly urge you and recommend you create your own addon folder.
Placing content in 'our' addons folder will work, but, if you ever have to update just your code, or remove your code, or remove someone elses code you followed the instructions for placing thier code in our addon folder,  you could end up damaging files from our addon.
To make your own addon, you'd need the following (at least for this code)
Remove addons/ulx/lua/ulx/modules/cl/motdmenu.lua
Copy your code to /addons/YOUR_addon_NAME_custom_motd_whatever/lua/ulx/modules/cl/motdmenu.
Create your own /addons/YOUR_addon_NAME_custom_motd_whatever/addon.txt (search gmod wiki or google to find out how, or base off another addon (but I'd still recommend wiki, some people just make stuff up))

Now, when ULX starts up, it will use your code.
When you update ULX, it won't overwrite your motdmenu.lua, it will just replace the missing one, and you can go remove it again.
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

Offline RalphORama

  • Newbie
  • *
  • Posts: 17
  • Karma: 0
We strongly urge you and recommend you create your own addon folder.
Placing content in 'our' addons folder will work, but, if you ever have to update just your code, or remove your code, or remove someone elses code you followed the instructions for placing thier code in our addon folder,  you could end up damaging files from our addon.
To make your own addon, you'd need the following (at least for this code)
Remove addons/ulx/lua/ulx/modules/cl/motdmenu.lua
Copy your code to /addons/YOUR_addon_NAME_custom_motd_whatever/lua/ulx/modules/cl/motdmenu.
Create your own /addons/YOUR_addon_NAME_custom_motd_whatever/addon.txt (search gmod wiki or google to find out how, or base off another addon (but I'd still recommend wiki, some people just make stuff up))

Now, when ULX starts up, it will use your code.
When you update ULX, it won't overwrite your motdmenu.lua, it will just replace the missing one, and you can go remove it again.
Uh oh.
I'll do that and upload it over the weekend, didn't realize that was an issue!

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

Offline Shalmendo

  • Newbie
  • *
  • Posts: 36
  • Karma: 1
Has the Addon been uploaded anywhere since this thread? I could really use something like this on my own server. Also, thank you for making this!

Offline Decicus

  • Hero Member
  • *****
  • Posts: 552
  • Karma: 81
    • Alex Thomassen
I created an addon out of it, so you can just drag and down the folder from the archive into the server's "addons" folder.
You might have to go into the file itself (just go into each directory until you hit 'motdmenu.lua') to edit how long the timer is. Default is 14. (Just follow the comments in the file to edit them).

Keep in mind you will still have to delete the default motdmenu.lua from ULx inside "addons/ulx/lua/ulx/modules/cl/motdmenu.lua".

All credit goes to RalphORama for the code, I just put it in the right folders and added an "addon.txt".
Contact information:
E-mail: alex@thomassen.xyz.
You can also send a PM.

Offline Shalmendo

  • Newbie
  • *
  • Posts: 36
  • Karma: 1
Would it be possible to modify this code so that the MOTD is only timelocked for specific groups?

On the server I'm administrating we have a 'guest' group which has limited privleges and are forced to use the charple model via URS. I would like to force all guests to view the MOTD for at least 30 seconds, but prevent the close button from being locked for members and others (admins, ops, etc). Unfortunately I'm nowhere near being a coder of any sort so I'm going to have to rely on the generosity and kindness of the community here to get me anywhere close to this kind of goal.

I would greatly appreciate any help that can be provided, even if it's just some advice. Coding isn't really my area unfortunately.

  • Print