M
Marc Lucksch
Maybe I'm an idiot here, but I can't figure this one out even if my life
would depend on it:
I have an file in the quite easy INI format, put I have no idea how to
store it in a way where it can be easily accessed by other people and
without any long explanations.
Anyway here is the example file:
The file is from the Microsoft game Freelancer, but it is unlike any
normal ini files:
- The section names are doubled, (there are multiple [Ship] entries)
- Some of the keys are doubled as well (0 - 4 fuse entries for example)
- Some of the values are seperated by ",". (That's not a big problem)
The backstory of this whole thing is:
In 1999 Microsoft/Digital Anvil made this game and it came with a lot of
BINI files, which are just somewhat compressed INI files, looking like
the one above. After half a year BINI file decompressors and compressors
were written and I plan to write/wrote one as well for another project
(plasma.sf.net) in Perl of course. The normal decompressors converted
the file first and then read it, that's why tools based on this, like
FL-Datastorm, take 10 Minutes to scan the game and my implementation
takes about 2 seconds. (10 seconds when counting models)
But why INI-files, It would seem abitrary to convert them to INI files,
since it was a binary format before that look like it. However the game
also accepts gladly uncompressed INI files.
The game itself has many, many mods for it, since you just have to edit
INI files mostly, and people have found a way to 'break' the BINI files
in a way that only Freelancer can read them and not any other tools.
This is a second reason for the parser, since I can't use most tools for
my own server operator, since it _has_ to read those files. That is also
the reason I can't just ship it with just a complete set of data files.
Now while I want to put the parser on CPAN, I can't find any way to
represent this type of data in an easy way... (While a little voice is
constantly screaming "They are just INI files, ^*&*&%^%^*&$#$")
So I tried the some of the many INI parsers on CPAN. (Since I also have
to read normal ini files) But I have found none that can even parse that
file correctly... (See below for examples)
I would love for it to have an easy interface, not for me, but for
others who might want to use it:
First idea was TIE, but that won't work with the duality of the thing.
Overload might go, but that opens another can of worms with adding new
sections and keys that need converting objects and other things.
And overload+TIE is not good at all... (See man overload)
And a pure Object based model is what Python and Java would do, not very
perlish.
So there I am, no idea, and I need help: First on the datastructure
issue and second on a nice parser on CPAN that can read that file obove
right. I don't want to write Yet::Another::INI:arser::Again for the
fifth time.
Marc "Maluku" Lucksch
__DATA__
Config::INI::Reader of that file:
Result: One section missing, 4 fuses missing, fuse and LOD not splitted.
Config::Format::INI
Result: One section missing, 4 fuses missing, LODRanges and ids_info1
not parsed (why?). The missing LODRanges confuse me a lot here.
Result: Well it's all there, but I can't work with it and value are not
splitted by the comma
And my one FlBini (Games::Freelancer::BINI, when I figure this out)..
$VAR1 = bless( {
Result: cubersome, no direct key access, therefore full scan is needed
with a good reason. But all data is there.
would depend on it:
I have an file in the quite easy INI format, put I have no idea how to
store it in a way where it can be easily accessed by other people and
without any long explanations.
Anyway here is the example file:
[Ship]
ids_name = 237033
ids_info = 66567
ids_info1 = 66567
ship_class = 1
nickname = li_elite
LODranges = 0, 75, 150, 1300
fuse = intermed_damage_smallship01, 0.000000, 400
fuse = intermed_damage_smallship02, 0.000000, 200
;#Well its a lot more in one section, but this proves the point.
[Ship]
ids_name = 237033
ids_info = 66567
ship_class = 1
nickname = li_elite2
LODranges = 0, 175, 150, 1300
fuse = intermed_damage_smallship01, 0.000000, 400
fuse = intermed_damage_smallship02, 0.000000, 200
fuse = intermed_damage_smallship03, 0.000000, 133
;.... (about 250kb of this)
The file is from the Microsoft game Freelancer, but it is unlike any
normal ini files:
- The section names are doubled, (there are multiple [Ship] entries)
- Some of the keys are doubled as well (0 - 4 fuse entries for example)
- Some of the values are seperated by ",". (That's not a big problem)
The backstory of this whole thing is:
In 1999 Microsoft/Digital Anvil made this game and it came with a lot of
BINI files, which are just somewhat compressed INI files, looking like
the one above. After half a year BINI file decompressors and compressors
were written and I plan to write/wrote one as well for another project
(plasma.sf.net) in Perl of course. The normal decompressors converted
the file first and then read it, that's why tools based on this, like
FL-Datastorm, take 10 Minutes to scan the game and my implementation
takes about 2 seconds. (10 seconds when counting models)
But why INI-files, It would seem abitrary to convert them to INI files,
since it was a binary format before that look like it. However the game
also accepts gladly uncompressed INI files.
The game itself has many, many mods for it, since you just have to edit
INI files mostly, and people have found a way to 'break' the BINI files
in a way that only Freelancer can read them and not any other tools.
This is a second reason for the parser, since I can't use most tools for
my own server operator, since it _has_ to read those files. That is also
the reason I can't just ship it with just a complete set of data files.
Now while I want to put the parser on CPAN, I can't find any way to
represent this type of data in an easy way... (While a little voice is
constantly screaming "They are just INI files, ^*&*&%^%^*&$#$")
So I tried the some of the many INI parsers on CPAN. (Since I also have
to read normal ini files) But I have found none that can even parse that
file correctly... (See below for examples)
I would love for it to have an easy interface, not for me, but for
others who might want to use it:
my $ini=read...("file.ini")
print $ini->{Ship}->{nickname}; #When there is one ship only, also
foreach my $ship(%{$ini->{Ship}) {
foreach my $fuse(
print $ship->{nickname}
}
}
First idea was TIE, but that won't work with the duality of the thing.
Overload might go, but that opens another can of worms with adding new
sections and keys that need converting objects and other things.
And overload+TIE is not good at all... (See man overload)
And a pure Object based model is what Python and Java would do, not very
perlish.
So there I am, no idea, and I need help: First on the datastructure
issue and second on a nice parser on CPAN that can read that file obove
right. I don't want to write Yet::Another::INI:arser::Again for the
fifth time.
Marc "Maluku" Lucksch
__DATA__
Config::INI::Reader of that file:
$VAR1 = {
'Ship' => {
'ship_class' => '1',
'ids_info' => '66567',
'ids_info1' => '66567',
'nickname' => 'li_elite2',
'fuse' => 'intermed_damage_smallship03, 0.000000, 133',
'ids_name' => '237033',
'LODranges' => '0, 175, 150, 1300'
}
};
Result: One section missing, 4 fuses missing, fuse and LOD not splitted.
Config::Format::INI
$VAR1 = {
'Ship' => {
'ship_class' => ['1'],
'ids_info' => ['66567'],
'nickname' => ['li_elite2'],
'fuse' => [
'intermed_damage_smallship03',
'0.000000',
'133'
],
'ids_name' => ['237033']
}
};
Result: One section missing, 4 fuses missing, LODRanges and ids_info1
not parsed (why?). The missing LODRanges confuse me a lot here.
$VAR1 = {
'Ship' => {
'ship_class' => ['1','1'],
'ids_info' => ['66567','66567'],
'ids_info1' => '66567',
'nickname' => ['li_elite','li_elite2'],
'fuse' => [
'intermed_damage_smallship01, 0.000000, 400',
'intermed_damage_smallship02, 0.000000, 200',
'intermed_damage_smallship03, 0.000000, 133',
'intermed_damage_smallship01, 0.000000, 400',
'intermed_damage_smallship02, 0.000000, 200',
'intermed_damage_smallship03, 0.000000, 133'
],
'ids_name' => ['237033','237033'],
'LODranges' => [
'0, 75, 150, 1300',
'0, 175, 150, 1300'
]
}
};
Result: Well it's all there, but I can't work with it and value are not
splitted by the comma
And my one FlBini (Games::Freelancer::BINI, when I figure this out)..
$VAR1 = bless( {
'Iter' => 0,
'Data' => [
'Ship',
bless( {
'Iter' => 0,
'Data' => [
'ids_name',
['237033'],
'ids_info',
['66567'],
'ids_info1',
['66567'],
'ship_class',
['1'],
'nickname',
['li_elite'],
'LODranges',
[
'0',
'75',
'150',
'1300'
],
'fuse',
[
'intermed_damage_smallship01',
'0.000000',
'400'
],
'fuse',
[
'intermed_damage_smallship02',
'0.000000',
'200'
],
'fuse',
[
'intermed_damage_smallship03',
'0.000000',
'133'
]
]
}, 'INIArray' ),
'Ship',
bless( {
'Iter' => 0,
'Data' => [
'ids_name',
['237033],
'ids_info',
['66567],
'ship_class',
['1'],
'nickname',
['li_elite2],
'LODranges',
[
'0',
'175',
'150',
'1300'
],
'fuse',
[
'intermed_damage_smallship01',
'0.000000',
'400'
],
'fuse',
[
'intermed_damage_smallship02',
'0.000000',
'200'
],
'fuse',
[
'intermed_damage_smallship03',
'0.000000',
'133'
]
]
}, 'INIArray' )
]
}, 'INIArray' )
Result: cubersome, no direct key access, therefore full scan is needed
with a good reason. But all data is there.