mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r26611) -Feature: Save and load grfid and md5sum of newgrfs in config file (frosch)
This commit is contained in:
parent
8755c26793
commit
c1e7c32f07
|
@ -1407,6 +1407,40 @@ static void GameLoadConfig(IniFile *ini, const char *grpname)
|
|||
if (item->value != NULL) config->StringToSettings(item->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a character to a hex nibble value, or \c -1 otherwise.
|
||||
* @param c Character to convert.
|
||||
* @return Hex value of the character, or \c -1 if not a hex digit.
|
||||
*/
|
||||
static int DecodeHexNibble(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'A' && c <= 'F') return c + 10 - 'A';
|
||||
if (c >= 'a' && c <= 'f') return c + 10 - 'a';
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a sequence of characters (supposedly hex digits) into a sequence of bytes.
|
||||
* After the hex number should be a \c '|' character.
|
||||
* @param pos First character to convert.
|
||||
* @param dest [out] Output byte array to write the bytes.
|
||||
* @param dest_size Number of bytes in \a dest.
|
||||
* @return Whether reading was successful.
|
||||
*/
|
||||
static bool DecodeHexText(char *pos, uint8 *dest, size_t dest_size)
|
||||
{
|
||||
while (dest_size > 0) {
|
||||
int hi = DecodeHexNibble(pos[0]);
|
||||
int lo = (hi >= 0) ? DecodeHexNibble(pos[1]) : -1;
|
||||
if (lo < 0) return false;
|
||||
*dest++ = (hi << 4) | lo;
|
||||
pos += 2;
|
||||
dest_size--;
|
||||
}
|
||||
return *pos == '|';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a GRF configuration
|
||||
* @param ini The configuration to read from.
|
||||
|
@ -1423,16 +1457,41 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati
|
|||
if (group == NULL) return NULL;
|
||||
|
||||
for (item = group->item; item != NULL; item = item->next) {
|
||||
GRFConfig *c = new GRFConfig(item->name);
|
||||
GRFConfig *c = NULL;
|
||||
|
||||
uint8 grfid_buf[4], md5sum[16];
|
||||
char *filename = item->name;
|
||||
bool has_grfid = false;
|
||||
bool has_md5sum = false;
|
||||
|
||||
/* Try reading "<grfid>|" and on success, "<md5sum>|". */
|
||||
has_grfid = DecodeHexText(filename, grfid_buf, lengthof(grfid_buf));
|
||||
if (has_grfid) {
|
||||
filename += 1 + 2 * lengthof(grfid_buf);
|
||||
has_md5sum = DecodeHexText(filename, md5sum, lengthof(md5sum));
|
||||
if (has_md5sum) filename += 1 + 2 * lengthof(md5sum);
|
||||
|
||||
uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
|
||||
if (has_md5sum) {
|
||||
const GRFConfig *s = FindGRFConfig(grfid, FGCM_EXACT, md5sum);
|
||||
if (s != NULL) c = new GRFConfig(*s);
|
||||
}
|
||||
if (c == NULL && !FioCheckFileExists(filename, NEWGRF_DIR)) {
|
||||
const GRFConfig *s = FindGRFConfig(grfid, FGCM_NEWEST_VALID);
|
||||
if (s != NULL) c = new GRFConfig(*s);
|
||||
}
|
||||
}
|
||||
if (c == NULL) c = new GRFConfig(filename);
|
||||
|
||||
/* Parse parameters */
|
||||
if (!StrEmpty(item->value)) {
|
||||
c->num_params = ParseIntList(item->value, (int*)c->param, lengthof(c->param));
|
||||
if (c->num_params == (byte)-1) {
|
||||
SetDParamStr(0, item->name);
|
||||
int count = ParseIntList(item->value, (int*)c->param, lengthof(c->param));
|
||||
if (count < 0) {
|
||||
SetDParamStr(0, filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL);
|
||||
c->num_params = 0;
|
||||
count = 0;
|
||||
}
|
||||
c->num_params = count;
|
||||
}
|
||||
|
||||
/* Check if item is valid */
|
||||
|
@ -1449,7 +1508,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati
|
|||
SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
|
||||
}
|
||||
|
||||
SetDParamStr(0, item->name);
|
||||
SetDParamStr(0, StrEmpty(filename) ? item->name : filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL);
|
||||
delete c;
|
||||
continue;
|
||||
|
@ -1459,7 +1518,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati
|
|||
bool duplicate = false;
|
||||
for (const GRFConfig *gc = first; gc != NULL; gc = gc->next) {
|
||||
if (gc->ident.grfid == c->ident.grfid) {
|
||||
SetDParamStr(0, item->name);
|
||||
SetDParamStr(0, c->filename);
|
||||
SetDParamStr(1, gc->filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_DUPLICATE_GRFID, WL_CRITICAL);
|
||||
duplicate = true;
|
||||
|
@ -1557,10 +1616,15 @@ static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *li
|
|||
const GRFConfig *c;
|
||||
|
||||
for (c = list; c != NULL; c = c->next) {
|
||||
/* Hex grfid (4 bytes in nibbles), "|", hex md5sum (16 bytes in nibbles), "|", file system path. */
|
||||
char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
|
||||
char params[512];
|
||||
GRFBuildParamList(params, c, lastof(params));
|
||||
|
||||
group->GetItem(c->filename, true)->SetValue(params);
|
||||
char *pos = key + seprintf(key, lastof(key), "%08X|", BSWAP32(c->ident.grfid));
|
||||
pos = md5sumToString(pos, lastof(key), c->ident.md5sum);
|
||||
seprintf(pos, lastof(key), "|%s", c->filename);
|
||||
group->GetItem(key, true)->SetValue(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue