ctf-server
old server for hosting capture-the-flag
git clone https://9o.is/git/ctf-server.git
Flag.scala
(2766B)
1 package com.jcabrra
2 package model
3
4 import net.liftweb._
5 import mapper._
6 import util.Helpers._
7
8 class Flag extends LongKeyedMapper[Flag] with IdPK with ManyToMany {
9 def getSingleton = Flag
10
11 /* The challenge this flag belongs to. */
12 object challenge extends MappedLongForeignKey(this, Challenge)
13
14 /* They key, the string that needs to be captured from the GPS location. */
15 object key extends MappedLong(this)
16
17 /* The flag/answer. */
18 object answer extends MappedLong(this)
19
20 /* Capturing this flag leads you to the end/win/prize/game over */
21 object winner extends MappedBoolean(this)
22
23 /* GPS coordinate of the flag. */
24 object long extends MappedDouble(this)
25 object lat extends MappedDouble(this)
26
27 /* Users that captured this flag. */
28 object capturedBy extends MappedManyToMany(CapturedFlags, CapturedFlags.flag, CapturedFlags.user, User)
29
30 /* This challenge cannot be accessed unless a required flag has been captured. */
31 object prerequisite extends MappedManyToMany(RequiredFlags, RequiredFlags.succeeding, RequiredFlags.preceding, Flag)
32
33 def meetsPrerequisite(user: User): Boolean = {
34 user.capturedFlags.exists(flag => prerequisite.exists(_.id == flag.id)) ||
35 prerequisite.isEmpty
36 }
37
38 def isCorrectGuess(guess: String): Boolean = {
39 val long = this.long.get.toString
40 val lat = this.lat.get.toString
41 val gps = (lat + long).filter(_.toString.matches("[0-9]"))
42 tryo((key.get ^ gps.toLong).toString == guess) openOr false
43 }
44
45 /* Generates a nearby gps location to place this flag on the map. */
46 def genNearbyGPS: (Double, Double) = challenge.obj.map(_.genNearbyGPS).openOr((0,0))
47
48 /* If this flag was capture by a certain user. */
49 def wasCapturedBy(user: User): Boolean = user.capturedFlags.exists(_.id == this.id)
50
51 /* What challenges unlock after capturing this flag? */
52 def unlocks: List[Challenge] = RequiredFlags.
53 findAll(By(RequiredFlags.preceding, this)).
54 flatMap(_.succeeding.obj).
55 flatMap(_.challenge.obj)
56 }
57
58 object Flag extends Flag with LongKeyedMetaMapper[Flag]
59
60 /*
61 Join Table for captured flags.
62 */
63 object CapturedFlags extends CapturedFlags with LongKeyedMetaMapper[CapturedFlags]
64
65 class CapturedFlags extends LongKeyedMapper[CapturedFlags] with IdPK {
66 def getSingleton = CapturedFlags
67 object user extends MappedLongForeignKey(this, User)
68 object flag extends MappedLongForeignKey(this, Flag)
69 }
70
71 /*
72 Join Table for required flags. Creates a "chain".
73 */
74 object RequiredFlags extends RequiredFlags with LongKeyedMetaMapper[RequiredFlags]
75
76 class RequiredFlags extends LongKeyedMapper[RequiredFlags] with IdPK {
77 def getSingleton = RequiredFlags
78 object preceding extends MappedLongForeignKey(this, Flag)
79 object succeeding extends MappedLongForeignKey(this, Flag)
80 }