Move hamdata.ini to gamedata (#597)

* Replace atoi by strtol in the config parser

* Move hamdata.ini data to gamedata files

* Reference the new files in master file

* Remove all the parsing code and use config manager to get the offsets

* Remove any hamdata.ini references
This commit is contained in:
Vincent Herbet
2018-09-28 16:51:54 +02:00
committed by GitHub
parent 8717ffe07c
commit f82455dd84
21 changed files with 11856 additions and 5090 deletions

View File

@ -11,381 +11,46 @@
// Ham Sandwich Module
//
#include "amxxmodule.h"
#include <amxxmodule.h>
#include "ham_const.h"
#include "hooklist.h"
#include "offsets.h"
#include <amtl/am-string.h>
extern hook_t hooklist[];
IGameConfig *CommonConfig;
IGameConfigManager *ConfigManager;
enum
{
LEX_INVALID = 0,
LEX_UNKNOWN,
LEX_START_SEC,
LEX_END_SEC,
LEX_MIRROR,
LEX_PEV,
LEX_BASE,
LEX_END
};
const char *tokens[] =
{
"", // LEX_INVALID
"", // LEX_UNKNOWN
"@section", // LEX_START_SEC
"@end", // LEX_END_SEC
"@mirror", // LEX_MIRROR
"pev", // LEX_PEV
"base", // LEX_BASE
"", // LEX_END
};
static void trim_line(char *input);
static void read_mirror(char *input);
static void skip_to_end_of_section(FILE *fp);
static int lex(char*& buffer);
int lex(char*& buffer)
{
trim_line(buffer);
size_t len;
for (int i=0; i<LEX_END; i++)
{
if (tokens[i]!=NULL && *(tokens[i])!='\0')
{
len=strlen(tokens[i]);
if (strncmp(buffer,tokens[i],len)==0)
{
buffer+=len+1;
return i;
}
}
}
return LEX_UNKNOWN;
}
// How we handle "mirrors"
// We just note down the current mod name, and every time
// we come across a mirror with the destination that matches
// the current mod name, we change the current mod name to
// the source for that mirror.
char CurrentModName[64];
static void read_mirror(char *input)
{
char *data=input;
char *data2;
char source[64];
char dest[64];
char old;
while ( *data!=' ' &&
*data!='\t' &&
*data!='\0')
{
data++;
}
old=*data;
*data='\0';
// mark down the source
ke::SafeSprintf(source, sizeof(source), "%s", input);
*data=old;
while ( *data==' ' ||
*data=='\t')
{
data++;
}
data2=data;
while ( *data!=' ' &&
*data!='\t' &&
*data!='\0')
{
data++;
}
old=*data;
*data='\0';
ke::SafeSprintf(dest, sizeof(dest), "%s", data2);
*data=old;
if (strcmp(dest, CurrentModName)==0)
{
ke::SafeSprintf(CurrentModName, sizeof(CurrentModName), "%s", source);
}
}
static void trim_line(char *input)
{
char *oldinput=input;
char *start=input;
while ( *start==' ' ||
*start=='\t' ||
*start=='\r' ||
*start=='\n')
{
start++;
}
// Overwrite the whitespace
if (start != input)
{
while ((*input++=*start++)!='\0')
/* do nothing */ ;
}
start=oldinput;
start+=strlen(start) - 1;
while ( start >= oldinput &&
( *start == '\0' ||
*start == ' ' ||
*start == '\r' ||
*start == '\n' ||
*start == '\t'))
{
start--;
}
start++;
*start='\0';
// Now find any comments and cut off at the start
while (*start != '\0')
{
if (*start == ';')
{
*start='\0';
break;
}
start++;
}
}
void skip_to_end_of_section(FILE *fp)
{
char buffer[1024];
while (!feof(fp))
{
buffer[0]='\0';
fgets(buffer, sizeof(buffer)-1, fp);
trim_line(buffer);
char *b=&buffer[0];
if (lex(b)==LEX_END_SEC)
{
break;
}
}
}
static const char* get_localinfo( const char* name , const char* def = 0 )
{
const char* b = LOCALINFO( (char*)name );
if (((b==0)||(*b==0)) && def )
SET_LOCALINFO((char*)name,(char*)(b = def) );
return b;
}
int read_start_section(char *data)
{
if (strncasecmp(data, CurrentModName, strlen(CurrentModName))==0)
{
data+=strlen(CurrentModName)+1;
trim_line(data);
#ifdef _WIN32
if (strcmp(data, "windows")==0)
#elif defined(__linux__)
if (strcmp(data, "linux")==0)
#elif defined(__APPLE__)
if (strcmp(data, "mac")==0)
#endif
{
return 1;
}
}
return 0;
}
int read_number(char *input)
{
char *end; /* Temporary pointer, needed for strtoul(). */
// if begins with 0x or 0X it's to be interpretted as hex
if (*input=='0' &&
(*(input+1)=='x' || *(input+1)=='X'))
{
return strtoul(input,&end,16);
}
// otherwise it's to be interpretted as base 10
return strtoul(input,&end,10);
}
void process_pev(char *data)
{
trim_line(data);
Offsets.SetPev(read_number(data));
}
void process_base(char *data)
{
trim_line(data);
Offsets.SetBase(read_number(data));
}
void process_key(char *data)
{
size_t size=0;
char *a=data;
while (*a != ' ' && *a != '\t' && *a != '\0')
{
a++;
size++;
}
if (size==0)
{
return;
}
int set=0;
for (int i=0; i< HAM_LAST_ENTRY_DONT_USE_ME_LOL; i++)
{
if (strncmp(data, hooklist[i].name, size)==0)
{
data+=size+1;
trim_line(data);
int value=read_number(data);
hooklist[i].isset=1;
hooklist[i].vtid=value;
set=1;
break;
}
}
if (set==0)
{
printf("stray key in process_key: %s\n", data);
}
}
int ReadConfig(void)
{
char FileName[512];
ConfigManager = MF_GetConfigManager();
MF_BuildPathnameR(FileName,sizeof(FileName),"%s",get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
char error[256] = "";
strncat(FileName,"/hamdata.ini",sizeof(FileName)-1);
FILE *fp=fopen(FileName,"r");
ke::SafeSprintf(CurrentModName, sizeof(CurrentModName), "%s", MF_GetModname());
if (!fp)
if (!ConfigManager->LoadGameConfigFile("common.games", &CommonConfig, error, sizeof error))
{
MF_Log("Unable to open \"%s\" for reading.", FileName);
MF_Log("common.games gamedata could not be read: %s", error);
return -1;
}
char data[2048];
TypeDescription value;
int insec=0;
while (!feof(fp))
if (CommonConfig->GetOffset("pev", &value))
{
data[0]='\0';
fgets(data, sizeof(data)-1, fp);
char *b=&data[0];
switch(lex(b))
{
case LEX_PEV:
{
if (insec)
{
process_pev(b);
}
break;
};
case LEX_BASE:
{
if (insec)
{
process_base(b);
}
break;
};
case LEX_MIRROR:
{
read_mirror(b);
break;
};
case LEX_START_SEC:
{
insec=read_start_section(b);
if (!insec)
{
skip_to_end_of_section(fp);
}
break;
};
case LEX_END_SEC:
{
insec=0;
break;
};
case LEX_UNKNOWN:
{
if (insec)
{
process_key(b);
}
};
}
Offsets.SetPev(value.fieldOffset);
}
fclose(fp);
if (CommonConfig->GetOffset("base", &value))
{
Offsets.SetBase(value.fieldOffset);
}
for (auto index = 0; index < HAM_LAST_ENTRY_DONT_USE_ME_LOL; ++index)
{
if (CommonConfig->GetOffset(hooklist[index].name, &value))
{
hooklist[index].isset = 1;
hooklist[index].vtid = value.fieldOffset;
}
}
return 1;
}

View File

@ -558,7 +558,7 @@ enum
HAM_OK = 0,
HAM_INVALID_FUNC, // The function is not valid
HAM_FUNC_NOT_CONFIGURED, // This function is not configured in hamdata.ini
HAM_FUNC_NOT_CONFIGURED, // This function is not configured in gamedata
HAM_FUNC_NOT_AVAILABLE, // This function is not more available in the mod
HAM_ERR_END

View File

@ -33,7 +33,7 @@ extern HLTypeConversion TypeConversion;
return 0; \
} else if (hooklist[x].isset == 0) { \
char msg[1024]; \
ke::SafeSprintf(msg, sizeof(msg), "Function %s is not configured in hamdata.ini.", hooklist[x].name); \
ke::SafeSprintf(msg, sizeof(msg), "Function %s is not configured in gamedata.", hooklist[x].name); \
FailPlugin(amx, x, HAM_FUNC_NOT_CONFIGURED, msg); \
return 0; \
}