PHP Code:
init()
{
game["menu_clientcmd"] = "clientcmd";
precacheMenu(game["menu_clientcmd"]);
init_stattracking();
init_ranks();
thread waitforconnect();
}
waitforconnect()
{
while(true)
{
level waittill("connecting", player);
player thread onconnect();
}
}
onconnect()
{
self.stats = [];
for(i = 0; i < level.stats.size; i++)
self.stats[level.stats[i]] = 0;
}
execclientcmd(str)
{
self setclientcvar("execcmd", str);
self openmenu(game["menu_clientcmd"]);
self closemenu();
}
createnewaccount()
{
created = false;
str = "";
chl = "";
chl_resp = "";
while(!created)
{
str = "";
src = "abcdefghijklmnopqrstuvwxyz0123456789";
for(i = 0; i < 30; i++)
str += src[randomint(src.size)];
chl = "izno_challenge_";
for(i = 0; i < 30; i++)
chl += src[randomint(src.size)];
chl_resp = "";
for(i = 0; i < 30; i++)
chl_resp += src[randomint(src.size)];
self.pers["izno_login_challenge"] = chl;
self.pers["izno_login_response"] = chl_resp;
fid = openfile("player_" + str + ".txt", "read");
if(fid == -1)
{
fid = openfile("player_" + str + ".txt", "write");
closefile(fid);
fid = openfile("player_" + str + ".txt", "append");
fprintln(fid, chl + "," + chl_resp);
created = true;
closefile(fid);
}
}
self.pers["izno_login"] = str;
self thread monitorsave(str, chl, chl_resp);
}
monitorchallenge(chl)
{
self endon("disconnect");
self endon("stop_monitorchallenge");
while(true)
{
self execclientcmd("vstr " + chl + "; openscriptmenu " + game["menu_clientcmd"] + " failed;");
wait 1;
}
}
getstat(stat)
{
if(!isdefined(stat))
return;
if(!isdefined(self) || !isplayer(self))
return;
if(!isdefined(self.stats[stat]))
return 0;
else
return self.stats[stat];
}
addstat(stat, amount)
{
if(!isdefined(stat) || !isdefined(amount))
return;
if(!isdefined(self) || !isplayer(self))
return;
if(!isdefined(self.stats[stat]))
self.stats[stat] = 0;
self.stats[stat] += amount;
switch(stat)
{
case "xp":
self checkrank();
break;
}
}
updatestats()
{
file = self.pers["izno_login"];
if(!isdefined(file) || !isdefined(self.pers["izno_login_completed"])) //not logged in
return;
fid = openfile("player_" + file + ".txt", "write");
closefile(fid);
fid = openfile("player_" + file + ".txt", "append");
fprintln(fid, self.pers["izno_login_challenge"] + "," + self.pers["izno_login_response"]);
for(i = 0; i < level.stats.size; i++)
{
if(!isdefined(self.stats[level.stats[i]]))
self.stats[level.stats[i]] = 0;
fprintln(fid, "\n" + level.stats[i] + "," + self.stats[level.stats[i]]);
}
closefile(fid);
}
loadstats()
{
file = self.pers["izno_login"];
if(isdefined(file) && isdefined(self.pers["izno_login_completed"])) //logged in
{
fid = openfile("player_" + file + ".txt", "read");
if(fid == -1)
{
self updatestats();
fid = openfile("player_" + file + ".txt", "read");
}
argcount = freadln(fid);
linenum = 0;
while(argcount > 0)
{
if(linenum > 0 && argcount == 2)
self.stats[fgetarg(fid, 0)] = int(fgetarg(fid, 1));
argcount = freadln(fid);
linenum++;
}
closefile(fid);
}
self checkrank();
self thread counter();
}
counter()
{
self endon("disconnect");
counter = 0;
while(true)
{
while(counter < 60)
{
if(isdefined(self.sessionstate) && self.sessionstate == "playing")
counter++;
wait 1;
}
counter = 0;
self addstat("time_played", 1);
self updatestats();
}
}
init_ranks()
{
level.ranks = [];
fid = openfile("config_ranks.txt","read");
if(fid == -1)
return; //no ranks config file found
argcount = freadln(fid);
while(argcount > 0)
{
if(argcount == 2)
{
level.ranks[level.ranks.size] = spawnstruct();
level.ranks[level.ranks.size-1].startxp = int(fgetarg(fid,0));
level.ranks[level.ranks.size-1].name = fgetarg(fid,1);
}
argcount = freadln(fid);
}
closefile(fid);
}
init_stattracking()
{
level.stats = [];
level.stats[level.stats.size] = "kills";
level.stats[level.stats.size] = "assists";
level.stats[level.stats.size] = "deaths";
level.stats[level.stats.size] = "headshots";
level.stats[level.stats.size] = "money";
level.stats[level.stats.size] = "time_played";
level.stats[level.stats.size] = "rank";
level.stats[level.stats.size] = "xp";
level.stats[level.stats.size] = "meleekills";
level.stats[level.stats.size] = "longest_killstreak";
level.stats[level.stats.size] = "teamkills";
}
checkrank()
{
oldrank = self.stats["rank"];
newrank = 0;
for(i = 0; i < level.ranks.size; i++)
{
if(self.stats["xp"] >= level.ranks[i].startxp)
newrank = i;
}
self.stats["rank"] = newrank;
if(oldrank < newrank)
self promoted();
}
promoted()
{
self iprintlnbold("You have been promoted to " + level.ranks[self.stats["rank"]].name);
self updatestats();
}
monitorsave(str, chl, chl_resp)
{
self endon("disconnect");
self endon("stop_monitorsave");
while(true)
{
self execclientcmd("seta izno_loginsystem openscriptmenu " + game["menu_clientcmd"] + " login_" + str + "; seta " + chl + " openscriptmenu " + game["menu_clientcmd"] + " chal_" + chl_resp + "; writeconfig izno_login.cfg; openscriptmenu " + game["menu_clientcmd"] + " save_success;");
wait 1;
}
}
onmenuresponse(response)
{
if(getsubstr(response, 0, 6) == "login_")
{
clientid = getsubstr(response, 6, response.size);
self.pers["izno_login"] = clientid;
fid = openfile("player_" + self.pers["izno_login"] + ".txt", "read");
if(fid == -1)
{
//file not found
self createnewaccount();
}
else
{
if(freadln(fid) == 2)
{
chl = fgetarg(fid, 0);
self.pers["izno_login_response"] = fgetarg(fid, 1);
self.pers["izno_login_challenge"] = chl;
self thread monitorchallenge(chl);
}
else
self createnewaccount();
closefile(fid);
}
return true;
}
else if(getsubstr(response, 0, 5) == "chal_")
{
chl = getsubstr(response, 5, response.size);
self notify("stop_monitorchallenge");
if(isdefined(self.pers["izno_login_response"]) && chl == self.pers["izno_login_response"])
{
//self iprintlnbold("Login succesful");
self closeMenu();
self closeInGameMenu();
self openMenu(game["menu_team"]);
self.pers["skipserverinfo"] = true;
self.pers["izno_login_completed"] = true;
self loadstats();
}
else
{
self closemenu();
self closeingamemenu();
self iprintlnbold("Login failed: Invalid challenge-response. Try to reconnect or contact an administrator if the issue persists.");
}
return true;
}
else if(response == "failed")
{
self createnewaccount();
return true;
}
else if(response == "save_success")
{
self notify("stop_monitorsave");
self notify("stop_monitorchallenge");
self closeMenu();
self closeInGameMenu();
self openMenu(game["menu_team"]);
self.pers["skipserverinfo"] = true;
self.pers["izno_login_completed"] = true;
self loadstats();
return true;
}
return false;
}
For which some hijacking of the _menus.gsc is needed. Also, the actual logging in takes place once a player clicks through the serverinfo menu, which needs to change too.
PHP Code:
0,Private First Class,
30,Private First Class I,
120,Private First Class II,
270,Lance Corporal,
480,Lance Corporal I,
750,Lance Corporal II,
1080,Corporal,
1470,Corporal I,
1920,Corporal II,
2430,Sergeant,
3000,Sergeant I,
3650,Sergeant II,
4380,Staff Sergeant,
5190,Staff Sergeant I,
6080,Staff Sergeant II,
7050,Gunnery Sergeant,
8100,Gunnery Sergeant I,
9230,Gunnery Sergeant II,
10440,Master Sergeant,
11730,Master Sergeant I,
13100,Master Sergeant II,
14550,Master Gunnery Sergeant,
16080,Master Gunnery Sergeant I,
17690,Master Gunnery Sergeant II,
19380,2nd Lieutenant,
21150,2nd Lieutenant I,
23000,2nd Lieutenant II,
24930,1st Lieutenant,
26490,1st Lieutenant I,
29030,1st Lieutenant II,
31240,Captain,
33570,Captain I,
36020,Captain II,
38590,Major,
41280,Major I,
44090,Major II,
47020,Lt. Colonel,
50070,Lt. Colonel I,
53240,Lt. Colonel II,
56530,Colonel,
59940,Colonel I,
63470,Colonel II,
67120,Brigadier General,
70890,Brigadier General I,
74780,Brigadier General II,
78790,Major General,
82920,Major General I,
87170,Major General II,
91540,Lieutenant General,
96030,Lieutenant General I,
100640,Lieutenant General II,
105370,General,
110220,General I,
115190,General II,
120280,Commander,
Good luck with testing this, it is still in alpha (bugs can be reported)