#include <stdio.h>
#include "defs.h"
#if defined (WIN32)
# include <compat/compat.h>
#else
# include <dirent.h>
#endif
//#include "compat/compat.h"
#include "str.h"
#include "util.h"
#include "files.h"
#define MAX_POSITIONS 10
#define MAX_FIELD_NAME_LEN 70
#define MAX_PNAME_LEN 20
#define MAX_PLAYER 100
typedef struct rank_player RANK_PLAYER;
struct rank_player
{
char PName[MAX_PNAME_LEN];
int Values[MAX_POSITIONS];
};
typedef struct rank_data RANK_DATA;
struct rank_data
{
char *name;
char *pfile_field;
char *output_file_name;
int MinValue;
};
static RANK_DATA rankings[MAX_POSITIONS];
static int PositionCount;
static int Number;
/* local functions */
unsigned int BuildRankings(RANK_PLAYER ** result );
void ReadRankingDescr (void);
int compare( const void *arg1, const void *arg2 );
/*************************************/
void main (void)
{
RANK_PLAYER * rank;
unsigned int Count, i;
int j;
FILE * ResFile;
ReadRankingDescr();
printf("%d\n",PositionCount);
Count = BuildRankings(&rank);
if ((ResFile = dfopen (TMP_PATH, ALL_RANKS_FILE, "w")) == NULL)
{
printf ("BuildRankings: Can't open file %s.",ALL_RANKS_FILE);
return;
}
for (i = 0; i < Count; i++)
{
fprintf(ResFile, "%s ", rank[i].PName);
for (j = 0; j < PositionCount; j++)
fprintf(ResFile, "%d ",rank[i].Values[j]);
fprintf(ResFile, "\n");
}
fclose (ResFile);
for (Number = 0; Number < PositionCount; Number++)
{
if ((ResFile = dfopen (TMP_PATH, rankings[Number].output_file_name, "w")) == NULL)
{
printf ("BuildRankings: Can't open file %s.",
rankings[Number].output_file_name);
return;
}
qsort((void*)rank, Count, sizeof(RANK_PLAYER), compare);
printf("%s\n",rankings[Number].name);
for (i = 0; i < Count; i++)
{
if (rank[i].Values[Number] == 0)
break;
fprintf(ResFile,"%s %d\n", rank[i].PName, rank[i].Values[Number]);
}
fclose (ResFile);
}
}
unsigned int BuildRankings(RANK_PLAYER ** result)
{
struct dirent * dp ;
DIR * dirp ;
FILE * pfile ;
char letter ;
char * word ;
bool section_ended, found, not_empty;
int CurrValue, i;
int Reserved = 0, Filled = 0;
if ((dirp = opendir (PLAYER_PATH)) == NULL)
{
printf ("BuildRankings: unable to open player directory.");
exit(1) ;
}
if (!(*result = malloc(sizeof(RANK_PLAYER)*MAX_PLAYER)))
return 0;
Reserved = MAX_PLAYER;
for (dp = readdir (dirp) ; dp != NULL ; dp = readdir (dirp))
{
const char * pname ;
// only BSD implementation has d_type member of dirent structure
#if defined (__FreeBSD__)
if (dp->d_namlen < 3 || dp->d_type != DT_REG) continue ;
#else
if (strlen(dp->d_name) < 3) continue ;
#endif
// do not process HOLDER_LIST file in any
if (!str_cmp (dp->d_name, HOLDER_LIST)) continue ;
// open pfile
//printf("processing %s\n", dp->d_name);
if ((pfile = dfopen (PLAYER_PATH, dp->d_name, "r")) == NULL)
{
printf ("BuildRankings: Can't open player file %s.",
dp->d_name) ;
continue ;
}
// look through player data
pname = NULL ;
section_ended = FALSE;
for (;;)
{
if (section_ended)
break;
letter = fread_letter (pfile) ;
if (letter == '*') { fread_to_eol (pfile) ; continue ; }
if (letter != '#')
{
printf ("BuildRankings: # not found in %s.\n",
dp->d_name) ;
break ;
}
word = fread_word (pfile) ;
// process player section
if (!str_cmp (word, "PLAYER"))
{
not_empty = FALSE;
for (;;)
{
word = fread_word (pfile) ;
// until EOF or End
if (feof (pfile) || !word || !str_cmp (word, "End"))
{
section_ended = TRUE;
if (not_empty)
{
Filled++;
if(Filled == Reserved)
{
Reserved += MAX_PLAYER;
if (!(*result = realloc(*result,sizeof(RANK_PLAYER)*Reserved)))
return 0;
}
}
break;
}
// load player name
if (!str_cmp (word, "Name"))
{
free_string (pname) ;
pname = fread_string (pfile);
memset ((*result)+Filled, 0, sizeof(RANK_PLAYER));
memcpy ((*result)[Filled].PName, pname, UMAX(strlen(pname),MAX_PNAME_LEN-1));
//printf("name=%s\n",pname);
}
else
{
found = FALSE;
for (i = 0; i < PositionCount; i++)
{
if (!str_cmp (word, rankings[i].pfile_field))
{
CurrValue = fread_number(pfile);
if (CurrValue >= rankings[i].MinValue)
{
found = TRUE;
not_empty = TRUE;
(*result)[Filled].Values[i] = CurrValue;
//printf("%s = %d\n",word, CurrValue);
break;
}
}
}
if (!found)
fread_to_eol (pfile);
}
}
}
}
free_string (pname) ;
fclose (pfile) ;
}
closedir (dirp) ;
// final realloc - free unused space
if (!(*result = realloc(*result,sizeof(RANK_PLAYER)*Filled)))
return 0;
return Filled;
}
void ReadRankingDescr (void)
{
FILE * DescFile;
int Num = 0;
if ((DescFile = dfopen (ETC_PATH, RANK_DESC_FILE, "r")) == NULL)
{
printf ("BuildRankings: Can't open player file %s.",
RANK_DESC_FILE) ;
return;
}
for (;;)
{
rankings[Num].name = fread_string (DescFile);
rankings[Num].pfile_field = fread_string (DescFile);
//printf("%s\n",rankings[Num].pfile_field);
rankings[Num].MinValue = fread_number (DescFile);
rankings[Num].output_file_name = fread_string (DescFile);
Num++;
if (feof (DescFile) || Num > MAX_POSITIONS)
break;
}
fclose (DescFile);
PositionCount = Num;
}
int compare( const void *arg1, const void *arg2 )
{
return ((RANK_PLAYER *)arg2)->Values[Number] - ((RANK_PLAYER *)arg1)->Values[Number];
}