//////////////////////////////////// // // // Player Mail Addon // // Created by Cobalt // // Donut Steel Inc, (c) 2014 // // // //////////////////////////////////// if ( SERVER ) then util.AddNetworkString( "SendMail" ) util.AddNetworkString( "SendMailCallback" ) util.AddNetworkString( "RequestPlys" ) util.AddNetworkString( "RequestPlysCallback" ) net.Receive( "SendMail", function( len, ply ) local txt = net.ReadString() local ent = net.ReadString() local sender = ply:Nick() local pl local steamid for k, v in pairs( player.GetAll() ) do if v:Nick() == ent then pl = v steamid = v:SteamID() break end end if pl then net.Start( "SendMailCallback" ) net.WriteString( txt ) net.WriteString( sender ) net.WriteString( steamid ) net.Send( pl ) end end ) net.Receive( "RequestPlys", function( len, ply ) local plys = player.GetAll() net.Start( "RequestPlysCallback" ) net.WriteTable( plys ) net.Send( ply ) end ) hook.Add( "PlayerInitialSpawn", "SendMessageCheck", function( ply ) timer.Simple( 3, function() if ply:IsValid() then umsg.Start( "CheckMessages", ply ) umsg.End() end end ) end ) hook.Add( "PlayerSay", "MailChatCommand", function( ply, text, public ) if string.sub( text, 1, 5 ) == "!mail" or string.sub( text, 1, 8 ) == "!mailbox" then ply:ConCommand( "mailbox" ) return "" else return end end ) end if ( CLIENT ) then if not file.Exists( "mail", "DATA" ) then file.CreateDir( "mail" ) end net.Receive( "SendMailCallback", function() local txt = net.ReadString() or "(No Message)" local ply = net.ReadString() local stid = net.ReadString() local str = tostring( os.date( "%A %B %d 20%y %H_%M_%S %p" ) ) file.Write( "mail/Message from " .. str .. ".txt", "From: " .. ply .. " (" .. stid .. ")\n" .. "---------------\n\n" .. txt ) surface.PlaySound( "garrysmod/content_downloaded.wav" ) hook.Add( "HUDPaint", "NewNotification", function() --draw.RoundedBox( 4, ScrW() / 2 - 160, 10, 320, 30, Color( 0, 0, 0, 100 ) ) draw.DrawText( "New message from " .. ply .. "!", "Trebuchet24", ScrW() / 2 + 2, 12, Color( 255, 255, 255, 200 ), TEXT_ALIGN_CENTER ) end ) timer.Simple( 3, function() hook.Remove( "HUDPaint", "NewNotification" ) end ) MsgN( "New message from " .. ply .. "!" ) end ) concommand.Add( "mailbox", function() local main = vgui.Create( "DFrame" ) main:SetPos( 50,50 ) main:SetSize( 800, 500 ) main:SetTitle( "Mailbox" ) main:SetVisible( true ) main:SetDraggable( true ) main:ShowCloseButton( true ) main:MakePopup() main:Center() main.Paint = function() surface.SetDrawColor( 255, 255, 255, 220 ) surface.DrawOutlinedRect( 0, 0, main:GetWide(), main:GetTall() ) surface.SetDrawColor( 0, 0, 0, 200 ) surface.DrawRect( 1, 1, main:GetWide() - 2, main:GetTall() - 2 ) end local list = vgui.Create( "DListView" ) list:SetParent( main ) list:SetPos( 4, 27 ) list:SetSize( 392, 419 ) list:SetMultiSelect( false ) list:AddColumn( "Filename" ) local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end local txt = vgui.Create( "DTextEntry", main ) txt:SetPos( 397, 27 ) txt:SetSize( 399, 419 ) txt:SetMultiline( true ) txt:SetEditable( true ) txt:SetText( "Double click or right click on a message to view its contents" ) list.DoDoubleClick = function( main, line ) local str = string.lower( list:GetLine( line ):GetValue( 1 ) ) if string.find( list:GetLine( line ):GetValue( 1 ), "(Unread)" ) then txt:SetText( file.Read( "mail/" .. string.sub( str:gsub( ":", "_" ), 1, -10 ) .. ".txt" ) ) file.Append( string.lower( "mail/" .. string.sub( list:GetLine( line ):GetValue( 1 ), 1, -10 ) ):gsub( ":", "_" ) .. ".txt", "\n\n###read###" ) else txt:SetText( file.Read( "mail/" .. str:gsub( ":", "_" ) .. ".txt" ):gsub( "###read###", "" ) ) end list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end end list.OnRowRightClick = function( main, line ) local str = string.lower( list:GetLine( line ):GetValue( 1 ) ) local menu = DermaMenu() menu:AddOption( "View Contents", function() if string.find( list:GetLine( line ):GetValue( 1 ), "(Unread)" ) then txt:SetText( file.Read( "mail/" .. string.sub( str:gsub( ":", "_" ), 1, -10 ) .. ".txt" ) ) file.Append( string.lower( "mail/" .. string.sub( list:GetLine( line ):GetValue( 1 ), 1, -10 ) ):gsub( ":", "_" ) .. ".txt", "\n\n###read###" ) else txt:SetText( file.Read( "mail/" .. str:gsub( ":", "_" ) .. ".txt" ):gsub( "###read###", "" ) ) end list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end end ):SetIcon( "icon16/user_edit.png" ) if not string.find( list:GetLine( line ):GetValue( 1 ), "(Unread)" ) then menu:AddOption( "Mark Unread", function() local f = file.Read( "mail/" .. str:gsub( ":", "_" ) .. ".txt" ) f = string.gsub( f, "###read###", "" ) file.Write( "mail/" .. str:gsub( ":", "_" ) .. ".txt", f ) list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end end ):SetIcon( "icon16/zoom.png" ) else menu:AddOption( "Mark Read", function() file.Append( string.lower( "mail/" .. string.sub( list:GetLine( line ):GetValue( 1 ), 1, -10 ) ):gsub( ":", "_" ) .. ".txt", "\n\n###read###" ) list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end end ):SetIcon( "icon16/zoom.png" ) end menu:AddOption( "Delete", function() Derma_Query( "Are you sure you want to delete this message?", "Notice", "Yes", function() if not string.find( str, "(unread)" ) then file.Delete( "mail/" .. str:gsub( ":", "_" ) .. ".txt" ) chat.AddText( "Message deleted!" ) else file.Delete( "mail/" .. string.sub( str:gsub( ":", "_" ), 1, -10 ) .. ".txt" ) chat.AddText( "Message deleted!" ) end list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end end, "No", function() end ) end ):SetIcon( "icon16/delete.png" ) menu:Open() end local f = file.Find( "mail/*", "DATA" ) local n = 0 for k, v in pairs( f ) do local t = file.Read( "mail/" .. v ) if not string.find( t, "###read###" ) then n = ( n + 1 ) end end main:SetTitle( "Mailbox (" .. #list:GetLines() .. " messages, " .. n .." unread)" ) surface.CreateFont( "MailFont", { font = "Arial", size = 17, weight = 350, blursize = 0, scanlines = 0, antialias = true, underline = false, italic = false, strikeout = false, symbol = false, rotary = false, shadow = false, additive = false, outline = false, } ) local compose = vgui.Create( "DButton", main ) compose:SetText( "" ) compose:SetPos( 4, 449 ) compose:SetSize( 150, 47 ) compose.Paint = function() surface.SetDrawColor( 255, 255, 255, 150 ) surface.DrawOutlinedRect( 0, 0, compose:GetWide(), compose:GetTall() ) surface.SetFont( "MailFont" ) if compose:IsDown() then surface.SetTextColor( 0, 128, 255, 255 ) else surface.SetTextColor( 255, 255, 255, 255 ) end surface.SetTextPos( 29, 15 ) surface.DrawText( "Compose Mail" ) return true end compose.DoClick = function() local cmain = vgui.Create( "DFrame" ) local v = Vector( main:GetPos() ) cmain:SetPos( v.x + 803, v.y ) cmain:SetSize( 400, 250 ) cmain:SetTitle( "Compose Message" ) cmain:SetVisible( true ) cmain:SetDraggable( true ) cmain:ShowCloseButton( true ) cmain:MakePopup() cmain.Paint = function() surface.SetDrawColor( 255, 255, 255, 220 ) surface.DrawOutlinedRect( 0, 0, cmain:GetWide(), cmain:GetTall() ) surface.SetDrawColor( 0, 0, 0, 200 ) surface.DrawRect( 1, 1, cmain:GetWide() - 2, cmain:GetTall() - 2 ) end cmain:RequestFocus() local txt = vgui.Create( "DTextEntry", cmain ) txt:SetPos( 4, 26 ) txt:SetSize( 392, 198 ) txt:SetMultiline( true ) txt:SetEditable( true ) txt:SetText( "" ) local stid = vgui.Create( "DTextEntry", cmain ) stid:SetPos( 137, 226 ) stid:SetSize( 130, 20 ) stid:SetMultiline( false ) stid:SetEditable( true ) stid:SetText( "SteamID" ) stid:SetDisabled( true ) stid:SetEditable( false ) local plys = vgui.Create( "DComboBox", cmain ) plys:SetPos( 4, 226 ) plys:SetSize( 130, 20 ) plys:SetValue( "Player" ) net.Start( "RequestPlys" ) net.SendToServer() net.Receive( "RequestPlysCallback", function() local tbl = net.ReadTable() for k, v in ipairs( tbl ) do plys:AddChoice( v:Nick() ) end plys:AddChoice( "Offline SteamID" ) end ) local box = "Player" plys.OnSelect = function( panel, index, value, data ) if tostring( value ) == "Offline SteamID" then stid:SetDisabled( false ) stid:SetEditable( true ) else stid:SetDisabled( true ) stid:SetEditable( false ) end box = tostring( value ) end local send = vgui.Create( "DButton", cmain ) send:SetText( "Send" ) send:SetPos( 270, 226 ) send:SetSize( 126, 20 ) send.Paint = function() surface.SetDrawColor( 255, 255, 255, 220 ) surface.DrawOutlinedRect( 0, 0, send:GetWide(), send:GetTall() ) end send.DoClick = function() if not ( box == "Offline SteamID" or box == "Player" ) then net.Start( "SendMail" ) net.WriteString( txt:GetText() ) net.WriteString( box ) net.SendToServer() if box == LocalPlayer():GetName() then hook.Add( "HUDPaint", "SNotification", function() --draw.RoundedBox( 4, ScrW() / 2 - 160, 50, 320, 30, Color( 0, 0, 0, 100 ) ) draw.DrawText( "Message sent to " .. box .. "!", "Trebuchet24", ScrW() / 2 + 2, 53, Color( 255, 255, 255, 200 ), TEXT_ALIGN_CENTER ) end ) timer.Simple( 3, function() hook.Remove( "HUDPaint", "SNotification" ) end ) else surface.PlaySound( "garrysmod/content_downloaded.wav" ) hook.Add( "HUDPaint", "SNotification", function() --draw.RoundedBox( 4, ScrW() / 2 - 160, 10, 320, 30, Color( 0, 0, 0, 100 ) ) draw.DrawText( "Message sent to " .. box .. "!", "Trebuchet24", ScrW() / 2 + 2, 12, Color( 255, 255, 255, 200 ), TEXT_ALIGN_CENTER ) end ) timer.Simple( 3, function() hook.Remove( "HUDPaint", "SNotification" ) end ) end cmain:Close() elseif box == "Offline SteamID" then chat.AddText( "Input a steamid!" ) elseif box == "Player" then chat.AddText( "Select a player!" ) end end end local refresh = vgui.Create( "DButton", main ) refresh:SetText( "" ) refresh:SetPos( 158, 449 ) refresh:SetSize( 150, 47 ) refresh.Paint = function() surface.SetDrawColor( 255, 255, 255, 150 ) surface.DrawOutlinedRect( 0, 0, refresh:GetWide(), refresh:GetTall() ) surface.SetFont( "MailFont" ) if refresh:IsDown() then surface.SetTextColor( 0, 128, 255, 255 ) else surface.SetTextColor( 255, 255, 255, 255 ) end surface.SetTextPos( 29, 15 ) surface.DrawText( " Refresh" ) return true end refresh.DoClick = function() list:Clear() local files = file.Find( "mail/*", "DATA" ) for k, v in pairs( files ) do local text = tostring( v ):sub( 1, -5 ) local str if string.find( text, "%s" ) then string.sub( text, string.find( text, "%s" ), string.len( text ) ) str = text:gsub( "^%l", string.upper ) end local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then list:AddLine( str:gsub( "_", ":" ) .. " (Unread)" ) else list:AddLine( str:gsub( "_", ":" ) ) end end surface.PlaySound( "garrysmod/ui_return.wav" ) end end ) timer.Create( "CheckMessages", 60, 0, function() local files = file.Find( "mail/*", "DATA" ) local num = 0 for k, v in pairs( files ) do local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then num = ( num + 1 ) end end if num > 0 then surface.PlaySound( "garrysmod/content_downloaded.wav" ) MsgN( "You have " .. num .. " unread message(s)!" ) hook.Add( "HUDPaint", "Notification", function() --draw.RoundedBox( 4, ScrW() / 2 - 160, 10, 320, 30, Color( 0, 0, 0, 100 ) ) draw.DrawText( "You have " .. num .. " unread message(s)!", "Trebuchet24", ScrW() / 2 + 2, 12, Color( 255, 255, 255, 200 ), TEXT_ALIGN_CENTER ) end ) timer.Simple( 3, function() hook.Remove( "HUDPaint", "Notification" ) end ) end end ) usermessage.Hook( "CheckMessages", function() local files = file.Find( "mail/*", "DATA" ) local num = 0 for k, v in pairs( files ) do local temp = file.Read( "mail/" .. v ) if not string.find( temp, "###read###" ) then num = ( num + 1 ) end end if num > 0 then surface.PlaySound( "garrysmod/content_downloaded.wav" ) MsgN( "You have " .. num .. " unread message(s)!" ) hook.Add( "HUDPaint", "Notificationumsg", function() --draw.RoundedBox( 4, ScrW() / 2 - 160, 10, 320, 30, Color( 0, 0, 0, 100 ) ) draw.DrawText( "You have " .. num .. " unread message(s)!", "Trebuchet24", ScrW() / 2 + 2, 12, Color( 255, 255, 255, 200 ), TEXT_ALIGN_CENTER ) end ) timer.Simple( 3, function() hook.Remove( "HUDPaint", "Notificationumsg" ) end ) end end ) end