Skip to content

Commit

Permalink
Merge pull request #4 from meag/master
Browse files Browse the repository at this point in the history
MVDPARSER: sv_bigcoords support, fragfile definition update, .json/xml output, some bugfixes
  • Loading branch information
deurk authored Sep 19, 2020
2 parents bd4a278 + 72485cf commit 5005ded
Show file tree
Hide file tree
Showing 14 changed files with 757 additions and 184 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.vs
Debug
Release
*.vcxproj.user
16 changes: 13 additions & 3 deletions frag_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ static void InitFragDefs(void)
goto nextline; \
}

#define FRAGS_CHECKARGS3(x, y, z) \
if (c != x && c != y && c != z) { \
Sys_PrintError("Fragfile warning (line %d): %d, %d or %d tokens expected\n", line, x, y, z); \
goto nextline; \
}

#define FRAGS_CHECK_VERSION_DEFINED() \
if (!gotversion) { \
Sys_PrintError("Fragfile error: #FRAGFILE VERSION must be defined at the head of the file\n"); \
Expand Down Expand Up @@ -345,7 +351,7 @@ qbool LoadFragFile(char *filename, qbool quiet)

if (!strcasecmp(Cmd_Argv(1), "WEAPON_CLASS") || !strcasecmp(Cmd_Argv(1), "WC"))
{
FRAGS_CHECKARGS2(4, 5);
FRAGS_CHECKARGS3(4, 5, 6);
token = Cmd_Argv(2);

if (!strcasecmp(token, "NOWEAPON") || !strcasecmp(token, "NONE") || !strcasecmp(token, "NULL"))
Expand Down Expand Up @@ -675,8 +681,12 @@ void Frags_Parse(mvd_info_t *mvd, char *fragmessage, int level)
case mt_suicide :
{
mvd->fragstats[p1->pnum].suicides++;
p1->death_count++;
Log_Event(&logger, mvd, LOG_DEATH, p1->pnum);

// If it's a normal suicide then it'll get picked up by health < 0
if (!mess->wclass_index) {
p1->death_count++;
Log_Event(&logger, mvd, LOG_DEATH, p1->pnum);
}
break;
}
case mt_fragged :
Expand Down
222 changes: 207 additions & 15 deletions logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

logger_t logger;

char *LogVarValueAsString(mvd_info_t *mvd, const char *varname, int player_num);
char *LogVarValueAsString(mvd_info_t *mvd, const char *varname, int player_num, encoding_mode_t encoding);

#define LOG_CHECK_NUMARGS(num) \
{ \
Expand Down Expand Up @@ -102,6 +102,14 @@ static log_eventlogger_type_t Log_ParseEventloggerType(const char *event_logger_
{
return LOG_MATCHEND_ALL;
}
else if (!strcasecmp(event_logger_type, "MATCHEND_ALL_BETWEEN"))
{
return LOG_MATCHEND_ALL_BETWEEN;
}
else if (!strcasecmp(event_logger_type, "MATCHEND_FINAL"))
{
return LOG_MATCHEND_FINAL;
}
else if (!strcasecmp(event_logger_type, "DEMOSTART"))
{
return LOG_DEMOSTART;
Expand Down Expand Up @@ -404,7 +412,7 @@ qbool Log_ParseOutputTemplates(logger_t *logger, const char *template_file)
return true;
}

char *Log_ExpandTemplateString(logger_t *logger, mvd_info_t *mvd, const char *template_string, int player_num, int *output_len)
char *Log_ExpandTemplateString(logger_t *logger, mvd_info_t *mvd, const char *template_string, int player_num, int *output_len, encoding_mode_t encoding)
{
char var_value[1024];
char tmp[1024];
Expand Down Expand Up @@ -458,7 +466,7 @@ char *Log_ExpandTemplateString(logger_t *logger, mvd_info_t *mvd, const char *te

// Expand the variable based on the current mvd context / player.
snprintf(tmp, min((var_end - var_start), sizeof(tmp)), "%s", var_start);
strlcpy(var_value, LogVarValueAsString(mvd, tmp, player_num), sizeof(var_value));
strlcpy(var_value, LogVarValueAsString(mvd, tmp, player_num, encoding), sizeof(var_value));

// Add the value to the output string.
vv = var_value;
Expand All @@ -474,6 +482,10 @@ char *Log_ExpandTemplateString(logger_t *logger, mvd_info_t *mvd, const char *te
}

input = var_end;

if (!input[0]) {
break;
}
}
}

Expand Down Expand Up @@ -548,8 +560,8 @@ void Log_Event(logger_t *logger, mvd_info_t *mvd, log_eventlogger_type_t type, i
int p;
int player_start = player_num;
int player_count = 1;
int output_len = 0;
char *output = NULL;
int output_len[encoding_count] = { 0, 0, 0 };
char *output[encoding_count] = { NULL };
char *expanded_filename = NULL;
log_eventlogger_t *eventlogger = NULL;
log_outputfile_t *output_file = NULL;
Expand Down Expand Up @@ -582,7 +594,10 @@ void Log_Event(logger_t *logger, mvd_info_t *mvd, log_eventlogger_type_t type, i
}

// Expand the event loggers template string into an output string.
output = Q_strdup(Log_ExpandTemplateString(logger, mvd, eventlogger->output_template_string, player_num, &output_len));
for (j = 0; j < encoding_count; ++j) {
output_len[j] = 0;
output[j] = Q_strdup(Log_ExpandTemplateString(logger, mvd, eventlogger->output_template_string, player_num, &output_len[j], j));
}

// See the above comment for setting player_count for explination.
// TODO : Make this more readable by making the stuff inside the for-loop a separate function, and calling it in two separate if-cases instead.
Expand All @@ -597,7 +612,7 @@ void Log_Event(logger_t *logger, mvd_info_t *mvd, log_eventlogger_type_t type, i
// and then write the output to the files.
for (j = 0; j < eventlogger->templates_count; j++)
{
expanded_filename = Log_ExpandTemplateString(logger, mvd, eventlogger->outputfile_templates[j]->name, p, NULL);
expanded_filename = Log_ExpandTemplateString(logger, mvd, eventlogger->outputfile_templates[j]->name, p, NULL, normal_encoding);

// Search for the expanded filename in the output_hashtable.
output_file = Log_OutputFilesHashTable_GetValue(logger, expanded_filename);
Expand All @@ -609,11 +624,23 @@ void Log_Event(logger_t *logger, mvd_info_t *mvd, log_eventlogger_type_t type, i
output_file->filename = Q_strdup(expanded_filename);
output_file->file = fopen(expanded_filename, "w");

if (strstr(expanded_filename, ".xml")) {
output_file->encoding = xml_encoding;
}
else if (strstr(expanded_filename, ".json")) {
output_file->encoding = json_encoding;
}
else {
output_file->encoding = normal_encoding;
}

if (!output_file->file)
{
Q_free(output_file->filename);
Q_free(output_file);
Q_free(output);
for (j = 0; j < encoding_count; ++j) {
Q_free(output[j]);
}
Sys_Error("Log_Event: Failed to open the file %s (expanded from %s) for output.\n", output_file->filename, eventlogger->outputfile_templates[j]->name);
}

Expand Down Expand Up @@ -644,17 +671,18 @@ void Log_Event(logger_t *logger, mvd_info_t *mvd, log_eventlogger_type_t type, i
num_written_to++;
}*/

if (output_len > 0)
{
if (output_len[output_file->encoding] > 0) {
// Write the expanded output to the file.
fwrite(output, sizeof(char), output_len, output_file->file);
fwrite(output[output_file->encoding], sizeof(char), output_len[output_file->encoding], output_file->file);
fflush(output_file->file);
}
}
}
}

Q_free(output);
for (j = 0; j < encoding_count; ++j) {
Q_free(output[j]);
}
}

void Log_OutputFilesHashTable_Clear(logger_t *logger)
Expand Down Expand Up @@ -684,6 +712,16 @@ void Log_OutputFilesHashTable_Clear(logger_t *logger)
// Log variables
// ============================================================================

static char* LogVar_suicides(mvd_info_t* mvd, const char* varname, int player_num)
{
return va("%d", mvd->fragstats[player_num].suicides);
}

static char* LogVar_teamkills(mvd_info_t* mvd, const char* varname, int player_num)
{
return va("%d", mvd->fragstats[player_num].teamkills);
}

static char *LogVar_name(mvd_info_t *mvd, const char *varname, int player_num)
{
return mvd->players[player_num].name;
Expand Down Expand Up @@ -1161,6 +1199,12 @@ static char *LogVar_teamplay(mvd_info_t *mvd, const char *varname, int player_nu
}

static char *LogVar_map(mvd_info_t *mvd, const char *varname, int player_num)
{
// to keep old templates correct: used to return mapname from svc_serverdata and then overwrite with file from serverinfo
return mvd->serverinfo.mapfile;
}

static char* LogVar_mapname(mvd_info_t* mvd, const char* varname, int player_num)
{
return mvd->serverinfo.mapname;
}
Expand Down Expand Up @@ -1254,6 +1298,7 @@ logvar_t logvar_list[] =
LOGVAR_DEFINE(matchtime, LOGVAR_DEMO),
LOGVAR_DEFINE(mvdframe, LOGVAR_DEMO),
LOGVAR_DEFINE(map, LOGVAR_DEMO),
LOGVAR_DEFINE(mapname, LOGVAR_DEMO),
LOGVAR_DEFINE(gamedir, LOGVAR_DEMO),
LOGVAR_DEFINE(maxfps, LOGVAR_DEMO),
LOGVAR_DEFINE(zext, LOGVAR_DEMO),
Expand Down Expand Up @@ -1335,7 +1380,9 @@ logvar_t logvar_list[] =
LOGVAR_DEFINE(topcolor, LOGVAR_PLAYER),
LOGVAR_DEFINE(bottomcolor, LOGVAR_PLAYER),
LOGVAR_DEFINE(droppedweapon, LOGVAR_PLAYER),
LOGVAR_DEFINE(droppedweaponstr, LOGVAR_PLAYER)
LOGVAR_DEFINE(droppedweaponstr, LOGVAR_PLAYER),
LOGVAR_DEFINE(teamkills, LOGVAR_PLAYER),
LOGVAR_DEFINE(suicides, LOGVAR_PLAYER)
};

#define LOGVARS_LIST_SIZE (sizeof(logvar_list) / sizeof(logvar_t))
Expand Down Expand Up @@ -1380,7 +1427,140 @@ void LogVarHashTable_AddValue(logvar_t **hashtable, logvar_t *logvar)
}
}

char *LogVarValueAsString(mvd_info_t *mvd, const char *varname, int player_num)
#define MAX_STRINGS 128

static char* json_string(const char* input)
{
// >>>> like va(...) ... eugh
static char string[MAX_STRINGS][1024];
static int index = 0;
char* ch, * start;

index %= MAX_STRINGS;
// <<<<

start = ch = string[index++];
while (*input) {
unsigned char current = *input;

if (ch - start >= 1000) {
break;
}

if (current == '\\' || current == '"') {
*ch++ = '\\';
*ch++ = current;
}
else if (current == '\n') {
*ch++ = '\\';
*ch++ = 'n';
}
else if (current == '\r') {
*ch++ = '\\';
*ch++ = 'r';
}
else if (current == '\b') {
*ch++ = '\\';
*ch++ = 'b';
}
else if (current == '\t') {
*ch++ = '\\';
*ch++ = 't';
}
else if (current == '\f') {
*ch++ = '\\';
*ch++ = 'f';
}
else if (current < ' ' || current >= 128) {
*ch++ = '\\';
*ch++ = 'u';
*ch++ = '0';
*ch++ = '0';
if (current < 16) {
*ch++ = '0';
*ch++ = "0123456789ABCDEF"[(int)current];
}
else {
*ch++ = "0123456789ABCDEF"[((int)(current)) >> 4];
*ch++ = "0123456789ABCDEF"[((int)(current)) & 15];
}
}
else {
*ch++ = current;
}
++input;
}
*ch = '\0';
return start;
}

char* xml_string(const char* original)
{
static char string[MAX_STRINGS][1024];
static int index = 0;
int length = strlen(original);
int newlength = 0;
int i = 0;

index %= MAX_STRINGS;

memset(string[index], 0, sizeof(string[0]));

for (i = 0; i < length; ++i) {
unsigned char ch = (unsigned char)original[i];

if (ch == '<') {
if (newlength < sizeof(string[0]) - 4) {
string[index][newlength++] = '&';
string[index][newlength++] = 'l';
string[index][newlength++] = 't';
string[index][newlength++] = ';';
}
}
else if (ch == '>') {
if (newlength < sizeof(string[0]) - 4) {
string[index][newlength++] = '&';
string[index][newlength++] = 'g';
string[index][newlength++] = 't';
string[index][newlength++] = ';';
}
}
else if (ch == '"') {
if (newlength < sizeof(string[0]) - 5) {
string[index][newlength++] = '&';
string[index][newlength++] = '#';
string[index][newlength++] = '3';
string[index][newlength++] = '4';
string[index][newlength++] = ';';
}
}
else if (ch == '&') {
if (newlength < sizeof(string[0]) - 5) {
string[index][newlength++] = '&';
string[index][newlength++] = 'a';
string[index][newlength++] = 'm';
string[index][newlength++] = 'p';
string[index][newlength++] = ';';
}
}
else if (ch == '\'') {
if (newlength < sizeof(string[0]) - 5) {
string[index][newlength++] = '&';
string[index][newlength++] = '#';
string[index][newlength++] = '3';
string[index][newlength++] = '9';
string[index][newlength++] = ';';
}
}
else {
string[index][newlength++] = ch;
}
}

return string[index++];
}

char *LogVarValueAsString(mvd_info_t *mvd, const char *varname, int player_num, encoding_mode_t encoding)
{
logvar_t *logvar = LogVarHashTable_GetValue(logvar_hashtable, varname);

Expand All @@ -1407,7 +1587,19 @@ char *LogVarValueAsString(mvd_info_t *mvd, const char *varname, int player_num)
return "";
}

return logvar->func(mvd, logvar->name, player_num);
if (encoding == xml_encoding) {
const char* source = logvar->func(mvd, logvar->name, player_num);

return xml_string(source);
}
else if (encoding == json_encoding) {
const char* source = logvar->func(mvd, logvar->name, player_num);

return json_string(source);
}
else {
return logvar->func(mvd, logvar->name, player_num);
}
}

void LogVarHashTable_Init(void)
Expand Down
Loading

0 comments on commit 5005ded

Please sign in to comment.