Jump to content
ahmad

Limit players enter per mac

Recommended Posts

Hello, @ahmad!

 

You can try make the limit in a function after_enter_<mapname>(role), file ctrl.lua of required map.

 

1) Get MAC of role using LuaSQL;

2) Check that the MAC was used no more than X times (N <= X);

3) if the limit is exceeded, then kick the character from the map;

4) else increment N - number of MAC uses.

 

Also you will need decrease N in function before_leave_<mapname>(role), when role leaves the map.

 

Another way:

1) Execute the following SQL query using LuaSQL (example):

SELECT l.last_login_mac, COUNT (c.cha_id) AS n FROM GameDB.dbo.character AS c LEFT JOIN GameDB.dbo.account AS a ON (a.act_id = c.act_id) LEFT JOIN AccountServer.dbo.account_login AS l ON (l.name = a.act_name COLLATE Cyrillic_General_CI_AS) WHERE c.mem_addr = 0 AND c.map = 'garner' GROUP BY l.last_login_mac

It will return the number of each MAC (N) used in the map. 

2) Get MAC of role using LuaSQL;

3) Find role's MAC in the query result and get N;

4) Check that the MAC was used no more than X times (N <= X);

5) ...


Share this post


Link to post
Share on other sites
4 hours ago, V3ct0r said:

Hello, @ahmad!

 

You can try make the limit in a function after_enter_<mapname>(role), file ctrl.lua of required map.

 

1) Get MAC of role using LuaSQL;

2) Check that the MAC was used no more than X times (N <= X);

3) if the limit is exceeded, then kick the character from the map;

4) else increment N - number of MAC uses.

 

Also you will need decrease N in function before_leave_<mapname>(role), when role leaves the map.

 

Another way:

1) Execute the following SQL query using LuaSQL (example):


SELECT l.last_login_mac, COUNT (c.cha_id) AS n FROM GameDB.dbo.character AS c LEFT JOIN GameDB.dbo.account AS a ON (a.act_id = c.act_id) LEFT JOIN AccountServer.dbo.account_login AS l ON (l.name = a.act_name COLLATE Cyrillic_General_CI_AS) WHERE c.mem_addr = 0 AND c.map = 'garner' GROUP BY l.last_login_mac

It will return the number of each MAC (N) used in the map. 

2) Get MAC of role using LuaSQL;

3) Find role's MAC in the query result and get N;

4) Check that the MAC was used no more than X times (N <= X);

5) ...

can you please explain how the function could be?
i'm using this to get the players mac
 

function GetAccountMAC(Player)
	local AccountName = GetActName(Player)
	local String = "SELECT last_login_mac FROM AccountServer.dbo.account_login WHERE name = '"..AccountName.."'"
	local Connect, CID = LuaSQL("connect", SQL.AccountServer.Host, SQL.AccountServer.User, SQL.AccountServer.Password)
	if Connect == SQL_SUCCESS_WITH_INFO then
		local Success, Query = LuaSQL("query", CID, String)
		if Success == SQL_SUCCESS_WITH_INFO then
			local Data = LuaSQL("fetch", CID, Query)
			LuaSQL("freehandle", CID, Query)
			LuaSQL("close", CID)
			return Data["last_login_mac"]
		end
	end
end

can use your query like this or how?
 

function GetAccountMACn(Player)
local AccountName = GetActName(Player)
local String = "SELECT l.last_login_mac, COUNT (c.cha_id) AS n FROM GameDB.dbo.character AS c LEFT JOIN GameDB.dbo.account AS a ON (a.act_id = c.act_id) LEFT JOIN AccountServer.dbo.account_login AS l ON (l.name = a.act_name COLLATE Cyrillic_General_CI_AS) WHERE c.mem_addr = 0 AND c.map = 'garner' GROUP BY l.last_login_mac"
	local Connect, CID = LuaSQL("connect", SQL.AccountServer.Host, SQL.AccountServer.User, SQL.AccountServer.Password, SQL.GameDB.Host, SQL.GameDB.User, SQL.GameDB.Password)
	if Connect == SQL_SUCCESS_WITH_INFO then
		local Success, Query = LuaSQL("query", CID, String)
		if Success == SQL_SUCCESS_WITH_INFO then
			local Data = LuaSQL("fetch", CID, Query)
			LuaSQL("freehandle", CID, Query)
			LuaSQL("close", CID)
			return Data["l.last_login_mac"]
		end
	end
end

 

Share this post


Link to post
Share on other sites

Using this function:

function GetAccountMAC(Player)
	local AccountName = GetActName(Player)
	local String = "SELECT last_login_mac FROM AccountServer.dbo.account_login WHERE name = '"..AccountName.."'"
	local Connect, CID = LuaSQL("connect", SQL.AccountServer.Host, SQL.AccountServer.User, SQL.AccountServer.Password)
	if Connect == SQL_SUCCESS_WITH_INFO then
		local Success, Query = LuaSQL("query", CID, String)
		if Success == SQL_SUCCESS_WITH_INFO then
			local Data = LuaSQL("fetch", CID, Query)
			LuaSQL("freehandle", CID, Query)
			LuaSQL("close", CID)
			return Data["last_login_mac"]
		end
	end
end

Do this (using Chaos Argent as an example):

ChaosArgentMAC = ChaosArgentMAC or {}

function check_can_enter_garner2(Player, CopyMGR)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = ChaosArgentMAC[PlayerMac] or false
	if ChaosArgentMAC[PlayerMac] then
		return 0
	end
end
function after_enter_garner2(Player, MapCopy)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = true
end
function before_leave_garner2(Player)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = false
end
function map_copy_close_garner2(MapCopy)
	...
	ChaosArgentMAC = {}
end

Give that a try and let me know. Although it relies heavily on loading LuaSQL constantly when trying to enter, entering and leaving so I don't know what effects it may have on server stability when having a high player base. Also just in case, reset the variable after map closing so it's persistent.

Also, I don't know if the variable will be stored correctly, maybe you can convert it to a string so it stores without a problem? Don't know. Try the above, if any issues then convert the MAC address using "tostring" function on each "GetAccountMAC" call.

Edited by Angelix
  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, Angelix said:

Using this function:


function GetAccountMAC(Player)
	local AccountName = GetActName(Player)
	local String = "SELECT last_login_mac FROM AccountServer.dbo.account_login WHERE name = '"..AccountName.."'"
	local Connect, CID = LuaSQL("connect", SQL.AccountServer.Host, SQL.AccountServer.User, SQL.AccountServer.Password)
	if Connect == SQL_SUCCESS_WITH_INFO then
		local Success, Query = LuaSQL("query", CID, String)
		if Success == SQL_SUCCESS_WITH_INFO then
			local Data = LuaSQL("fetch", CID, Query)
			LuaSQL("freehandle", CID, Query)
			LuaSQL("close", CID)
			return Data["last_login_mac"]
		end
	end
end

Do this (using Chaos Argent as an example):


ChaosArgentMAC = ChaosArgentMAC or {}

function check_can_enter_garner2(Player, CopyMGR)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = ChaosArgentMAC[PlayerMac] or false
	if ChaosArgentMAC[PlayerMac] then
		return 0
	end
end
function after_enter_garner2(Player, MapCopy)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = true
end
function before_leave_garner2(Player)
	...
	local PlayerMac = GetAccountMAC(Player)
	ChaosArgentMAC[PlayerMac] = false
end
function map_copy_close_garner2(MapCopy)
	...
	ChaosArgentMAC = {}
end

Give that a try and let me know. Although it relies heavily on loading LuaSQL constantly when trying to enter, entering and leaving so I don't know what effects it may have on server stability when having a high player base. Also just in case, reset the variable after map closing so it's persistent.

Also, I don't know if the variable will be stored correctly, maybe you can convert it to a string so it stores without a problem? Don't know. Try the above, if any issues then convert the MAC address using "tostring" function on each "GetAccountMAC" call.

he can use this way too , but its may be heavily loading idk 
 


function UPOGCin(Player)--player enter
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	
	local macplayer = GetAccountMAC(Player)
	
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
	end
	if UPOGCmap[macplayer].Limit > 2 then
	UPOGCmap[macplayer].Limit = 2
	end
	UPOGCmap[macplayer].Limit = UPOGCmap[macplayer].Limit + 1
	table.save(UPOGCmap, File)
end
function UPOGCout(Player)--player leave
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	
	local macplayer = GetAccountMAC(Player)
	
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
	end
	if UPOGCmap[macplayer].Limit < 0 then
	UPOGCmap[macplayer].Limit = 0
	end
	UPOGCmap[macplayer].Limit = UPOGCmap[macplayer].Limit - 1
	table.save(UPOGCmap, File)
end
function after_enter_UPOGC(role, map_copy)
UPOGCin(role)
end

before_leave_UPOGC(role)
UPOGCout(role)
	
end

function check_can_enter_UPOGC(role, copy_mgr)

	local UPOGC_charlimits = 2	--  mean player can join with 2 characters only --
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	local macplayer = GetAccountMAC(role)
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
		end
	if UPOGCmap[macplayer].Limit >= UPOGC_charlimits then
	BickerNotice(role,"You have  2 characters Inside")
	return 0
	end
end

this one works fine , 

Edited by mkhzaleh
  • Like 1

Share this post


Link to post
Share on other sites

Well of course it can work. The issue still persist and you amplified it though. On a server, opening and closing too many files at once will hang the server, and that’s what serialization does. It should work with the code I provided, maybe adjust a bit to allow more than one address per map so no use of aerialization. 

 

No no issues should arise on a low population server, the problem starts when a high population server uses a heavily triggered function that uses serialization (don’t know if it gets caused on LuaSQL). The GameServer will constantly open and close text files (generated by serialization) when called by the function and it will cause lag (hang by causing functions long execution times). 

 

Also, too much code and mine is less lines. Hahah

  • Like 1

Share this post


Link to post
Share on other sites


if won't use serialization  , this @Angelix function but will allow u to adjust  how many characters  can join  , 

ChaosArgentMAC = ChaosArgentMAC or {} 


function check_can_enter_halloween( role, copy_mgr )
----------Player characters check inside the maze------
local PlayerMac = tostring(GetAccountMAC(role))
		local	limit = 2
		if ChaosArgentMAC[PlayerMac] == limit then
		Notice("you can't enter")
		return 0
		end
-------------

return 1
end
function after_enter_halloween(role, map_copy)

	local PlayerMac = tostring(GetAccountMAC(role))
	if ChaosArgentMAC[PlayerMac] == nil then
	ChaosArgentMAC[PlayerMac] = 0
	end
	
	ChaosArgentMAC[PlayerMac] = ChaosArgentMAC[PlayerMac] + 1
	Notice(""..ChaosArgentMAC[PlayerMac].."")

end
function before_leave_halloween(role)

	local PlayerMac = tostring(GetAccountMAC(role))
	if ChaosArgentMAC[PlayerMac] == nil then
	ChaosArgentMAC[PlayerMac] = 0
	end
	
	ChaosArgentMAC[PlayerMac] = ChaosArgentMAC[PlayerMac] - 1
	Notice(""..ChaosArgentMAC[PlayerMac].."")
	

end
function map_copy_close_halloween(MapCopy)
	
	ChaosArgentMAC = {}
end

image.png.558774e7709cb61c21aa6b9a1b4d0a71.png

Share this post


Link to post
Share on other sites

There you go since I saw you added 'tostring'.

ChaosArgentMac = ChaosArgentMac or {}
ChaosArgentMacLimit = 1
function check_can_enter_garner2(Player, CopyMGR)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] or 0
	if ChaosArgentMac[PlayerMac] >= ChaosArgentMacLimit then
		SystemNotice(Player, "You cannot enter since you already have "..ChaosArgentMacLimit.." accounts inside.")
		return 0
	end
end
function after_enter_garner2(Player, MapCopy)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] + 1
end
function before_leave_garner2(Player)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] - 1
end
function map_copy_close_garner2(MapCopy)
	...
	ChaosArgentMac = {}
end

 

Share this post


Link to post
Share on other sites
On 2/25/2019 at 9:06 PM, Angelix said:

There you go since I saw you added 'tostring'.


ChaosArgentMac = ChaosArgentMac or {}
ChaosArgentMacLimit = 1
function check_can_enter_garner2(Player, CopyMGR)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] or 0
	if ChaosArgentMac[PlayerMac] >= ChaosArgentMacLimit then
		SystemNotice(Player, "You cannot enter since you already have "..ChaosArgentMacLimit.." accounts inside.")
		return 0
	end
end
function after_enter_garner2(Player, MapCopy)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] + 1
end
function before_leave_garner2(Player)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] - 1
end
function map_copy_close_garner2(MapCopy)
	...
	ChaosArgentMac = {}
end

 

Hmm can anyone guide or help? Willing to pay :)

Share this post


Link to post
Share on other sites
On 2/25/2019 at 4:19 AM, mkhzaleh said:

he can use this way too , but its may be heavily loading idk 
 



function UPOGCin(Player)--player enter
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	
	local macplayer = GetAccountMAC(Player)
	
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
	end
	if UPOGCmap[macplayer].Limit > 2 then
	UPOGCmap[macplayer].Limit = 2
	end
	UPOGCmap[macplayer].Limit = UPOGCmap[macplayer].Limit + 1
	table.save(UPOGCmap, File)
end
function UPOGCout(Player)--player leave
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	
	local macplayer = GetAccountMAC(Player)
	
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
	end
	if UPOGCmap[macplayer].Limit < 0 then
	UPOGCmap[macplayer].Limit = 0
	end
	UPOGCmap[macplayer].Limit = UPOGCmap[macplayer].Limit - 1
	table.save(UPOGCmap, File)
end
function after_enter_UPOGC(role, map_copy)
UPOGCin(role)
end

before_leave_UPOGC(role)
UPOGCout(role)
	
end

function check_can_enter_UPOGC(role, copy_mgr)

	local UPOGC_charlimits = 2	--  mean player can join with 2 characters only --
	local pKey = "pKey"
	local File = GetResPath("../PlayerData/GoddessCollisio/"..pKey..".db")
	local macplayer = GetAccountMAC(role)
	if UPOGCmap == nil then
		if file_exists(File) == false then
			UPOGCmap = {}
			table.save(UPOGCmap, File)
		else
			UPOGCmap = table.load(File)
		end
	end
		if UPOGCmap[macplayer] == nil then
		UPOGCmap[macplayer] = {Limit = 0}
		table.save(UPOGCmap, File)
		end
	if UPOGCmap[macplayer].Limit >= UPOGC_charlimits then
	BickerNotice(role,"You have  2 characters Inside")
	return 0
	end
end

this one works fine , 

Could you tell me where you placed this function, to also put it on my server

Share this post


Link to post
Share on other sites
21 hours ago, eatsangels said:

Could you tell me where you placed this function, to also put it on my server

Looks like this code is located in the file:

GameServer\resource\UPOGC\ctrl.lua

 


Share this post


Link to post
Share on other sites
57 minutes ago, V3ct0r said:

Looks like this code is located in the file:


GameServer\resource\UPOGC\ctrl.lua

 

That folder is not inside my files. If I create the folder and create the .lua, will it work the same?

Share this post


Link to post
Share on other sites
On 8/15/2022 at 3:04 PM, eatsangels said:

That folder is not inside my files. If I create the folder and create the .lua, will it work the same?

Instead of "UPOGC" use a map on which you want apply the script. Do not forget rename functions accordingly with your map name.


Share this post


Link to post
Share on other sites
1 hour ago, V3ct0r said:

Instead of "UPOGC" use a map on which you want apply the script. Do not forget rename functions accordingly with your map name.

I tried to paste the script and change the name but it didn't work for me

Share this post


Link to post
Share on other sites
Just now, V3ct0r said:

Instead of "UPOGC" use a map on which you want apply the script. Do not forget rename functions accordingly with your map name.

put the function at the end of all and change the function name from function UPOGCin(Player)--player enter to garner2in(Player)--player enter and the map does not open. Could you tell me in which part is that the function goes. At the end, at the beginning, or should I remove one of the ones on the map.

Edited by eatsangels

Share this post


Link to post
Share on other sites
On 8/18/2022 at 5:48 AM, V3ct0r said:

Instead of "UPOGC" use a map on which you want apply the script. Do not forget rename functions accordingly with your map name.

Could you tell me then in which part is that I should paste the script. If I want it to be for CA (Garner 2), what should I do?

Share this post


Link to post
Share on other sites
On 2/25/2019 at 11:06 PM, Angelix said:

There you go since I saw you added 'tostring'.


ChaosArgentMac = ChaosArgentMac or {}
ChaosArgentMacLimit = 1
function check_can_enter_garner2(Player, CopyMGR)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] or 0
	if ChaosArgentMac[PlayerMac] >= ChaosArgentMacLimit then
		SystemNotice(Player, "You cannot enter since you already have "..ChaosArgentMacLimit.." accounts inside.")
		return 0
	end
end
function after_enter_garner2(Player, MapCopy)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] + 1
end
function before_leave_garner2(Player)
	...
	local PlayerMac = tostring(GetAccountMAC(Player))
	ChaosArgentMac[PlayerMac] = ChaosArgentMac[PlayerMac] - 1
end
function map_copy_close_garner2(MapCopy)
	...
	ChaosArgentMac = {}
end

 

Could you help me please?. I want to implement this script on some of my maps and I haven't been able to get it to work. Some help please.

Share this post


Link to post
Share on other sites

Hello @eatsangels,

 

I don't know how this script work and what dependencies are needed for it to work. And honestly, I don't want to understand it. I can only give some general advice.

 

Also, maybe it's not a good solution to restrict map entry by MAC address? The MAC address can be easily spoofed. IMHO, it is better to take some valuable resource from players (gold, reputation points, items).


Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...