diff --git a/.gitignore b/.gitignore
index 2f836aa..1ffe6b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
*~
+*#
*.pyc
diff --git a/Makefile b/Makefile
index b282985..6b12412 100644
--- a/Makefile
+++ b/Makefile
@@ -6,19 +6,16 @@ BIN = $(BASE)/bin
SBIN = $(BASE)/sbin
BASE_URL = /ctf/
-install:
- id ctf || useradd --system --shell /bin/false --home $(VAR) \
- --comment "Capture The Flag" ctf
- install --directory $(LIB) $(BIN) $(SBIN) $(LIB)/disabled
- install --directory --owner=ctf $(VAR)
- install --directory --owner=ctf $(WWW)
- install --directory --owner=ctf $(WWW)/puzzler
- install --directory --owner=ctf $(VAR)/points
- install --directory --owner=ctf $(VAR)/points/tmp
- install --directory --owner=ctf $(VAR)/points/cur
- install --directory --owner=ctf $(VAR)/flags
+TEMPLATE = $(CURDIR)/template.html
+MDWNTOHTML = $(CURDIR)/mdwntohtml.py --template=$(TEMPLATE) --base=$(BASE_URL)
-# Tanks has a lot of files.
+default: install
+
+SUBDIRS = mdwn
+INSTALL_TARGETS = $(addsuffix -install, $(SUBDIRS))
+include $(addsuffix /*.mk, $(SUBDIRS))
+
+install: base-install $(INSTALL_TARGETS)
install --directory --owner=ctf $(VAR)/tanks
install --directory --owner=ctf $(VAR)/tanks/results
install --directory --owner=ctf $(VAR)/tanks/errors
@@ -47,7 +44,34 @@ install:
./mkpuzzles.py --base=$(BASE_URL) --puzzles=puzzles \
--htmldir=$(WWW)/puzzler --keyfile=$(LIB)/puzzler.keys
+ install --directory $(VAR)/disabled
+ touch $(VAR)/disabled/bletchley
+ touch $(VAR)/disabled/compaq
+ touch $(VAR)/disabled/crypto
+ touch $(VAR)/disabled/forensics
+ touch $(VAR)/disabled/hackme
+ touch $(VAR)/disabled/hispaniola
+ touch $(VAR)/disabled/net-re
+ touch $(VAR)/disabled/skynet
+ touch $(VAR)/disabled/survey
+
+
+base-install:
+ id ctf || useradd --system --shell /bin/false --home $(VAR) \
+ --comment "Capture The Flag" ctf
+ install --directory $(LIB) $(BIN) $(SBIN)
+ install --directory --owner=ctf $(VAR)
+ install --directory --owner=ctf $(WWW)
+ install --directory --owner=ctf $(WWW)/puzzler
+ install --directory --owner=ctf $(VAR)/points
+ install --directory --owner=ctf $(VAR)/points/tmp
+ install --directory --owner=ctf $(VAR)/points/cur
+ install --directory --owner=ctf $(VAR)/flags
+
uninstall:
rm -rf $(VAR) $(WWW) $(LIB) $(BIN) $(SBIN)
rmdir $(BASE) || true
+
+
+clean: $(addsuffix -clean, $(SUBDIRS))
diff --git a/mdwn/mdwn.mk b/mdwn/mdwn.mk
new file mode 100644
index 0000000..12667a5
--- /dev/null
+++ b/mdwn/mdwn.mk
@@ -0,0 +1,16 @@
+MDWN_DIR = mdwn
+
+MDWN_SRC += $(wildcard $(MDWN_DIR)/src/*.mdwn)
+MDWN_SRC += $(wildcard $(MDWN_DIR)/src/*/*.mdwn)
+MDWN_SRC += $(wildcard $(MDWN_DIR)/src/*/*/*.mdwn)
+
+MDWN_OUT = $(subst $(MDWN_DIR)/src/, $(WWW)/, $(MDWN_SRC:.mdwn=.html))
+
+mdwn-install: $(MDWN_OUT)
+
+$(WWW)/%.html: $(MDWN_DIR)/src/%.mdwn
+ install -d $(@D)
+ $(MDWNTOHTML) $< $@
+
+mdwn-clean:
+ rm -f $(MDWN_OUT)
\ No newline at end of file
diff --git a/mdwn/src/index.mdwn b/mdwn/src/index.mdwn
new file mode 100644
index 0000000..222ec5f
--- /dev/null
+++ b/mdwn/src/index.mdwn
@@ -0,0 +1,15 @@
+Title: Welcome
+
+Welcome to Café Scientifique Capture The Flag.
+
+1. [Register](register.cgi) your team
+2. [View the score board](scoreboard.html)
+3. Check out the [base conversion table](table.html)
+4. Start playing
+
+The following categories exist for this version of CTF:
+
+* [Sequence](puzzler.cgi?c=sequence)
+* [Code Breaking](puzzler.cgi?c=codebreaking)
+* [Webapp](puzzler.cgi?c=webapp)
+* [Tanks](tanks/results.html)
diff --git a/mdwn/src/intro.mdwn b/mdwn/src/intro.mdwn
new file mode 100644
index 0000000..8ce18bb
--- /dev/null
+++ b/mdwn/src/intro.mdwn
@@ -0,0 +1,103 @@
+Title: Introduction
+
+Welcome to Capture The Flag.
+
+
+What This Is
+============
+
+* A hacking contest
+* A chance to experience the nature of cyber incident response
+* An environment to safely experiment with offensive techniques
+
+
+What This Is Not
+================
+
+* An arena for purely malicious attacks
+* A rave
+
+
+Rules
+=====
+
+Important Rules
+---------------
+
+* The contest network is 10.x.x.x. **Do
+ not attack machines outside the contest network**. All
+ federal, state, and school laws still apply to the outside
+ network.
+* If the "outside network" requires you to plug into a different
+ switch, do not connect any machine that has been on the contest
+ network.
+* Consider this network hostile: your machine may be
+ compromised.
+* We expect you to be disruptive within the framework of the
+ game (malicious code, network scanning, social engineering,
+ etc.). Disruptive behavior outside the game will result in a
+ public and humiliating ejection from the contest area.
+* No ARP attacks. While cute, they are not particularly clever
+ given our network topology, and would require expensive and
+ bulky equipment to prevent. Find something else to do.
+
+Less-Important Rules
+--------------------
+
+* If IRC is up, you should use it to communicate with the
+ contest staff. Staff will have operator status in #ctf.
+* If you think something is wrong with the game, you are
+ expected to demonstrate the problem and explain what you think
+ is the correct behavior.
+
+
+Scoring
+=======
+
+The contest is made up of multiple categories. Each category is worth
+one point toward the total score; the percentage of the total points
+held by your team is the percentage of one point your team has for that
+category. The team that has 30% of the points in each of five
+categories has 1.5 points, whereas the team that has 80% of the points
+in only one category has 0.8 points. It is typically better to have a
+few points in many categories, than many points in a few categories.
+
+There are two kinds of categories: *flags* and *puzzles*.
+
+
+Flags
+-----
+
+Flag categories are challenges with a notion of a *winner* or *service
+availability*. In these categories, the flag-holder (the winner, or
+each team with a running service) makes 1 point per minute for as long
+as they hold the flag. If there is a single flag-holder, and the flag
+changes hands, a point is awarded to the new winner at the moment the
+flag moves.
+
+
+Puzzles
+-------
+
+Most of the categories come in the form of multiple *puzzles*: for each
+puzzle presented, a key (answer) must be found to recieve the amount of
+points that puzzle is worth. Any team may answer any puzzle question at
+any time. A new puzzle is revealed when a team correctly answers the
+highest-valued puzzle in that category.
+
+
+Hints
+=====
+
+If you are really stuck, you can ask for a hint. It will cost you
+points, though. For puzzles, you will lose ¼ of the points for that
+puzzle even if you never solve the puzzle. For other events,
+the staff member will decide how many points it will cost. You can try
+to bribe or otherwise fanagle information out of us or other
+contestants. *It's a hacking contest.*
+
+About Us
+========
+
+We are the dirtbags. People pay us
+money to do the sorts of things you'll be doing in this contest.
diff --git a/mdwn/src/table.mdwn b/mdwn/src/table.mdwn
new file mode 100644
index 0000000..6dc095b
--- /dev/null
+++ b/mdwn/src/table.mdwn
@@ -0,0 +1,161 @@
+Title: Counting in different bases
+
+
+
Base
+
+
2
+
0
+
1
+
10
+
11
+
100
+
101
+
110
+
111
+
1000
+
1001
+
1010
+
1011
+
1100
+
1101
+
1110
+
1111
+
10000
+
10001
+
10010
+
10011
+
10100
+
10101
+
10110
+
10111
+
11000
+
11001
+
11010
+
11011
+
11100
+
11101
+
11110
+
11111
+
100000
+
100001
+
100010
+
100011
+
+
+
8
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
40
+
41
+
42
+
43
+
+
+
10
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
+
+
16
+
0
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
a
+
b
+
c
+
d
+
e
+
f
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
1a
+
1b
+
1c
+
1d
+
1e
+
1f
+
20
+
21
+
22
+
23
+
+
\ No newline at end of file
diff --git a/mdwn/src/tanks/docs.mdwn b/mdwn/src/tanks/docs.mdwn
new file mode 100644
index 0000000..22756a9
--- /dev/null
+++ b/mdwn/src/tanks/docs.mdwn
@@ -0,0 +1,332 @@
+Title: Tanks Documentation
+
+Introduction
+============
+
+You are the proud new operator of a M-375 Pflanzarr Tank. Your tank is
+equipped with a powerful laser cannon, independently rotating turret
+section, up to 10 enemy detection sensors, and a standard issue NATO
+hull. Unfortunately, it lacks seats, and thus must rely own its own
+wits and your skills at designing those wits to survive.
+
+
+An Example Tank
+===============
+
+You can to paste this tank code into the [submit page](submit.html) page
+to get started. Then, start changing things to see how it affects your
+tank's behavior.
+
+ >addsensor(50, 0, 5, 1); # Sensor 0: Fire Sensor
+ >addsensor(30, 0, 50); # Sensor 1: Anti-collision sensor
+
+ # Commands
+ : move(90, 100) . turretset(0); # Always do this
+ sense(0) : fire(); # If sensor 0 is active, fire
+ sense(1) : move(-100, 100) # If sensor 1 is active, turn
+
+
+Programming Your Tank
+=====================
+
+Your tanks are programmed using the Super Useful Command and Kontrol
+language, the very best in laser tank AI languages. It includes amazing
+features such as comments (Started by a #, ended at EOL), logic,
+versatility, and semi-colons (all lines must end in one). As with all
+new military systems it utilizes only integers; we must never rest in
+our diligence against the communist floating point conspiracy.
+Whitespace is provided by trusted contractors, and should never
+interfere with operations.
+
+Your program should be separated into Setup and AI commands. The
+definitions section lets you designated the behaviors of its
+sensors and memory. Each setup command must begin with a
+'>'. Placing setup commands after the first AI command is a
+violation of protocol. Here are some examples of correct setup
+commands:
+
+ >addsensor(80, 90, 33);
+ >addsensor(50, 0, 10, 1);
+ >addtimer(3);
+
+The AI section will act as the brain of your tank. Each AI line
+is separated into a group of conditions functions and a group of
+action functions. If all the conditions are satisfactory (true),
+all of the actions are given as orders. Conditions are separated
+by ampersands, actions separated by periods. Here are some
+examples of AI commands:
+
+ sense(1) & sense(2) & fireready() : fire();
+ sense(0,0)&sin(5): move(40, 30) . turretcw(50);
+ sense(4) & random(4,5) : led(1).settoggle(0,1);
+
+Your tank will execute its program each turn(frame), and attempt
+to the best of its abilities to carry out its orders (or die
+trying). Like any military mind, your tank may receive a plethora
+of often conflicting orders and information. This a SMART TANK,
+however. It knows that the proper thing to do with each subsystem
+is to have that subsystem follow only the last order given each
+turn.
+
+ #Setup commands define your tank when your program
+ #compiles
+ >addsensor(50, 0, 5, 1); # 0-Fire Sensor
+ >addsensor(30, 0, 180); # 1-Anti-collision sensor
+
+ # These commands execute each frame.
+ # Blank condition sections are true.
+ : move(90, 100).
+ turretset(0);
+ sense(0) : fire();
+ sense(1) : move(-100, 100)
+
+Setup Actions
+-------------
+
+These functions can be used to setup your tank. Abuse of these
+functions has, in the past, resulted in mine sweeping duty. With
+a broom.
+
+
+
addsensor(range, angle, width, [turretAttached])
+
+
Add a new sensor to the tank.
+
+ Sensors are an arc (pie slice) centered on the tank that
+ detect other tanks within their sweep.
+ A sensor is 'on' if another tank is within this arc.
+
+
+ Sensors are numbered, starting at 0, in the order they are
+ added.
+
+
+ range - The range of the sensor, as a percent of the tanks max
+ range.
+ angle - The angle of the center of the sensor, in degrees.
+ width - The width of the sensor, in degrees.
+ turretAttached - Normally, the angle is relative to the front of
+ the
+ tank. When this is set, the angle is relative to the current
+ turret
+ direction.
+
+
+
+
addtimer(timeout)
+
+
+ Add a new timer (they're numbered in the order added, starting from 0),
+ with the given timeout.
+
+
+ The timeout is in number of turns.
+ The timer
+ is created in inactive mode. You'll need to do a starttimer()
+ action
+ to reset and start the timer. When the timer expires, the
+ timer()
+ condition will begin to return True.
+
+
+
+
addtoggle([state])
+
+
Add a toggle to the tank.
+
+ The state of the toggle defaults to 0 (False).
+ese essentially act as a single bit of memory.
+e the toggle() condition to check its state and the settoggle,
+eartoggle,
+d toggle actions to change the state. Toggles are named
+merically,
+arting at 0.
+
+
+
+
+Conditions
+----------
+
+These functions are used to check the state of reality. If reality
+stops being real, refer to chapter 5 in your girl scout handbook.
+
+
+
cos(T)
+
+
+ A cos wave with period T (in turns).
+
+
+
+ Returns True when the wave is
+ positive. A wave of period 1 is always True. Period
+ 2 is True every
+ other turn, etc.
+
+
+
+
firenotready()
+
+
+ True when the tank can not fire.
+
+
+
+
fireready()
+
+
+ True when the tank can fire.
+
+
+
+
random(n,m)
+
+
Generate a random number.
+
+
+ Takes two
+ arguments, n and m. Generates a random number between 1
+ and m (inclusive) each time it's checked. If the random
+ number is less
+ than or equal
+ to n, then the condition returns True. Returns False
+ otherwise.
+
+
+
+
sense(#, [invert])
+
+
True when a sensor is activated.
+
+
+ Takes a Sensor number as an argument.
+
+ Returns True if the given sensor is currently activated, False
+ otherwise.
+ If the option argument invert is set to true then logic is
+ inverted,
+ and then sensor returns True when it is NOT activated, and
+ False when
+ it is. Invert is false by default.
+
+
+
+
sin(T)
+
+
A sin wave of period T (in turns).
+
+
+ Returns True when the wave is positive.
+ A wave with period 1 or 2 is always False (it's 0 each turn),
+ only
+ at periods of 3 or more does this become useful.
+
+
+
+
timer(#, [invert])
+
+
+
Checks the state of timer # 'key'.
+
+
+ Returns True if time has run
+ out.
+
+ If invert is given (and true), then True is returned if the
+ timer has
+ yet to expire.
+
+
+
+
toggle(#)
+
+
Returns True if the given toggle is set, False
+ otherwise.
+
+
+
+Actions
+-------
+
+These actions are not for cowards. Remember, if actions contradict,
+your tank will simply do the last thing it was told in a turn. If
+ordered to hop on a plane to hell it will gladly do so. If order to
+make tea shortly afterwards, it will serve it politely and with cookies
+instead.
+
+
+
+
cleartimer(#)
+
+
Clear the given timer such that it is no longer active (inactive timers
+ are always False).
+
+
+
fire()
+
+
Attempt to fire the tanks laser cannon.
+
+ Its range is 50% of your sensor range.
+
+
+
+
led(state)
+
+
Set the tank's LED to state (true is on, false is off).
+
+ The led is a light that appears behind the tanks turret.
+ It remains on for a single turn.
+
+
+
+
move(left tread speed, right tread speed)
+
+
Set the speeds for the tanks right and left treads.
+
+
+ The speeds should
+ be a number (percent power) between -100 and
+ 100.
+
+
+
+
settoggle(key, state)
+
+
Set toggle 'key' to 'state'.
+
+
+
starttimer(#)
+
+
Start (and reset) the given timer, but only if it is
+ inactive.
+
+
+
toggle(key)
+
+
Toggle the value of toggle 'key'.
+
+
+
turretccw([percent speed])
+
+
Rotate the turret counter clockwise as a
+ percentage of the max speed.
+
+
+
turretcw([percent speed])
+
+
Rotate the turret clockwise at a rate
+ preportional to speed.
+
+
+
turretset([angle])
+
+
Set the turret to the given angle, in degrees, relative to the
+ front of the tank.
+
+ Angles increase counterclockwise. The angle can be left
+ out; in that case, this locks the turret to its current
+ position.
+
+
+
diff --git a/mdwn/src/tanks/links.xml b/mdwn/src/tanks/links.xml
new file mode 100644
index 0000000..c86c136
--- /dev/null
+++ b/mdwn/src/tanks/links.xml
@@ -0,0 +1,10 @@
+
A chance to experience the nature of cyber incident response
-
An environment to safely experiment with offensive techniques
-
-
-
-
What This Is Not
-
-
-
An arena for purely malicious attacks
-
A rave
-
-
-
Rules
-
-
Important Rules
-
-
The contest network is 10.x.x.x. Do
- not attack machines outside the contest network. All
- federal, state, and school laws still apply to the outside
- network.
-
If the "outside network" requires you to plug into a different
- switch, do not connect any machine that has been on the contest
- network.
-
Consider this network hostile: your machine may be
- compromised.
-
We expect you to be disruptive within the framework of the
- game (malicious code, network scanning, social engineering,
- etc.). Disruptive behavior outside the game will result in a
- public and humiliating ejection from the contest area.
-
No ARP attacks. While cute, they are not particularly clever
- given our network topology, and would require expensive and
- bulky equipment to prevent. Find something else to do.
-
-
-
Less-Important Rules
-
-
If IRC is up, you should use it to communicate with the
- contest staff. Staff will have operator status in #ctf.
-
If you think something is wrong with the game, you are
- expected to demonstrate the problem and explain what you think
- is the correct behavior.
-
-
-
Scoring
-
-
- The contest is made up of multiple categories. Each
- category is worth one point toward the total score; the percentage
- of the total points held by your team is the percentage of one
- point your team has for that category. The team that has 30% of
- the points in each of five categories has 1.5 points, whereas the
- team that has 80% of the points in only one category has 0.8
- points.
-
-
-
- There are two kinds of categories: flags
- and puzzles.
-
-
-
Flags
-
-
- Flag categories are challenges with a notion of a winner
- or service availability. In these categories, the
- flag-holder (the winner, or each team with a running service)
- makes 1 point per minute for as long as they hold the flag. If
- there is a single flag-holder, and the flag changes hands, a point
- is awarded to the new winner at the moment the flag moves.
-
-
-
Puzzles
-
-
- Most of the categories come in the form of
- multiple puzzles: for each puzzle presented, a key
- (answer) must be found to recieve the amount of points that puzzle
- is worth. Any team may answer any puzzle question at any time. A
- new puzzle is revealed when a team correctly answers the
- highest-valued puzzle in that category.
-
-
-
Hints
-
-
- If you are really stuck, you can ask for a hint. It will cost you
- points, though. For puzzles, you will lose ¼ of the points for
- that puzzle even if you never solve the puzzle. For
- other events, the staff member will decide how many points it will
- cost. You can try to bribe or otherwise fanagle information out
- of us or other contestants. It's a hacking contest.
-
-
-
About Us
-
-
- We are the dirtbags. People
- pay us money to do the sorts of things you'll be doing in this
- contest.
-
Cyber Security Collaboration Survey — Tracer FIRE II
-
-
-
-'''
-
-if validate(form):
- results = [client, str(time.time())]
-
- for k in fields.keys():
- val = form.getfirst(k) or ''
- if k == 'comments':
- val = val.replace(',', ' ')
- val = val.replace(':', ' ')
- val = val.replace('\n', ' ')
- val = val.replace('\r', ' ')
- results.append('%s:%s' % (k, val))
-
- f = open('/var/lib/ctf/survey/%s' % client, 'a')
- f.write(','.join(results) + '\n')
- f.close()
-
- print '
SUCCESS! Your survey submission has been accepted. Please do not retake the survey. Thanks!
'
-else:
- print '''
-
FAIL! It looks like you bypassed the client-side validation of the survey! That's too easy and the contest
- hasn't even begun yet! Would you please go back and just take the survey? It is very important!
Cyber Security Collaboration Survey — Tracer FIRE II
-
-
-
-
-
Please take a few minutes to fill out and submit this survey. One of
- the primary goals of the Cyber Tracer Team, the people behind Tracer FIRE,
- is to improve the existing collaboration environment between NNSA sites
- and other stakeholders. The information you provide in this survey will help
- us to accomplish that goal.
- You are the proud new operator of a M-375 Pflanzarr Tank. Your
- tank is equipped with a powerful laser cannon, independently
- rotating turret section, up to 10 enemy detection sensors, and a
- standard issue NATO hull. Unfortunately, it lacks seats, and thus
- must rely own its own wits and your skills at designing those wits
- to survive.
-
-
-
Programming Your Tank
-
-
- Your tanks are programmed using the Super Useful Command and
- Kontrol language, the very best in laser tank AI languages. It
- includes amazing features such as comments (Started by a #, ended
- at EOL), logic, versatility, and semi-colons (all lines must end
- in one). As with all new military systems it utilizes only
- integers; we must never rest in our diligence against the
- communist floating point conspiracy. Whitespace is provided by
- trusted contractors, and should never interfere with operations.
-
-
-
- Your program should be separated into Setup and AI commands. The
- definitions section lets you designated the behaviors of its
- sensors and memory. Each setup command must begin with a
- '>'. Placing setup commands after the first AI command is a
- violation of protocol. Here are some examples of correct setup
- commands:
-
- The AI section will act as the brain of your tank. Each AI line
- is separated into a group of conditions functions and a group of
- action functions. If all the conditions are satisfactory (true),
- all of the actions are given as orders. Conditions are separated
- by ampersands, actions separated by periods. Here are some
- examples of AI commands:
-
- Your tank will execute its program each turn(frame), and attempt
- to the best of its abilities to carry out its orders (or die
- trying). Like any military mind, your tank may receive a plethora
- of often conflicting orders and information. This a SMART TANK,
- however. It knows that the proper thing to do with each subsystem
- is to have that subsystem follow only the last order given each
- turn.
-
-
-
#Setup commands define your tank when your program
-#compiles
->addsensor(50, 0, 5, 1); # 0-Fire Sensor
->addsensor(30, 0, 180); # 1-Anti-collision sensor
-
-# These commands execute each frame.
-# Blank condition sections are true.
- : move(90, 100).
- turretset(0);
-sense(0) : fire();
-sense(1) : move(-100, 100)
-
-
Setup Actions:
-
-
- These functions can be used to setup your tank. Abuse of these
- functions has, in the past, resulted in mine sweeping duty. With
- a broom.
-
-
-
-
-
addsensor(range, angle, width, [turretAttached])
-
-
Add a new sensor to the tank.
-
- Sensors are an arc (pie slice) centered on the tank that
- detect other tanks within their sweep.
- A sensor is 'on' if another tank is within this arc.
-
-
- Sensors are numbered, starting at 0, in the order they are
- added.
-
-
- range - The range of the sensor, as a percent of the tanks max
- range.
- angle - The angle of the center of the sensor, in degrees.
- width - The width of the sensor, in degrees.
- turretAttached - Normally, the angle is relative to the front of
- the
- tank. When this is set, the angle is relative to the current
- turret
- direction.
-
-
-
-
addtimer(timeout)
-
-
- Add a new timer (they're numbered in the order added, starting from 0),
- with the given timeout.
-
-
- The timeout is in number of turns.
- The timer
- is created in inactive mode. You'll need to do a starttimer()
- action
- to reset and start the timer. When the timer expires, the
- timer()
- condition will begin to return True.
-
-
-
-
addtoggle([state])
-
-
Add a toggle to the tank.
-
- The state of the toggle defaults to 0 (False).
- These essentially act as a single bit of memory.
- Use the toggle() condition to check its state and the settoggle,
- cleartoggle,
- and toggle actions to change the state. Toggles are named
- numerically,
- starting at 0.
-
-
-
-
-
Conditions:
-
-
- These functions are used to check the state of reality. If reality
- stops being real, refer to chapter 5 in your girl scout
- handbook.
-
-
-
-
cos(T)
-
-
- A cos wave with period T (in turns).
-
-
-
- Returns True when the wave is
- positive. A wave of period 1 is always True. Period
- 2 is True every
- other turn, etc.
-
-
-
-
firenotready()
-
-
- True when the tank can not fire.
-
-
-
-
fireready()
-
-
- True when the tank can fire.
-
-
-
-
random(n,m)
-
-
Generate a random number.
-
-
- Takes two
- arguments, n and m. Generates a random number between 1
- and m (inclusive) each time it's checked. If the random
- number is less
- than or equal
- to n, then the condition returns True. Returns False
- otherwise.
-
-
-
-
sense(#, [invert])
-
-
True when a sensor is activated.
-
-
- Takes a Sensor number as an argument.
-
- Returns True if the given sensor is currently activated, False
- otherwise.
- If the option argument invert is set to true then logic is
- inverted,
- and then sensor returns True when it is NOT activated, and
- False when
- it is. Invert is false by default.
-
-
-
-
sin(T)
-
-
A sin wave of period T (in turns).
-
-
- Returns True when the wave is positive.
- A wave with period 1 or 2 is always False (it's 0 each turn),
- only
- at periods of 3 or more does this become useful.
-
-
-
-
timer(#, [invert])
-
-
-
Checks the state of timer # 'key'.
-
-
- Returns True if time has run
- out.
-
- If invert is given (and true), then True is returned if the
- timer has
- yet to expire.
-
-
-
-
toggle(#)
-
-
Returns True if the given toggle is set, False
- otherwise.
-
-
-
-
Actions:
-
-
- These actions are not for cowards. Remember, if actions
- contradict, your tank will simply do the last thing it was told in
- a turn. If ordered to hop on a plane to hell it will gladly do
- so. If order to make tea shortly afterwards, it will serve it
- politely and with cookies instead.
-
-
-
-
-
cleartimer(#)
-
-
Clear the given timer such that it is no longer active (inactive timers
- are always False).
-
-
-
fire()
-
-
Attempt to fire the tanks laser cannon.
-
- Its range is 50% of your sensor range.
-
-
-
-
led(state)
-
-
Set the tank's LED to state (true is on, false is off).
-
- The led is a light that appears behind the tanks turret.
- It remains on for a single turn.
-
-
-
-
move(left tread speed, right tread speed)
-
-
Set the speeds for the tanks right and left treads.
-
-
- The speeds should
- be a number (percent power) between -100 and
- 100.
-
-
-
-
settoggle(key, state)
-
-
Set toggle 'key' to 'state'.
-
-
-
starttimer(#)
-
-
Start (and reset) the given timer, but only if it is
- inactive.
-
-
-
toggle(key)
-
-
Toggle the value of toggle 'key'.
-
-
-
turretccw([percent speed])
-
-
Rotate the turret counter clockwise as a
- percentage of the max speed.
-
-
-
turretcw([percent speed])
-
-
Rotate the turret clockwise at a rate
- preportional to speed.
-
-
-
turretset([angle])
-
-
Set the turret to the given angle, in degrees, relative to the
- front of the tank.
-
- Angles increase counterclockwise. The angle can be left
- out; in that case, this locks the turret to its current
- position.
-
-
-
-
-
diff --git a/www/tanks/errors.cgi b/www/tanks/errors.cgi
index 32ece0f..c0b3ab1 100755
--- a/www/tanks/errors.cgi
+++ b/www/tanks/errors.cgi
@@ -23,7 +23,9 @@ body = []
fields = cgi.FieldStorage()
team = fields.getfirst('team', '').strip()
passwd = fields.getfirst('passwd', '').strip()
-if teams.chkpasswd(team, passwd):
+if not team:
+ pass
+elif teams.chkpasswd(team, passwd):
path = os.path.join(basedir, 'errors', quote(team))
if os.path.isfile(path):
body.append('