LogicAndTrick / sledge-formats

C# parsers and formats for Half-Life 1 and related engines.
MIT License
71 stars 10 forks source link

Surface and content flags crash when parsing Valve formats #19

Closed Charanor closed 1 year ago

Charanor commented 1 year ago

Hello it's me again :D

When parsing valve formats as output by TrenchBroom (e.g. "Quake 2 (Valve)", "Quake 3 (Valve)"), if any surface has a surface or content flag the QuakeMapFormat will crash with the following error:

System.Exception: Parsing error (line 10, column 83): Unexpected token value Whitespace( )
   at Sledge.Formats.Tokens.TokenParsing.Expect(IEnumerator`1 it, TokenType type, Predicate`1 valueChecker) in E:\Projects\C#\sledge-formats\Sledge.Formats\Tokens\TokenParsing.cs:line 29
   at Sledge.Formats.Map.Formats.QuakeMapFormat.ReadSolid(IEnumerator`1 it) in E:\Projects\C#\sledge-formats\Sledge.Formats.Map\Formats\QuakeMapFormat.cs:line 180
   at Sledge.Formats.Map.Formats.QuakeMapFormat.ReadEntity(IEnumerator`1 it) in E:\Projects\C#\sledge-formats\Sledge.Formats.Map\Formats\QuakeMapFormat.cs:line 155
   at Sledge.Formats.Map.Formats.QuakeMapFormat.Read(Stream stream) in E:\Projects\C#\sledge-formats\Sledge.Formats.Map\Formats\QuakeMapFormat.cs:line 111

I assume this is because it's expecting a new line but got the contentflags number instead. Here is a map file that can reproduce this error:

// Format: Quake2 (Valve)
// entity 0
{
"mapversion" "220"
"classname" "worldspawn"
"_tb_textures" "textures"
// brush 0
{
( -64 -64 -16 ) ( -64 -63 -16 ) ( -64 -64 -15 ) __TB_empty [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 1 0 0
( -64 -64 -16 ) ( -64 -64 -15 ) ( -63 -64 -16 ) __TB_empty [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 1 0 0
( -64 -64 -16 ) ( -63 -64 -16 ) ( -64 -63 -16 ) __TB_empty [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 1 0 0
( 64 64 16 ) ( 64 65 16 ) ( 65 64 16 ) __TB_empty [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 1 0 0
( 64 64 16 ) ( 65 64 16 ) ( 64 64 17 ) __TB_empty [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 1 0 0
( 64 64 16 ) ( 64 64 17 ) ( 64 65 16 ) __TB_empty [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 1 0 0
}
}

I think the "Valve" format is the same as the "Worldcraft" format but with the contentflags surfaceflags value values tacked on at the end like in "idTech3" format.

// Worldcraft:
( x y z ) ( x y z ) ( x y z ) texturename [ ux uy uz xshift ] [ vx vy vz yshift ] rotation xscale yscale
// Valve:
( x y z ) ( x y z ) ( x y z ) texturename [ ux uy uz xshift ] [ vx vy vz yshift ] rotation xscale yscale contentflags surfaceflags value
LogicAndTrick commented 1 year ago

Should be fixed in 1.0.6 :)