- Personal DownloadBlocker - - Page 2
 

News:

29 December 2022 - PtokaX 0.5.3.0 (20th anniversary edition) released...
11 April 2017 - PtokaX 0.5.2.2 released...
8 April 2015 Anti child and anti pedo pr0n scripts are not allowed anymore on this board!
28 September 2015 - PtokaX 0.5.2.1 for Windows 10 IoT released...
3 September 2015 - PtokaX 0.5.2.1 released...
16 August 2015 - PtokaX 0.5.2.0 released...
1 August 2015 - Crowdfunding for ADC protocol support in PtokaX ended. Clearly nobody want ADC support...
30 June 2015 - PtokaX 0.5.1.0 released...
30 April 2015 Crowdfunding for ADC protocol support in PtokaX
26 April 2015 New support hub!
20 February 2015 - PtokaX 0.5.0.3 released...
13 April 2014 - PtokaX 0.5.0.2 released...
23 March 2014 - PtokaX testing version 0.5.0.1 build 454 is available.
04 March 2014 - PtokaX.org sites were temporary down because of DDOS attacks and issues with hosting service provider.

Main Menu

- Personal DownloadBlocker -

Started by Optimus, 27 November, 2003, 16:40:32

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

BoJlk

Is it possible to make this script to block from user on my hub downloading from me.

It's important to preserve the Upload bandwidth...

honda

Hello

I saw the option to send the message in PM.

curUser:SendPM(sBot, nick.." is now unblocked.")

But what is the command for in Opchat.. Then every Op knows it....

Skyhawk


Skyhawk

#28
QuoteOriginally posted by nErBoS

3) Just change this line ....

Quoteif (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.bOperator then

for this...

Quoteif (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and user.iProfile == 0 then

I have bolded the changrd parts to you understand  ;)

Best regards, nErBoS


If i do this then the script doesn't work anymore (i.e. the bot doesn't reply eg  ... has been blocked.



I am using PtokaX DC Hub 0.3.3.0 build 15.25 [debug]

if you have any other version higher than that please tell me

bastya_elvtars

QuoteOriginally posted by BoJlk
Is it possible to make this script to block from user on my hub downloading from me.

It's important to preserve the Upload bandwidth...

don't share anything
Everything could have been anything else and it would have just as much meaning.

honda

hello me again

SendPmToOps that works.. But what i mean was..
How can i get the message in Opchat??
Its handy that  i can send to Ops but in Opchat is better way for me.


Sorry for the bad english

nErBoS

Hi,

Honda try out this...

SendPmToNick("YOUR_OPCHAT_NAME", sBot, nick.." is now unblocked.")

Skyhawk, sorry wrong table, try this one...

Quoteif (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.iProfile == 0 then

Best regards, nErBoS
--## nErBoS Spot ##--

honda

hello Nerbos

Thnx for the info..
I have tried it. And when i set my nick in it or a other persons nick no problem it works.. But when i do the Opchat name nothing..
Can there be a problem with rights??

The profiles working good..

Greetings..

nErBoS

Hi,

Try out this one then...

SendPmToOps("YOUR_OPCHAT_NAME", nick.." is now unblocked.")

like Skyhawk has sugested.

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Works great Mutor..

Thanks for the help everybody..

honda

Hello

I have added a extra command !unblock. And it works.
A little cut and paste work.

But i have a problem that ik can't solve by myself.

How can i make a !showblock. Then you can see who are blocked.
The Operators and higher can use this command.
Can someone help me with this??
This is the scirpt..

--100% Blocker by chill
--Table Load and Save (added by nErBoS)

sBot = "BLOCK-BOT"

cmd1 = "!block"
cmd2 = "!unblock"
--cmd3 = "!showblock"


BlockedNicks = {}
fBlock = "block.dat"
OpChatName = frmHub:GetOpChatName()	--Use this line for inbuilt Px opchat


--## Configuration ##--

uLaterPtokax = 1	-- Choose 0 if you are using Ptokax Version 0.3.3.0 or higher
			-- Choose 1 if you are using Ptokax Version lower then 0.3.3.0

--## END ##--

function Main()
	frmHub:RegBot(sBot)
	frmHub:EnableFullData(1) 
	LoadFromFile(fBlock)
end

function OnExit()
	SaveToFile(fBlock , BlockedNicks , "BlockedNicks")
end

BlockTriggs = {
	["$Rev"] = 1,
	["$Con"] = 2,
}

function DataArrival(curUser,data)
	if strsub(data,1,1) == "$" then
		local str1 = strsub(data,1,4)
		if BlockTriggs[str1] then
			if BlockedNicks[strlower(curUser.sName)] then
				curUser:SendData("*** You are not authorized to download.")
				return 1
			else if BlockTriggs[str1] == 1 then
				local _,_,conNick = strfind(data,"(%S+)|$")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
					return 1
				end
			else if BlockTriggs[str1] == 2 then
				local _,_,conNick = strfind(strsub(data,14,strlen(data)),"^(%S+)")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
					return 1
				end
			end
			end
			end
		end
	end
	if (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.iProfile == 5 or curUser.iProfile == 0 then
		data = strsub(data,1,strlen(data)-1)
		local _,_,cmd,nick = strfind(data,"%b<>%s+(%S+)%s+(%S+)")
		if cmd and cmd == cmd2 and nick then
			if BlockedNicks[strlower(nick)] then
				BlockedNicks[strlower(nick)] = nil
				SendPmToOps(OpChatName, nick.." is now unblocked.")
				return 1
			end
		else if cmd and cmd == cmd1 then
			if BlockedNicks[strlower(nick)] == 1 then
				curUser:SendPM(sBot, nick.." is already blocked. Use !unblock  to unblock this user.")
				return 1 
			else
				BlockedNicks[strlower(nick)] = 1
				SendPmToOps(OpChatName, nick.." is now blocked.") 
				return 1
			end
			if (uLaterPtokax == 1) then
				OnExit()
			end
				
			return 1  -- TELLS THE HUB TO STOP PROCESSING THE DATA
		end
		end
	end
end



function Serialize(tTable, sTableName, sTab)
	assert(tTable, "tTable equals nil");
	assert(sTableName, "sTableName equals nil");
	assert(type(tTable) == "table", "tTable must be a table!");
	assert(type(sTableName) == "string", "sTableName must be a string!");
	sTab = sTab or "";
	sTmp = ""
	sTmp = sTmp..sTab..sTableName.." = {\n"
	for key, value in tTable do
		local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);
		if(type(value) == "table") then
			sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
		else
			local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
			sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
		end
		sTmp = sTmp..",\n"
	end
	sTmp = sTmp..sTab.."}"
	return sTmp
end

function SaveToFile(file , table , tablename)
	writeto(file)
	write(Serialize(table, tablename))
	writeto()
end

function LoadFromFile(file)
	if (readfrom(file) ~= nil) then
		readfrom(file)
		dostring(read("*all"))
		readfrom()
	end
end

nErBoS

#36
Hi,

Try this...

--100% Blocker by chill
--Table Load and Save (added by nErBoS)

sBot = "BLOCK-BOT"

cmd1 = "!block"
cmd2 = "!unblock"
cmd3 = "!showblock"


BlockedNicks = {}
fBlock = "block.dat"
OpChatName = frmHub:GetOpChatName()	--Use this line for inbuilt Px opchat


--## Configuration ##--

uLaterPtokax = 1	-- Choose 0 if you are using Ptokax Version 0.3.3.0 or higher
			-- Choose 1 if you are using Ptokax Version lower then 0.3.3.0

--## END ##--

function Main()
	frmHub:RegBot(sBot)
	frmHub:EnableFullData(1) 
	LoadFromFile(fBlock)
end

function OnExit()
	SaveToFile(fBlock , BlockedNicks , "BlockedNicks")
end

BlockTriggs = {
	["$Rev"] = 1,
	["$Con"] = 2,
}

function DataArrival(curUser,data)
	if strsub(data,1,1) == "$" then
		local str1 = strsub(data,1,4)
		if BlockTriggs[str1] then
			if BlockedNicks[strlower(curUser.sName)] then
				curUser:SendData("*** You are not authorized to download.")
				return 1
			else if BlockTriggs[str1] == 1 then
				local _,_,conNick = strfind(data,"(%S+)|$")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
					return 1
				end
			else if BlockTriggs[str1] == 2 then
				local _,_,conNick = strfind(strsub(data,14,strlen(data)),"^(%S+)")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
					return 1
				end
			end
			end
			end
		end
	end
	if (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.iProfile == 5 or curUser.iProfile == 0 then
		data = strsub(data,1,strlen(data)-1)
		local _,_,cmd = strfind(data,"%b<>%s+(%S+)")
		local _,_,nick = strfind(data,"%b<>%s+%S+%s+(%S+)")
		if cmd and cmd == cmd2 and nick then
			if BlockedNicks[strlower(nick)] then
				BlockedNicks[strlower(nick)] = nil
				SendPmToOps(OpChatName, nick.." is now unblocked.")
				return 1
			end
		elseif cmd and cmd == cmd1 then
			if BlockedNicks[strlower(nick)] == 1 then
				curUser:SendPM(sBot, nick.." is already blocked. Use !unblock  to unblock this user.")
				return 1 
			else
				BlockedNicks[strlower(nick)] = 1
				SendPmToOps(OpChatName, nick.." is now blocked.") 
				return 1
			end
			if (uLaterPtokax == 1) then
				OnExit()
			end
				
			return 1  -- TELLS THE HUB TO STOP PROCESSING THE DATA
		elseif (cmd and cmd == cmd3 and curUser.bOperator) then
			local sTmp,aux,nick = "Users Blocked in this HUB:\r\n\r\n"
			for nick, aux in BlockedNicks do
				sTmp = sTmp.."User: "..nick.."\r\n"
			end
			curUser:SendPM(sBot, sTmp)
			return 1		
		end
	end
end



function Serialize(tTable, sTableName, sTab)
	assert(tTable, "tTable equals nil");
	assert(sTableName, "sTableName equals nil");
	assert(type(tTable) == "table", "tTable must be a table!");
	assert(type(sTableName) == "string", "sTableName must be a string!");
	sTab = sTab or "";
	sTmp = ""
	sTmp = sTmp..sTab..sTableName.." = {\n"
	for key, value in tTable do
		local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);
		if(type(value) == "table") then
			sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
		else
			local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
			sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
		end
		sTmp = sTmp..",\n"
	end
	sTmp = sTmp..sTab.."}"
	return sTmp
end

function SaveToFile(file , table , tablename)
	writeto(file)
	write(Serialize(table, tablename))
	writeto()
end

function LoadFromFile(file)
	if (readfrom(file) ~= nil) then
		readfrom(file)
		dostring(read("*all"))
		readfrom()
	end
end

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Hello Nerbos

I have tried it. But getting nothing.. with !showblock

No error of something like that. I tried some changes but no hope..

nErBoS

Hi,

I have fixed that in the script above.

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Hi

I have tried that script above bot isn't working or i do something wrong  :)) .

That's why my question.. I have tried many thing with the script above..

Greetings

honda

nErBoS

Hi,

I have tried and the script is working fine. What is not working ?? Do you have any error on the script editor of your ptokax ???

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Oke will test every thing tonight.. The big problem was   !showblock maybe i will change the name to something else.. Maybe that is the problem..

Greetings honda

Thnx voor response

nErBoS

Hi,

No problem on changing the command name for another command name, just need to change here...

cmd3 = "!showblock"

Best regards, nErBoS
--## nErBoS Spot ##--

johnynl

#43
    --100% Blocker by chill
    --Table Load and Save (added by nErBoS)

    sBot = "BLOCK-BOT"

    cmd1 = "!block"
    cmd2 = "!unblock"
    cmd3 = "!laatzien"


    BlockedNicks = {}
    fBlock = "block.dat"
    OpChatName = frmHub:GetOpChatName()   --Use this line for inbuilt Px opchat


    --## Configuration ##--

    uLaterPtokax = 0   -- Choose 0 if you are using Ptokax Version 0.3.3.0 or higher
             -- Choose 1 if you are using Ptokax Version lower then 0.3.3.0

    --## END ##--

    function Main()
       frmHub:RegBot(sBot)
       frmHub:EnableFullData(1)
       LoadFromFile(fBlock)
    end

    function OnExit()
       SaveToFile(fBlock , BlockedNicks , "BlockedNicks")
    end

    BlockTriggs = {
       ["$Rev"] = 1,
       ["$Con"] = 2,
    }

    function DataArrival(curUser,data)
       if strsub(data,1,1) == "$" then
          local str1 = strsub(data,1,4)
          if BlockTriggs[str1] then
             if BlockedNicks[strlower(curUser.sName)] then
                curUser:SendData("*** You are not authorized to download.")
                return 1
             else if BlockTriggs[str1] == 1 then
                local _,_,conNick = strfind(data,"(%S+)|$")
                if BlockedNicks[strlower(conNick)] then
                   curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
                   return 1
                end
             else if BlockTriggs[str1] == 2 then
                local _,_,conNick = strfind(strsub(data,14,strlen(data)),"^(%S+)")
                if BlockedNicks[strlower(conNick)] then
                   curUser:SendData("*** The user ..nick.. you are trying to download from is not authorized to upload.")
                   return 1
                end
             end
             end
             end
          end
       end
       if (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.iProfile == 5 or curUser.iProfile == 0 then
          data = strsub(data,1,strlen(data)-1)
          local _,_,cmd,nick = strfind(data,"%b<>%s+(%S+)%s+(%S+)")
          if cmd and cmd == cmd2 and nick then
             if BlockedNicks[strlower(nick)] then
                BlockedNicks[strlower(nick)] = nil
                SendPmToOps(OpChatName, nick.." is now unblocked.")
                SaveToFile(fBlock , BlockedNicks , "BlockedNicks")    ---------
                return 1
             end
          elseif cmd and cmd == cmd1 then
             if BlockedNicks[strlower(nick)] == 1 then
                curUser:SendPM(sBot, nick.." is already blocked. Use !unblock to unblock this user.")
                return 1
             else
                BlockedNicks[strlower(nick)] = 1
                SendPmToOps(OpChatName, nick.." is now blocked.")
                SaveToFile(fBlock , BlockedNicks , "BlockedNicks")    ---------
                return 1
             end
             if (uLaterPtokax == 1) then
                OnExit()
             end
                
             return 1  -- TELLS THE HUB TO STOP PROCESSING THE DATA
          elseif (cmd and cmd == cmd3 and curUser.bOperator) then
             LoadFromFile(file)   -------
             local sTmp,aux,nick = "Users Blocked in this HUB:\r\n\r\n"
             for nick, aux in BlockedNicks do
                sTmp = sTmp.."User: "..nick.."\r\n"
             end
    --         curUser:SendPM(sBot, sTmp)
             SendPMToOps(OpChatName, sTemp)
              return 1      
          end
       end
    end



    function Serialize(tTable, sTableName, sTab)
       assert(tTable, "tTable equals nil");
       assert(sTableName, "sTableName equals nil");
       assert(type(tTable) == "table", "tTable must be a table!");
       assert(type(sTableName) == "string", "sTableName must be a string!");
       sTab = sTab or "";
       sTmp = ""
       sTmp = sTmp..sTab..sTableName.." = {\n"
       for key, value in tTable do
          local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);
          if(type(value) == "table") then
             sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
          else
             local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
             sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
          end
          sTmp = sTmp..",\n"
       end
       sTmp = sTmp..sTab.."}"
       return sTmp
    end

    function SaveToFile(file , table , tablename)
       writeto(file)
       write(Serialize(table, tablename))
       writeto()
    end

    function LoadFromFile(file)
       if (readfrom(file) ~= nil) then
          readfrom(file)
          dostring(read("*all"))
          readfrom()
       end
    end

well this is what we got till this far now but the next part of the script does not give any error at all
also no text in any screen at all
    elseif (cmd and cmd == cmd3 and curUser.bOperator) then
             LoadFromFile(file)   -------
             local sTmp,aux,nick = "Users Blocked in this HUB:\r\n\r\n"
             for nick, aux in BlockedNicks do
                sTmp = sTmp.."User: "..nick.."\r\n"
             end
    --         curUser:SendPM(sBot, sTmp)
             SendPMToOps(OpChatName, sTemp)
              return 1      
          end

plz help us out
Yeah yeah ok
I am alway\'s running the latest Robocop version.
Im running Ptokax 0.3.3.0 build 17.05[debug]
Powered by: Robocop RCv10.01e

plz visit our hub at cccl-nl.no-ip.org:411

honda

#44
Hello

I try every thing.. But the show command is not working.. I can block and unblock ppl. But when i try !showblock or !please.. its not working.

The strange thing is no error on the ptokax software.. of that there is fault in data arrival or something.

It looks that it works good but i getting no pm with the names of de blocked ppl..

Kind regards Honda

nErBoS

Hi,

Honda...

The command will only work with a Master, not to OP.

johnynl...

change this...

SendPMToOps(OpChatName, sTemp)

to this...

SendPMToOps(OpChatName, sTmp)

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Thnx nerbos

Its working now.. With master en netfounder..

Nice work..  :D

johnynl

Yep great man.
but we still got one question:
is ot posible to add the name to the file who put the block?
would be a nice option to see that too, so we can take action if someone put's to many ppl on block

many thank for this script so far from our ops and me.
Yeah yeah ok
I am alway\'s running the latest Robocop version.
Im running Ptokax 0.3.3.0 build 17.05[debug]
Powered by: Robocop RCv10.01e

plz visit our hub at cccl-nl.no-ip.org:411

nErBoS

#48
Hi,

Here you have...

--100% Blocker by chill
--Table Load and Save (added by nErBoS)

sBot = "BLOCK-BOT"

cmd1 = "!block"
cmd2 = "!unblock"
cmd3 = "!showblock"


BlockedNicks = {}
fBlock = "block.dat"
OpChatName = frmHub:GetOpChatName()	--Use this line for inbuilt Px opchat


--## Configuration ##--

uLaterPtokax = 1	-- Choose 0 if you are using Ptokax Version 0.3.3.0 or higher
			-- Choose 1 if you are using Ptokax Version lower then 0.3.3.0

--## END ##--

function Main()
	frmHub:RegBot(sBot)
	frmHub:EnableFullData(1) 
	LoadFromFile(fBlock)
end

function OnExit()
	SaveToFile(fBlock , BlockedNicks , "BlockedNicks")
end

BlockTriggs = {
	["$Rev"] = 1,
	["$Con"] = 2,
}

function DataArrival(curUser,data)
	if strsub(data,1,1) == "$" then
		local str1 = strsub(data,1,4)
		if BlockTriggs[str1] then
			if BlockedNicks[strlower(curUser.sName)] then
				curUser:SendData("*** You are not authorized to download.")
				return 1
			else if BlockTriggs[str1] == 1 then
				local _,_,conNick = strfind(data,"(%S+)|$")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user "..nick.." you are trying to download from is not authorized to upload.")
					return 1
				end
			else if BlockTriggs[str1] == 2 then
				local _,_,conNick = strfind(strsub(data,14,strlen(data)),"^(%S+)")
				if BlockedNicks[strlower(conNick)] then
					curUser:SendData("*** The user "..nick.." you are trying to download from is not authorized to upload.")
					return 1
				end
			end
			end
			end
		end
	end
	if (strsub(data,1,1) == "<" or strsub(data,1,5+strlen(sBot)) == "$To: "..sBot) and curUser.iProfile == 5 or curUser.iProfile == 0 then
		data = strsub(data,1,strlen(data)-1)
		local _,_,cmd = strfind(data,"%b<>%s+(%S+)")
		local _,_,nick = strfind(data,"%b<>%s+%S+%s+(%S+)")
		if cmd and cmd == cmd2 and nick then
			if BlockedNicks[strlower(nick)] then
				BlockedNicks[strlower(nick)] = nil
				SendPmToOps(OpChatName, nick.." is now unblocked.")
				return 1
			end
		elseif cmd and cmd == cmd1 then
			if BlockedNicks[strlower(nick)] == 1 then
				curUser:SendPM(sBot, nick.." is already blocked. Use !unblock  to unblock this user.")
				return 1 
			else
				BlockedNicks[strlower(nick)] = curUser.sName
				SendPmToOps(OpChatName, nick.." is now blocked.") 
				return 1
			end
			if (uLaterPtokax == 1) then
				OnExit()
			end
				
			return 1  -- TELLS THE HUB TO STOP PROCESSING THE DATA
		elseif (cmd and cmd == cmd3 and curUser.bOperator) then
			local sTmp,aux,nick = "Users Blocked in this HUB:\r\n\r\n"
			for nick, aux in BlockedNicks do
				sTmp = sTmp.."User: "..nick.."\tBlocked by: "..aux.."\r\n"
			end
			curUser:SendPM(sBot, sTmp)
			return 1		
		end
	end
end



function Serialize(tTable, sTableName, sTab)
	assert(tTable, "tTable equals nil");
	assert(sTableName, "sTableName equals nil");
	assert(type(tTable) == "table", "tTable must be a table!");
	assert(type(sTableName) == "string", "sTableName must be a string!");
	sTab = sTab or "";
	sTmp = ""
	sTmp = sTmp..sTab..sTableName.." = {\n"
	for key, value in tTable do
		local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);
		if(type(value) == "table") then
			sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
		else
			local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
			sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
		end
		sTmp = sTmp..",\n"
	end
	sTmp = sTmp..sTab.."}"
	return sTmp
end

function SaveToFile(file , table , tablename)
	writeto(file)
	write(Serialize(table, tablename))
	writeto()
end

function LoadFromFile(file)
	if (readfrom(file) ~= nil) then
		readfrom(file)
		dostring(read("*all"))
		readfrom()
	end
end

BEWARE: If you use this script you must delete your "block.dat" because this will save the table with the nick of the person who blocked.

Best regards, nErBoS
--## nErBoS Spot ##--

honda

Cool.. Work Nerbos..

I have just make one adjustment  at this place

BlockedNicks[strlower(nick)] = user.sName


to this

BlockedNicks[strlower(nick)] = curUser.sName


Then it works great..

SMF spam blocked by CleanTalk