Extra Point Flags!

Expand and mod your server.
Post Reply
User avatar
I_Died_Once
Special Forces
Special Forces
Posts: 635
Joined: Sun Nov 28, 2004 5:27 pm
Location: The Dark Side
Contact:

Extra Point Flags!

Post by I_Died_Once » Sat Jun 09, 2012 9:12 pm

So, I found a rogue programmer, right... I held a gun to the back of his head and made him write a couple custom flag, then I stole the code. I did some tweaking and made a couple of extra flags out of it.

These flags fire normally, like any other normal shot. However, kills made with these flags count towards extra points!

I'm going to release them all under the GPL - feel free to use, hack, and defile these plugins at will. A couple of warnings, however - these could potentially be game breakers, and purists will scoff at the mere idea. If you look at the source, its faily straightforward... and do NOT - EVER go to excess and try to get a score over 32762, the server gets funky with the scoring once you do.

Now, admittedly, all I did was change some obvious values. You could set it to award any number of points. Just keep in mind fairness, responsibility, and dignity when deploying flags that give a hundred points (or any outrageous amount of points) on a public server... and remember, flag or not - a player with a score of 2245 - 5 is going to raise cheat accusations.

No, you will not see all three of these flags in plat at Planet MoFo anytime soon.

Enjoy!
Attachments
hundredPoint.cpp
hundredPoint
(1.16 KiB) Downloaded 182 times
triplePoint.cpp
triplePoint
(1.14 KiB) Downloaded 188 times
doublePoint.cpp
doublePoint
(1.12 KiB) Downloaded 192 times
...This has been a recording.

User avatar
gnu-sense
Private First Class
Private First Class
Posts: 78
Joined: Wed Nov 22, 2006 1:21 am

Re: Extra Point Flags!

Post by gnu-sense » Fri Jun 15, 2012 3:25 pm

32762.

Not 32767? Two's-complement mall integer roll-over value. I got a snort out of that!

gnu-sense

User avatar
Tanx
Private First Class
Private First Class
Posts: 125
Joined: Sat Mar 22, 2008 11:14 pm

Re: Extra Point Flags!

Post by Tanx » Fri Jun 29, 2012 12:38 am

there are a couple of errors, some I know what caused them, others I'm not entirely sure, I can read it, just not necessary write it. If I could write it, I probably would be able to figure out the ones I don't know the cause of. Well back to the errors.

1. sometimes on apoc when you attempt to grab a fifty point flag the flag instead vanishes when you should pick it up. I was able to confirm this when the flag that disappeared spawned 15 WU away, and it was of course, a fifty point flag.

2. You can seriously mess up strayers with it. not by killing others, but by killing youself, I altered my bzclient so it would show what strayers bzstats thinks I had. the pic is in the attachment. I'll use hundred points as my example

Code: Select all

    // Special behaviour for selfkill to do with order of score change
      if (k == d->playerID)
        bz_setPlayerWins(k, bz_getPlayerWins(k) - 99)
in fifty points it's negative 49 kills, there is the problem. If you kill yourself when you have less then 49 kills you'll end up with negative kills. It's obvious from my highscore on strayers that somewhere there's a unsigned short, but in src/bzflag its a signed short. I didn't find it in the bzflag code (a unsigned short), so I changed them to unsigned shorts to get the picture below. Also I tested what overdoing this would do, and when I got into the negative 1500 kills two crashes occured within 5 minutes of each other, I don't know if this is a coincidence or not. It could very easily not be the cause I wasn't running my debug client so I can't tell you that. Especially since apoc's crashes were happening before this flag. I didn't anticipate that it might cause a crash, otherwise I would've ran my linux debug client instead of my windows client.

3. it messes up normalized score

Code: Select all

// returns a value between 1.0 and -1.0
float Player::getNormalizedScore() const
{
  return ((float)wins - losses) / ((wins+losses>20) ? wins+losses : 20);
}
but with negative kills, and since I could easily find fifty point and shoot myself before I was killed enough to be close to the negative 49 kills it would give me, it kept adding .05 to my normalized score. in fact my normalized score was around -170, and there's nothing to stop it either. since my kills+deaths was no where near 20, it was in the negative thousands. I was around -2500 with only 300-400 deaths, 75% of which were self kills.

4. getting negative kills draws the attention of others

I got accused of cheating by a few people, and had a few pollbans raised to ban me.
Anyone who might want to use these plugins should be aware of these.

-Edit-

after testing this plugin out locally there is another thing that anyone who uses this should consider

5. with tks being on you'll get 48 points per tk, one death, but 49 kills for it. So the plugin in its current state is strictly restricted to places where teamkills aren't possible.
Attachments
bzfi0001.png
picture
(52.34 KiB) Not downloaded yet
known as: Tanx, Eoncho, ckw.
Bzflag player since 2001.

User avatar
gnu-sense
Private First Class
Private First Class
Posts: 78
Joined: Wed Nov 22, 2006 1:21 am

Re: Extra Point Flags!

Post by gnu-sense » Sun Jul 01, 2012 11:36 pm

This is really interesting. I haven't looked at the plugin source but I've been over the game source, especially RecordReplay.cxx and anything I needed to decode recorded game files (THAT sent me down the rabbit hole more than once). For MsgScore packets, I have the following code (please ignore the SQL bits that are there for my output):

Code: Select all

		case MsgScore: {
			uint8_t numScores;
			vbuf = nboUnpackUByte(vbuf, numScores);

			if (sqlTrue) {
				lastMessage += "array[" ;
			}
			
			for (int i = 0; i < numScores; i++) {
				uint16_t winners, loosers, teamkillers;
				vbuf = nboUnpackUByte(vbuf, p);
				vbuf = nboUnpackUShort(vbuf, winners);
				vbuf = nboUnpackUShort(vbuf, loosers);
				vbuf = nboUnpackUShort(vbuf, teamkillers);

				if (sqlTrue) {
					lastMessage += (i > 0 ? ",\n" : "") + 
					TextUtils::format("('%s',%d,%d,%d,%d)", // (ts,p,wins,losses,tks) values 
									  timeString.c_str(),
									  p, winners, loosers, teamkillers) + sqlEnd ;
				} else {
					lastMessage += (i > 0 ? "\n" : "") + msgBegin + 
					TextUtils::format(" p: %d wins: %d losses: %d tks: %d",
									  p, winners, loosers, teamkillers);
				}
			}
			if (sqlTrue) {
				lastMessage += "]" ;
			}
			
			break;
		}
"u" might suggest "unsigned". The type uint_16 is further defined above in the same file as

Code: Select all

typedef uint16_t u16;
u16 has to be defined somewhere else (that I am simply not adept at finding), but the "u" strongly suggests it is unsigned. So the observations you make about the handling of negative scores could be readily explained by the use of an unsigned int in the MsgScore packet to encode winners, losers and teamkillers, even if the rest of the bz code uses signed ints. As far as the plugin goes, it should probably be fixed to test for negative scores and truncate them to zero. It might also want to use a matching unsigned type so that numeric value fall in the same range as the packet design permits.

I checked on an old version of the SQL schema that strayer once shared with me (I did that first actually), and I don't see anything there that would give an unsigned int value. Most SQL versions probably use default integer types equivalent to long signed ints, giving a max value of somewhere over 2 billion.

Code: Select all

CREATE TABLE ladder_player_data ( 
    serverID integer NOT NULL default '0', 
    playerID integer NOT NULL default '0', 
    first_seen timestamp NOT NULL default CURRENT_TIMESTAMP, 
    wins integer NOT NULL default '0', 
    losses integer NOT NULL default '0', 
    teamkills integer default '0', 
    minScore integer default '0', 
    maxScore integer default '0', 
    team smallint default '0', 
    pID smallint default '0', 
    type smallint default NULL, 
    last_seen timestamp NULL,
    count integer default '1',
    PRIMARY KEY (serverID,playerID,first_seen)
);
This was sort of interesting!

gnu-sense

Post Reply