mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
More mod changes.
This commit is contained in:
parent
c86b7966bb
commit
5d0bcfdb95
3 changed files with 90 additions and 222 deletions
|
|
@ -87,14 +87,14 @@ int main(int argc, char *argv[]) {
|
|||
mod.add_map_good("location6.mmo", "B_L6_IK_FINDER", "GL_S3_PS_FINDER1", R"(
|
||||
47 4c 5f 53 33 5f 50 53 5f 46 49 4e 44 45 52 32
|
||||
00 d2 e2 77 42 04 06 00 35 01 00 00 76 0c 01 30
|
||||
00 5f 4c 36 5f 49 4b 5f 46 32 2e 43 4f 4d 50 4c
|
||||
54 5f 4c 36 5f 49 4b 5f 46 32 2e 43 4f 4d 50 4c
|
||||
45 54 45 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00
|
||||
)"_bin); // 54
|
||||
)"_bin);
|
||||
//mod.add_resource("MOD_GL_S3_PS_FINDER1");
|
||||
//mod.add_resource("TEX_GL_S3_PS_FINDER1_MASK.TM");
|
||||
// patch note: add Finder-2 model and textures from aim2 game (lz)
|
||||
|
|
@ -128,31 +128,36 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// patch note: Database Changes
|
||||
// patch note: DB
|
||||
auto db = mod.db().open();
|
||||
// patch note: set glider GL_S3_PS_FINDER2 model to MOD_GL_S3_PS_FINDER2 (lz)
|
||||
mod.db().edit_value(u8"Ãëàéäåðû", "GL_S3_PS_FINDER2", "MODEL", "MOD_GL_S3_PS_FINDER2");
|
||||
db(u8"Ãëàéäåðû", "GL_S3_PS_FINDER2", "MODEL") = "MOD_GL_S3_PS_FINDER2";
|
||||
// patch note: change MOD_GL_S3_PS_FINDER2 model radius to MOD_GL_S3_PS_FINDER1 radius (lz)
|
||||
mod.db().edit_value(u8"Ìîäåëè", "MOD_GL_S3_PS_FINDER2", "RADIUS", 4.012578f);
|
||||
db(u8"Ìîäåëè", "MOD_GL_S3_PS_FINDER2", "RADIUS") = 4.768386f; // from finder1 - 4.012578f;
|
||||
// patch note: double gun for config CFG_NARGOON (double electro discharge) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_NARGOON", "HEAVYGUN1", "GUN_ELECTRO_DISCHARGER");
|
||||
auto tblcfg = db(u8"Êîíôèãóðàöèè");
|
||||
tblcfg("CFG_NARGOON", "HEAVYGUN1") = "GUN_ELECTRO_DISCHARGER";
|
||||
// patch note: double gun for config CFG_NARGOON1 (double two-barreled atomic gun) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_NARGOON1", "HEAVYGUN1", "GUN_DOUBLE_BARRELED_ATOMIC_GUN");
|
||||
tblcfg("CFG_NARGOON1", "HEAVYGUN1") = "GUN_DOUBLE_BARRELED_ATOMIC_GUN";
|
||||
// patch note: double gun for config CFG_BASE_NARG - Nargoon (double two-barreled atomic gun) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_BASE_NARG", "HEAVYGUN1", "GUN_DOUBLE_BARRELED_ATOMIC_GUN");
|
||||
tblcfg("CFG_BASE_NARG", "HEAVYGUN1") = "GUN_DOUBLE_BARRELED_ATOMIC_GUN";
|
||||
// patch note: double gun for config CFG_STNAR-97 - Nargoon (double GUN_INFRAATOMIC_PLASMA_GUN) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_STNAR-97", "HEAVYGUN1", "GUN_INFRAATOMIC_PLASMA_GUN");
|
||||
tblcfg("CFG_STNAR-97", "HEAVYGUN1") = "GUN_INFRAATOMIC_PLASMA_GUN";
|
||||
// patch note: double gun for config CFG_FINDER_1 (std.3): from GUN_MICROWAVE_OSCILLATOR (std.4) and GUN_CHAOS_GENERATOR (std.4) to double GUN_FOUR_BARRELED_IMP_GAZER (std.3) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_FINDER_1", "LIGHTGUN1", "GUN_FOUR_BARRELED_IMP_GAZER");
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_FINDER_1", "HEAVYGUN1", "GUN_FOUR_BARRELED_IMP_GAZER");
|
||||
auto finder1 = tblcfg("CFG_FINDER_1");
|
||||
finder1("LIGHTGUN1") = "GUN_FOUR_BARRELED_IMP_GAZER";
|
||||
finder1("HEAVYGUN1") = "GUN_FOUR_BARRELED_IMP_GAZER";
|
||||
// patch note: double gun for config CFG_FINDER_2: from GUN_FOUR_BARRELED_IMP_GAZER (std.3) + GUN_POZITRON_EMITTER (std.4) to double GUN_TACHYON_HEATER (std.3) (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_FINDER_2", "LIGHTGUN1", "GUN_TACHYON_HEATER");
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_FINDER_2", "HEAVYGUN1", "GUN_TACHYON_HEATER");
|
||||
auto finder2 = tblcfg("CFG_FINDER_2");
|
||||
finder2("LIGHTGUN1") = "GUN_TACHYON_HEATER";
|
||||
finder2("HEAVYGUN1") = "GUN_TACHYON_HEATER";
|
||||
// patch note: double gun for config CFG_EYEDSTONE_1: from GUN_FAST_ELECTROMAGNETIC_BEAM to double GUN_FAST_ELECTROMAGNETIC_BEAM (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_EYEDSTONE_1", "LIGHTGUN1", "GUN_FAST_ELECTROMAGNETIC_BEAM");
|
||||
tblcfg("CFG_EYEDSTONE_1", "LIGHTGUN1") = "GUN_FAST_ELECTROMAGNETIC_BEAM";
|
||||
// patch note: double gun for config CFG_EYEDSTONE_2: from GUN_FAST_ELECTROMAGNETIC_BEAM to double GUN_FAST_ELECTROMAGNETIC_BEAM (lz)
|
||||
mod.db().edit_value(u8"Êîíôèãóðàöèè", "CFG_EYEDSTONE_2", "LIGHTGUN1", "GUN_FAST_ELECTROMAGNETIC_BEAM");
|
||||
tblcfg("CFG_EYEDSTONE_2", "LIGHTGUN1") = "GUN_FAST_ELECTROMAGNETIC_BEAM";
|
||||
// patch note: INFORMATION
|
||||
auto quest = mod.quest().open();
|
||||
// patch note: add name for SINIGR armor, it was unnamed before (lz)
|
||||
mod.quest().add_value("INFORMATION", "EQP_ZERO_ARMOR_S_SIN", "NAME", u8"Îñîáàÿ íóëü-áðîíÿ");
|
||||
quest("INFORMATION", "EQP_ZERO_ARMOR_S_SIN", "NAME") = u8"Îñîáàÿ íóëü-áðîíÿ";
|
||||
// patch note:
|
||||
|
||||
// patch note: Game Changes
|
||||
|
|
@ -174,6 +179,11 @@ int main(int argc, char *argv[]) {
|
|||
// patch note dev: Developer Mode!!!
|
||||
// patch note dev: enabled developer mode (free camera - F3 key, time shift - N key) (lz, Solant)
|
||||
mod.enable_free_camera();
|
||||
// patch note dev: make initial reactor (EQP_GLUON_REACTOR_S1) and drive (EQP_ION_DRIVE_S1) more powerful
|
||||
db(u8"Îáîðóäîâàíèå", "EQP_GLUON_REACTOR_S1", "VALUE1") = 9'000'000.f;
|
||||
db(u8"Îáîðóäîâàíèå", "EQP_ION_DRIVE_S1", "VALUE1") = 4158000.f;
|
||||
// patch note dev: make EQP_VACUUM_DRIVE_S4 more powerful
|
||||
db(u8"Îáîðóäîâàíèå", "EQP_VACUUM_DRIVE_S4", "VALUE1") = 4158000.f;
|
||||
// patch note dev: start money, rating, glider and sector access
|
||||
mod.replace("Script/bin/B_L1_BASE1.scr", "_ADDBALANCE(300)", R"(
|
||||
_ADDBALANCE(300 )
|
||||
|
|
@ -223,6 +233,8 @@ int main(int argc, char *argv[]) {
|
|||
// patch note: lz
|
||||
// patch note:
|
||||
// patch note: Have fun!
|
||||
db.~files();
|
||||
quest.~files();
|
||||
mod.apply();
|
||||
|
||||
// patch note:
|
||||
|
|
|
|||
|
|
@ -186,30 +186,12 @@ struct mod_maker {
|
|||
c.push_back("a");
|
||||
c.push_back(ar); // we use zip as more common
|
||||
for (auto &&f : files_to_distribute) {
|
||||
c.push_back(f);
|
||||
c.push_back(f.is_absolute() ? f.lexically_relative(game_dir) : f);
|
||||
}
|
||||
for (auto &&f : code_files_to_distribute) {
|
||||
c.push_back(f);
|
||||
c.push_back(f.is_absolute() ? f.lexically_relative(game_dir) : f);
|
||||
}
|
||||
run_command(c);
|
||||
|
||||
auto rename = [&](auto &&from, auto &&to) {
|
||||
primitives::Command c;
|
||||
c.working_directory = game_dir;
|
||||
c.push_back("7z");
|
||||
c.push_back("rn");
|
||||
c.push_back(ar);
|
||||
c.push_back(from);
|
||||
c.push_back(to);
|
||||
run_command(c);
|
||||
};
|
||||
for (auto &&f : code_files_to_distribute) {
|
||||
if (f.filename() == path{loc.file_name()}.filename()) {
|
||||
rename(f.filename(), path{"data"} / "mods" / get_full_mod_name() / get_full_mod_name() += ".cpp");
|
||||
} else {
|
||||
rename(f.filename(), path{"data"} / "mods" / get_full_mod_name() / f.filename());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -314,8 +296,13 @@ struct mod_maker {
|
|||
ENABLE_DISABLE_FUNC(win_key, 0x00, 0x10)
|
||||
#undef ENABLE_DISABLE_FUNC
|
||||
|
||||
void add_code_file_for_archive(const path &fn) {
|
||||
code_files_to_distribute.insert(path{loc.file_name()}.parent_path() / fn);
|
||||
void add_code_file_for_archive(path fn) {
|
||||
if (!fn.is_absolute()) {
|
||||
fn = path{loc.file_name()}.parent_path() / fn.filename();
|
||||
}
|
||||
auto dst_fn = get_mod_dir() / fn.filename();
|
||||
fs::copy_file(fn, dst_fn, fs::copy_options::overwrite_existing);
|
||||
code_files_to_distribute.insert(dst_fn);
|
||||
}
|
||||
void add_resource(path fn) {
|
||||
fn = find_real_filename(fn);
|
||||
|
|
@ -330,16 +317,21 @@ struct mod_maker {
|
|||
}
|
||||
|
||||
private:
|
||||
void make_bak_file(const path &fn) {
|
||||
path make_bak_file(const path &fn) {
|
||||
auto backup = path{fn} += ".bak";
|
||||
if (!fs::exists(backup)) {
|
||||
fs::copy_file(fn, backup);
|
||||
}
|
||||
return backup;
|
||||
}
|
||||
auto open_db(auto &&name) {
|
||||
auto d = db2{get_data_dir() / name, db_codepage};
|
||||
for (auto &&f : d.open().get_files()) {
|
||||
make_bak_file(f);
|
||||
auto files = d.open().get_files();
|
||||
for (auto &&f : files) {
|
||||
auto bak = make_bak_file(f);
|
||||
if (fs::exists(bak)) {
|
||||
fs::copy_file(bak, f, fs::copy_options::overwrite_existing);
|
||||
}
|
||||
files_to_distribute.insert(f);
|
||||
}
|
||||
return d;
|
||||
|
|
@ -363,9 +355,17 @@ private:
|
|||
void init(const path &dir) {
|
||||
read_name();
|
||||
detect_game_dir(dir);
|
||||
#ifdef NDEBUG
|
||||
if (fs::exists(get_mod_dir())) {
|
||||
fs::remove_all(get_mod_dir());
|
||||
}
|
||||
#endif
|
||||
fs::create_directories(get_mod_dir());
|
||||
code_files_to_distribute.insert(loc.file_name());
|
||||
auto src_fn = get_mod_dir() / get_full_mod_name() += ".cpp";
|
||||
fs::copy_file(loc.file_name(), src_fn, fs::copy_options::overwrite_existing);
|
||||
code_files_to_distribute.insert(src_fn);
|
||||
detect_tools();
|
||||
create_backup_exe_file();
|
||||
prepare_injections();
|
||||
#ifndef NDEBUG
|
||||
enable_win_key();
|
||||
|
|
@ -482,7 +482,6 @@ private:
|
|||
::memcpy(p + off, to.data(), to.size());
|
||||
}
|
||||
void prepare_injections() {
|
||||
create_backup_exe_file();
|
||||
#ifdef NDEBUG
|
||||
make_injected_dll();
|
||||
#endif
|
||||
|
|
@ -592,16 +591,17 @@ FF D7 ; call edi
|
|||
}
|
||||
// from https://github.com/Solant/aim-patches
|
||||
void free_camera(uint8_t val) {
|
||||
create_backup_exe_file();
|
||||
patch(aim_exe, 0x1F805, val);
|
||||
}
|
||||
void win_key(uint8_t val) {
|
||||
create_backup_exe_file();
|
||||
patch(aim_exe, 0x4A40D, val);
|
||||
}
|
||||
void create_backup_exe_file() {
|
||||
auto fn = find_real_filename(aim_exe);
|
||||
make_bak_file(fn);
|
||||
auto bak = make_bak_file(fn);
|
||||
if (fs::exists(bak)) {
|
||||
fs::copy_file(bak, fn, fs::copy_options::overwrite_existing);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void patch_raw(path fn, uint32_t offset, T val) const {
|
||||
|
|
|
|||
210
src/common/db2.h
210
src/common/db2.h
|
|
@ -100,6 +100,14 @@ struct db2 {
|
|||
};
|
||||
// actual db
|
||||
struct files {
|
||||
template <typename T, typename V>
|
||||
struct setter {
|
||||
T field;
|
||||
V value;
|
||||
void operator=(auto &&v) {
|
||||
value.set_field(field, v);
|
||||
}
|
||||
};
|
||||
struct table {
|
||||
files &f;
|
||||
db2::tab::table t;
|
||||
|
|
@ -149,6 +157,17 @@ struct db2 {
|
|||
}
|
||||
return value{*this,*itv};
|
||||
}
|
||||
auto operator()(auto &&name) {
|
||||
return find_value(name);
|
||||
}
|
||||
auto operator()(auto &&vname, auto &&fname) {
|
||||
auto value = find_value(vname);
|
||||
if constexpr (std::is_convertible_v<decltype(fname), const char *>) {
|
||||
return setter<const char *, decltype(value)>{fname, value};
|
||||
} else {
|
||||
return setter<std::string, decltype(value)>{fname, value};
|
||||
}
|
||||
}
|
||||
};
|
||||
struct value {
|
||||
table t;
|
||||
|
|
@ -166,6 +185,9 @@ struct db2 {
|
|||
void set_field(auto &&name, auto &&v) {
|
||||
using T = std::decay_t<decltype(v)>;
|
||||
auto f = t.find_field(name, field_type(v));
|
||||
if (f.type != field_type(v)) {
|
||||
throw std::runtime_error{"field type mismatch: "s + t.f.db.utf8_to_dbstr(name)};
|
||||
}
|
||||
dat::field_value_base newfield{f.id};
|
||||
if constexpr (std::same_as<std::decay_t<decltype(v)>, int> ||
|
||||
std::same_as<std::decay_t<decltype(v)>, float>) {
|
||||
|
|
@ -215,13 +237,12 @@ struct db2 {
|
|||
this->v.offset = t.f.dat_.f.sz;
|
||||
memcpy(t.f.dat_.f.alloc_raw(t.f.dat_.f.sz + reallen), data.data(), reallen);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct setter {
|
||||
T field;
|
||||
value value;
|
||||
void operator=(auto &&v) {
|
||||
value.set_field(field, v);
|
||||
auto operator()(auto &&name) {
|
||||
if constexpr (std::is_convertible_v<decltype(name), const char *>) {
|
||||
return setter<const char *, value>{name, *this};
|
||||
} else {
|
||||
return setter<std::string, value>{name, *this};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -258,13 +279,16 @@ struct db2 {
|
|||
}
|
||||
|
||||
// [] not in msvc yet
|
||||
auto operator()(auto &&tname) {
|
||||
return find_table(tname);
|
||||
}
|
||||
auto operator()(auto &&tname, auto &&vname, auto &&fname) {
|
||||
auto tbl = find_table(tname);
|
||||
auto value = tbl.find_value(vname);
|
||||
if constexpr (std::is_convertible_v<decltype(fname), const char *>) {
|
||||
return setter<const char *>{fname, value};
|
||||
return setter<const char *, decltype(value)>{fname, value};
|
||||
} else {
|
||||
return setter<std::string>{fname, value};
|
||||
return setter<std::string, decltype(value)>{fname, value};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -272,174 +296,6 @@ struct db2 {
|
|||
auto open() {
|
||||
return files{*this,fn};
|
||||
}
|
||||
void add_value(auto &&table, auto &&value, auto && ... fields1) {
|
||||
auto f = open();
|
||||
auto tbl = f.tab_.data->tables();
|
||||
auto fields = f.tab_.data->fields();
|
||||
auto values = f.ind_.data->values();
|
||||
|
||||
auto table_db_cp = utf8_to_dbstr(table);
|
||||
auto value_db_cp = utf8_to_dbstr(value);
|
||||
|
||||
auto calc_fields_size = [&](this auto &&f, auto &&field_name, auto &&n, auto &&v, auto &&...fields) {
|
||||
if (field_name == n) {
|
||||
if constexpr (std::same_as<std::decay_t<decltype(v)>, int>) {
|
||||
return sizeof(db2::dat::field_value_base) + sizeof(int);
|
||||
} else if constexpr (std::same_as<std::decay_t<decltype(v)>, float>) {
|
||||
return sizeof(db2::dat::field_value_base) + sizeof(float);
|
||||
} else {
|
||||
auto s = utf8_to_dbstr(v);
|
||||
return sizeof(db2::dat::field_value_base) + s.size() + 1;
|
||||
}
|
||||
}
|
||||
if constexpr (sizeof...(fields)) {
|
||||
return f(field_name, fields...);
|
||||
}
|
||||
if constexpr (std::same_as<std::decay_t<decltype(v)>, int>) {
|
||||
return sizeof(db2::dat::field_value_base) + sizeof(int);
|
||||
} else if constexpr (std::same_as<std::decay_t<decltype(v)>, float>) {
|
||||
return sizeof(db2::dat::field_value_base) + sizeof(float);
|
||||
} else {
|
||||
return sizeof(db2::dat::field_value_base) + 1;
|
||||
}
|
||||
};
|
||||
auto write_fields = [&](this auto &&f, auto &&p, auto &&field, auto &&field_name, auto &&n, auto &&v, auto &&...fields) {
|
||||
if (field_name == n) {
|
||||
if constexpr (std::same_as<std::decay_t<decltype(v)>, int>) {
|
||||
if (field.type != db2::field_type::integer) {
|
||||
throw std::runtime_error{"field type mismatch"};
|
||||
}
|
||||
(*(db2::dat::field_value_base*)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base*)p).size = sizeof(int);
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
*(int*)p = v;
|
||||
p += sizeof(int);
|
||||
return;
|
||||
} else if constexpr (std::same_as<std::decay_t<decltype(v)>, float>) {
|
||||
if (field.type != db2::field_type::float_) {
|
||||
throw std::runtime_error{"field type mismatch"};
|
||||
}
|
||||
(*(db2::dat::field_value_base *)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base *)p).size = sizeof(float);
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
*(float *)p = v;
|
||||
p += sizeof(float);
|
||||
return;
|
||||
} else {
|
||||
if (field.type != db2::field_type::string) {
|
||||
throw std::runtime_error{"field type mismatch"};
|
||||
}
|
||||
auto s = utf8_to_dbstr(v);
|
||||
(*(db2::dat::field_value_base *)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base *)p).size = s.size() + 1;
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
memcpy(p, s.data(), s.size());
|
||||
p[s.size()] = 0;
|
||||
p += s.size() + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if constexpr (sizeof...(fields)) {
|
||||
return f(p, field, field_name, fields...);
|
||||
}
|
||||
if constexpr (std::same_as<std::decay_t<decltype(v)>, int>) {
|
||||
(*(db2::dat::field_value_base *)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base *)p).size = 0;
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
return;
|
||||
} else if constexpr (std::same_as<std::decay_t<decltype(v)>, float>) {
|
||||
(*(db2::dat::field_value_base *)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base *)p).size = 0;
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
return;
|
||||
} else {
|
||||
(*(db2::dat::field_value_base *)p).field_id = field.id;
|
||||
(*(db2::dat::field_value_base *)p).size = 1;
|
||||
p += sizeof(db2::dat::field_value_base);
|
||||
p[1] = 0;
|
||||
p += 1;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
auto it = std::ranges::find_if(tbl, [&](auto &v){return v.name == table_db_cp;});
|
||||
if (it == tbl.end()) {
|
||||
throw std::runtime_error{"no such table: "s + table_db_cp};
|
||||
}
|
||||
auto &t = *it;
|
||||
auto itv = std::ranges::find_if(values, [&](auto &v){return v.table_id == t.id && value_db_cp == v.name;});
|
||||
if (itv == values.end()) {
|
||||
db2::ind::value i{};
|
||||
i.table_id = t.id;
|
||||
memcpy(i.name, value_db_cp.data(), value_db_cp.size());
|
||||
i.offset = f.dat_.f.sz;
|
||||
for (auto &&f : fields) {
|
||||
if (f.table_id != t.id) {
|
||||
continue;
|
||||
}
|
||||
std::string_view fn = f.name;
|
||||
i.size += calc_fields_size(fn, fields1...);
|
||||
}
|
||||
|
||||
++f.ind_.data->n_values;
|
||||
auto p = f.ind_.f.alloc_raw(f.ind_.f.sz + sizeof(i));
|
||||
memcpy(p, &i, sizeof(i));
|
||||
|
||||
p = f.dat_.f.alloc_raw(f.dat_.f.sz + i.size);
|
||||
for (auto &&f : fields) {
|
||||
if (f.table_id != t.id) {
|
||||
continue;
|
||||
}
|
||||
std::string_view fn = f.name;
|
||||
write_fields(p, f, fn, fields1...);
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void edit_value(auto &&table, auto &&value, auto &&field, const T &field_value) {
|
||||
auto f = open();
|
||||
auto fields = f.tab_.data->fields();
|
||||
auto values = f.ind_.data->values();
|
||||
|
||||
auto value_db_cp = utf8_to_dbstr(value);
|
||||
auto field_db_cp = utf8_to_dbstr(field);
|
||||
|
||||
/*auto t = f.find_table(table);
|
||||
auto itv = std::ranges::find_if(values, [&](auto &v) {
|
||||
return v.table_id == t.id && value_db_cp == v.name;
|
||||
});
|
||||
if (itv == values.end()) {
|
||||
throw std::runtime_error{"no such value: "s + value_db_cp};
|
||||
}
|
||||
auto itf = std::ranges::find_if(fields, [&](auto &v) {
|
||||
return v.table_id == t.id && field_db_cp == v.name;
|
||||
});
|
||||
if (itf == fields.end()) {
|
||||
throw std::runtime_error{"no such field: "s + field_db_cp};
|
||||
}
|
||||
|
||||
auto p = f.dat_.f.p + itv->offset;
|
||||
while (p < f.dat_.f.p + itv->offset + itv->size) {
|
||||
auto &header = *(dat::field_value_base*)p;
|
||||
p += sizeof(header);
|
||||
if (header.field_id == itf->id) {
|
||||
if constexpr (std::same_as<std::decay_t<decltype(field_value)>, int>) {
|
||||
*(int*)p = field_value;
|
||||
} else if constexpr (std::same_as<std::decay_t<decltype(field_value)>, float>) {
|
||||
*(float *)p = field_value;
|
||||
} else {
|
||||
auto s = utf8_to_dbstr(field_value);
|
||||
if (s.size() + 1 != header.size) {
|
||||
throw std::runtime_error{"not implemented yet"}; // maybe just assign new value into the end of db
|
||||
}
|
||||
memcpy(p, s.data(), s.size());
|
||||
}
|
||||
return;
|
||||
}
|
||||
p += header.size;
|
||||
}*/
|
||||
throw std::runtime_error{"no such field"};
|
||||
}
|
||||
|
||||
private:
|
||||
std::string utf8_to_dbstr(const char *s) const {
|
||||
|
|
|
|||
Loading…
Reference in a new issue