--[[
	MOD/lua/shinycow/trackplayers.lua
	Shinycow ت | (STEAM_0:0:29257121) | [06-08-13 07:36:35PM]
	===BadFile===
]]

---- Tracks player name changes while their in the server.
---- Also keeps their steamid in a table so if they leave you can still get their info.

-------------------- SHOULD I SAVE THE DATA IN A SQL DB AND MAKE THIS OVERLY COMPLEX??? Nahhh. 


-- HEY YOU: YOU HIGH FUCK!! MAKE A PLAYER TRACKER THINGY AND LOG WHER LAST SAW THE PLAYER
-- ADN TELL YOURSELF WERE YOU LAST SAW THEM!!!


	-- THIS IS MEANT FOR YOU TO BE ABLE TO STALK PLAYERS.
	-- get yer own api key. u cant have mine
local APIKey = "nothing"
APIKey = "7381C1CCC4D813CCE7698495C3E5F515"

--[[--[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
	THIS IS NOT A FUCKING MINGING SCRIPT. IT'S MORE OF AN ADMINISTRATION SCRIPT.
	
	
	Yet fools may still try to detect it. So we'll still hide it just a smidgem.
--]]--]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

local SCE = {}
local propkillers = {}
local halptracking = {}

	-- Only using for when they open their steam page with no argument.
local FoundPlayer = NULL
local FoundPlayerName = nil
local FoundPlayer64 = nil


local gameevent = gameevent
local AddConsoleCommand = AddConsoleCommand
local string = string
local tostring = tostring
local hook = hook
local file = file
local chat = chat
local PrintTable = PrintTable
local print = print
local pairs = pairs

gameevent.Listen("player_info")
gameevent.Listen("player_connect")

local function sce_AddCommand( cmd, func, help )
	SCE[ "sc_" .. cmd:lower() ] = {Function = func, Help = help}
	AddConsoleCommand( "sc_" .. cmd:lower(), help )
end

--[[local oldfileRead = file.Read
function file.Read(contents, type, b_IsShittySecurity)
	if not contents then return nil end
	if string.lower(contents):find("trackplayers")
	or string.lower(contents):find("shinycow")
	and not b_IsShittySecurity
	then return nil end
  
	
	return oldfileRead(contents, type)
end]]

--[[local oldfileExists = file.Exists
function file.Exists(contents, type, b_IsShittySecurity)
	if not contents then return nil end
	if not b_IsShittySecurity then
	if string.lower(contents):find("trackplayers")
	or string.lower(contents):find("shinycow")
	then return nil end end
	
	return oldfileExists(contents, type)
end]]


local oldICC = InjectConsoleCommand
function InjectConsoleCommand( player, command, arguments, args )
	if SCE[ command:lower() ] then
		SCE[ command:lower() ].Function( player, command, arguments, args )
		return true
	end
	
	oldICC( player, command, arguments, args )
end

if not file.Exists("shinycow", "DATA") then
	LocalPlayer():ChatPrint("DEBUG: CREATING DIR SHINYCOW.")
	file.CreateDir("shinycow")
end

	-- friendsid - <arg unknown>
	-- index	-	<int - player entity.>
	-- bot	=	<int boolean - 0 is not bot; 1 is bot>
	-- networkid	=	<steamid. bot = BOT>
	-- name	=	<player (new) name>
	-- userid	=	<int - player's userid.>
hook.Add("player_info", "shinycow_namechanges", function( data )
	--print("player info:\n")
	--PrintTable(data)
	
	timer.Simple(1.2, function()
		print(tostring(Player(data.userid)))
		if not IsValid(Player(data.userid)) then return end
	
		if not halptracking[ data.networkid ] then
			if Player(data.userid).SteamName then
				-- we can use darkrp!
				halptracking[ data.networkid ] = 
				{
				steamname = Player(data.userid):SteamName(),
				current = data.name,
				steamid = data.networkid,
				steamid64 = Player(data.userid):SteamID64(),
				id = data.userid,
				reconnects = 0,
				namechanges = {}
				}
			else
				-- we improvise and hope it's right.
				halptracking[ data.networkid ] =
				{
				steamname = data.name,
				current = data.name,
				steamid = data.networkid,
				steamid64 = Player(data.userid):SteamID64(),
				id = data.userid,
				reconnects = 0,
				namechanges = {}
				}
			end
			LocalPlayer():ChatPrint( data.name .. " joined the server." )
			timer.Simple(1, function()
				for k,v in pairs(player.GetAll()) do
					if v:IsAdmin() or string.find(string.lower(v:GetNWString("UserGroup")), "mod")then
						LocalPlayer():ChatPrint( v:Nick() .. " is admen." )
					end
				end
			end)
			--if Player(data.userid):IsAdmin() then LocalPlayer():ChatPrint("He's admen.") end
		else
				-- They rejoined the server.
			if halptracking[ data.networkid ].steamname == data.name then
				LocalPlayer():ChatPrint( data.name .. " reconnected." )
				halptracking[ data.networkid ].reconnects = halptracking[ data.networkid ].reconnects + 1
			else
				LocalPlayer():ChatPrint( halptracking[ data.networkid ].steamname .. " changed their name to " .. data.name )
				
				halptracking[ data.networkid ].current = data.name
				halptracking[ data.networkid ].namechanges[ #halptracking[ data.networkid ].namechanges + 1 ] = data.name
			end
		end
		
		if string.find( string.lower(gmod.GetGamemode().Name), "propkill" ) or string.lower(gmod.GetGamemode().Name) == "deathzone" then
			if file.Exists("shinycow/propkillers.txt", "DATA") then
				local output = util.JSONToTable( file.Read("shinycow/propkillers.txt", "DATA") )
				PrintTable(output)
				
				for k,v in pairs(output) do
					if not propkillers[ k ] then
						propkillers[ k ] = true
					end
				end
				
				file.Write("shinycow/propkillers.txt", util.TableToJSON(propkillers))
			else
				LocalPlayer():ChatPrint("DEBUG: File doesnt exist?!")
				
				propkillers[ data.networkid ] = true
				
				file.Write("shinycow/propkillers.txt", util.TableToJSON(propkillers))
			end
		end
	end)
end)


	-- Since player_info is only called when players first join / name changes,
	-- we put them in the list when we first join.
for i=1,#player.GetAll() do
	local v = player.GetAll()[ i ]
		
	if not halptracking[ v:SteamID() ] then
		halptracking[ v:SteamID() ] = 
		{
		steamname = v:Nick(),
		current = v:Nick(),
		steamid = v:SteamID(),
		steamid64 = v:SteamID64(),
		id = v:UserID(),
		reconnects = 0,
		namechanges = {}
		}
	else
		halptracking[ v:SteamID() ].current = v:Nick()
		halptracking[ v:SteamID() ].namechanges[ #halptracking[ v:SteamID() ].namechanges + 1 ] = v:Nick()
	end
end

timer.Simple(1, function()
	print("Yaw")
	
	if file.Exists("shinycow/propkillers.txt", "DATA") then
		for k,v in pairs(util.JSONToTable( file.Read("shinycow/propkillers.txt", "DATA") )) do
			if not propkillers[ k ] then
				propkillers[ k ] = true
			end
		end
	end
	
	if string.find( string.lower(gmod.GetGamemode().Name), "propkill" ) or string.lower(gmod.GetGamemode().Name) == "deathzone" then
		for k,v in pairs(player.GetAll()) do
			if v != LocalPlayer() then
			
				if not propkillers[ v:SteamID() ] then
					propkillers[ v:SteamID() ] = true
					print(v:Nick())
				end
			
			end
		end
	end
	
	if not file.Exists("shinycow/propkillers.txt", "DATA") then
		file.Write("shinycow/propkillers.txt", util.TableToJSON(propkillers))
	end
	
end)

hook.Add("player_connect", "shinycow_showpropkillers", function( data )
	if not file.Exists("shinycow/propkillers.txt", "DATA") then LocalPlayer():ChatPrint("i guess it doesnt exist now??") return end
	
	timer.Simple(0.5, function()
		LocalPlayer():ChatPrint("testsettt")
		if propkillers[ data.networkid ] then
			LocalPlayer():ChatPrint( data.name .. " (" .. data.networkid .. ") is (most likely) a propkiller!" )
		else
			LocalPlayer():ChatPrint( "player not found in propkiller database.")
		end
	end)
end)

sce_AddCommand("tracking_list", function()
	PrintTable(halptracking)
	print("\n------------PROPKILLERS------------\n")
	PrintTable(propkillers)
end)

local function FindPlayer( pl )
	local output = {}

	for k,v in pairs(halptracking) do
		-- lookup steamid first.
		if string.find(string.lower(v.steamid), string.lower(tostring(pl))) then
			print("found by steamid " .. v.steamname .. "; " .. k)
			
			local outputuse = NULL
			
			if IsValid(Player(v.id)) then
				outputuse = Player(v.id)
			
				FoundPlayer = Player(v.id)
				FoundPlayerName = Player(v.id):Nick()
			else
				FoundPlayerName = v.current
			end
			FoundPlayer64 = v.steamid64
			
			-- Outputs their information, player entity.
			return halptracking[ k ], outputuse
			
		-- secondly lookup by steam name
		elseif string.find(string.lower(v.steamname), string.lower(tostring(pl))) then
			print("found by steamname " .. v.steamname .. "; " .. k)
			
			local outputuse = NULL
			
			if IsValid(Player(v.id)) then
				outputuse = Player(v.id)
			
				FoundPlayer = Player(v.id)
				FoundPlayerName = Player(v.id):Nick()
			else
				FoundPlayerName = v.current
			end
			FoundPlayer64 = v.steamid64
			
			-- Outputs their information, player entity.
			return halptracking[ k ], outputuse
			
		-- i suppose we can try their userid!
		elseif v.id == tonumber(pl) then
			print("found by userid " .. v.id .. "; " .. k)
			
			local outputuse = NULL
			
			if IsValid(Player(v.id)) then
				outputuse = Player(v.id)
			
				FoundPlayer = Player(v.id)
				FoundPlayerName = Player(v.id):Nick()
			else
				FoundPlayerName = v.current
			end
			FoundPlayer64 = v.steamid64
			
			-- Outputs their information, player entity.
			return halptracking[ k ], outputuse
		
		-- all else fails we loop through their known names.
		else
			for a,b in pairs(v.namechanges) do
				if string.find(string.lower(b), string.lower(tostring(pl))) then
					print("hey i found him! by namechanges of course.. " .. v.steamname .. "; " .. b .. "; " .. k)
					
					local outputuse = NULL
					
					if IsValid(Player(v.id)) then
						outputuse = Player(v.id)
					
						FoundPlayer = Player(v.id)
						FoundPlayerName = Player(v.id):Nick()
					else
						FoundPlayerName = v.current
					end
					FoundPlayer64 = v.steamid64
					
					-- Outputs their information, player entity.
					return halptracking[ k ], outputuse
				end
			end
		end
	end
	
	-- well that failed.
	return nil
end

local function retrieveUser( body, len, headers, code )
	
	print("\nsuccess\n")
	
	local data = util.JSONToTable( body )
	data = data["response"]
	PrintTable(data["players"][1])
	
end


hook.Add("OnPlayerChat", "shinycow_lookup", function( pl, txt, b_teamonly, b_isdead )
	if pl != LocalPlayer() then return end
	
	local args = string.Explode(" ", txt)
	
	if args[1] == "!findplayer" or args[1] == "!getplayer" or args[1] == "!lookup" then
		
		local args2 = args[2]
		if not args2 then return txt end
		
		local player_table,target = FindPlayer(args2)
		if not player_table then chat.AddText(Color(75,155,155,255), "Give me something I can find!") return txt end
		
		chat.AddText(Color(75,155,155,255), "Found ", color_white, player_table.current, Color(75,155,155,255), "; Check console for more info.")
		
		if args[3] then
			if args[4] then
				local toclipboard = player_table.steamid
				for k,v in pairs(player_table) do
					if args[4] == k and (type(k) != "table") then
						toclipboard = v
					end
				end
				
				SetClipboardText(toclipboard)
				chat.AddText(color_white, toclipboard, Color(75,155,155,255), " was copied to your clipboard.")
			else
				SetClipboardText(player_table.steamid)
				chat.AddText(color_white, player_table.steamid, Color(75,155,155,255), " was copied to your clipboard.")
			end
		end
		
		print("\n")
		PrintTable(player_table)
		print("\n")
		
	elseif args[1] == "!open" then
	
		-- Ugh.
		local args2 = args[2]
		if args2 then
		
			local player_table,target = FindPlayer(args2)
			if not player_table then chat.AddText(Color(75,155,155,255), "Give me something I can find!") return txt end 
							
			
			chat.AddText(Color(75,155,155,255), "Found ", color_white, player_table.current, Color(75,155,155,255), ". Opening steam overlay.")
			
			if IsValid(target) then
				FoundPlayer:ShowProfile()
			else
				
				chat.AddText(color_white, FoundPlayerName, Color(75,155,155,255), " left. Sorry for this shoddy menu.")
				
				local mainmenu = vgui.Create("DFrame")
				mainmenu:SetSize( (ScrW() * 0.5) - 50, (ScrH() * 0.5) + 60 )
				mainmenu:Center()
				mainmenu:SetTitle( FoundPlayerName .. " Steam Overlay" )
				mainmenu:SetVisible( true )
				mainmenu:SetDraggable( false )
				mainmenu:ShowCloseButton( true )
				mainmenu:MakePopup()
				
				local aamgg = vgui.Create("HTML", mainmenu)
				aamgg:SetPos( 3, 23 )
				aamgg:SetSize( (ScrW() * 0.5) - 53, (ScrH() * 0.5) + 57)
				aamgg:OpenURL( "http://steamcommunity.com/profiles/" .. tostring(FoundPlayer64) )
			end
				
				
		
		-- The easy part. Somewhat.
		else

			if not FoundPlayer64 then print("tracking players - hopefully it just does this to bots.") return end
			
			-- Oh thank god.
			if IsValid(FoundPlayer) then
			
				chat.AddText(Color(75,155,155,255), "Found ", color_white, FoundPlayer:Nick(), Color(75,155,155,255), ". Opening steam overlay.")
				FoundPlayer:ShowProfile()
				
			-- Fuck me.
			else
				
				chat.AddText(color_white, FoundPlayerName, Color(75,155,155,255), " left. Sorry for this shoddy menu.")
				
				local mainmenu = vgui.Create("DFrame")
				mainmenu:SetSize( (ScrW() * 0.5) - 50, (ScrH() * 0.5) + 60 )
				mainmenu:Center()
				mainmenu:SetTitle( FoundPlayerName .. " Steam Overlay" )
				mainmenu:SetVisible( true )
				mainmenu:SetDraggable( false )
				mainmenu:ShowCloseButton( true )
				mainmenu:MakePopup()
				
				local aamgg = vgui.Create("HTML", mainmenu)
				aamgg:SetPos( 3, 23 )
				aamgg:SetSize( (ScrW() * 0.5) - 53, (ScrH() * 0.5) + 57)
				aamgg:OpenURL( "http://steamcommunity.com/profiles/" .. tostring(FoundPlayer64) )
				
			end
			
		end
		
	elseif args[1] == "!getuser" or args[1] == "!finger" then
		
			-- Ugh.
		local args2 = args[2]
		if args2 then
		
			local player_table,target = FindPlayer(args2)
			if not player_table then chat.AddText(Color(75,155,155,255), "Give me something I can find!") return txt end 
							
			
			chat.AddText(Color(75,155,155,255), "Found ", color_white, player_table.current, Color(75,155,155,255), ". Printing xml version of user.")
			
			--local userurl = "http://steamcommunity.com/profiles/" .. player_table.steamid64 .. "/games?tab=all&xml=1"
			local userurl = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" .. APIKey .. "&format=json&steamids=" .. player_table.steamid64
		
			http.Fetch(userurl,
				retrieveUser,
				function( fail )
					print("Couldn't retrieve player: " .. fail)
				end
			)
			
		end
	
	elseif args[1] == "!help" then
		
		chat.AddText("")
		chat.AddText(color_white, "Tracking players help has been printed to your console.")
		chat.AddText("")
		
		for i=1,10 do print("\n") end
		print("Hallo I am tracking halp!")
		print("\n\n\n")
		
	end
end)
