Jump to content

[HELP] SCRIPT TOPTIME


HenryC

Recommended Posts

executeSQLCreateTable ("huntertimes","map TEXT,name TEXT,serial TEXT,country TEXT,country2 TEXT,date TEXT,time INT")

local HunterTable = {}

local function getTopPos(time,map)
	local rank = executeSQLQuery("SELECT count(*)+1 as rank FROM huntertimes WHERE time < "..time.." and map='"..map.."' LIMIT 1")
	return rank[1].rank
end

local function msToTimeStr(ms)
	local centiseconds = tostring(math.floor(math.fmod(ms,1000)/10))
	if #centiseconds == 1 then
		centiseconds = '0' .. centiseconds
	end
	local s = math.floor(ms/1000)
	local seconds = tostring(math.fmod(s,60))
	if #seconds == 1 then
		seconds = '0'..seconds
	end
	return tostring(math.floor(s/60))..':'.. seconds ..':'..centiseconds
end

local function getDate()
	local time = getRealTime()
	local m = time.month+1
	local d = time.monthday
	if tonumber(d) < 8 then
		d = "0"..d
	end
	if tonumber(m) < 8 then
		m = "0"..m
	end
	return d.."."..m.."."..tostring(tonumber(time.year)+1900)
end

function HexToRGB(hex)
  local hex = hex:gsub("#","")
  return tonumber("0x"..hex:sub(1,2)), tonumber("0x"..hex:sub(3,4)), tonumber("0x"..hex:sub(5,6))
end

local function rDarkColor(str)
	local hexpos = string.find(str,"#%x%x%x%x%x%x")
	if hexpos then
		local hex = string.sub(str,hexpos,hexpos+6)
		local r,g,b = HexToRGB(hex)
		if 60 > r and 60 > g and 60 > b then
			str = string.gsub(str,hex,"")
		end
		hexpos2 = string.find(str,"#%x%x%x%x%x%x",4)
		if hexpos2 then
			local hex2 = string.sub(str,hexpos2,hexpos2+6)
			local r2,g2,b2 = HexToRGB(hex2)
			if 60 > r2 and 60 > g2 and 60 > b2 then
				str = string.gsub(str,hex2,"")
			end
		end
	end
	return str
end

local function createLocalTopTable(player,map)
	local table = {false}
	local accountname = getPlayerSerial(player)
	local t = executeSQLQuery("SELECT time,name,date,country2 FROM huntertimes WHERE serial='"..accountname.."' AND map='"..map.."' LIMIT 1")
	if t[1] then
		table = {msToTimeStr(t[1].time),rDarkColor(t[1].name),t[1].date,t[1].country2,getTopPos(t[1].time,map)}
	end
	return table
end

local function createTopTable(map)
	local table = {}
	local amount = 0
	local te = {"--Empty--","","",""}
	local t = executeSQLQuery("SELECT time,name,date,country2 FROM huntertimes WHERE map='"..map.."' ORDER BY time ASC LIMIT 8")
	local hm = executeSQLQuery("SELECT count(*) as count FROM huntertimes WHERE map='"..map.."' LIMIT 1")
	amount = hm[1].count
	local i = 0
	while i ~= 8 do
		i = i + 1
		if t[i] then
			table[i] = {msToTimeStr(t[i].time),rDarkColor(t[i].name),t[i].date,t[i].country2}
		else
			table[i] = te
		end
	end
	table[12] = {type,string.sub(map.."("..amount.." tops)",1,44)}
	return table
end

addEvent("onClientWantRanking",true)
addEventHandler("onClientWantRanking",root,
function(player)
	local map = string.gsub(getElementData(player,"Map"),"[(')]+","") 
	local ranking = createTopTable(map)
	ranking[11] = createLocalTopTable(player,map)
	triggerClientEvent(player,"onServerSendRanking",player,ranking)
end)

addEvent("onRaceStateChanging",true)
addEventHandler("onRaceStateChanging", root,
function(new,old)
	if new == "LoadingMap" then
		setTimer(function()
		HunterTable = {}
		end,1000,1)
		setTimer(function()
		local map = string.gsub(getMapName(),"[(')]+","") 
		local ranking = createTopTable(map)
		for k,v in ipairs(getElementsByType("player")) do
			if getElementData(v,"state") and getElementData(v,"state") == "alive" then
				local t = ranking
				t[11] = createLocalTopTable(v,map)
				triggerClientEvent(v,"onServerSendRanking",v,t)
			end
		end
		end,8000,1)
	end
end)

local block = {};

function removeBlock(player)
	block[player] = nil;
end

function addTT(time,source)
	if not block[source] then
		block[source] = true;
		setTimer(removeBlock,20000,1,source);
		local map = string.gsub(getElementData(source,"Map"),"[(')]+","")
		local pos = getTopPos(time,map)
		if not string.find(map,"Hunter") then
			outputChatBox("#BF4343*[Map] #ffffff "..map,root,255,255,255,true)
			if pos == 1 then
				outputChatBox("#BF4343*[Hunter]#ffffff "..getPlayerName(source).."#ffffff has made the #00ff00WORLD RECORD #ffffffwith time "..msToTimeStr(time),root,255,255,255,true)
			else
				outputChatBox("#BF4343*[Hunter]#ffffff "..getPlayerName(source).."#ffffff has got the hunter #BF4343["..msToTimeStr(time).."]#ffffff and pos. #BF4343["..pos.."]",root,255,255,255,true)
			end
		end
		local accountname = getPlayerSerial(source)
		local result = executeSQLQuery("SELECT time FROM huntertimes WHERE serial='"..accountname.."' AND map='"..map.."' LIMIT 1")
		if not result[1] then
			executeSQLInsert ("huntertimes", "'"..map.."','"..string.gsub(getPlayerName(source),"[(')]+","").."','"..accountname.."','"..tostring(getElementData(source,"country") or "Europe").."','"..tostring(getElementData(source,"Country") or "EU").."','"..getDate().."',"..time.."")
		else
			if result[1].time > time then
				executeSQLUpdate("huntertimes","time = "..time..",name = '"..string.gsub(getPlayerName(source),"[(')]+","").."'","serial='"..accountname.."' AND map='"..map.."'")
			end
		end
		local ranking = createTopTable(map)
		ranking[11] = createLocalTopTable(source,map)
		triggerClientEvent(source,"onServerSendRanking",source,ranking)
		triggerClientEvent(source,"onServerSendRanking2",source,ranking)
	end
end

Error on line 94 = local map = string.gsub(getElementData(player,"Map"),"[(')]+","") 

error spacer.png

Link to comment
  • Moderators

- You use getElementData "Map" but where do you setElementData "Map" ? The element data doesn't exist when it is called and you get false instead of the map's name.

- Don't escape strings yourself with gsub, use "?" placeholders instead. It will prevents bad things like SQL Injections for you. Example:

local playerName = getPlayerName(source)
executeSQLQuery("SELECT * FROM players WHERE name=?", playerName)

 

- At line 144 I see you use getElementData "country" and "Country" are you sure about the names ?
image.png.e91ae0e54346481c92c57d2634389d43.png
Why do you have 2 versions of the country data ? Looks like bad practice and looks confusing

 

- [perf] Why do you need to trigger onServerSendRanking AND onServerSendRanking2 ?? They are the exact same calls, just use onServerSendRanking on both client handlers

triggerClientEvent(source,"onServerSendRanking",source,ranking)
triggerClientEvent(source,"onServerSendRanking2",source,ranking)

 

- [perf] Don't use getElementData for the same data twice where you can call it once:

if getElementData(v,"state") and getElementData(v,"state") == "alive" then

Do this instead:

local state = getElementData(v, "state")
if state and state == "alive" then

 

- [bug] Should be `< 10` here on both lines because you want that "8" or "9" turns into "08" or "09" respectively

image.png.3bbb7e2db78d7cad6cfb53dbf2de0103.png

 

- Don't use reserved keywords for your variable names. Here table is a reserved keyword:

image.png.ea11b07a541277ae97d2803b32f80815.png

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...