ID:2830533
 
Resolved
The server did not properly recognize when an object ID had been reused in RenderIcon(), causing old information to be used in some cases.
BYOND Version:515.1593
Operating System:Windows 10 Home
Web Browser:Chrome 106.0.0.0
Applies to:Dream Daemon
Status: Resolved (515.1594)

This issue has been resolved.
Descriptive Problem Summary:
RenderIcon when used to display multiple icons in the browser glitches out causing all returned cache from RenderIcon to the 1st thing rendered.

Code Snippet (if applicable) to Reproduce Problem:
mob/proc/RenderOutfit(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O)
var obj/outfit/o = new
o.icon = icon
o.icon_state = icon_state
o.Edit(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O)
client << browse_rsc(client.RenderIcon(o),"O[A][B][C][D][E][F][G][H][I][J][K][L][M][N][O].png")
return "O[A][B][C][D][E][F][G][H][I][J][K][L][M][N][O].png"


mob/player
icon = 'base.dmi'
icon_state = "human female"
Login()
InitializeOutfit()
outfit.Edit(1,1,1,1,1,1,3,5,1,1,0,0,0,0,0)
..()
src << browse({"
<img src=
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>
<img src=
[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0)]><br>
"}
)
var obj/outfit/outfit


Expected Results:
Displays each outfit with the parameters provided.
Each argument is a equipment slot for a item, which is a number to represent the item in that slot.

Actual Results:
It seems to replace all outfits provided when sent to the browser with the first outfit generated.


Moar Information:
This is what it looks like using RenderOutfit() twice in the browser.



This is what it looks like after deleting the top RenderOutfit() call and just having the bottom one.




I'm gonna need a test project for this. The snippet is both too complex and not complete enough to test on its own.
In response to Lummox JR
PM sent
src << browse({"
<img src=
[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0)]><br>
<img src=
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>
"}
)


Issue being if you use it more than once it doesn't render them correctly.
I'm confused. Your test case doesn't do anything where it does more than one RenderIcon(). There's only one verb and it doesn't do anything but count possible permutations.
The issue is this

mob/player
Login()
src << browse({"
<img src=
[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0)]><br>
<img src=
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>
"}
)


Using RenderOutfit() should output 2 separate blank bases with different hair styles.

However they appear to be the same thing unless you remove one of the lines.

<img src=[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0)]><br>
<img src=[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>


RenderOutfit just creates a outfit object and dresses it up with the arguments then returns the cached file to use in the img tag

return "O[A][B][C][D][E][F][G][H][I][J][K][L][M][N][O].png"
Though it would probably exhibit the same bug, I will point out that using RenderIcon() at all here is an unnecessary round trip, and the client could just render the icon directly in the browser with the new related feature. You know, <img src=\ref[thing]> or whatever
In response to Exxion
Exxion wrote:
img src=\ref[thing]

I tried having the proc return the object itself and used \ref and doesn't render anything for me.

The outfit object I'm rendering is just a base icon for a human female, with 15 overlayed objects that need drawn on to be displayed in the browser.
I haven't tried it in a test project, but this works in SS13:
/proc/bicon(var/obj)
return "<img src='\ref[obj]'>"


Also in SS13, I can't seem to reproduce this bug, with either approach. I'm not using your exact snippet, though.
Oh, wait. Maybe it has to do with the fact that the outfit object gets deleted right after the first call. The one in the second call likely inherits the same ref the first had. Its appearance shouldn't have the same ref, though, so I'm not sure why the cache would get confused at this.

EDIT: The object getting deleted is probably why the direct method isn't working for you, too. The object technically loses its last reference, and thus gets deleted, before the client tries to render it. I wonder if using \ref[thing.appearance] instead of just \ref[thing] would work.

EDIT: It definitely has to do with the object being deleted, and using appearance does not fix it. If I make a verb spawn a barstool and output its icon to the client without keeping the barstool around, it fails to render it at all, and even prevents the client from rendering any other identical barstools in the future.
In response to Exxion
Exxion wrote:
Oh, wait. Maybe it has to do with the fact that the outfit object gets deleted right after the first call. The one in the second call likely inherits the same ref the first had. Its appearance shouldn't have the same ref, though, so I'm not sure why the cache would get confused at this.

EDIT: The object getting deleted is probably why the direct method isn't working for you, too. The object technically loses its last reference, and thus gets deleted, before the client tries to render it. I wonder if using \ref[thing.appearance] instead of just \ref[thing] would work.

Yupp, this is the issue. However they're still being rendered incorrectly for some reason.



The top base with no hair has the parameter 4 which should result in

src << browse({"

<img src=\ref
[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0).appearance]><br>
<img src=\ref
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0).appearance]><br>
"}
)


Causes the icons to display as naked bases with no overlays.
Your test case doesn't have two calls in a row. Is the test case incomplete?
Dang yea, I was trying to figure out the issue.

2 calls

src << browse({"
<img src=
[RenderOutfit(0,0,0,0,0,0,0,4,0,0,0,0,0,0,0)]><br>
<img src=
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>
"}
)


1 call

src << browse({"
<img src=
[RenderOutfit(0,0,0,0,0,0,0,3,0,0,0,0,0,0,0)]><br>
"}
)
Lummox JR resolved issue with message:
The server did not properly recognize when an object ID had been reused in RenderIcon(), causing old information to be used in some cases.