/* * FragRank 0.7 by Phil "Crazy" Spencer Released under the GPL GNU Public License */ #include #include #include #define LOGPATH "/home/spencep/.quakeforge/qw/frag_%04d.log" //#define LOGPATH "/home/spencep/quake/philsqw/frag_%d.log" /* If using quakeforge change the filename to frag_%04d.log * Regular quake world server is frag_%d.log */ #define TITLE "FragRank by CrazySpence" #define HEADLINE "Philtopia.com Killers" #define HCOLOR "#840d05" #define NUMCOLOR "#840d05" #define NAMECOLOR "#2911af" #define FRAGCOLOR "#0a5b07" #define FRAGGEDCOLOR "#0a5b07" #define SUICIDECOLOR "#0a5b07" #define SCORECOLOR "#2911af" #define FCOLOR "#840d05" struct player { char *name; double frags; double fragged; double dumbass; //suicide variable double score; // frags divided by fragged Score struct player *next; //pointer to next allocated struct }; char *charreplace(char *string, char match, char *change);//character replacement function int isplayer(char *search); //check if player exists void displayplayers(int max); //format html and display output void *findplayernum(char *name); //search for existing player void *sortplayers(); //sort players for display by score struct player *head,*prev, *current; int numplayers = 0; double totalfrags = 0; double totalfragged = 0; double totalscore = 0; double totaldumbass = 0; int main() { FILE *file; char buf[512]; char backup[512]; char *s; char killer[255]; char killed[255]; char path[255]; int filenum = 0; int i; sprintf(path,LOGPATH,filenum); while ((file = fopen(path,"r")) != NULL) { /* Why is this a file opening while loop? let me tell you! * Quake world will not log all frags to just one file, if you * restart qwsv it logs the frags to a new file but fortunatley * they are all frag_#.log so we just loop through until a file * is not there, not the nicest way to do this but it does the job * quickly actually it might be the nicest...I never looked for * another way but there probably is a more sane way *shrugs* */ while (fgets(buf,512,file) != NULL) { strcpy(backup,charreplace(charreplace(buf,'<',"<"),'>',">")); //replace < and >'s with < and > to prevent tom's from executing code within fragstats s = strtok(backup,"\\"); strcpy(killer,s); if (numplayers != 0) { if ((isplayer(s)) != 1) { //new player found in killer, add to linked list current = (struct player *) malloc(sizeof(struct player)); prev->next = current; current->next = NULL; current->name = strdup(s); prev = current; numplayers++; } } else { //add first player current = (struct player *) malloc(sizeof(struct player)); head = current; current->next = NULL; current->name = strdup(s); numplayers++; prev = current; } s = strtok(NULL,"\\"); strcpy(killed,s); if ((isplayer(s)) != 1) { //new player found in killed field, add to linked list current = (struct player *) malloc(sizeof(struct player)); prev->next = current; current->next = NULL; current->name = strdup(s); numplayers++; prev = current; } if (strcmp(killer,killed) == 0) { current = (struct player *) findplayernum(killer); current->frags--; current->dumbass++; totaldumbass++; totalfrags--; } else { current = (struct player *) findplayernum(killer); current->frags++; //increase killers frags current = (struct player *) findplayernum(killed); current->fragged++; //increase killed fragged totalfrags++; totalfragged++; } } fclose(file); filenum++; sprintf(path,LOGPATH,filenum); //setup path for next file } current = head; while (current != NULL) {//add the scores if (current->fragged == 0) current->score = current->frags; //quick fix to avoid divide by 0 error else current->score = current->frags / current->fragged; current = current->next; } if (totalfragged == 0) totalscore = totalfrags; //also to avoid divide by zero error else totalscore = totalfrags / totalfragged; displayplayers(numplayers); return 0; } int isplayer(char *search) { current = head; while (current != NULL) { if (strcasecmp(search,current->name) == 0) { return 1; } current = current->next; } return 0; } void displayplayers(int max) { /* * This is the fancy HTML part of the code stfu erik! */ int i; struct player *players; players = sortplayers(); printf("Content-type: text/html\n\n"); printf("\n"); printf("\n"); printf("\n\n%s\n\n\n",TITLE); printf("

%s

\n",HEADLINE); printf("\n"); printf("\n",HCOLOR); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); for (i = 0 ; i < max ; i++) { printf("\n"); printf("\n",NUMCOLOR,i+1); printf("\n",NAMECOLOR,players[i].name); printf("\n",FRAGCOLOR,players[i].frags); printf("\n",FRAGGEDCOLOR,players[i].fragged); printf("\n",SUICIDECOLOR,players[i].dumbass); printf("\n",SCORECOLOR,players[i].score); printf("\n"); } printf("\n",FCOLOR); printf("\n"); printf("\n"); printf("\n",totalfrags); printf("\n",totalfragged); printf("\n",totaldumbass); printf("\n",totalscore); printf("\n"); printf("
#NameFragsFraggedSuicideScore
%d%s%.0f%.0f%.0f%.1f
Total:%.0f%.0f%.0f%.1f
\n"); printf("
\n

\n\n\"Valid\n\n

\n
\n"); printf("\n\n"); free(players); //free the sorted players struct from memory } void *sortplayers() { int top; int big; int i; struct player temp, *players; players = (struct player *) malloc(numplayers * sizeof(struct player)); current = head; i = 0; while (current != NULL) { players[i] = *current; current = current->next; i++; } //selection sort to sort players by scores for (top = (numplayers - 1) ; top >= 1 ; top--) { big = 0; for (i = 1 ; i <= top ; i++) { if (players[i].score < players[big].score) big = i; temp = players[top]; players[top] = players[big]; players[big] = temp; } } return players; } void *findplayernum(char *name) { int i = 0; current = head; while (current != NULL) { if (strcasecmp(current->name,name) == 0) return current; current = current->next; } return NULL; //this wont ever happen unless I break the code heh } char *charreplace(char *string, char match, char *change) { /* I made this function so i could replace < and >'s with < and > * however I do not care for the way i implemented it but it does work for * what is needed */ int i,k,l; int count = 0; char *replaced; i = 0; while (string[i] != '\0') { if (string[i] == match) count++; //count occrences of match i++; } if (count == 0) return string; //no match, return original string replaced = (char *) malloc(strlen(string) + (count * strlen(change))); //prepare new string i = 0; l = 0; while (string[i] != '\0') { if (string[i] == match) { k = 0; while (change[k] != '\0') { replaced[l] = change[k]; k++; l++; } } else { replaced[l] = string[i]; l++; } i++; } return replaced; //send back modified string }