diff --git a/lua/includes/modules/schemavalidator.lua b/lua/includes/modules/schemavalidator.lua index 670c499..68804a4 100644 --- a/lua/includes/modules/schemavalidator.lua +++ b/lua/includes/modules/schemavalidator.lua @@ -79,6 +79,7 @@ end ---@class SchemaTypeObject: SchemaType ---@field ValidateField fun(self: SchemaTypeObject, key: any, value: any): (boolean, string) +---@field HasField fun(self: SchemaTypeObject, key: any): boolean ---@field fields { [string]: SchemaType } ---@param tbl { [string]: SchemaType } @@ -90,6 +91,9 @@ function SchemaValidator.Object( tbl ) Optional = function( self ) return SchemaValidator.Optional( self ) end, + HasField = function( self, key ) + return self.fields[key] ~= nil + end, ValidateField = function( self, key, value ) local fieldType = self.fields[key] if not fieldType then diff --git a/lua/mapvote/client/modules/admin_menu.lua b/lua/mapvote/client/modules/admin_menu.lua index 6081cc1..bf1dd0e 100644 --- a/lua/mapvote/client/modules/admin_menu.lua +++ b/lua/mapvote/client/modules/admin_menu.lua @@ -9,20 +9,21 @@ local function updateconfigKey( key ) end local configMenuOptions = { - { "Map Limit", schema.fields.MapLimit, "MapLimit" }, - { "Time Limit", schema.fields.TimeLimit, "TimeLimit" }, - { "Allow Current Map", schema.fields.AllowCurrentMap, "AllowCurrentMap" }, - { "RTV Percent Players Required 0-1", schema.fields.RTVPercentPlayersRequired, "RTVPercentPlayersRequired" }, - { "RTV Wait", schema.fields.RTVWait, "RTVWait" }, - { "Sort Maps", schema.fields.SortMaps, "SortMaps" }, - { "Default Map", schema.fields.DefaultMap, "DefaultMap" }, - { "Enable Cooldown", schema.fields.EnableCooldown, "EnableCooldown" }, - { "Maps Before Revote", schema.fields.MapsBeforeRevote, "MapsBeforeRevote" }, - { "RTV Player Count", schema.fields.RTVPlayerCount, "RTVPlayerCount" }, - { "Minimum Players Before Reset", schema.fields.MinimumPlayersBeforeReset, "MinimumPlayersBeforeReset" }, - { "Time To Reset", schema.fields.TimeToReset, "TimeToReset" }, - { "Map Prefixes", schema.fields.MapPrefixes, "MapPrefixes" }, - { "Player RTV Cooldown", schema.fields.PlyRTVCooldownSeconds, "PlyRTVCooldownSeconds" }, + { seperator = true, text = "Voting" }, + { "The amount of maps in a vote", schema.fields.MapLimit, "MapLimit" }, + { "The length of a vote in seconds", schema.fields.TimeLimit, "TimeLimit" }, + { "Should the current map have a chance to appear in votes", schema.fields.AllowCurrentMap, "AllowCurrentMap" }, + { "Should the maps in a vote be sorted", schema.fields.SortMaps, "SortMaps" }, + { seperator = true, text = "RTV" }, + { "Percentage of players who need to RTV between 0 and 1", schema.fields.RTVPercentPlayersRequired, "RTVPercentPlayersRequired" }, + { "The time RTV is disabled after a map change in seonds", schema.fields.RTVWait, "RTVWait" }, + { "How long should a player wait between RTV commands", schema.fields.PlyRTVCooldownSeconds, "PlyRTVCooldownSeconds" }, + { "Minimum players required to enable RTVing", schema.fields.RTVPlayerCount, "RTVPlayerCount" }, + { seperator = true, text = "Maps" }, + { "Map prefixes automatically enabled, comma seperated list", schema.fields.MapPrefixes, "MapPrefixes" }, + { "Use map prefixes from gamemode.txt", schema.fields.UseGamemodeMapPrefixes, "UseGamemodeMapPrefixes" }, + { "Disable a map after its played", schema.fields.EnableCooldown, "EnableCooldown" }, + { "The amount of maps that need to be played before a map is enabled again", schema.fields.MapsBeforeRevote, "MapsBeforeRevote" }, } MapVote._mapconfigFrame = nil @@ -34,7 +35,7 @@ function MapVote.openconfig() return end local frame = vgui.Create( "MapVote_Frame" ) --[[@as DFrame]] - frame:SetSize( 800, 600 ) + frame:SetSize( 1000, ScrH() * 0.9 ) frame:Center() frame:MakePopup() frame:SetTitle( "MapVote Config" ) @@ -43,6 +44,7 @@ function MapVote.openconfig() local configMenu = vgui.Create( "MapVote_ConfigPanel", frame ) --[[@as ConfigPanel]] configMenu:SetSize( 800, 600 ) configMenu:Dock( FILL ) + configMenu:DockMargin( 10, 10, 10, 10 ) ---@diagnostic disable-next-line: duplicate-set-field frame.OnClose = function( _ ) @@ -55,7 +57,9 @@ function MapVote.openconfig() MapVote.Net.sendConfigRequest( function() configMenu:Clear() for _, option in pairs( configMenuOptions ) do - if IsValid( configMenu ) and configMenu.AddConfigItem then + if option.seperator then + configMenu:AddSeperator( option.text ) + elseif IsValid( configMenu ) and configMenu.AddConfigItem then configMenu:AddConfigItem( option[1], option[2], updateconfigKey( option[3] ), MapVote.config[option[3]] ) end end @@ -110,7 +114,7 @@ function MapVote.addMapRow( map ) local row = vgui.Create( "Panel" ) --[[@as Panel]] row:SetSize( 800, 128 ) - local mapIcon = vgui.Create( "MapVote_MapIcon", row ) --[[@as MapIcon]] + local mapIcon = vgui.Create( "MapVote_MapIcon", row ) mapIcon:SetSize( 128, 128 ) mapIcon:SetMap( map ) mapIcon:Dock( LEFT ) diff --git a/lua/mapvote/client/modules/net.lua b/lua/mapvote/client/modules/net.lua index fb958e8..68a3721 100644 --- a/lua/mapvote/client/modules/net.lua +++ b/lua/mapvote/client/modules/net.lua @@ -51,8 +51,11 @@ net.Receive( "MapVote_VoteCancelled", function() end ) net.Receive( "RTV_Delay", function() - chat.AddText( Color( 102, 255, 51 ), "[RTV]", Color( 255, 255, 255 ), - " The vote has been rocked, map vote will begin on round end" ) + -- this timer makes sure the message shows up after the RTV message + timer.Simple( 0.2, function() + chat.AddText( Color( 102, 255, 51 ), "[RTV]", Color( 255, 255, 255 ), + " The vote has been rocked, map vote will begin on round end" ) + end ) end ) diff --git a/lua/mapvote/client/vgui/config_panel.lua b/lua/mapvote/client/vgui/config_panel.lua index 740cfed..1d172c7 100644 --- a/lua/mapvote/client/vgui/config_panel.lua +++ b/lua/mapvote/client/vgui/config_panel.lua @@ -2,6 +2,7 @@ local PANEL = {} function PANEL:Init() + self.largestLabelWidth = 0 end function PANEL:Paint( w, h ) @@ -21,13 +22,39 @@ function PANEL:configRow( displayName ) optionPanel:Dock( TOP ) local label = vgui.Create( "DLabel", optionPanel ) --[[@as DLabel]] - label:SetText( displayName .. ": " ) + label:SetText( displayName ) label:Dock( LEFT ) - label:SetSize( 200, 35 ) - label:SetFont( MapVote.style.configLabelFont ) + label:SetFont( "MapVote_ConfigItem" ) + label:SizeToContents() + self.largestLabelWidth = math.max( self.largestLabelWidth, label:GetWide() ) + optionPanel.label = label return optionPanel end +function PANEL:PerformLayout() + for _, child in pairs( self:GetCanvas():GetChildren() ) do + if child.label then + child.label:SetWide( self.largestLabelWidth + 50 ) + end + end +end + +surface.CreateFont( "MapVote_ConfigItem", { + font = "Arial", + size = 20, + weight = 600, + antialias = true, + shadow = false +} ) + +function PANEL:AddSeperator( text ) + local seperator = vgui.Create( "MapVote_Seperator", self ) + seperator:SetText( text ) + seperator:Dock( TOP ) + seperator:DockMargin( 5, 15, 5, 5 ) + self:AddItem( seperator ) +end + ---@param displayName string ---@param itemType SchemaType function PANEL:AddConfigItem( displayName, itemType, action, startingValue ) @@ -58,9 +85,11 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue ) end end elseif itemType.name == "bool" then - entryPanel = vgui.Create( "DCheckBox", optionPanel ) --[[@as DCheckBox]] - entryPanel:SetSize( 25, 25 ) - entryPanel:SetValue( startingValue or false ) + entryPanel = vgui.Create( "MapVote_Switch", optionPanel ) + entryPanel:SetOn( startingValue or false ) + entryPanel.ColorOff = MapVote.style.colorSecondaryFG + entryPanel.ColorOn = MapVote.style.colorGreen + entryPanel.ColorSwitch = MapVote.style.colorPrimaryBG ---@diagnostic disable-next-line: duplicate-set-field entryPanel.OnChange = function( _, val ) local ok, err = itemType:Validate( val ) @@ -89,7 +118,7 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue ) entryPanel:SetSize( 100, 25 ) elseif itemType.name == "string" then entryPanel = vgui.Create( "MapVote_TextEntry", optionPanel ) --[[@as DTextEntry]] - entryPanel:SetSize( 100, 25 ) + entryPanel:SetSize( 300, 25 ) entryPanel:SetValue( startingValue or "" ) ---@diagnostic disable-next-line: duplicate-set-field @@ -108,7 +137,22 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue ) entryPanel = vgui.Create( "MapVote_TextEntry", optionPanel ) --[[@as DTextEntry]] entryPanel:SetSize( 100, 25 ) entryPanel:SetValue( startingValue or "" ) - entryPanel:SetEnabled( false ) + entryPanel:SetEnabled( true ) + entryPanel.OnValueChanged = function( _, val ) + val = string.Split( val, "," ) + for i = #val, 1, -1 do + val[i] = string.Trim( val[i] ) + if val[i] == "" then + table.remove( val, i ) + end + end + local ok, err = itemType:Validate( val ) + errLabel:SetText( err or "" ) + errLabel:Dock( LEFT ) + if ok then + action( val ) + end + end else error( "Unknown type " .. itemType.name ) end diff --git a/lua/mapvote/client/vgui/frame.lua b/lua/mapvote/client/vgui/frame.lua index 90ea719..eae6d5d 100644 --- a/lua/mapvote/client/vgui/frame.lua +++ b/lua/mapvote/client/vgui/frame.lua @@ -1,33 +1,6 @@ ---@class MapVote_Frame : DFrame local PANEL = {} -local function disableColor( c ) - return Color( c.r / 2, c.g / 2, c.b / 2 ) -end - -local function drawCircle( x, y, radius, seg ) - draw.NoTexture() - local cir = {} - - table.insert( cir, { x = x, y = y, u = 0.5, v = 0.5 } ) - for i = 0, seg do - local a = math.rad( (i / seg) * -360 ) - table.insert( cir, - { - x = x + math.sin( a ) * radius, - y = y + math.cos( a ) * radius, - } ) - end - - local a = math.rad( 0 ) -- This is needed for non absolute segment counts - table.insert( cir, - { - x = x + math.sin( a ) * radius, - y = y + math.cos( a ) * radius, - } ) - - surface.DrawPoly( cir ) -end function surface.DrawTexturedRectRotatedPoint( x, y, w, h, rot, x0, y0 ) local c = math.cos( math.rad( rot ) ) local s = math.sin( math.rad( rot ) ) @@ -42,6 +15,14 @@ function PANEL:SetHideOnClose( hide ) self.hideOnClose = hide end +surface.CreateFont( "MapVote_CloseButton", { + font = "Marlett", + size = 20, + weight = 1, + extended = true, + symbol = true +} ) + function PANEL:Init() local blur = MapVote.style.frameBlur or 0 if blur > 0 then @@ -50,32 +31,27 @@ function PANEL:Init() self.blurMat:Recompute() end - local circleSegments = 30 self.btnClose:SetSize( 25, 25 ) ---@diagnostic disable-next-line: duplicate-set-field - self.btnClose.Paint = function( _, w, h ) - local r = (w - 13) / 2 - surface.SetDrawColor( MapVote.style.colorCloseButton ) - drawCircle( w / 2, h / 2 + 2, r, circleSegments ) - surface.SetDrawColor( MapVote.style.colorTextPrimary ) - surface.DrawTexturedRectRotatedPoint( w / 2, h / 2 + 2, r * 1.5, 2, 45, 0, 0 ) - surface.DrawTexturedRectRotatedPoint( w / 2, h / 2 + 2, r * 1.5, 2, 315, 0, 0 ) + self.btnClose.Paint = function( selfClose, w, h ) + if selfClose.Hovered then + draw.RoundedBox( 0, 0, 0, w, h, MapVote.style.colorCloseButton ) + end + surface.SetTextColor( Color( 255, 255, 255, 200 ) ) + surface.SetFont( "MapVote_CloseButton" ) + local tw, th = surface.GetTextSize( "r" ) + surface.SetTextPos( w / 2 - tw / 2, h / 2 - th / 2 ) + surface.DrawText( "r" ) end self.btnMaxim:SetSize( 25, 25 ) ---@diagnostic disable-next-line: duplicate-set-field - self.btnMaxim.Paint = function( _, w, h ) - local r = (w - 13) / 2 - surface.SetDrawColor( disableColor( MapVote.style.colorGreen ) ) - drawCircle( w / 2, h / 2 + 2, r, circleSegments ) + self.btnMaxim.Paint = function() end self.btnMinim:SetSize( 25, 25 ) ---@diagnostic disable-next-line: duplicate-set-field - self.btnMinim.Paint = function( _, w, h ) - local r = (w - 13) / 2 - surface.SetDrawColor( disableColor( MapVote.style.colorYellow ) ) - drawCircle( w / 2, h / 2 + 2, r, circleSegments ) + self.btnMinim.Paint = function() end self.btnClose.DoClick = function() if self.hideOnClose then @@ -104,7 +80,7 @@ function PANEL:ApplyBlur() render.UpdateScreenEffectTexture() local x, y = self:LocalToScreen( 0, 0 ) - surface.DrawTexturedRect( -x, -y, ScrW(), ScrH()) + surface.DrawTexturedRect( -x, -y, ScrW(), ScrH() ) end local basePanel = baseclass.Get( "Panel" ) diff --git a/lua/mapvote/client/vgui/map_icon.lua b/lua/mapvote/client/vgui/map_icon.lua index 72bbea6..991e8ec 100644 --- a/lua/mapvote/client/vgui/map_icon.lua +++ b/lua/mapvote/client/vgui/map_icon.lua @@ -4,14 +4,23 @@ local PANEL = {} function PANEL:Init() self.button = vgui.Create( "DImageButton", self ) --[[@as DImageButton]] self.button:Dock( FILL ) - self.button:DockMargin( 2, 2, 2, 0 ) + self.button:DockMargin( 1, 1, 1, 0 ) self.button.DoClick = function() self:DoClick() end - self.label = vgui.Create( "DLabel", self ) --[[@as DLabel]] - self.label:Dock( BOTTOM ) - self.label:SetContentAlignment( 5 ) + self.infoRow = vgui.Create( "Panel", self.button ) --[[@as DPanel]] + self.infoRow:Dock( BOTTOM ) + self.infoRow:SetTall( 20 ) + self.infoRow.Paint = function( _, w, h ) + surface.SetDrawColor( Color( MapVote.style.colorSecondaryFG.r, MapVote.style.colorSecondaryFG.g, MapVote.style.colorSecondaryFG.b, 230 ) ) + surface.DrawRect( 0, 0, w, h ) + end + + self.label = vgui.Create( "DLabel", self.infoRow ) --[[@as DLabel]] + self.label:Dock( LEFT ) + self.label:DockMargin( 5, 0, 0, 0 ) + self.label:SetContentAlignment( 4 ) self.label:SetFont( "DermaDefaultBold" ) end @@ -26,6 +35,8 @@ end function PANEL:SetMap( map ) self.label:SetText( map ) + self.label:SizeToContents() + self.label:SetWide( math.min( self.label:GetWide(), self:GetWide() - 5 ) ) MapVote.ThumbDownloader:QueueDownload( map, function( filepath ) MapVote.TaskManager.AddFunc( function() diff --git a/lua/mapvote/client/vgui/mapvote_panel.lua b/lua/mapvote/client/vgui/mapvote_panel.lua index 1f5dbe7..96967cd 100644 --- a/lua/mapvote/client/vgui/mapvote_panel.lua +++ b/lua/mapvote/client/vgui/mapvote_panel.lua @@ -31,9 +31,11 @@ function PANEL:PerformLayout() -- This is expensive, but must be done so avatar positions dont get misaligned when parent panel is being minimized and resized for _, map in ipairs( self.maps ) do for i, voter in ipairs( map.voters ) do - local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( map, i ) - voter:SetPos( newX, newY ) - voter:SetVisible( not willOverflow ) + if not voter.inAnimation then + local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( map, i ) + voter:SetPos( newX, newY ) + voter:SetVisible( not willOverflow ) + end end end end @@ -83,8 +85,10 @@ function PANEL:SetVote( identifier, mapIndex ) local voter = oldMapData.voters[i] local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( oldMapData, i ) voter:SetVisible( true ) - voter:MoveTo( newX, newY, 0.2, nil, nil, function( _, pnl ) + voter.inAnimation = true + voter:MoveTo( newX, newY, 0.3, nil, 1, function( _, pnl ) pnl:SetVisible( not willOverflow ) + pnl.inAnimation = false end ) end @@ -103,10 +107,10 @@ function PANEL:SetVote( identifier, mapIndex ) local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( mapData ) panel:SetVisible( true ) - panel:MoveTo( newX, newY, 0.2, nil, nil, function() - if willOverflow then - panel:SetVisible( not willOverflow ) - end + panel.inAnimation = true + panel:MoveTo( newX, newY, 0.3, nil, 1, function( _, pnl ) + pnl:SetVisible( not willOverflow ) + pnl.inAnimation = false end ) end diff --git a/lua/mapvote/client/vgui/seperator.lua b/lua/mapvote/client/vgui/seperator.lua new file mode 100644 index 0000000..e4d8c80 --- /dev/null +++ b/lua/mapvote/client/vgui/seperator.lua @@ -0,0 +1,49 @@ +---@class MapVote_Seperator : DPanel +local PANEL = {} + +surface.CreateFont( "MapVote_Seperator", { + font = "Arial", + size = 30, + weight = 600, + antialias = true, + shadow = false +} ) + +function PANEL:Init() + self:SetTall( 1 ) + self.text = "" + self.title = nil + self.divider = vgui.Create( "DPanel", self ) + self.divider:SetTall( 1 ) + self.divider.Paint = function( _, w, h ) + draw.RoundedBox( 0, 0, 0, w, h, Color( 255, 255, 255, 255 ) ) + end + self.divider:DockMargin( 0, 1, 0, 0 ) + self.divider:Dock( BOTTOM ) + self:SetTall( 40 ) +end + +function PANEL:SetText( text ) + if text == nil and self.title then + self.title:Remove() + self.title = nil + return + elseif text == nil then + return + end + + if self.title then + self.title:SetText( text ) + else + self.title = vgui.Create( "DLabel", self ) + self.title:SetText( text ) + self.title:SetFont( "MapVote_Seperator" ) + self.title:Dock( TOP ) + self.title:SizeToContents() + end + + self:InvalidateLayout( true ) + self:SizeToChildren( false, true ) +end + +vgui.Register( "MapVote_Seperator", PANEL, "Panel" ) diff --git a/lua/mapvote/client/vgui/switch.lua b/lua/mapvote/client/vgui/switch.lua new file mode 100644 index 0000000..b793033 --- /dev/null +++ b/lua/mapvote/client/vgui/switch.lua @@ -0,0 +1,54 @@ +---@class MapVote_Switch : DButton +local PANEL = {} + +function PANEL:Init() + self:SetSize( 40, 22 ) + self:SetText( "" ) + self.On = false + self.LastClicked = 0 + self.ColorOff = Color( 50, 50, 50 ) + self.ColorOn = Color( 250, 250, 250 ) + self.ColorSwitch = Color( 5, 5, 5 ) +end + +function PANEL:Toggle() + self.On = not self.On + self:OnChange( self.On ) +end + +function PANEL:GetOn() + return self.On +end + +function PANEL:SetOn( on ) + self.On = on + self:OnChange( self.On ) +end + +function PANEL:OnChange( _on ) +end + +function PANEL:Paint( w, h ) + if self.On then + draw.RoundedBox( 180, 0, 0, w, h, self.ColorOn ) + else + draw.RoundedBox( 180, 0, 0, w, h, self.ColorOff ) + end + + local timeSince = SysTime() - self.LastClicked + local fraction = math.min( timeSince / 0.2, 1 ) + if self.On then + local x = Lerp( fraction, 0, w - h ) + draw.RoundedBox( 180, x + 2, 2, h - 4, h - 4, self.ColorSwitch ) + else + local x = Lerp( fraction, w - h, 0 ) + draw.RoundedBox( 180, x + 2, 2, h - 4, h - 4, self.ColorSwitch ) + end +end + +function PANEL:DoClick() + self:Toggle() + self.LastClicked = SysTime() +end + +vgui.Register( "MapVote_Switch", PANEL, "DButton" ) diff --git a/lua/mapvote/server/modules/config.lua b/lua/mapvote/server/modules/config.lua index d9be50d..62ef262 100644 --- a/lua/mapvote/server/modules/config.lua +++ b/lua/mapvote/server/modules/config.lua @@ -6,13 +6,17 @@ end function MapVote.MergeConfig( conf ) for k, v in pairs( conf ) do + local hasField = MapVote.configSchema:HasField( k ) local valid, reason = MapVote.configSchema:ValidateField( k, v ) - if not valid then + if not hasField then + print( "MapVote MergeConfig config has extra field: " .. k ) + elseif not valid then MapVote.configIssues = {} print( "MapVote MergeConfig config is invalid: " .. reason ) return reason + else + MapVote.config[k] = v end - MapVote.config[k] = v end end diff --git a/lua/mapvote/server/modules/map_reset.lua b/lua/mapvote/server/modules/map_reset.lua index 7ebcba6..8b13789 100644 --- a/lua/mapvote/server/modules/map_reset.lua +++ b/lua/mapvote/server/modules/map_reset.lua @@ -1,22 +1 @@ -local resetMapTimerName = "MapVote_ResetMap" - -local function checkMapReset() - local count = MapVote.RTV.GetPlayerCount() - local conf = MapVote.GetConfig() - - if count < conf.MinimumPlayersBeforeReset then - local map = conf.DefaultMap - timer.Create( resetMapTimerName, 5 * 60, 1, function() - RunConsoleCommand( "changelevel", map ) - end ) - else - timer.Remove( resetMapTimerName ) - end -end - -hook.Add( "MapVote_Loaded", "MapVote_StartReset", function() - local conf = MapVote.GetConfig() - if conf.MinimumPlayersBeforeReset <= 0 then return end - timer.Create( "MapVote_CheckResetMap", 60, 0, checkMapReset ) -end ) diff --git a/lua/mapvote/server/modules/map_vote.lua b/lua/mapvote/server/modules/map_vote.lua index bda9ca2..24c85bb 100644 --- a/lua/mapvote/server/modules/map_vote.lua +++ b/lua/mapvote/server/modules/map_vote.lua @@ -1,6 +1,6 @@ function MapVote.isMapAllowed( m ) local conf = MapVote.config - local prefixes = conf.MapPrefixes or MapVote.gamemodeMapPrefixes or {} + local hookResult = hook.Run( "MapVote_IsMapAllowed", m ) if hookResult ~= nil then return hookResult end @@ -9,9 +9,19 @@ function MapVote.isMapAllowed( m ) if conf.ExcludedMaps[m] then return false end -- dont allow excluded maps in vote if conf.IncludedMaps[m] then return true end -- skip prefix check if map is in included maps - for _, v in pairs( prefixes ) do - if string.find( m, "^" .. v ) then - return true + if conf.MapPrefixes then + for _, v in pairs( conf.MapPrefixes ) do + if string.find( m, "^" .. v ) then + return true + end + end + end + + if conf.UseGamemodeMapPrefixes and MapVote.gamemodeMapPrefixes then + for _, v in pairs( MapVote.gamemodeMapPrefixes ) do + if string.find( m, "^" .. v ) then + return true + end end end return false diff --git a/lua/mapvote/server/modules/net.lua b/lua/mapvote/server/modules/net.lua index f82e723..47c984d 100644 --- a/lua/mapvote/server/modules/net.lua +++ b/lua/mapvote/server/modules/net.lua @@ -76,6 +76,14 @@ MapVote.Net.receiveWithMiddleware( "MapVote_RequestVoteState", function( _, ply end ) end, MapVote.Net.rateLimit( "MapVote_RequestVoteState", 2, 0.1 ) ) +MapVote.Net.receiveWithMiddleware( "MapVote_RequestWorkshopIDTable", function( _, ply ) + local requestedMaps = net.ReadTable() + local addonWorkshopIDs = MapVote.getWorkshopIDs( requestedMaps ) + net.Start( "MapVote_WorkshopIDTable" ) + net.WriteTable( addonWorkshopIDs ) + net.Send( ply ) +end, MapVote.Net.rateLimit( "MapVote_RequestWorkshopIDTable", 5, 0.5 ) ) + -- to client function MapVote.Net.sendVoteStart( endTime, mapsInVote, ply ) diff --git a/lua/mapvote/server/modules/thumb.lua b/lua/mapvote/server/modules/thumb.lua index 1431e1c..2197540 100644 --- a/lua/mapvote/server/modules/thumb.lua +++ b/lua/mapvote/server/modules/thumb.lua @@ -5,25 +5,23 @@ function MapVote.getAllWorkshopIDs() local addonWorkshopIDs = {} for _, addon in ipairs( engine.GetAddons() ) do local files = file.Find( "maps/*.bsp", addon.title ) - for _, f in ipairs(files) do + for _, f in ipairs( files ) do addonWorkshopIDs[string.Replace( f, ".bsp", "" )] = addon.wsid end end MapVote.addonWorkshopIDs = addonWorkshopIDs end -net.Receive( "MapVote_RequestWorkshopIDTable", function( _, ply ) - local requestedMaps = net.ReadTable() +function MapVote.getWorkshopIDs( maps ) local addonWorkshopIDs = {} - for _, map in ipairs( requestedMaps ) do + for _, map in ipairs( maps ) do if MapVote.addonWorkshopIDs[map] then addonWorkshopIDs[map] = MapVote.addonWorkshopIDs[map] else print( "MapVote: No workshop ID found for map", map ) end end - net.Start( "MapVote_WorkshopIDTable" ) - net.WriteTable( addonWorkshopIDs ) - net.Send( ply ) -end ) + return addonWorkshopIDs +end + hook.Add( "Initialize", "MapVote_GetWorkshopIDs", MapVote.getAllWorkshopIDs ) diff --git a/lua/mapvote/shared/modules/config_schema.lua b/lua/mapvote/shared/modules/config_schema.lua index d2f7d03..31453d3 100644 --- a/lua/mapvote/shared/modules/config_schema.lua +++ b/lua/mapvote/shared/modules/config_schema.lua @@ -8,15 +8,13 @@ local schema = SV.Object { RTVPercentPlayersRequired = SV.Number { min = 0, max = 1 }, RTVWait = SV.Number(), SortMaps = SV.Bool(), - DefaultMap = SV.String(), + UseGamemodeMapPrefixes = SV.Bool():Optional(), MapPrefixes = SV.List( SV.String() ):Optional(), EnableCooldown = SV.Bool(), MapsBeforeRevote = SV.Int { min = 1 }, RTVPlayerCount = SV.Int { min = 1 }, ExcludedMaps = SV.Map( SV.String(), SV.Bool() ), IncludedMaps = SV.Map( SV.String(), SV.Bool() ), - MinimumPlayersBeforeReset = SV.Int {}, - TimeToReset = SV.Int { min = 1 }, PlyRTVCooldownSeconds = SV.Int { min = 1 }, MapIconURLs = SV.Map( SV.String(), SV.String() ):Optional(), } @@ -29,11 +27,10 @@ local default = { EnableCooldown = true, MapsBeforeRevote = 3, RTVPlayerCount = 3, + UseGamemodeMapPrefixes = true, + MapPrefixes = {}, IncludedMaps = {}, ExcludedMaps = {}, - MinimumPlayersBeforeReset = -1, - TimeToReset = 5 * 60, - DefaultMap = "gm_construct", RTVPercentPlayersRequired = 0.66, SortMaps = false, PlyRTVCooldownSeconds = 120,