Need help on friends list

Post Reply
ChristienChapman
Member
Posts: 117
Joined: Sat May 28, 2022 00:04

Need help on friends list

by ChristienChapman » Post

I am going to add a friends list to Minetest Zombies Minigame but I have two issues...

1. How do I get a list of players who have created an account on the server (authorized?) and put them into a comparable list which can be gathered together, then, when the player searches for that person to add, they can do so since they are on the list. I'm willing to compromise and just do connected players instead if it is not possible.

2. How do I store a simple array of 16 strings to store friends. It also needs to be editable, as in a friend can be removed from the list. And finally, how do I access this array of 16 for each user? I could use the get playername. Reminder: all of these are stored seperately for each user.

Anyone who helps will be credited in my project.

Thanks and God bless you!
God bless you.

List of releases:
Minetest Zombies Minigame - viewtopic.php?f=9&t=28442&p=412633#p412633

- > cdb_1d60e1a03f83

User avatar
Blockhead
Member
Posts: 1624
Joined: Wed Jul 17, 2019 10:14
GitHub: Montandalar
IRC: Blockhead256
In-game: Blockhead Blockhead256
Location: Land Down Under
Contact:

Re: Need help on friends list

by Blockhead » Post

I did do a cursory search but apparently nobody has written a mod for this purpose yet. It should be possible to write a general-purpose mod for this kind of thing. I'll outline it below.

First, you will want to persist your friends data properly. For something this small, basically a simple table, I would use mod storage. You will want to write back to mod storage periodically or when operations happen. I'll include writing back to the mod storage in all the code examples that follow. I haven't tested the code properly, but you should be able to copy all the pieces into a mod.

Code: Select all

-- friends being the hypothetical mod name
friends = {}
friends.storage = minetest.get_mod_storage()
1. You can get a list from the authentication handler by the .iterate method, and cache that into your own mod's table. We'll add it as an empty table to begin with.

Code: Select all

friends.players = {}
for playername in minetest.get_auth_handler().iterate() do
	local record = friends.storage.get_string(playername)
	if record == "" then
		friends.players[playername] = {}
		return
	end
	friends.players[playername] = minetest.deserialize(record, true)
end
Let's add on_joinplayer and on_leaveplayer callbacks as well to make sure our list does not get out of date if new players join while the server is running:

Code: Select all

minetest.register_on_joinplayer(function(player, last_login)
	if last_login ~= nil then return end
	friends.players[player:get_player_name()] = {}
	friends.storage.set_string(playername, minetest.serialize({})
end)

minetest.register_on_leaveplayer(function(player, timed_out))
	-- No-op for now, but you can add something like a 'last online' timestamp here.
end)
Then you would be able to add something like a chat command (formspecs are also possible but don't make for good succinct examples) to search for friends. Of course some people may not want to be found, so you could add a way to let people opt out, but let's assume for simplicity's sake everyone is fine with wanting to be found.

Code: Select all

minetest.register_chatcommand("find_player", {
	params = "find_player <part of name>",
	description "Search for players who have played on this server by a part of their name",
	func = function(name, param)
		local matches = {}
		for playername in minetest.get_auth_handler().iterate() do
			if string.find(playername, param, nil, true) then
				table.insert(matches, playername)
			end
		end
		return true, "Found players: " .. table.concat(matches, ", ")
	end
})
There are a lot of improvements that could be made like nicer formatting, GUIs, fuzzy finding but that's the bare bones of it. Next is actually adding and storing the friends in part 2 of your question.

2. The Lua-preferred way to do it is not to use arrays but tables with named indexes. I have been doing it this way up to now without quite explaining it. Indices scales a lot better for larger numbers of players as friends, although it can be worse for smaller numbers. I'm just going to do it the Lua way though because I think it's important to understand how to deal with tables properly and not just as purely arrays. The structure of the friends.players table if printed it might look like this:

Code: Select all

{
	Alice = {
		Bob = true,
		Charlie = true,
	},
	Bob = {
		Alice = true,
	},
	Charlie = {}
}
This assumes friendship is a one-way arrangement from each side, which I think is how a lot of games handle friends lists, though many websites like Facebook require mutual friendship, but that serves different purposes. In Minetest, you can easily see who is online anyway so friendship just provides an easy avenue to track when your friends were last online and so on.

Let's write out the skeleton of the commands to add and remove a friend now. We assume people will use either find_friend from above or see the usernames of online people.

Code: Select all

minetest.register_chatcommand("friend_add", {
	params = "friend_add <username>",
	description = "Add a player to your friends list",
	func = function(name, param)
		if friends.players[param] == nil then
			return false, "No such player"
		end
		friends.players[name][param] = true
		friends.storage.set_string(name, minetest.serialize(friends.players[name]))
		return true, "Added '" .. param .. "' as a friend"
	end
})

minetest.register_chatcommand("friend_remove", {
	params = "friend_remove username",
	description = "Remove a player from your friends list",
	func = function(name, param)
		friends.players[name][param] = nil
		friends.storage.set_string(name, minetest.serialize(friends.players[name]))
		return true, "Removed '" .. param  .. "' as a friend"
	end
})
That's the skeleton of the mod all together. Like I said, I haven't tested it properly, just written it up here. But I hope that helps you get started anyway. The core things to know here are that Minetest has a mechanism to query all the user data and that you can use the mod storage API to store persistent data from your own mod. You can post followup questions if need be.
/˳˳_˳˳]_[˳˳_˳˳]_[˳˳_˳˳\ Advtrains enthusiast | My map: Noah's Railyard | My Content on ContentDB ✝️♂

ChristienChapman
Member
Posts: 117
Joined: Sat May 28, 2022 00:04

Re: Need help on friends list

by ChristienChapman » Post

Woah I was not expecting a full on api. Thanks. I had a cheesy way of doing this but this looks way better!
God bless you.

List of releases:
Minetest Zombies Minigame - viewtopic.php?f=9&t=28442&p=412633#p412633

- > cdb_1d60e1a03f83

ChristienChapman
Member
Posts: 117
Joined: Sat May 28, 2022 00:04

Re: Need help on friends list

by ChristienChapman » Post

Disregard post, a solution has been found. Thanks everyone for your submissions!
God bless you.

List of releases:
Minetest Zombies Minigame - viewtopic.php?f=9&t=28442&p=412633#p412633

- > cdb_1d60e1a03f83

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests