/*
[SKEL-TUD v1.3] Top Uploaders/Downloaders

/**********************/
/*****  Includes  *****/
/**********************/

#include <proto/all.h>
#include <stdio.h>

#include <string.h>
#include <skeleton/commas.h>
#include <Tempest/Headers.h>
#include <Tempest/Skel-Data.h>

VOID DSort(VOID);
VOID USort(VOID);
VOID Print(VOID);

/************************/
/*****  Structures  *****/
/************************/

struct Uploads
 {
  char   Handle[31],Location[31];
  long   BytesUL,BytesDL;
  USHORT TimesCalled;
 };
struct Downloads
 {
  char   Handle[31],Location[31];
  long   BytesUL,BytesDL;
  USHORT TimesCalled;
 };
struct Uploads UP[5];
struct Downloads DOWN[5];
struct User User;
struct SKEL SKEL;

/*******************************/
/*****  Global Variables  ******/
/*******************************/

char  string[200],OUTPATH[200],shit1[200];
int   RANK = 5;
float Percent;

/**************************/
/*****  Main Program  *****/
/**************************/

void main(int argc,char *argv[])
{
 int stat,fd;
 sprintf(shit1,"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"");
 if(argc != 3 )
  {
   PutStr("\n[m[1m    _______ _________\n");
   PutStr("   / ___/ [4m/[m[1m/ / ___/ /    [[32mSKEL-TUD v3.29[m[1m] - [3mTop Uploaders/Downloaders[m\n");
   PutStr("[1m  [4m/[m[1m__  /   _/ ___/ [4m/[m[1m__\n");
   PutStr("[1m [4m/[m[1m____[4m/[m[1m_/\\_[4m)[m[1m____[4m/[m[1m____/   For Tempest BBS - [Programmer: Michael Bockert]\n");
   PutStr(shit1);
   PutStr("\n[m   USAGE: SKEL-TUD OutFile BBS:\n");
   PutStr(" EXAMPLE: SKEL-TUD RAM:TEST BBS:\n\n");
   PutStr("[OutFile] Path & Name of the created file\n");
   PutStr("   [BBS:] Path of Accounts.Data file\n\n");
   exit(0);
  }
 strcpy(OUTPATH,argv[1]);

/*********************************/
/*****  Load Skel-Data.Data  *****/
/*********************************/

 sprintf(string,"%sSetup/Skel-Data.Data",argv[2]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("Skel-Data.Data not found!\n");
   setmem(&SKEL,sizeof(struct SKEL),NULL);
  }
 else
  {
   Read(fd,(char *)&SKEL, sizeof(struct SKEL));
   Close(fd);
  }

/********************************/
/*****  Load Accounts.Data  *****/
/********************************/

 sprintf(string,"%sAccounts.data",argv[2]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nAccounts.data not found.\n");
   exit(0);
  }
 NEXTFILE:
 stat=Read(fd,(char *)&User, sizeof(struct User));
 if(stat <=0 )
  {
   Close(fd);
   Print();
   PutStr("\nSKEL-TUD Done!\n");
   exit(0);
  }
 USort();
 DSort();
 goto NEXTFILE;
}

/*************************/
/*****  Upload Sort  *****/
/*************************/

VOID USort(VOID)
{
 register int x =0,y,HOLDER;
 do
  {
   if((User.Slot_Number==1)||(User.Status!=1)||(User.Total_ULBytes < 1000000L))
       break;
   if(User.Total_ULBytes > UP[x].BytesUL)  /* move other entries down one */
    {
     HOLDER = x;
     y=0;
     while(x+1<RANK)
      {
       y++;
       CopyMem(&UP[RANK-(y+1)],&UP[RANK-y],sizeof(struct Uploads));
       x++;
      }
     x=HOLDER;
     strcpy(UP[x].Handle,User.Name);
     strcpy(UP[x].Location,User.City);
     UP[x].BytesUL     = User.Total_ULBytes;
     UP[x].BytesDL     = User.Total_DLBytes;
     UP[x].TimesCalled = User.Total_Calls;
     return;
    }
   x++;
  }
 while(x < RANK);
}

/***************************/
/*****  Download Sort  *****/
/***************************/

VOID DSort(VOID)
{
 register int x =0,y,HOLDER;
 RANK = 5;
 do
  {
   if((User.Slot_Number==1)||(User.Status!=1)||(User.Total_DLBytes < 1000000L))
       break;
   if(User.Total_DLBytes >= DOWN[x].BytesDL)  /* move other entries down one */
    {
     HOLDER = x;
     y=0;
     while(x+1<RANK)
      {
       y++;
       CopyMem(&DOWN[RANK-(y+1)],&DOWN[RANK-y],sizeof(struct Downloads));
       x++;
      }
     x=HOLDER;
     strcpy(DOWN[x].Handle,User.Name);
     strcpy(DOWN[x].Location,User.City);
     DOWN[x].BytesUL     = User.Total_ULBytes;
     DOWN[x].BytesDL     = User.Total_DLBytes;
     DOWN[x].TimesCalled = User.Total_Calls;
     return;
    }
   x++;
  }
 while(x < RANK);
}

/********************/
/*****  Output  *****/
/********************/

VOID Print(VOID)
{
 register int x=0;
 char  Ratio2[40],shit2[255];
 float Ratio;
 FILE  *out2;
 out2=fopen(OUTPATH,"w");
 if(out2==NULL)
  {
   PutStr("Error writing output file!\n");
   exit(0);
  }
 strcpy(shit2,"==-==================-==============-=======-=====-=====-======================\n");
 fprintf(out2,"\f~+                         [36mTop Uploaders/Downloaders\n");
 fprintf(out2,"[34m%s\"\"\"\"\"\"\"\n",shit1);
 fprintf(out2,"[0m#  Top Uploaders            UL Bytes Percent Ratio Calls Location/Group\n");
 fprintf(out2,"[34m%s",shit2);
 strcpy(shit1,"-----------------------------");
 do
  {
   Ratio = (float) UP[x].BytesDL / UP[x].BytesUL;
   if((Ratio>3.00) && (UP[x].BytesDL > 1000000L))
       strcpy(Ratio2,"[34mLAMER");
   else
    {
     if((Ratio < 0.16) && (Ratio >= 0.00) && (UP[x].BytesUL >= 5000000L))
         strcpy(Ratio2,"[33mELITE");
     else
         sprintf(Ratio2,"%4.2f",Ratio);
    }
   Percent = (float) ((UP[x].BytesUL+1L) / 1024L) / ((SKEL.TotalULKB+1L) / 100L);
   if(strlen(UP[x].Handle) > 2)
    {
     fprintf(out2,"[0m%d. [36m%-18.18s [34m([35m%13s [31m%5.2f[32m%[34m) [36m%5s [0m%4d  [31m%-22.22s\n",
         x+1,UP[x].Handle,commas(UP[x].BytesUL,buff),Percent,Ratio2,UP[x].TimesCalled,UP[x].Location);
    }
   x++;
  }
 while(x<RANK);
 x = 0;
 fprintf(out2,"\n[0m#  Top Downloaders          DL Bytes Percent Ratio Calls Location/Group\n");
 fprintf(out2,"[34m%s",shit2);
 do
  {
   Ratio = (float) DOWN[x].BytesDL / DOWN[x].BytesUL;
   if((Ratio>3.00) && (DOWN[x].BytesDL > 1000000L))
       strcpy(Ratio2,"[34mLAMER");
   else
    {
     if((Ratio < 0.16) && (Ratio >= 0.00) && (DOWN[x].BytesUL >= 5000000L))
         strcpy(Ratio2,"[33mELITE");
     else
         sprintf(Ratio2,"%4.2f",Ratio);
    }
   Percent = (float) ((DOWN[x].BytesDL+1L) / 1024L) / ((SKEL.TotalDLKB+1L) / 100L);
   if(strlen(DOWN[x].Handle) > 2)
    {
     fprintf(out2,"[0m%d. [36m%-18.18s [34m([35m%13s [31m%5.2f[32m%[34m) [36m%5s [0m%4d  [31m%-22.22s\n",
         x+1,DOWN[x].Handle,commas(DOWN[x].BytesDL,buff),Percent,Ratio2,DOWN[x].TimesCalled,DOWN[x].Location);
    }
   x++;
  }
 while(x<RANK);
 fprintf(out2,"[34m.%s.-.-------------.-.%s.\n",shit1,shit1);
 fprintf(out2,"[34m| [36mULed Files   [35m[[0m%9s[35m]    [34m|[33m=[34m| [36mUsers[35m[[0m%4d[35m] [34m|[33m=[34m| [36mDLed Files   [35m[",
               commas(SKEL.TotalUL,buff),SKEL.TotalUsers);
 fprintf(out2,"[0m%9s[35m]    [34m|\n",
               commas(SKEL.TotalDL,buff));
 fprintf(out2,"[34m| [36mULed Bytes [35m[[0m%11s[35m] [32mKB [34m| `-------------' | [36mDLed Bytes [35m[",
               commas(SKEL.TotalULKB,buff));
 fprintf(out2,"[0m%11s[35m] [32mKB [34m|\n",
               commas(SKEL.TotalDLKB,buff));
 fprintf(out2,"[34m`%s'                 `%s'[0m~r\n",shit1,shit1);
 fclose(out2);
}
