/*******************************************************************************
  ymboc Rate Manager v1.01
 
  Credits: RBBOT for the original & the backbone of this plugin
           (really, he deserves most of the credit)
 
  Installation: 1) Compile plugin_ymboc_rateman.sma (Optional)
                2) Copy plugin_ymboc_rateman.amx into [mod]\dlls
                3) Add line "dlls/plugin_ymboc_rateman.amx" to plugin.ini
                4) Add line "admin_bandwidth [rate]" to server.cfg
                5) Start server and/or change map to load plugin
 
  Usage: admin_bandwidth 0       -> To Disable Rate Management, Restore Settings
         admin_bandwidth [rate]  -> To Set Available Bandwidth in kBps (Bytes/s)
         admin_bandwidth [rate]k -> To Set Available Bandwidth in kbps (Bits/s) 
 
  Commments: youmustbeoncrack@hotmail.com
 
*******************************************************************************/
 
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
 
#define DEFAULT_BANDWIDTH 16384
#define MAX_BANDWIDTH	  1048576
#define MIN_BANDWIDTH	  0
 
#define DEFAULT_MAX_RATE 10000
#define DEFAULT_MIN_RATE 3000
 
#define DEFAULT_BANDWIDTHMANAGE 1
#define MIN_BANDWIDTHMANAGE 0
#define MAX_BANDWIDTHMANAGE 1
 
new g_Bandwidth=DEFAULT_BANDWIDTH;
new g_BandwidthManage=DEFAULT_BANDWIDTHMANAGE;
new g_MaxRate=DEFAULT_MAX_RATE;
new g_MinRate=DEFAULT_MIN_RATE;
 
public plugin_init() {
  plugin_registerinfo("ymboc Rate Manager","Reduces Lag","1.01");
  plugin_registercmd("admin_bandwidth","AdminBandWidth",ACCESS_CONFIG,"admin_bandwidth [0 = Disabled|[ratevalue]|[XXX]K - sets internet connection bandwidth in rate, or Kbps");
  readvaultnum("admin_bandwidth",g_Bandwidth, DEFAULT_BANDWIDTH,MIN_BANDWIDTH,MAX_BANDWIDTH);
 
  g_MaxRate = getvar("sv_maxrate");
  if (g_MaxRate == 0) g_MaxRate = 8000;
  g_MinRate = getvar("sv_minrate");
  if (g_MinRate == 0) g_MinRate = 3000;
 
  return PLUGIN_CONTINUE;
}
 
public plugin_connect(HLUserName, HLIP, UserIndex) {
  SetRate();
  return PLUGIN_CONTINUE;
}
 
public plugin_disconnect(HLUserName, UserIndex) {
  SetRate();
  return PLUGIN_CONTINUE;
}
 
public AdminBandWidth(HLCommand,HLData,HLUserName,UserIndex) {
  new Data[MAX_DATA_LENGTH];
  convert_string(HLData,Data,MAX_DATA_LENGTH);
 
  /* Check for data being supplied in Kbps */  
  new len = strlen(Data);
  if ( len > 0) {
    if ((Data[len-1] == 'K') || (Data[len-1] == 'k')) {
      if (readHLnum(HLData,g_Bandwidth,DEFAULT_BANDWIDTH/128,MIN_BANDWIDTH/128,MAX_BANDWIDTH/128)) {
      	g_Bandwidth = g_Bandwidth * 128;
	writevaultnum("admin_bandwidth",g_Bandwidth);
	SetRate();
      }  
    }
 
    else {  
      if (readHLnum(HLData,g_Bandwidth,DEFAULT_BANDWIDTH,MIN_BANDWIDTH,MAX_BANDWIDTH)) {
	writevaultnum("admin_bandwidth",g_Bandwidth);
        if (g_Bandwidth == 0) Restore();
	SetRate();
      }
    }
  }
  ShowInfo();
  return PLUGIN_HANDLED;
}
 
 
public AdminBandwidthMan(HLCommand,HLData,HLUserName,UserIndex) {
  if (readHLnum(HLData,g_BandwidthManage,DEFAULT_BANDWIDTHMANAGE,MIN_BANDWIDTHMANAGE,MAX_BANDWIDTHMANAGE)) {
    writevaultnum("admin_bandwidthman",g_BandwidthManage);
  }
  ShowInfo();
  return PLUGIN_HANDLED;
}
 
SetRate() {
  if (g_Bandwidth == 0 || playercount() < 1) { return 0;}
 
  new RateCmd[MAX_TEXT_LENGTH];
  new Rate = g_Bandwidth / playercount();
 
  if (Rate>g_MaxRate) { Rate = g_MaxRate; }
  if (Rate<g_MinRate) { Rate = g_MinRate; } 
 
  snprintf(RateCmd,MAX_TEXT_LENGTH,"sv_maxrate %i",Rate + 1);
  exec(RateCmd);
  snprintf(RateCmd,MAX_TEXT_LENGTH,"sv_minrate %i",Rate - 1);
  exec(RateCmd);
 
  return 0;
}
 
Restore() {
  new RateCmd[MAX_TEXT_LENGTH];
  snprintf(RateCmd,MAX_TEXT_LENGTH,"sv_maxrate %i",g_MaxRate);
  exec(RateCmd);
  snprintf(RateCmd,MAX_TEXT_LENGTH,"sv_minrate %i",g_MinRate);
  exec(RateCmd);
}
 
 
ShowInfo() {
  new data[MAX_TEXT_LENGTH];
 
  selfmessage("ymboc Rate Manager 1.01");
 
  if (g_Bandwidth == 0) {
    selfmessage("Bandwidth   : Disabled");
  }
  else {
    snprintf(data,MAX_TEXT_LENGTH,"Bandwidth   : %i / %iK",g_Bandwidth,g_Bandwidth/128);
    selfmessage(data);
  }
 
  ShowLine("Max Rate    : %i",getvar("sv_maxrate"));
  ShowLine("Min Rate    : %i",getvar("sv_minrate"));
  ShowLine("#Players    : %i",playercount());
 
  return 0;
}
 
ShowLine(msg[],value) {
  new data[MAX_TEXT_LENGTH];
  snprintf(data,MAX_TEXT_LENGTH,msg,value);
  selfmessage(data);
  return 0;
}
 
/* Support functions */
 
readvaultnum(name[],&output,defaultval,minimum,maximum) {
  /* Read saved setting from vault */
  new Buffer[10]="";
  get_vaultdata(name,Buffer,10);
  if (strlen(Buffer)>0) {
    output = strtonum(Buffer);
    if ((output <minimum) || (output > maximum)) {
      output = defaultval;
    }
    return 1;
  }
  return 0;
 
}
 
writevaultnum(name[],value) {
  /* write number to vault */
  new Buffer[10];
  numtostr(value,Buffer);
  set_vaultdata(name,Buffer);
  return 0;
}
 
readHLnum(HLData,&output,defaultval,minimum,maximum) {
  /* Read setting from halflife string */
  new Data[MAX_DATA_LENGTH];
  convert_string(HLData,Data,MAX_DATA_LENGTH);
  if (strlen(Data) > 0) {
    output = strtonum(Data);
    if ((output <minimum) || (output > maximum)) {
      output = defaultval;
    }
    return 1;
  }
  return 0;
}