guilds-plugin / Guilds

Adding RPG to your server has never been more fun and action-packed!
MIT License
171 stars 59 forks source link

Guild Name Permission #126

Open Enyzat opened 5 years ago

Enyzat commented 5 years ago

Context

I need plus permissions into guild, with the guild name. That would look like this: guild.name.{guildname} .For example if I am in a guild called OKF, I would have a guild.name.okf permission. That would help me a lot. And other people could create many new features with it.

Enyzat

darbyjack commented 5 years ago

How do you propose we handle the permission nodes where a user might have a colored name / UTF characters in it?

Enyzat commented 5 years ago

I don't know but I need this feature. Now I have to add the permission to the player manually, and that is annoying, and if the player is no longer member of the guild I have to remove the permission from him. Do you know any solution? In my servers the guilds are fix, for example the okf is the National Directorate-General for Disaster Management (Országos Katasztófavédelmi Főigazgatóság). So with this perm they can use the guild's car, helicopter and they can 'fire-fighting'. I am very uncomfortable in this situation.

darbyjack commented 5 years ago

This seems more like a feature for a single server at this point, which is not something I can just implement for the sole purpose of a single user. I'm not entirely sure what your issue is, but the plugin is open source, therefore you could fork it and implement whatever you need for your server yourself, but at this point in time, since it's only been required a single time, I will not be implementing it until more people request it.

If I added every single request I've ever gotten for a single server, the plugin would be too bloated.

Enyzat commented 5 years ago

Do you know any other solution for my problem? :-/

darbyjack commented 5 years ago

Not aware of any kind of solution for that. You could just prevent people from leaving it once they join so that you don't have to worry about removing the permission nodes.

AeSix commented 5 years ago

I like this idea, and have a suggestion. It may help with storing in MySQL as well.

The guild name should be just a name (such as OKF), it can then have a display name (O҉KF́). the name would be used for administrative purposes, unique key, and permissions. The display name would then be detached from that, allowing for utf and color codes without affecting permissions.

Having per-guild permissions could also resolve issues with WorldGuard. One instance is pvp within a non-pvp region.

This could also allow for staff guilds, by adding the permission to the staff group - basically auto-enrolling staff into the guild, or having a config option to allow enrolling in the guild. This could be used for a more strict setup as well, where the server owners would set up pre-built guilds, and the players choose which guild they would like to be part of without having to be invited. Guild changes would either need to be manually done by an admin, or with the use of some method within Guilds which would basically reset the player to new, so there is no advantage to swapping guilds. Though, this may need to be an add-on to Guilds.

Another use-case for per-guild perms is for special events, special access areas - a guild member could potentially "purchase" (with in-game currencies, tokens, credits, etc, or possibly real life currencies) access to special areas of the map for their entire guild (by setting the WG access to allow anyone with the per-guild perm). This could range in antyhing from a mining area with a surplus of valuables, to a GvG arena.

And of course, this could be a togglable option in the config, to turn on per-guild perms.

darbyjack commented 5 years ago

Thanks for the in-depth response @AeSix . MySQL support is currently in the works. Each Guild is currently identified by a random UUID so that no matter what the name or the prefix is, we can always figure out which guild it is. My main concern with per-name guild permissions is that what if they change the name? It's a lot of work to handle supporting adding it on.

I have a counter-proposal for you to consider. So since each guild is identified by a UUID, why don't I just use the last set of hash digits to assign to guild permission? So if the UUID was ac596af1-a7d1-442c-b2a3-a410f681c30e I could use the last hash or the first hash. This would be to handle name changes and whatnot and prevent any future issues.

AeSix commented 5 years ago

Though UUID collisions are almost impossible, it's technically possible for a UUID to collide (a duplicate UUID) - This increases greatly when you have less digits. a UUID of 1 digit will collide when 0-9 are used (as an overly simplistic view)

Since you are already identifying the guilds with UUIDs - every aspect of the guild should be handled strictly with UUID. Each UUID should have a human-readable alias, preferably a-z,A-Z,0-9, and -,_ only (so 64 characters usable). No matter what, that UUID will always represent that alias, and vice-versa. That alias would then required to be unique. The alias would be generated from the supplied guild name at guild creation. The alias would then forevermore be tied to the UUID, and since the whole of the guild is tied to that UUID, as is the alias, no matter the name or displayname.

An example

-------------------------------------------------------------------------------------
|SQL Unique Key |   UUID        |   Alias       |   Name        |   DisplayName |
-------------------------------------------------------------------------------------
| 000000000001  |   UUID        |   AeSixGuild  |   AeSixGuild  |   AeSixGuild  |
| 000000000002  |   UUID        |   DarbyGuild  |   DarbyGuild  |   ^Darby^     |
| 000000000003  |   UUID        |   Chibi-Doge  |   Such_Guild  |   &lMuch-Wow  |
------------------------------------------------------------------------------------- 

line 1: I create a guild "AeSixGuild" - I never change the name, or the display name. All three fields are identical (It would be better to check if the Name/DisplayName fields had been populated actually)

line 2: You created "DarbyGuild" and never changed the name, but you changed the displayname to "^Darby^"

link 3: Someone else created "Chibi-Doge" - but they changed they Name to "Such_Guild" /and/ changed the displayname to "Much-Wow" (as seen with the &l)

In any circumstance, the Alias remains, and can be used for human-readable data, such as permissions.

You could do something cool with that too, like have the UUID/Alias string appear on hover over for the guild badge in chat, so no matter the name or displayname, at least admins would be able to identify the alias, for confirmation/verification, etc.

darbyjack commented 5 years ago

I see your point in this situation. My only concern is how do you plan to handle the current JSON implementation of it? If a user is simply just wanting to have permission to tie to their guild, why wouldn't the current partial hash of the guild UUID work fine? I could even add in an extra check to make you feel safer on the creation of a guild. I'll have to try to match the UUID of a guild being created to all existing guilds. If the UUID hash matches another (again, very unlikely) it'll just generate another one and give it to the guild. This would be a simple way to handle the JSON implementation of it and would still work for the SQL version of it. Your way only seems to cover how to handle it when it's on MySQL.

AeSix commented 5 years ago

The data relationships can be the same for all - json, yml, sql. The structure is what changes. SQL has advantages over flat file in being able to cache certain things, and make associations between data, but that's optimization, not function.

Here's what it could look like in json:

{
  "AeSixGuild": {   <-- the alias (would be converted from current version's guild "name"
    "uuid": "00000000-0000-0000-0000-000000000000",
    "name": "AeSixGuild", <-- Would also be converted form current version's guild "name", stripping UTF/colors
    "displayname"  <-- converted from current versions' "name", keeping utf/colors

And for converting to SQL if the admin so chooses to do, you would just import that data into the db one at a time, to allow the db server to assign the unique key (which probably don't even need to be used by the Guilds plugin)

The json structure would be based on the alias, and so do a quick lookup for just the alias, comparing the new guild name with the aliases from the json file.

At the point you're willing to truncate a UUID and then add a seed seems overly complicated when you could just handle the UUID. As far as doing lookups by UUID, you're already doing that with player UUIDs inside guilds. Caching the UUID/alias relation in memory, and garbage collecting when the last guild member leaves the server should take up too much space.

The goal here is to handle guilds by alias for any human tasks. Ultimately, this would lead to players being able to address the guild by it's alias, no matter how often the owner changes the guilds name. It would be easier on staff, for administrative purposes as well.

AeSix commented 5 years ago

I was thinking, it might be a good idea to split the guild meta info into a file by itself, and the guild memberships into a separate file. This would be the same as using a couple of different tables in sql, and may be a helpful step for you mysql branch.

guilds.json would have the members (and their roles) pulled out and put into guild-members.json

splitting into two files could potentially see performance increases with lookups, both for guilds and members, as well as set the stage for a better mysql structure implementation.

When looking up by alias, you would look in the guilds.json file - this is helpful for new guild name comparisons. When looking up a guild's members (especially useful for per-guild perms), you would search the UUID in the guild-members.json, as it would be UUID based.

I may have that backwards though. 🤔

darbyjack commented 5 years ago

I think everything that you have talked about is certainly a possibility. My current concern is I've already changed the data so much lately and if I were to redesign it yet again, I feel it would be a very confusing time for players. I'm not saying no to this forever, I'm just saying it's something to heavily consider for the time being.

It seems like overkill for a single feature (pertaining to the original reason this issue was opened). This is something that could be implemented in the future, but this is honestly not my current focus right now. Maybe a goal for over the summer.

This project is currently pretty big (currently 120 classes last time I checked) and I feel that I have to put other things on a higher priority for the time being.

You really seem to be someone who knows what they are talking about and I'd love to continue to talk about this either here or via Discord. Your insight could be pretty key to the future of this project in terms of stability and optimization.

AeSix commented 5 years ago

Unfortunately I'm not skilled as a programmer. I could probably do all the work myself, but it'd be Christmas before I got something working lol.

I've been around a long time, I understand the concepts and principles. My wife is a developer, has been for 25+ years, and over the last several that we've been together, she's taught me a lot.

I'm better at bash, commandhelper scripts than I am with Java - but even bash and CH can utilize multiple methods of data storage, and so I've do a lot of research into that for some projects I'm working on.

What I've said could be done over time, even be able to create the guild-members.json file, and just not use it for a few versions, just make sure it's working properly. Then enable a "experiemental" setting in the config to allow admins to test it for readability at some point. Keep duplicating the data in guilds.json and guild-members.json, as need until the time comes to stop writing members to guilds.json - and just ignore the members that are there (making sure they've been added to guild-members.json, of course) That too could be confusing, but if they're playing with an experimental feature, which could be outlined in comments in the config file, then they should have some understanding of what they're doing.

As far as more pressing issues, I understand that as well. I feel the route I've laid out could be beneficial to both the advent of MySQL storage as well as tertiary features (perms). It could be something done over time, as I pointed out above - but it would be a lot easier to implement when/if the time comes, if decisions going forward keep that route in mind.

Good luck!

darbyjack commented 5 years ago

It's funny cause I'm actually the other way around. While I know how to program, I'm only recently new to programming as a whole over the past few years. I'm not that good with coming up with ideas, but I know how to turn ideas into code.

I will make sure to leave this issue open so I remember to check this out from time to time in order to keep it alive and a possibility.

One thing I'll probably do is look for some kind of software I can use while testing to get some in-depth results on how different methods/functions work for memory and whatnot.

Currently, the way JSON implementation works is that on the startup of the server, the plugin will loop through all the files in the data folder and then we use a library called GSON (developed by Google) to deserialize the files into actual Guild objects. While the server is running, all those objects are constantly being modified via in-game actions such as creating new guilds, members joining, members leaving, and whatnot and so on. Then, when the server shuts down, the plugin will go and grab that list of Guild objects and then save them back into the respective files.

Once I'm able to sit down and do some testing, I'd be able to see how much memory is currently being used and if/how I can optimize it to make it work better on the server.

The good news is I have not heard of any kind of memory leaks so I feel the foundation of data storage is fairly solid right now, but everything can always be improved.

If you or your wife have any suggestions/ideas, I'm 100% open to talking to people who have been doing this longer than I have. I know I have a long ways to go and there are many ways that this plugin could still be optimized.

I'm just trying to give the players the best I can!