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
|
||||
;Must be non-zero to use the edit/get/reset_critical script functions
|
||||
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
|
||||
|
||||
;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
|
||||
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
|
||||
[Debugging]
|
||||
;Extra sfall configuration settings that can be used by modders
|
||||
|
||||
@@ -53,6 +53,8 @@ static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId);
|
||||
|
||||
static int idle;
|
||||
|
||||
std::string ScriptExtender::iniConfigFolder;
|
||||
|
||||
struct GlobalScript {
|
||||
ScriptProgram prog;
|
||||
int count;
|
||||
@@ -724,6 +726,19 @@ void ScriptExtender::init() {
|
||||
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);
|
||||
if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT);
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
const char* name() { return "ScriptExtender"; }
|
||||
void init();
|
||||
|
||||
static std::string iniConfigFolder;
|
||||
|
||||
// Called before map exit (before map_exit_p_proc handlers in normal scripts)
|
||||
static Delegate<>& OnMapExit();
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "..\..\..\Utils.h"
|
||||
#include "..\..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\AI.h"
|
||||
#include "..\..\Combat.h"
|
||||
@@ -523,7 +524,8 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
||||
if (!key) return -1;
|
||||
|
||||
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, "|");
|
||||
if (!key) return -1;
|
||||
@@ -533,9 +535,24 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
||||
|
||||
file[0] = '.';
|
||||
file[1] = '\\';
|
||||
if (!ScriptExtender::iniConfigFolder.empty()) {
|
||||
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);
|
||||
section[seclen] = 0;
|
||||
|
||||
@@ -546,7 +563,7 @@ static int ParseIniSetting(const char* iniString, const char* &key, char section
|
||||
static char IniStrBuffer[256];
|
||||
static DWORD GetIniSetting(const char* str, bool isString) {
|
||||
const char* key;
|
||||
char section[33], file[67];
|
||||
char section[33], file[128];
|
||||
|
||||
if (ParseIniSetting(str, key, section, file) < 0) {
|
||||
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];
|
||||
|
||||
void sf_get_ini_sections(OpcodeContext& ctx) {
|
||||
auto fileName = std::string(".\\") + ctx.arg(0).asString();
|
||||
GetPrivateProfileSectionNamesA(getIniSectionBuf, 5120, fileName.data());
|
||||
GetPrivateProfileSectionNamesA(getIniSectionBuf, 5120, GetIniFilePath(ctx.arg(0)).data());
|
||||
std::vector<char*> sections;
|
||||
char* section = getIniSectionBuf;
|
||||
while (*section != 0) {
|
||||
@@ -1256,9 +1285,8 @@ void sf_get_ini_sections(OpcodeContext& ctx) {
|
||||
}
|
||||
|
||||
void sf_get_ini_section(OpcodeContext& ctx) {
|
||||
auto fileName = std::string(".\\") + ctx.arg(0).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
|
||||
auto& arr = arrays[arrayId];
|
||||
char *key = getIniSectionBuf, *val = nullptr;
|
||||
|
||||
@@ -281,7 +281,7 @@ void sf_message_str_game(OpcodeContext& ctx) {
|
||||
|
||||
int fileId = fileIdArg.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);
|
||||
} else if (fileId >= 0x1000 && fileId <= 0x1005) { // proto msg files
|
||||
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);
|
||||
|
||||
const char* strfind(const char* source, const char* word);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user