Assign stable UUIDs to characters
magicus opened this issue ยท 10 comments
I have a plan, but I'm not going to be able to address it for a while. I'll sketch my idea here, and leave it open for anyone else to implement if they want. (Otherwise I'll do it when I get around to it.)
From the Wynncraft API we can get a json description of a player. Here is one describing me: https://api.wynncraft.com/v2/player/ca3ee631-a36c-48f4-9007-3c3c52c79840/stats
This contains, among other things, an array with all classes. The order in this array is similar to the order in the class selection screen, but not the same. API order is "total level", but class selection is "combat level". So there is not a simple 1-to-1 match that way. Also, API updates rather slowly. Actual changes in the characters take time (hours?) to propagate.
But. Thew good news is that the API has a stable naming of characters. In the object describing each class, there is a field "name", which will be unique per character. It is comprised of the class type (e.g. "archer") plus a monotonically increasing number (starting at 0, which is omitted). So the first archer you create is named "archer", the second "archer1", the next "archer2" etc. Even if you create and remove classes, numbers are not reused (confirmed).
What remains is to match characters found in the class selection screen with these characters from the API. We'll have to do a bit of fuzzy matching, but I think it'll be okay for all practical purposes. We can match on:
- class
- reskinned or not (the API name is "darkwizard" for a reskinned mage)
- combat level (bearing in mind that the class selection level can be slightly higher, but never lower, since the API lags a bit)
- combat XP percentage (with the same caveat; also if level has increased then XP can be lower as well)
- number of finished quests
It would be really bad luck if a player has two characters that match on all these properties. If that happens I think we might be excused if we make a mismatch. (We can detect if this happens and either print a warning, or refuse to do matching until they have changed level/number of quests) on one of them.)
Finally, I think we should assign these characters an unique UUID. We can do this by:
String uniqueName = player.getUUID() + "-" + character.getName();
characterUUID = UUID.nameUUIDFromBytes(uniqueName.getBytes());
or if we want to be really fancy and do it the Right Way for v3 UUIDs:
public static final UUID WYNNCRAFT_CHARACTER_NAMESPACE = new UUID("ac64c234-48c3-4e3f-ad29-6694affcfbfa"); // randomly generated UUID that just needs to be kept the same
String uniqueName = WYNNCRAFT_CHARACTER_NAMESPACE + "-" + player.getUUID() + "-" + character.getName();
characterUUID = UUID.nameUUIDFromBytes(uniqueName.getBytes());
Ideally, this UUID generation should be done by Wynncraft themselves. Maybe we should pest @HeyZeer0 until he implements it? ๐
One thing I'd really like to see, once we have stable UUIDs for characters, is to be able to assign names to characters. I'm soo longing for that. :)
reskinned or not (the API name is "darkwizard" for a reskinned mage)
players with the hero rank are able to change the skin of a class after creating it - have you tested how this interacts with the api? i assume it updates the name, but it would make life difficult if it didn't
Yes, my "archer4" became "hunter1". So that's, well, perhaps both good and bad. We need to handle that as a possible case as well.
Note for self:
Common fields between API and Character selection:
- Class
- Reskinned
- Combat level
- Finished quests
These may not match 100% though. I have a character which the API claims has done 108 quests, but the character selection screen says 110. (Maybe it is counting old, removed quests?)
Once we have selected a character though, things change. Now we have access to the compass menu, and can now also get the following common fields:
- Skill points
- Profession levels
- Actual list of completed quests
- Gamemode (hardcore etc)? (Possibly)
This should be enough to basically determine for all practical reasons that we has indeed selected the correct character.
@magicus this will be implemented by Wynncraft soon, see https://forums.wynncraft.com/threads/2-0-1-full-changelog.304461/.
For the past years, we have been storing characters with a unique identifier that consisted of the class type and the number of the same type of classes the player had (e.g hunter#4), this scheme was elaborated years ago and brought many issues alongside it. Within the release of the update, we are going to migrate all character data from using these ids to UUIDs in order to address these issues, with that you can expect Champion Character Backups to come back alongside data saving issues, like tomes sometimes being wiped, to be completely fixed.
@kristofbolyai I thought this ticket was mainly concerned on how to uniquely identify characters.
@HighCrit Imo, reopen this. Yes the characters will have a stable Uuid, but we still have to add code to match our ingame character to the API. Until that is added, I want this open.
@kristofbolyai I thought this ticket was mainly concerned on how to uniquely identify characters.
Yeah but we need an impl so๐
A short note on why this is still open:
Wynncraft started using uuids in the API, and later online in the game as well. (What that does is to show part of the uuid in the soul point tooltip.)
This all means that we have the pieces in place to get a proper UUID mapping to characters.
But we are not yet trying to map characters in the selection screen to UUID. And we're not mapping the partial UUID to full UUIDs.
I think we should do both. Then we could do lots of cool things, like the often requested feature to show the corresponding gear you are wearing on the avatar in the char selection screen, etc.