mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
Fix aim2 .mmo format reader.
This commit is contained in:
parent
a5989276a7
commit
b5ad31087d
5 changed files with 224 additions and 18 deletions
|
|
@ -1 +1,2 @@
|
||||||
python obj_extractor.py --db "h:\Games\Epic Games\Projects\Polygon4\Mods\db.sqlite" --dir "h:\Games\AIM\data\maps.pak.dir"
|
python obj_extractor.py --db "h:\Games\Epic Games\Projects\Polygon4\Mods\db.sqlite" --dir "h:\Games\AIM\data\maps.pak.dir" --prefix m1
|
||||||
|
python obj_extractor.py --db "h:\Games\Epic Games\Projects\Polygon4\Mods\db.sqlite" --dir "h:\Games\Steam\steamapps\common\AIM2\Data\mmo.pak\DATA\LOCS" --prefix m2
|
||||||
|
|
@ -33,6 +33,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
std::string prefix;
|
||||||
|
GameType gameType;
|
||||||
|
|
||||||
struct storage
|
struct storage
|
||||||
{
|
{
|
||||||
string name;
|
string name;
|
||||||
|
|
@ -41,6 +44,10 @@ struct storage
|
||||||
MapGoods mg;
|
MapGoods mg;
|
||||||
MapMusic mm;
|
MapMusic mm;
|
||||||
MapSounds ms;
|
MapSounds ms;
|
||||||
|
// aim2
|
||||||
|
Organizations orgs;
|
||||||
|
OrganizationBases orgsBases;
|
||||||
|
Prices prices;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -51,6 +58,12 @@ struct storage
|
||||||
mg.load(b);
|
mg.load(b);
|
||||||
mm.load(b);
|
mm.load(b);
|
||||||
ms.load(b);
|
ms.load(b);
|
||||||
|
if (gameType == GameType::Aim2)
|
||||||
|
{
|
||||||
|
orgs.load(b);
|
||||||
|
orgsBases.load(b);
|
||||||
|
prices.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
if (!b.eof())
|
if (!b.eof())
|
||||||
{
|
{
|
||||||
|
|
@ -87,6 +100,9 @@ void write_mmo(string db, const storage &s)
|
||||||
int p = max(p1, p2);
|
int p = max(p1, p2);
|
||||||
string map_name = s.name.substr(p + 1);
|
string map_name = s.name.substr(p + 1);
|
||||||
map_name = map_name.substr(0, map_name.find('.'));
|
map_name = map_name.substr(0, map_name.find('.'));
|
||||||
|
if (!prefix.empty())
|
||||||
|
map_name = prefix + "." + map_name;
|
||||||
|
transform(map_name.begin(), map_name.end(), map_name.begin(), ::tolower);
|
||||||
|
|
||||||
int map_id = 0;
|
int map_id = 0;
|
||||||
for (auto &m : storage->maps)
|
for (auto &m : storage->maps)
|
||||||
|
|
@ -209,11 +225,18 @@ void write_mmo(string db, const storage &s)
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (argc != 3)
|
if (argc != 4)
|
||||||
{
|
{
|
||||||
cout << "Usage:\n" << argv[0] << " db.sqlite file.mmo" << "\n";
|
cout << "Usage:\n" << argv[0] << " db.sqlite file.mmo" << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
prefix = argv[3];
|
||||||
|
if (prefix == "m1")
|
||||||
|
gameType = GameType::Aim1;
|
||||||
|
else if (prefix == "m2")
|
||||||
|
gameType = GameType::Aim2;
|
||||||
|
else
|
||||||
|
throw std::runtime_error("unknown prefix (game type)");
|
||||||
storage s = read_mmo(argv[2]);
|
storage s = read_mmo(argv[2]);
|
||||||
write_mmo(argv[1], s);
|
write_mmo(argv[1], s);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,21 @@ def main():
|
||||||
parser = argparse.ArgumentParser(description='Batch models converter')
|
parser = argparse.ArgumentParser(description='Batch models converter')
|
||||||
parser.add_argument('--dir', dest='dir', help='path to directory with maps')
|
parser.add_argument('--dir', dest='dir', help='path to directory with maps')
|
||||||
parser.add_argument('--db', dest='db', help='path to db')
|
parser.add_argument('--db', dest='db', help='path to db')
|
||||||
|
parser.add_argument('--prefix', dest='prefix', help='prefix')
|
||||||
pargs = parser.parse_args()
|
pargs = parser.parse_args()
|
||||||
|
|
||||||
if pargs.dir:
|
if not pargs.prefix:
|
||||||
run(pargs.dir, pargs.db)
|
pargs.prefix = ''
|
||||||
|
|
||||||
def run(dir, db):
|
if pargs.dir:
|
||||||
|
run(pargs.dir, pargs.db, pargs.prefix)
|
||||||
|
|
||||||
|
def run(dir, db, prefix):
|
||||||
for file in sorted(os.listdir(dir)):
|
for file in sorted(os.listdir(dir)):
|
||||||
if os.path.isdir(file) or os.path.splitext(file)[1] != ".mmo":
|
if os.path.isdir(file) or os.path.splitext(file)[1].lower() != ".mmo":
|
||||||
continue
|
continue
|
||||||
print('loading: ' + file)
|
print('loading: ' + file)
|
||||||
p = subprocess.Popen(['obj_extractor.exe', db, dir + '/' + file])
|
p = subprocess.Popen(['obj_extractor.exe', db, dir + '/' + file, prefix])
|
||||||
p.communicate()
|
p.communicate()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ void Objects::load(buffer &b)
|
||||||
auto seg = Segment::create_segment(b);
|
auto seg = Segment::create_segment(b);
|
||||||
if (!seg)
|
if (!seg)
|
||||||
break;
|
break;
|
||||||
seg->load(b);
|
seg->load(buffer(b, seg->segment_len));
|
||||||
segments.push_back(seg);
|
segments.push_back(seg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,18 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
enum class GameType
|
||||||
|
{
|
||||||
|
Aim1,
|
||||||
|
Aim2
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameType gameType;
|
||||||
|
|
||||||
struct MechGroup
|
struct MechGroup
|
||||||
{
|
{
|
||||||
char unk1[0x20];
|
char name[0x20];
|
||||||
char unk2[0x20];
|
char org[0x20];
|
||||||
uint32_t type1;
|
uint32_t type1;
|
||||||
uint32_t len1;
|
uint32_t len1;
|
||||||
char name1[0x70];
|
char name1[0x70];
|
||||||
|
|
@ -51,8 +59,8 @@ struct MechGroup
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, unk1);
|
READ(b, name);
|
||||||
READ(b, unk2);
|
READ(b, org);
|
||||||
READ(b, type1);
|
READ(b, type1);
|
||||||
READ(b, len1);
|
READ(b, len1);
|
||||||
READ(b, name1);
|
READ(b, name1);
|
||||||
|
|
@ -83,6 +91,7 @@ struct MechGroup
|
||||||
|
|
||||||
struct MechGroups
|
struct MechGroups
|
||||||
{
|
{
|
||||||
|
uint32_t length;
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
char prefix[0x30];
|
char prefix[0x30];
|
||||||
|
|
||||||
|
|
@ -90,6 +99,8 @@ struct MechGroups
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
if (gameType == GameType::Aim2)
|
||||||
|
READ(b, length);
|
||||||
READ(b, n);
|
READ(b, n);
|
||||||
READ(b, prefix);
|
READ(b, prefix);
|
||||||
|
|
||||||
|
|
@ -106,15 +117,23 @@ struct Good
|
||||||
{
|
{
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
char unk1[0x40];
|
char unk1[0x40];
|
||||||
|
uint32_t unk1_2;
|
||||||
float price;
|
float price;
|
||||||
float unk2[10];
|
float unk2[10];
|
||||||
|
float unk2_2[4];
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, name);
|
READ(b, name);
|
||||||
READ(b, unk1);
|
if (gameType == GameType::Aim1)
|
||||||
|
READ(b, unk1);
|
||||||
|
else
|
||||||
|
READ(b, unk1_2);
|
||||||
READ(b, price);
|
READ(b, price);
|
||||||
READ(b, unk2);
|
if (gameType == GameType::Aim1)
|
||||||
|
READ(b, unk2);
|
||||||
|
else
|
||||||
|
READ(b, unk2_2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -141,7 +160,7 @@ struct BuildingGoods
|
||||||
|
|
||||||
struct MapGoods
|
struct MapGoods
|
||||||
{
|
{
|
||||||
uint32_t unk1;
|
uint32_t length;
|
||||||
uint32_t unk2;
|
uint32_t unk2;
|
||||||
uint32_t unk3;
|
uint32_t unk3;
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
@ -150,9 +169,10 @@ struct MapGoods
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, unk1);
|
READ(b, length);
|
||||||
READ(b, unk2);
|
READ(b, unk2);
|
||||||
READ(b, unk3);
|
if (gameType != GameType::Aim2)
|
||||||
|
READ(b, unk3);
|
||||||
READ(b, n);
|
READ(b, n);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
|
|
@ -160,6 +180,8 @@ struct MapGoods
|
||||||
BuildingGoods bg;
|
BuildingGoods bg;
|
||||||
bg.load(b);
|
bg.load(b);
|
||||||
bgs.push_back(bg);
|
bgs.push_back(bg);
|
||||||
|
if (gameType == GameType::Aim2)
|
||||||
|
READ(b, unk2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -231,4 +253,160 @@ struct MapSounds
|
||||||
sounds.push_back(s);
|
sounds.push_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OrganizationConfig
|
||||||
|
{
|
||||||
|
uint32_t n_configs;
|
||||||
|
vector<string> configs;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_configs);
|
||||||
|
configs.resize(n_configs, string(0x20, 0));
|
||||||
|
for (int i = 0; i < n_configs; i++)
|
||||||
|
READ_N(b, configs[i][0], 0x20);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Organization
|
||||||
|
{
|
||||||
|
uint32_t unk0;
|
||||||
|
char name[0x20];
|
||||||
|
char unk1[0xE0];
|
||||||
|
OrganizationConfig configs[3];
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, unk1);
|
||||||
|
for (auto &c : configs)
|
||||||
|
c.load(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Organizations
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
uint32_t n;
|
||||||
|
vector<Organization> organizations;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, len);
|
||||||
|
READ(b, n);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
Organization s;
|
||||||
|
s.load(b);
|
||||||
|
organizations.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrganizationBase
|
||||||
|
{
|
||||||
|
char base_name[0x20];
|
||||||
|
char org_name[0x20];
|
||||||
|
uint32_t unk0;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, base_name);
|
||||||
|
READ(b, org_name);
|
||||||
|
READ(b, unk0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrganizationBases
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
vector<OrganizationBase> organizationBases;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
OrganizationBase s;
|
||||||
|
s.load(b);
|
||||||
|
organizationBases.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Price
|
||||||
|
{
|
||||||
|
char tov_name[0x20];
|
||||||
|
uint32_t unk0;
|
||||||
|
uint32_t unk1;
|
||||||
|
float unk2[3];
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, tov_name);
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, unk1);
|
||||||
|
READ(b, unk2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuildingPrice
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
uint32_t n_tov;
|
||||||
|
vector<Price> prices;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, n_tov);
|
||||||
|
for (int i = 0; i < n_tov; i++)
|
||||||
|
{
|
||||||
|
Price s;
|
||||||
|
s.load(b);
|
||||||
|
prices.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuildingPrices
|
||||||
|
{
|
||||||
|
uint32_t n_tov;
|
||||||
|
vector<Price> prices;
|
||||||
|
uint32_t n_bases;
|
||||||
|
vector<BuildingPrice> buildingPrices;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_tov);
|
||||||
|
for (int i = 0; i < n_tov; i++)
|
||||||
|
{
|
||||||
|
Price s;
|
||||||
|
s.load(b);
|
||||||
|
prices.push_back(s);
|
||||||
|
}
|
||||||
|
READ(b, n_bases);
|
||||||
|
for (int i = 0; i < n_bases; i++)
|
||||||
|
{
|
||||||
|
BuildingPrice s;
|
||||||
|
s.load(b);
|
||||||
|
buildingPrices.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Prices
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
uint32_t unk0;
|
||||||
|
BuildingPrices buildingPrices;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, len);
|
||||||
|
READ(b, unk0);
|
||||||
|
buildingPrices.load(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue