mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added IniConfigFolder option to override the path of all scripted ini
Fixed a crash bug in message_str_game function when passing a negative fileId value.
This commit is contained in:
+6
-1
@@ -364,7 +364,7 @@ AdditionalWeaponAnims=1
|
|||||||
;If the ExtraKillTypes option is enabled, this should be set to 3, with containing entries for any new types
|
;If the ExtraKillTypes option is enabled, this should be set to 3, with containing entries for any new types
|
||||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||||
OverrideCriticalTable=2
|
OverrideCriticalTable=2
|
||||||
;Uncomment the next line to specify an alternative path and file name for the critical table file
|
;To change the path and filename of the critical table file, uncomment the next line
|
||||||
;OverrideCriticalFile=CriticalOverrides.ini
|
;OverrideCriticalFile=CriticalOverrides.ini
|
||||||
|
|
||||||
;Set to 1 to get notification of karma changes in the notification window
|
;Set to 1 to get notification of karma changes in the notification window
|
||||||
@@ -724,6 +724,11 @@ CreditsAtBottom=0
|
|||||||
;Paths outside of scripts folder are supported
|
;Paths outside of scripts folder are supported
|
||||||
GlobalScriptPaths=scripts\gl*.int,scripts\sfall\gl*.int
|
GlobalScriptPaths=scripts\gl*.int,scripts\sfall\gl*.int
|
||||||
|
|
||||||
|
;Uncomment the option to specify a common folder path for all scripted ini configuration files
|
||||||
|
;You will need to place all the available ini files of the mods to this directory
|
||||||
|
;The maximum length of the specified path is 61 characters
|
||||||
|
;IniConfigFolder=IniConfig
|
||||||
|
|
||||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
[Debugging]
|
[Debugging]
|
||||||
;Extra sfall configuration settings that can be used by modders
|
;Extra sfall configuration settings that can be used by modders
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId);
|
|||||||
|
|
||||||
static int idle;
|
static int idle;
|
||||||
|
|
||||||
|
std::string ScriptExtender::iniConfigFolder;
|
||||||
|
|
||||||
struct GlobalScript {
|
struct GlobalScript {
|
||||||
ScriptProgram prog;
|
ScriptProgram prog;
|
||||||
int count;
|
int count;
|
||||||
@@ -724,6 +726,19 @@ void ScriptExtender::init() {
|
|||||||
dlogr("Arrays in backward-compatiblity mode.", DL_SCRIPT);
|
dlogr("Arrays in backward-compatiblity mode.", DL_SCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iniConfigFolder = GetConfigString("Scripts", "IniConfigFolder", "");
|
||||||
|
size_t len = iniConfigFolder.length();
|
||||||
|
if (len) {
|
||||||
|
char c = iniConfigFolder[len - 1];
|
||||||
|
bool pathSeparator = (c == '\\' || c == '/');
|
||||||
|
if (len > 62 || (len == 62 && !pathSeparator)) {
|
||||||
|
iniConfigFolder.clear();
|
||||||
|
dlogr("Error: IniConfigFolder path is too long.", DL_SCRIPT);
|
||||||
|
} else if (!pathSeparator) {
|
||||||
|
iniConfigFolder += '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alwaysFindScripts = isDebug && (GetPrivateProfileIntA("Debugging", "AlwaysFindScripts", 0, ::sfall::ddrawIni) != 0);
|
alwaysFindScripts = isDebug && (GetPrivateProfileIntA("Debugging", "AlwaysFindScripts", 0, ::sfall::ddrawIni) != 0);
|
||||||
if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT);
|
if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ public:
|
|||||||
const char* name() { return "ScriptExtender"; }
|
const char* name() { return "ScriptExtender"; }
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
static std::string iniConfigFolder;
|
||||||
|
|
||||||
// Called before map exit (before map_exit_p_proc handlers in normal scripts)
|
// Called before map exit (before map_exit_p_proc handlers in normal scripts)
|
||||||
static Delegate<>& OnMapExit();
|
static Delegate<>& OnMapExit();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "..\..\..\Utils.h"
|
||||||
#include "..\..\..\FalloutEngine\Fallout2.h"
|
#include "..\..\..\FalloutEngine\Fallout2.h"
|
||||||
#include "..\..\AI.h"
|
#include "..\..\AI.h"
|
||||||
#include "..\..\Combat.h"
|
#include "..\..\Combat.h"
|
||||||
@@ -523,7 +524,8 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
|||||||
if (!key) return -1;
|
if (!key) return -1;
|
||||||
|
|
||||||
DWORD filelen = (DWORD)key - (DWORD)iniString;
|
DWORD filelen = (DWORD)key - (DWORD)iniString;
|
||||||
if (filelen >= 64) return -1;
|
if (ScriptExtender::iniConfigFolder.empty() && filelen >= 64) return -1;
|
||||||
|
const char* fileEnd = key;
|
||||||
|
|
||||||
key = strstr(key + 1, "|");
|
key = strstr(key + 1, "|");
|
||||||
if (!key) return -1;
|
if (!key) return -1;
|
||||||
@@ -533,9 +535,24 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
|||||||
|
|
||||||
file[0] = '.';
|
file[0] = '.';
|
||||||
file[1] = '\\';
|
file[1] = '\\';
|
||||||
memcpy(&file[2], iniString, filelen);
|
if (!ScriptExtender::iniConfigFolder.empty()) {
|
||||||
file[filelen + 2] = 0;
|
const char* pos = strfind(iniString, &::sfall::ddrawIni[2]);
|
||||||
|
if (pos && pos < fileEnd) goto ddraw;
|
||||||
|
size_t len = ScriptExtender::iniConfigFolder.length(); // limit to 62 characters
|
||||||
|
memcpy(&file[2], ScriptExtender::iniConfigFolder.c_str(), len);
|
||||||
|
int n = 0; // position of the beginning of the file name
|
||||||
|
for (int i = filelen - 4; i > 0; i--) {
|
||||||
|
if (iniString[i] == '\\' || iniString[i] == '/') {
|
||||||
|
n = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strncpy_s(&file[2 + len], (128 - 2) - len, &iniString[n], filelen - n); // copy filename (max len 63)
|
||||||
|
} else {
|
||||||
|
ddraw:
|
||||||
|
memcpy(&file[2], iniString, filelen);
|
||||||
|
file[filelen + 2] = 0;
|
||||||
|
}
|
||||||
memcpy(section, &iniString[filelen + 1], seclen);
|
memcpy(section, &iniString[filelen + 1], seclen);
|
||||||
section[seclen] = 0;
|
section[seclen] = 0;
|
||||||
|
|
||||||
@@ -546,7 +563,7 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
|||||||
static char IniStrBuffer[256];
|
static char IniStrBuffer[256];
|
||||||
static DWORD GetIniSetting(const char* str, bool isString) {
|
static DWORD GetIniSetting(const char* str, bool isString) {
|
||||||
const char* key;
|
const char* key;
|
||||||
char section[33], file[67];
|
char section[33], file[128];
|
||||||
|
|
||||||
if (ParseIniSetting(str, key, section, file) < 0) {
|
if (ParseIniSetting(str, key, section, file) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1232,11 +1249,23 @@ void sf_set_ini_setting(OpcodeContext& ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string GetIniFilePath(const ScriptValue& arg) {
|
||||||
|
std::string fileName(".\\");
|
||||||
|
if (ScriptExtender::iniConfigFolder.empty()) {
|
||||||
|
fileName += arg.strValue();
|
||||||
|
} else {
|
||||||
|
fileName += ScriptExtender::iniConfigFolder;
|
||||||
|
std::string name(arg.strValue());
|
||||||
|
int pos = name.find_last_of("\\/");
|
||||||
|
fileName += (pos > 0) ? name.substr(pos + 1) : name;
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
char getIniSectionBuf[5120];
|
char getIniSectionBuf[5120];
|
||||||
|
|
||||||
void sf_get_ini_sections(OpcodeContext& ctx) {
|
void sf_get_ini_sections(OpcodeContext& ctx) {
|
||||||
auto fileName = std::string(".\\") + ctx.arg(0).asString();
|
GetPrivateProfileSectionNamesA(getIniSectionBuf, 5120, GetIniFilePath(ctx.arg(0)).data());
|
||||||
GetPrivateProfileSectionNamesA(getIniSectionBuf, 5120, fileName.data());
|
|
||||||
std::vector<char*> sections;
|
std::vector<char*> sections;
|
||||||
char* section = getIniSectionBuf;
|
char* section = getIniSectionBuf;
|
||||||
while (*section != 0) {
|
while (*section != 0) {
|
||||||
@@ -1256,9 +1285,8 @@ void sf_get_ini_sections(OpcodeContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sf_get_ini_section(OpcodeContext& ctx) {
|
void sf_get_ini_section(OpcodeContext& ctx) {
|
||||||
auto fileName = std::string(".\\") + ctx.arg(0).asString();
|
|
||||||
auto section = ctx.arg(1).asString();
|
auto section = ctx.arg(1).asString();
|
||||||
GetPrivateProfileSectionA(section, getIniSectionBuf, 5120, fileName.data());
|
GetPrivateProfileSectionA(section, getIniSectionBuf, 5120, GetIniFilePath(ctx.arg(0)).data());
|
||||||
int arrayId = TempArray(-1, 0); // associative
|
int arrayId = TempArray(-1, 0); // associative
|
||||||
auto& arr = arrays[arrayId];
|
auto& arr = arrays[arrayId];
|
||||||
char *key = getIniSectionBuf, *val = nullptr;
|
char *key = getIniSectionBuf, *val = nullptr;
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ void sf_message_str_game(OpcodeContext& ctx) {
|
|||||||
|
|
||||||
int fileId = fileIdArg.asInt();
|
int fileId = fileIdArg.asInt();
|
||||||
int msgId = msgIdArg.asInt();
|
int msgId = msgIdArg.asInt();
|
||||||
if (fileId < 20) { // main msg files
|
if (fileId >= 0 && fileId <= 19) { // main msg files
|
||||||
msg = fo::GetMessageStr(gameMsgFiles[fileId], msgId);
|
msg = fo::GetMessageStr(gameMsgFiles[fileId], msgId);
|
||||||
} else if (fileId >= 0x1000 && fileId <= 0x1005) { // proto msg files
|
} else if (fileId >= 0x1000 && fileId <= 0x1005) { // proto msg files
|
||||||
msg = fo::GetMessageStr(&fo::var::proto_msg_files[fileId - 0x1000], msgId);
|
msg = fo::GetMessageStr(&fo::var::proto_msg_files[fileId - 0x1000], msgId);
|
||||||
|
|||||||
@@ -47,4 +47,17 @@ void strtrim(char* str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns position, find word must be lowercase
|
||||||
|
const char* strfind(const char* source, const char* word) {
|
||||||
|
if (source == 0 || word == 0 || *word == 0) return 0;
|
||||||
|
const char *w_pos, *s_pos;
|
||||||
|
while(*source != 0) {
|
||||||
|
w_pos = word, s_pos = source++;
|
||||||
|
while (tolower(*s_pos++) == *w_pos++) {
|
||||||
|
if (*w_pos == 0) return s_pos - (w_pos - word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,4 +32,6 @@ bool isSpace(char c);
|
|||||||
|
|
||||||
void strtrim(char* str);
|
void strtrim(char* str);
|
||||||
|
|
||||||
|
const char* strfind(const char* source, const char* word);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user