Moderators: Nexuiz Moderators, Moderators
diff -ru orig/Nexuiz/sources/qcsrc/server/g_world.qc Nexuiz/sources/qcsrc/server/g_world.qc
--- orig/Nexuiz/sources/qcsrc/server/g_world.qc 2006-06-13 14:59:26.000000000 +0200
+++ Nexuiz/sources/qcsrc/server/g_world.qc 2006-08-22 01:45:58.000000000 +0200
@@ -1,3 +1,5 @@
+float def_scorehist_len = 3;
+
string GetMapname();
void GotoNextMap();
@@ -681,6 +683,10 @@
{
local float file;
local string s;
+ local string player_map_id;
+ local string tmp;
+ local string tmp2;
+ local float i;
if(cvar("_printstats"))
cvar_set("_printstats", "0");
@@ -714,13 +720,52 @@
s = strcat(s, ftos(rint(time - other.jointime)), ":");
s = strcat(s, ftos(other.team), ":");
- if(cvar("sv_logscores_file"))
- fputs(file, strcat(s, other.netname, "\n"));
if(cvar("sv_eventlog") && gameover)
GameLogEcho(strcat(s, ftos(other.playerid), ":", other.netname), TRUE);
else if(cvar("sv_logscores_console"))
ServerConsoleEcho(strcat(s, other.netname), TRUE);
+
+ if (clienttype(other) == CLIENTTYPE_REAL)
+ s = strcat(s, "human:");
+ else
+ s = strcat(s, "bot:");
+ if(cvar("sv_logscores_file"))
+ fputs(file, strcat(s, other.netname, "\n"));
+
+ // update player score history used for advanced team balancing
+ if (clienttype(other) == CLIENTTYPE_REAL) {
+ local string fn;
+ local float fh;
+ local string newline;
+ local string oldlines;
+ fn = strcat("data/scores.db/", other.netname, ".dat");
+ ServerConsoleEcho(strcat(" fn = ",fn),TRUE);
+ fh = fopen ( fn, FILE_READ );
+ ServerConsoleEcho(strcat(" fh = ",ftos(fh)),TRUE);
+ newline = strcat(ftos(other.frags), "\n");
+ // get old player scores history data
+ if(fh!=-1) {
+ local float j;
+ local string line;
+ // read up to def_scorehist_len-1 lines from previous player scores history
+ j=0;
+ line = fgets(fh);
+ while(line && j<def_scorehist_len-1) {
+ ServerConsoleEcho(strcat(" line = ",line),TRUE);
+ oldlines = strcat ( oldlines, line, "\n" );
+ j++;
+ line = fgets(fh);
+ }
+ fclose(fh);
+ }
+ // write updated player scores history
+ fh = fopen ( fn, FILE_WRITE );
+ ServerConsoleEcho(strcat(" fh = ",ftos(fh)),TRUE);
+ fputs ( fh, strcat(newline,oldlines) );
+ fclose ( fh );
+ }
}
+
other = other.chain;
}
diff -ru orig/Nexuiz/sources/qcsrc/server/teamplay.qc Nexuiz/sources/qcsrc/server/teamplay.qc
--- orig/Nexuiz/sources/qcsrc/server/teamplay.qc 2006-06-12 19:49:22.000000000 +0200
+++ Nexuiz/sources/qcsrc/server/teamplay.qc 2006-08-22 01:45:58.000000000 +0200
@@ -583,6 +583,84 @@
}
}
+void GetTeamHistPts(entity ignore)
+{
+ entity head;
+ // now count how many players are on each team already
+
+ // FIXME: also find and memorize the lowest-scoring bot on each team (in case players must be shuffled around)
+ // also remember the lowest-scoring player
+
+ head = find(world, classname, "player");
+ while(head)
+ {
+ if(head != ignore)// && head.netname != "")
+ {
+ // compute avg player score for this map
+ local float avg;
+ local string fn;
+ local float fh;
+ fn = strcat("scores.db/", head.netname, ".dat");
+ fh = fopen ( fn, FILE_READ );
+ //ServerConsoleEcho(strcat(" fh = ",ftos(fh)),TRUE);
+ if(fh!=-1) {
+ local string line;
+ local float n;
+ n = 0;
+ avg = 0;
+ line = fgets(fh);
+ while(line) {
+ avg = avg + stof(line);
+ n++;
+ line = fgets(fh);
+ }
+ if(n>0) {
+ avg = avg / n;
+ } else {
+ avg = 1;
+ }
+ fclose(fh);
+ } else {
+ avg = 1;
+ }
+
+ if(head.team == COLOR_TEAM1)
+ {
+ if(c1 >= 0)
+ {
+ c1 = c1 + avg;
+ cb1 = cb1 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM2)
+ {
+ if(c2 >= 0)
+ {
+ c2 = c2 + avg;
+ cb2 = cb2 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM3)
+ {
+ if(c3 >= 0)
+ {
+ c3 = c3 + avg;
+ cb3 = cb3 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM4)
+ {
+ if(c4 >= 0)
+ {
+ c4 = c4 + avg;
+ cb4 = cb4 + avg;
+ }
+ }
+ }
+ head = find(head, classname, "player");
+ }
+}
+
// returns # of smallest team (1, 2, 3, 4)
// NOTE: Assumes CheckAllowedTeams has already been called!
float FindSmallestTeam(entity pl, float ignore_pl)
@@ -614,12 +692,6 @@
}
- // count how many players are in each team
- if(ignore_pl)
- GetTeamCounts(pl);
- else
- GetTeamCounts(world);
-
// c1...c4 now have counts of each team
// figure out which is smallest, giving priority to the team the player is already on as a tie-breaker
@@ -628,9 +700,25 @@
// 2 gives priority to what team you're already on, 1 goes in order
// 2 doesn't seem to work though...
- balance_type = 1;
+ // 3 is experimental for now and based on each player's performance during
+ // the last N games in the same map.
+ balance_type = 3;
+
+ // count how many players are in each team
+ if(balance_type < 3)
+ {
+ if(ignore_pl)
+ GetTeamCounts(pl);
+ else
+ GetTeamCounts(world);
+ } else {
+ if(ignore_pl)
+ GetTeamHistPts(pl);
+ else
+ GetTeamHistPts(world);
+ }
- if(balance_type == 1)
+ if(balance_type == 1 || balance_type == 3)
{
if(c1 >= 0 && c1 < smallestteam_count)
{
Cinquero wrote:
- Code: Select all
+ fn = strcat("data/scores.db/", other.netname, ".dat");
+ ServerConsoleEcho(strcat(" fn = ",fn),TRUE);
+ fh = fopen ( fn, FILE_READ );
+ ServerConsoleEcho(strcat(" fh = ",ftos(fh)),TRUE);
Nur in Nexuiz/sources: progs.dat.
Nur in Nexuiz/sources: progs.lno.
diff -ru orig/Nexuiz/sources/qcsrc/server/g_world.qc Nexuiz/sources/qcsrc/server/g_world.qc
--- orig/Nexuiz/sources/qcsrc/server/g_world.qc 2006-06-13 14:59:26.000000000 +0200
+++ Nexuiz/sources/qcsrc/server/g_world.qc 2006-08-22 04:30:52.000000000 +0200
@@ -1,3 +1,5 @@
+float def_scorehist_len = 3;
+
string GetMapname();
void GotoNextMap();
@@ -714,13 +716,19 @@
s = strcat(s, ftos(rint(time - other.jointime)), ":");
s = strcat(s, ftos(other.team), ":");
- if(cvar("sv_logscores_file"))
- fputs(file, strcat(s, other.netname, "\n"));
if(cvar("sv_eventlog") && gameover)
GameLogEcho(strcat(s, ftos(other.playerid), ":", other.netname), TRUE);
else if(cvar("sv_logscores_console"))
ServerConsoleEcho(strcat(s, other.netname), TRUE);
+
+ if (clienttype(other) == CLIENTTYPE_REAL)
+ s = strcat(s, "human:");
+ else
+ s = strcat(s, "bot:");
+ if(cvar("sv_logscores_file"))
+ fputs(file, strcat(s, other.netname, "\n"));
}
+
other = other.chain;
}
@@ -733,6 +741,52 @@
fputs(file, ":end\n");
fclose(file);
}
+
+ other = findchainflags(flags, FL_CLIENT);
+ while (other)
+ {
+ // TODO: replace player netnames by player IDs against which the client
+ // authenticates (for example by using a random token given by the server).
+ // This auth stuff should probably be done on a per-server basis.
+ // (We surely don't want unnecessary central servers on which everyone
+ // is dependent)
+
+ // update player score history used for advanced team balancing
+ if (clienttype(other) == CLIENTTYPE_REAL) {
+ local string fn;
+ local float fh;
+ local string newline;
+ local string oldlines;
+ local float j;
+ local string line;
+ fn = strcat("history/", GetMapname(), "/", other.netname, ".dat");
+ //fn = "all.dat";
+ ServerConsoleEcho(strcat(" fn = ",fn),TRUE);
+ fh = fopen ( fn, FILE_READ );
+ ServerConsoleEcho(strcat(" fh(read) = ",ftos(fh)),TRUE);
+ newline = strcat(ftos(other.frags), "\n");
+ // get old player scores history data
+ if(fh!=-1) {
+ // read up to def_scorehist_len-1 lines from previous player scores history
+ j=0;
+ line = fgets(fh);
+ while(line && j<def_scorehist_len-1) {
+ ServerConsoleEcho(strcat(" line = ",line),TRUE);
+ oldlines = strcat ( oldlines, line, "\n" );
+ j++;
+ line = fgets(fh);
+ }
+ fclose(fh);
+ }
+ // write updated player scores history
+ fh = fopen ( fn, FILE_WRITE );
+ ServerConsoleEcho(strcat(" fh(write) = ",ftos(fh)),TRUE);
+ fputs ( fh, strcat(newline,oldlines) );
+ fclose ( fh );
+ }
+
+ other = other.chain;
+ }
}
diff -ru orig/Nexuiz/sources/qcsrc/server/teamplay.qc Nexuiz/sources/qcsrc/server/teamplay.qc
--- orig/Nexuiz/sources/qcsrc/server/teamplay.qc 2006-06-12 19:49:22.000000000 +0200
+++ Nexuiz/sources/qcsrc/server/teamplay.qc 2006-08-22 04:30:52.000000000 +0200
@@ -1,3 +1,5 @@
+string GetMapname();
+
float COLOR_TEAM1 = 5; // red
float COLOR_TEAM2 = 14; // blue
float COLOR_TEAM3 = 10; // pink
@@ -583,6 +585,84 @@
}
}
+void GetTeamHistPts(entity ignore)
+{
+ entity head;
+ // now count how many players are on each team already
+
+ // FIXME: also find and memorize the lowest-scoring bot on each team (in case players must be shuffled around)
+ // also remember the lowest-scoring player
+
+ head = find(world, classname, "player");
+ while(head)
+ {
+ if(head != ignore)// && head.netname != "")
+ {
+ // compute avg player score for this map
+ local float avg;
+ local string fn;
+ local float fh;
+ fn = strcat("history/", GetMapname(), "/", head.netname, ".dat");
+ fh = fopen ( fn, FILE_READ );
+ //ServerConsoleEcho(strcat(" fh = ",ftos(fh)),TRUE);
+ if(fh!=-1) {
+ local string line;
+ local float n;
+ n = 0;
+ avg = 0;
+ line = fgets(fh);
+ while(line) {
+ avg = avg + stof(line);
+ n++;
+ line = fgets(fh);
+ }
+ if(n>0) {
+ avg = avg / n;
+ } else {
+ avg = 1;
+ }
+ fclose(fh);
+ } else {
+ avg = 1;
+ }
+
+ if(head.team == COLOR_TEAM1)
+ {
+ if(c1 >= 0)
+ {
+ c1 = c1 + avg;
+ cb1 = cb1 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM2)
+ {
+ if(c2 >= 0)
+ {
+ c2 = c2 + avg;
+ cb2 = cb2 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM3)
+ {
+ if(c3 >= 0)
+ {
+ c3 = c3 + avg;
+ cb3 = cb3 + avg;
+ }
+ }
+ if(head.team == COLOR_TEAM4)
+ {
+ if(c4 >= 0)
+ {
+ c4 = c4 + avg;
+ cb4 = cb4 + avg;
+ }
+ }
+ }
+ head = find(head, classname, "player");
+ }
+}
+
// returns # of smallest team (1, 2, 3, 4)
// NOTE: Assumes CheckAllowedTeams has already been called!
float FindSmallestTeam(entity pl, float ignore_pl)
@@ -614,12 +694,6 @@
}
- // count how many players are in each team
- if(ignore_pl)
- GetTeamCounts(pl);
- else
- GetTeamCounts(world);
-
// c1...c4 now have counts of each team
// figure out which is smallest, giving priority to the team the player is already on as a tie-breaker
@@ -628,9 +702,25 @@
// 2 gives priority to what team you're already on, 1 goes in order
// 2 doesn't seem to work though...
- balance_type = 1;
+ // 3 is experimental for now and based on each player's performance during
+ // the last N games in the same map.
+ balance_type = 3;
+
+ // count how many players are in each team
+ if(balance_type < 3)
+ {
+ if(ignore_pl)
+ GetTeamCounts(pl);
+ else
+ GetTeamCounts(world);
+ } else {
+ if(ignore_pl)
+ GetTeamHistPts(pl);
+ else
+ GetTeamHistPts(world);
+ }
- if(balance_type == 1)
+ if(balance_type == 1 || balance_type == 3)
{
if(c1 >= 0 && c1 < smallestteam_count)
{
^7:ctf:capture:14:1
^7Cinquero wins.
^7:scores:ctf_facing_worlds_nex_b1k:84
^7:player:21:0:32:5:1:Cinquero
^7:end
^7 fn = history/ctf_facing_worlds_nex_b1k/Cinquero.dat
^7 fh(read) = -1
^7 fh(write) = 0
^7:gameover
mark@voyager ctf_facing_worlds_nex_b1k $ pwd
/home/mark/.nexuiz/data/data/history/ctf_facing_worlds_nex_b1k
mark@voyager ctf_facing_worlds_nex_b1k $ ls -l
insgesamt 4
-rw-r--r-- 1 mark users 3 22. Aug 04:14 Cinquero.dat
mark@voyager ctf_facing_worlds_nex_b1k $ cat Cinquero.dat
21
float fh;
fh = fopen("foo/bar.txt", FILE_WRITE);
fputs(fh, "narf");
fclose(fh);
fh = fopen("foo/bar.txt", FILE_READ);
dprint(fgets(fh), "\n");
fclose(fh);
esteel wrote:I"m still not sure that such a database is the right way to balance the teams. I'd rather try to create some rating by points/time or points/death or maybe something combined.
Return to Nexuiz - Development
Users browsing this forum: No registered users and 1 guest