diff options
Diffstat (limited to 'lib/MasterWebInterface/Util')
| -rwxr-xr-x | lib/MasterWebInterface/Util/AdvancedFilterBox.pm | 207 | ||||
| -rwxr-xr-x | lib/MasterWebInterface/Util/BrowseHTML.pm | 44 | ||||
| -rwxr-xr-x | lib/MasterWebInterface/Util/FilterBox.pm | 43 | ||||
| -rwxr-xr-x | lib/MasterWebInterface/Util/Layout.pm | 77 |
4 files changed, 256 insertions, 115 deletions
diff --git a/lib/MasterWebInterface/Util/AdvancedFilterBox.pm b/lib/MasterWebInterface/Util/AdvancedFilterBox.pm new file mode 100755 index 0000000..a496a04 --- /dev/null +++ b/lib/MasterWebInterface/Util/AdvancedFilterBox.pm @@ -0,0 +1,207 @@ +package MasterWebInterface::Util::AdvancedFilterBox; +use strict; +use warnings; +use utf8; +use TUWF ':html', 'xml_escape'; +use Geography::Countries; +use Exporter 'import'; +our @EXPORT = qw| htmlAdvancedFilterBox |; +use Data::Dumper 'Dumper'; + +# display an advanced filter box with dropdown/search fields +# options: +# sel: select [g]ames or [s]ervers link (filter only works for servers anyway) +# dropdown selects: gamename, gametype, country +# text fields: hostname, mapname/maptitle +# user must first select a gamename before other options become available. +# gametype and country options are selected from database on available criteria. +# TODO: also list servers that expired or timed out (checkbox?) +# TODO: allow searching by IP, in combination with expired servers (and sanity check in javascript?) +sub htmlAdvancedFilterBox +{ + my($self, %opt) = @_; + + div class => 'mainbox'; + div class => "header"; + h1 "Advanced Filter"; + p class => "alttitle"; + txt "Filter for servers in all titles that are currently online. "; + txt "Advanced Filter is in Beta. Please report bugs on our "; + a href => "https://333networks.com/contact", "discord"; + txt "."; + end; + end; + + # advanced filter form + form action => "/adv", 'accept-charset' => 'UTF-8', method => 'get', class => "advancedfilter"; + fieldset class => 'advanced'; + a href => '/g', $opt{sel} eq 'g' ? (class => 'sel') : (), 'Games'; + a href => '/s', $opt{sel} eq 's' ? (class => 'sel') : (), 'Servers'; + + # parameters for error fields; + my $gameselect = "this game"; + + # table with all filter options + table; + + Tr; # gamename + td class => "desc", "Game: "; + td class => "param"; + Select onchange => "this.form.submit()", name => "gamename", id => "gamename"; + option class => "selection", value => "", "Select..."; + option value => $_->{gamename}, ($_->{gamename} eq $opt{gamename} ? (selected => ($gameselect = $_->{label})) : () ), + $_->{label} for $self->dbGameListGet(sort => "gamename" )->@*; + end; #select + end; + end; + + Tr; # gametype + td class => "desc", "Gametype: "; + td class => "param"; + # don't list gametypes until a gamename has been selected + if ( ! $opt{gamename} ) + { + Select onchange => "this.form.submit()", name => "gametype", id => "gametype", disabled => "true"; + + # if a gametype is still provided + if ( $opt{gametype} ) + { + option value => $opt{gametype}, disabled => 1, selected => 1, $opt{gametype}; + } + else + { + option class => "selection", value => "", "Select a game title first"; + } + end; # select + } + else + { + Select onchange => "this.form.submit()", name => "gametype", id => "gametype"; + option value => "", "All game types"; + my $valid_gt = 0; + my %seen = (); + for ($self->dbGetGameTypes(%opt)->@*) + { + # if not yet seen, add option and mark "seen" + if (! $seen{lc $_->{gametype}} ) + { + option value => $_->{gametype}, (lc $_->{gametype} eq lc $opt{gametype} ? (selected => ($valid_gt = 1)) : () ), $_->{gametype} ; + $seen{lc $_->{gametype}} = 1; + } + } + + # display incorrect values with grayed-out option + if (not $valid_gt and $opt{gametype}) + { + option value => $opt{gametype}, disabled => 1, selected => 1, $opt{gametype}; + } + + end; # select + + # notify user of incorrect option + if (not $valid_gt and $opt{gametype}) + { + br; + span class => "errorsel", "The gametype \"$opt{gametype}\" does not exist for $gameselect. Please select a valid gametype."; + } + } + end; + end; + + Tr; # hostname + td class => "desc", "Servername: "; + td class => "param"; + input type => 'text', name => 'hostname', id => 'hostname', class => 'text', value => $opt{hostname} // ""; + end; + end; + + + Tr; # mapname + td class => "desc", "Active map: "; + td class => "param"; + input type => 'text', name => 'mapname', id => 'mapname', class => 'text', value => $opt{mapname} // ""; + end; + end; + + Tr; # location / country + td class => "desc", "Country: "; + td class => "param"; + # don't list gametypes until a gamename has been selected + if ( ! $opt{gamename} ) + { + Select onchange => "this.form.submit()", name => "country", id => "country", disabled => "true"; + + # if a country is still provided + if ( $opt{country} ) + { + option value => $opt{country}, disabled => 1, selected => 1, "($opt{country}) ".(my $c = country $opt{country}); + } + else + { + option class => "selection", value => "", "Select a game title first"; + } + end; # select + } + else + { + Select onchange => "this.form.submit()", name => "country", id => "country"; + option class => "selection", value => "", "Everywhere"; + my $valid_c = 0; + option value => $_, ($_ eq $opt{country} ? (selected => ($valid_c = 1)) : () ), + "($_) ".(my $c = country $_) for map $_->{country}, $self->dbGetCountries(%opt)->@*; + + # display incorrect values with grayed-out option + if (not $valid_c and $opt{country}) + { + option value => $opt{country}, disabled => 1, selected => 1, "($opt{country}) ".(my $c = country $opt{country}); + }; + end; # select + + # notify user of incorrect option + if (not $valid_c and $opt{country}) + { + br; + span class => "errorsel"; + txt "No servers in "; + txt (my $c = country $opt{country}); + txt " found that meet the search criteria."; + end; + } + } + end; + end; + + Tr; # submit + td ""; + td; + input type => 'submit', class => 'submit', value => 'Filter'; + end; + end; + end; # table + + end 'fieldset'; + end; # form + + # debugging box + if ( 0 ) + { + h2 "Debug information"; + div class => "codeblock"; + pre; + txt Dumper \%opt; + end; + end; + } + + # return to simple filter/layout + div class => "simpleadvanced"; + a href => $opt{gamename} ? "/s/$opt{gamename}" : "/s"; + txt "simple filter "; + lit "\x{25B4}"; + end; + end; + + end 'div'; +} + +1; diff --git a/lib/MasterWebInterface/Util/BrowseHTML.pm b/lib/MasterWebInterface/Util/BrowseHTML.pm index 0be45dd..d1c8030 100755 --- a/lib/MasterWebInterface/Util/BrowseHTML.pm +++ b/lib/MasterWebInterface/Util/BrowseHTML.pm @@ -5,49 +5,7 @@ use utf8; use TUWF ':html', 'xml_escape'; use Exporter 'import'; use POSIX 'ceil'; -our @EXPORT = qw| htmlSearchBox htmlBrowse htmlBrowseNavigate |; - -# generates a search box, arguments: -# title => games/ (game) servers -# action => form action -# sel => g or s selected -# fq => form query string -sub htmlSearchBox -{ - my($self, %opt) = @_; - - div class => 'mainbox'; - div class => "header"; - h1 "Browse $opt{title}"; - p class => "alttitle", "An overview of games titles and servers that are currently online."; - end; - - # search box - form action => $opt{action}, 'accept-charset' => 'UTF-8', method => 'get'; - fieldset class => 'search'; - a href => '/g', $opt{sel} eq 'g' ? (class => 'sel') : (), 'Games'; - a href => '/s', $opt{sel} eq 's' ? (class => 'sel') : (), 'Servers'; - input type => 'text', name => 'q', id => 'q', class => 'text', - value => $opt{fq} || 'search...'; - input type => 'submit', class => 'submit', value => 'submit'; - end 'fieldset'; - - div class => "dropdown"; - a href => "#", onclick => "toggleAdvanced()"; - txt "advanced search "; - lit "\x{25BE}"; - end; - end; - - fieldset id => 'advancedsearch'; - #input type => 'text', name => 'aq', class => 'text', value => ''; - #input type => 'submit', class => 'submit', value => 'submit'; - txt "Patience, young one. With time, advanced search options will become available to you."; - end; - end; - - end 'div'; # mainbox -} +our @EXPORT = qw| htmlBrowse htmlBrowseNavigate |; # generates a browse box, arguments: # items => arrayref with the list items diff --git a/lib/MasterWebInterface/Util/FilterBox.pm b/lib/MasterWebInterface/Util/FilterBox.pm new file mode 100755 index 0000000..8db7a60 --- /dev/null +++ b/lib/MasterWebInterface/Util/FilterBox.pm @@ -0,0 +1,43 @@ +package MasterWebInterface::Util::FilterBox; +use strict; +use warnings; +use utf8; +use TUWF ':html', 'xml_escape'; +use Exporter 'import'; +our @EXPORT = qw| htmlFilterBox |; + +# generates a filter box, arguments: +# title => games/ (game) servers +# action => form action +# sel => g or s selected +# fq => form query string +sub htmlFilterBox +{ + my($self, %opt) = @_; + + div class => 'mainbox'; + div class => "header"; + h1 "Browse Servers"; + p class => "alttitle", "An overview of games titles and servers that are currently online."; + end; + + # filter box + form action => $opt{gamename} ? "/s/$opt{gamename}" : "/s", 'accept-charset' => 'UTF-8', method => 'get'; + fieldset class => 'simple'; + a href => '/g', $opt{sel} eq 'g' ? (class => 'sel') : (), 'Games'; + a href => '/s', $opt{sel} eq 's' ? (class => 'sel') : (), 'Servers'; + input type => 'text', name => 'q', id => 'q', class => 'text', value => $opt{fq} || 'filter...'; + input type => 'submit', class => 'submit', value => 'submit'; + end 'fieldset'; + end; # form + + div class => "simpleadvanced"; + a href => $opt{gamename} ? "/adv/$opt{gamename}" : "/adv"; + txt "advanced server filter "; + lit "\x{25BE}"; + end; + end; + end 'div'; # mainbox +} + +1; diff --git a/lib/MasterWebInterface/Util/Layout.pm b/lib/MasterWebInterface/Util/Layout.pm index d9f5516..fe7b5c5 100755 --- a/lib/MasterWebInterface/Util/Layout.pm +++ b/lib/MasterWebInterface/Util/Layout.pm @@ -13,34 +13,11 @@ sub htmlHeader { my($self, %o) = @_; - # CSS override: allow passing of style from GET --> ?style=classic - my $style = $self->{style}; - - if ( $self->{rotate_styles} ) - { - # rotate styles for different occasions. - my @dt = localtime(time); - # specify dates [m/d] = styles - if ($dt[4] == 2 && $dt[3] == 31) {$style = "april";} # 31 mar and 1 apr - if ($dt[4] == 3 && $dt[3] == 1) {$style = "april";} - if ($dt[4] == 9 && $dt[3] >= 1) {$style = "halloween";} - if ($dt[4] == 11 && $dt[3] >= 7) {$style = "xmas";} - } - - if (my $overrideStyle = $self->reqParam("style") ) - { - # default to custom style if specified option doesn't exist - $style = $overrideStyle; - } - - # default to default style if specified option does not exist - $style = ( -e "$self->{root}/s/style/$style" ) ? $style : $self->{style}; - html lang => "en"; head; title "$o{title} :: $self->{site_name} masterserver"; Link type => 'image/x-icon', rel => 'shortcut icon', href => "/favicon.ico"; - Link type => "text/css", rel => 'stylesheet', href => "/style/$style/style.css", media => "all"; + Link type => "text/css", rel => 'stylesheet', href => "/style/$self->{style}/style.css", media => "all"; if ( $o{noindex} ) { meta name => 'robots', content => 'noindex,nofollow,nosnippet,noodp,noarchive,noimageindex';end; @@ -48,57 +25,11 @@ sub htmlHeader end 'head'; body; - - my $topbar = $self->reqParam("topbar"); - if ($topbar && lc $topbar eq "true" ) - { - # games, servers, search bar - div class => 'nav'; - # search box - form action => "/g", 'accept-charset' => 'UTF-8', method => 'get'; - fieldset class => 'search'; - p id => 'searchtabs'; - a href => '/g', class => 'sel', 'Games'; - a href => '/s', 'Servers'; - input type => 'text', name => 'q', id => 'q', class => 'text', value => ''; - input type => 'submit', class => 'submit', value => '', style => "display:none"; - end; - a style => "font-size:x-small", href => "#", "advanced search"; - end 'fieldset'; - end; - end; - } - div id => "body"; # start the page content with a header logo box div class => "titlebox"; end; - - my $overrideStyle = $self->reqParam("style"); - if ($overrideStyle or $self->{style_box}) { - # debug feature: force list of styles on floaty-box - div class => "mainbox", - style => "position:absolute; left: 20px; top: 20px; width:200px"; - - div class => "header"; - h1 "Development"; - p "This box allows for testing of multiple styles. Disable it from config."; - end; - - ul style => "margin: 3px 20px 10pt 40px"; - opendir(DIR, "$self->{root}/s/style") or die $!; - while (my $file = readdir(DIR)) - { - next if ($file =~ m/^\./); - li; - a href => "?style=$file", $file; - end; - } - closedir(DIR); - end; - end; - } } ################################################################################ @@ -107,13 +38,15 @@ sub htmlHeader ################################################################################ sub htmlFooter { - my $self = shift; + my ($self, %o) = @_; br style => "clear:both"; div id => 'footer'; txt "$self->{site_name} | Powered by "; - a href => "https://333networks.com", "333networks"; + a href => "http://333networks.com", "333networks"; + txt " | "; + txt $o{last_edited} || "2022"; end; end 'div'; # body script type => 'text/javascript', src => "/masterscript.js", ''; |
