ctf-server
old server for hosting capture-the-flag
git clone https://9o.is/git/ctf-server.git
Challenge.scala
(2296B)
1 package com.jcabrra
2 package model
3
4 import net.liftweb.mapper._
5
6 class Challenge extends LongKeyedMapper[Challenge] with IdPK with ManyToMany {
7 def getSingleton = Challenge
8
9 /* Name of the challenge. */
10 object name extends MappedString(this, 255)
11
12 /* Gets all flags from this challenge. */
13 def flags: List[Flag] = Flag.findAll(By(Flag.challenge, this))
14
15 /* A hint to guide the user to a flag. */
16 object hint extends MappedString(this, 255)
17
18 /* GPS coordinate of the area center of this challenge. */
19 object long extends MappedDouble(this)
20 object lat extends MappedDouble(this)
21
22 /* The amount of area the challenge takes up in the map. Every unit is 0.00000625 gps decimals. */
23 object radius extends MappedInt(this) {
24 override def defaultValue = 40
25 }
26
27 /* This challenge cannot be accessed unless a required flag has been captured. */
28 def meetsPrerequisite(user: User): Boolean = flags.exists(_.meetsPrerequisite(user))
29
30 /* Gets a flag by its answer key. Useful to check if guess is correct. */
31 def findFlagByGuess(guess: String, user: User): Option[Flag] =
32 flags.filterNot(_.wasCapturedBy(user)).find(_.isCorrectGuess(guess))
33
34 /* The captured flags by a certain user for this challenge. */
35 def capturedFlags(user: User): List[Flag] = flags.filter(f => user.capturedFlags.exists(_.id == f.id))
36
37 /* Has a certain user solved the entire challenge or captured all flags? */
38 def fullySolvedBy(user: User): Boolean = flags.forall(flag => user.capturedFlags.exists(_.id == flag.id))
39
40 /*
41 * Generates a random nearby gps decimal coordinate so flags' exact location is not
42 * revealed on the map. Min and Max range is -0.000250. Return (longitude,latitude)
43 */
44 def genNearbyGPS: (Double, Double) = {
45 val range: Double = 0.00000625 * radius.get
46 val startLong: Double = long.get - range
47 val endLong = long.get + range
48 val startLat = lat.get - range
49 val endLat = lat.get + range
50 val r = new scala.util.Random
51
52 val nearLong = "%.6f".format(startLong + (endLong - startLong) * r.nextDouble).toDouble
53 val nearLat = "%.6f".format(startLat + (endLat - startLat) * r.nextDouble).toDouble
54
55 (nearLong, nearLat)
56 }
57 }
58
59 object Challenge extends Challenge with LongKeyedMetaMapper[Challenge]