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]