local lg = assert( love.graphics ) local scene = assert( require 'client.scene' ) local textInput = assert( require 'client.ui.textinput' ) local button = assert( require 'client.ui.button' ) local packet = assert( require 'shared.packet' ) local menu = assert( require 'client.ui.menu' ) local strings = assert( require 'client.assets.strings.strings' ) local fonts = assert( require 'client.ui.fonts' ) local utf8 = assert( require 'utf8' ) local browser = {} local test = assert( require 'client.test.browser' ) local font = fonts.font local cw = fonts.font:getWidth( "w" ) local function joinServerCallback( button ) if button.ip and button.port then return browser.joinIP( button.ip, button.port ) end end local function tryAdd( text, d, x ) local s = packet.getString( d ) return pcall( text.add, text, s, x ) or text:add( strings.utf8_error, x ) end local function serverInfoToText( server ) local cw = fonts.font:getWidth( "w" ) local text = lg.newText( fonts.font ) tryAdd( text, server.svname, 0 ) tryAdd( text, server.map, cw * 16 ) text:add( tostring( server.ip ), cw * 32 ) text:add( server.port, cw * ( 32 + 12 ) ) text:add( server.players, cw * ( 32 + 12 + 6 ) ) text:add( server.capacity, cw * ( 32 + 12 + 9 ) ) return text end local serverList = menu.new{ name = "serverList", buttons = {}, fg = lg.newMesh{ { 0.5, 0, 0.5, 0, 0, 0, 0, 0 }, { 1, 0, 1, 0, 1, 1, 1, 0.5 }, { 1, 1, 1, 1, 1, 1, 1, 0.5 }, { 0.5, 1, 0.5, 1, 0, 0, 0, 0 }, }, bg = lg.newMesh{ { 0, 0, 0, 0, 0.4, 0.05, 0.0, 0.9 }, { 1, 0, 1, 0, 0.8, 0.3, 0.1, 0.8 }, { 1, 1, 1, 1, 0.7, 0.4, 0.1, 0.8 }, { 0, 1, 0, 1, 0.4, 0.05, 0.05, 0.9 }, }, font = fonts.font, subScene = true } serverList.selected = false serverList.x = 25 serverList.y = 0 serverList.h = 36 local serverButtons = serverList.buttons local color = { 1, 0.6, 0.6, 0.1 } local ti = textInput.new{ width = lg.getWidth(), length = 20, x = cw, y = 35, h = 55, str = strings.ip_button, font = fonts.midFont, } function ti:callback() return self:enterText( browser.joinIPString ) end local headerButtons = { button{ callback = function() return serverList.refresh( test.getTestServers() ) end, text = lg.newText( fonts.midFont, strings.refresh_button ) , color = color, x = cw * 32, y = 75, w = 1400, h = 36 }, button{ callback = function() return scene.mainmenu() end, text = lg.newText( fonts.midFont, strings.mainmenu_button ) , color = color, x = cw, y = 75, w = 1400, }, ti, button{ x = cw * 53, color = color, y = 135, text = lg.newText( font, strings.svinfo_capacity ) }, button{ x = cw * 50, color = color, y = 135, text = lg.newText( font, strings.svinfo_players ) }, button{ x = cw * 44, color = color, y = 135, text = lg.newText( font, strings.svinfo_port ) }, button{ x = cw * 32, color = color, y = 135, text = lg.newText( font, strings.svinfo_ip ) }, button{ x = cw * 16, color = color, y = 135, text = lg.newText( font, strings.svinfo_map ) }, button{ x = cw , color = color, y = 135, text = lg.newText( font, strings.svinfo_name ) }, } for j, headerButton in ipairs( headerButtons ) do serverButtons[j] = headerButton end function serverList.refresh( serverInfo ) local n = #headerButtons + 1 for i, server in ipairs( serverInfo ) do local b = serverButtons[n] or button{} b.space = 0 b.x = cw b.w = lg.getWidth() b.y = 27 * i + 145 b.h = 24 b.color = { 0.3 + 0.1 * (n % 2), 0.3 + 0.1 * (n % 2), 0.8, 0.5 } b.callback = joinServerCallback b.serverInfo = server b.ip = tostring( server.ip ) b.port = server.port b.text = serverInfoToText( server ) b.active = ( b.y < lg.getHeight() ) serverButtons[n] = b n = n + 1 end for i = #headerButtons + #serverInfo + 1, #headerButtons + #serverButtons do serverButtons[i] = nil end return serverList:paint() end do local rs = serverList.resize serverList.resize = function( x, y ) rs( x, y ) for i, button in ipairs( serverButtons ) do button.w = x end return serverList:paint() end local ol = serverList.onLoad function serverList:onLoad() serverList.refresh( test.getTestServers() ) return ol( serverList ) end end function serverList.scroll( up ) local minY = 170 local maxY = lg.getHeight() + 40 if up and serverButtons[ #headerButtons + 1 ].y > minY then return end if ( not up ) and serverButtons[ #serverButtons ].y < maxY then return end up = 10 * ( up and 1 or -1 ) for i = #headerButtons + 1, #serverButtons do local sb = serverButtons[i] sb.y = sb.y + up sb.active = ( sb.y > minY ) and ( sb.y < maxY ) end return serverList:paint() end browser.selected = false function browser.draw() lg.setColor( 1, 1, 1, 1 ) serverList.draw() end function browser.update( dt ) end function browser.onLoad( ) serverList:onLoad() lg.setColor( 1, 1, 1, 1 ) end function browser.mousemoved( x, y, dx, dy, istouch ) return serverList.mousemoved( x, y, dx, dy, istouch ) end function browser.wheelmoved( x, y ) if y == 0 then return end return serverList.scroll( ( y > 0 ) ) end function browser.resize( x, y ) return serverList.resize( x, y ) end function browser.mousepressed(x, y, button, istouch, pressed) return serverList.mousepressed( x, y, button, istouch, pressed ) end function browser.joinIPString( s ) --Parse IP address and port from string. If it's valid, join the server. print( "browser: entered IP and port", s ) if not s then return end ti:clear() local ip, port = s:match '(%d+%.%d+%.%d+%.%d+)', s:match ':(%d+)' print( "browser:", "ip:", ip, port ) if ip and port then return browser.joinIP( ip, port ) end end function browser.joinIP( ip, port ) print( "Joining server:", ip, port ) return scene.loadScene( scene.connecting, { ip = ip, port = port } ) end function browser.keypressed( key, code, isRepeat ) if code == "escape" then return scene.mainmenu() end return serverList.keypressed( key, code, isRepeat ) end scene.browser = browser return browser