Token ID Bug strikes back

Thoughts, Help, Feature Requests, Bug Reports, Developing code for...

Moderators: Azhrei, dorpond, trevor

Forum rules
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior. :)
Post Reply
Glendwyr
Kobold
Posts: 11
Joined: Mon Apr 11, 2016 4:11 am

Token ID Bug strikes back

Post by Glendwyr »

So I've run into a problem with the dreaded token ID bug that I'd never run across before.

Generally the bag of tricks fix sorts this. As a reminder, basically it works as follows:
  • Generate a list of all token IDs
  • For each ID, if the ID is not 32 characters long, assume the ID should be padded to the left by a bunch of 0s
  • Copy the token with this presumed ID, and remove the token
That's always worked for me in the past. But tonight I hit the following token ID: 0000000090158353400E000000000000. Maptool turns this into 90158353400. That is, it strips off the leading zeroes, as well as E000000000000 which presumably it thinks is just scientific notation. Then the bag of tricks fix left-pads with a bunch of zeroes to give me 00000000000000000000090158353400. And this token can't be copied and removed because it doesn't exist.

Any useful suggestions?

Since all my tokens have unique names, I could presumably solve the problem by something like

Code: Select all

[IDList = getTokens("json",'{layer:["TOKEN","GM","OBJECT","BACKGROUND"]}')]
[NameList = getTokenNames()]
[ForEach(ID,IDList), Code:
{	[if(length(id) == 32), Code:
	{	[tName = getName(ID)]
		[tPos = listFind(NameList,tName)]
		[NameList = listDelete(NameList,tPos)]
	}]
}]
at which points NameList should contain a list of token names which correspond to tokens with invalid IDs. Then presumably I can copy/remove tokens on that basis. But this fix clearly relies on all token names being unique, which we can't assume in general.

Glendwyr
Kobold
Posts: 11
Joined: Mon Apr 11, 2016 4:11 am

Re: Token ID Bug strikes back

Post by Glendwyr »

I have a possible fix. Coding style is probably atrocious.

Code: Select all

[H: "<!-- Get the json array of token IDs --!>"]
[H: IDList = getTokens("json",'{layer:["TOKEN","GM","OBJECT","BACKGROUND"]}')]


[H: "<!-- Remove the good IDs from the json array --!>"]
[H: BadIDList = IDList]
[H, ForEach(ID,IDList), Code:
{	[if(length(ID) == 32), Code:
	{	[indx = json.indexOf(BadIDList,ID)]
		[If(indx > -1): BadIDList = json.remove(BadIDList,indx)]
	}]
}]


[H: "<!-- Now we're going to go through the list of bad ids and stringify individual elements.  Copy and remove tokens --!>"]
[H: NBadIDs = json.length(BadIDList)]
[H, c(NBadIDs), Code:
{   [TempList = BadIDList]
    [Ind = roll.count]
    [for(Indx,NBadIDs-1,-1,-1): TempList = if(Indx == Ind,TempList,json.remove(TempList,Indx))]
    [BadID = substring(TempList,1,35)]
    [MyName = getName(BadID)]
    [copyToken(BadID,1,"",json.set("{}","name",MyName,"delta",1,"x",0,"y",0))]
    [removeToken(BadID)]
    [broadcast(strformat("Token %{MyName} had a purely numeric ID, and was copied and removed.  Check again."))]
}]
The idea is as follows:
  • Generate a json array holding all token IDs.
  • Remove from that array all token IDs which are okay. What's left behind is a json array with all the bad IDs, each as a string.
  • For each entry in that array, we're going to generate a json array with one entry -- the one we're after. We'll do that by copying the array of bad IDs and removing all entries other than the one we want to fix.
  • Now treat that single-entry json array as if it were a string. It will be, in the case I listed earlier, ["0000000090158353400E000000000000"].
  • Chop off the first and last character of the string, to get "0000000090158353400E000000000000"
  • This is treated as a string and not as a number, so I can pass it as a valid token ID.
In testing, it seems to do the job.

User avatar
aliasmask
Deity
Posts: 8579
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Token ID Bug strikes back

Post by aliasmask »

I personally thought this was fixed. Are these "old" tokens? Another test is to see if isNumber() is true. These ids shouldn't look like a number. Once you get all your "bad ids", you can still use the original id from within the array to use the id to copy that token and delete the original. Just don't assign the token id to a variable (use json.get(array,index) method). Obviously, save the campaign before doing something major like this, just it case it goes sideways.

Glendwyr
Kobold
Posts: 11
Joined: Mon Apr 11, 2016 4:11 am

Re: Token ID Bug strikes back

Post by Glendwyr »

I think these tokens were from October or so, in whatever the current version was back then. I noticed on doing the fix that the new id started with 3something rather than 0000 so the bug may indeed have been squashed between making tokens and using them, which would be welcome!

Also, thanks for the suggestion on reading straight out of the array, which is a lot cleaner.

Edit: currently using 1.6.1, not 1.7.0, in case relevant.

Post Reply

Return to “MapTool”