Forum

> > CS2D > Scripts > Header Mismatch
Forums overviewCS2D overview Scripts overviewLog in to reply

English Header Mismatch

9 replies
To the start Previous 1 Next To the start

old Header Mismatch

Dousea
User Off Offline

Quote
SOLVED
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
CS2D specification map format has written
STRING = string, 8 bit per character, ended with a linebreak

Strings in CS2D map file ended with a linebreak and I guess its byte is 13 or carriage return. Used code below solved the problem by ignoring the last character which is the linebreak.
1
2
3
4
5
function readstring(file)
	local string = file:read("*l")
	
	return string:sub(1, #string - 1)
end
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

I want you to try code below. Write "test <map>" in console if you want to test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
addhook("parse", "parsehook")

function parsehook(command)
	if (command:sub(1, 4) == "test") then
		local file = io.open("maps/" .. command:sub(6, #command) .. ".map", "rb")
		local header = file:read("*l")
		
		print("Header = \"" .. header .. "\"")
		print("String = \"Unreal Software's Counter-Strike 2D Map File (max)\"")
		
		if (header == "Unreal Software's Counter-Strike 2D Map File (max)") then
			print("It works!")
		else
			print("What's wrong?")
		end
		
		return 2
	end
end
Okay, if you already tested the code, please help me with this header mismatch problem.
edited 1×, last 29.04.15 05:08:58 pm

old Re: Header Mismatch

Yates
Reviewer Off Offline

Quote
io.open can't find the file because you think it will magically find the folder called maps.

Specify the whole path.

Edit: Wait, didn't look properly (I would still specify the whole path though).

Changing line 11 to this works:
1
if (tostring(header):sub(1, 4)  == "Unre") then

So I have no idea why it doesn't work.
edited 1×, last 29.04.15 04:09:20 pm

old Re: Header Mismatch

Dousea
User Off Offline

Quote
But, user Yates, that's not the problem that I'm talking about. And no, io.open can find the file. CS2D sets Lua relative path to its installation path.

old Re: Header Mismatch

Yates
Reviewer Off Offline

Quote
1
if (tostring(header):sub(1, 50)  == "Unreal Software's Counter-Strike 2D Map File (max)") then

Quick fix. Still, no idea why it doesn't work.

Try writing the output into a text file, then copy paste that to see if it truly matches.

Edit: string.len(header) says the length is 51 characters, so there is a weird character at the end. I can't seem to find out what it is.

old Re: Header Mismatch

Dousea
User Off Offline

Quote
I checked the last character's byte and it was 13. In ASCII code 13 is carriage return which means a line break or new line I guess.

old Re: Header Mismatch

Flacko
User Off Offline

Quote
This might have something to do with the OS you're running.
Notably, the byte sequence for line break differs between Windows and Linux.

In Linux, the newline character is LF which is a linefeed, ASCII 0x0A = 10

While in Windows, a newline is composed by two characters: CR+LF
with CR being a carriage return, ASCII 0x0D = 13.

If you were to read a line from a text file written in windows in Linux, you would probably end with that CR at the end of your string.

old Re: Header Mismatch

Dousea
User Off Offline

Quote
Okay, so my solution is best for both OS whether the map saved in Windows or Linux because my code (in my first post) ignores the last character which is the new line. Also can you explain how the newline composed by two characters (CR + LF) in Windows while I only found CR?

old Re: Header Mismatch

VADemon
User Off Offline

Quote
user Flacko your assumption was implausible, because it'd be a bad practice to change file reading behaviour depending on the OS. I checked the I/O source code and Lua only checks for \n, which is excluded when the line value is returned.
So, blame user DC for CRLF

user Dousea, http://blog.codinghorror.com/the-great-newline-schism/

liolib.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static int read_line (lua_State *L, FILE *f, int chop) {
  luaL_Buffer b;
  int c = '\0';
  luaL_buffinit(L, &b);
  while (c != EOF && c != '\n') {  /* repeat until end of line */
    char *buff = luaL_prepbuffer(&b);  /* pre-allocate buffer */
    int i = 0;
    l_lockfile(f);  /* no memory errors can happen inside the lock */
    while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
      buff[i++] = c;
    l_unlockfile(f);
    luaL_addsize(&b, i);
  }
  if (!chop && c == '\n')  /* want a newline and have one? */
    luaL_addchar(&b, c);  /* add ending newline to result */
  luaL_pushresult(&b);  /* close buffer */
  /* return ok if read something (either a newline or something else) */
  return (c == '\n' || lua_rawlen(L, -1) > 0);
}

old Re: Header Mismatch

Flacko
User Off Offline

Quote
Quote
it'd be a bad practice to change file reading behaviour depending on the OS


The OS itself is the one that manages access to the file system, this is not a Lua-only issue and I never said it was: file reading behaviour in applications is totally attached to the OS they are running on. Without an OS, there is no file system, without a file system you have to access blocks on the disk directly, ergo, there is no HW abstraction.

If you were to open the file in text mode ("r") (although this was not the case, and I didn't realize until just now), you would get different results between Windows and Linux, because you are telling the OS you want to read plain text without minding the implementation details.

You could just go and try this program with a Windows text file of your choice
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char** argv) {
	FILE* f = fopen("helloworld.txt", "r");
	int c = getc(f);
	while (c != '\n' && c != EOF) {
		printf("0x%.2x ", c);
		c = getc(f);
	}
	fclose(f);
}
You will see different output between both platforms using the same code.

@user Dousea:
In this case you made the right decision by handling this issue manually using binary mode ("rb"), you should get the same results on all platforms.
Although the sequence is CR LF, Lua will stop reading at LF, strip that LF character and return everything it read before it, including the CR.

Another solution might be to compare the line like this:
1
if header=="Unreal Software's Counter-Strike 2D Map File (max)\r" then
That way you would compensate the extra CR in header with another CR in the string
edited 2×, last 05.05.15 02:36:42 am

old Re: Header Mismatch

DC
Admin Off Offline

Quote
The files are actually written using BlitzMax' standard file stream functions so if there's anything weird with the line breaks please blame BlitzMax and not me

Maybe a trim function would be useful here.
http://lua-users.org/wiki/StringTrim
A trim function removes all white spaces (including line breaks) from the beginning and ending of a string.
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview