diff --git a/admin/api/settings.go b/admin/api/settings.go
index a8610624..cbe9f759 100644
--- a/admin/api/settings.go
+++ b/admin/api/settings.go
@@ -54,6 +54,9 @@ func ApplySettings(config settings.FICSettings) {
fic.UnlockedChallenges = !config.EnableExerciceDepend
fic.FirstBlood = config.FirstBlood
fic.SubmissionCostBase = config.SubmissionCostBase
+ fic.HintCoefficient = config.HintCurCoefficient
+ fic.WChoiceCoefficient = config.WChoiceCurCoefficient
+ fic.SubmissionCostBase = config.SubmissionCostBase
fic.SubmissionUniqueness = config.SubmissionUniqueness
}
diff --git a/admin/static/views/settings.html b/admin/static/views/settings.html
index fbebb8ef..815e6ea5 100644
--- a/admin/static/views/settings.html
+++ b/admin/static/views/settings.html
@@ -60,17 +60,29 @@
+
+
@@ -97,9 +97,9 @@
-
diff --git a/libfic/db.go b/libfic/db.go
index 9f3bcec0..8790e497 100644
--- a/libfic/db.go
+++ b/libfic/db.go
@@ -314,6 +314,7 @@ CREATE TABLE IF NOT EXISTS team_hints(
id_team INTEGER,
id_hint INTEGER,
time TIMESTAMP NOT NULL,
+ coefficient FLOAT NOT NULL DEFAULT 1.0,
CONSTRAINT uc_displayed UNIQUE (id_team,id_hint),
FOREIGN KEY(id_hint) REFERENCES exercice_hints(id_hint),
FOREIGN KEY(id_team) REFERENCES teams(id_team)
@@ -326,6 +327,7 @@ CREATE TABLE IF NOT EXISTS team_wchoices(
id_team INTEGER,
id_flag INTEGER,
time TIMESTAMP NOT NULL,
+ coefficient FLOAT NOT NULL DEFAULT 1.0,
CONSTRAINT uc_displayed UNIQUE (id_team,id_flag),
FOREIGN KEY(id_flag) REFERENCES exercice_flags(id_flag),
FOREIGN KEY(id_team) REFERENCES teams(id_team)
diff --git a/libfic/hint.go b/libfic/hint.go
index d304b4ed..774c81d9 100644
--- a/libfic/hint.go
+++ b/libfic/hint.go
@@ -5,6 +5,9 @@ import (
"strings"
)
+// HintCoefficient is the current coefficient applied on its cost lost per showing
+var HintCoefficient = 1.0
+
// EHint represents a challenge hint.
type EHint struct {
Id int64 `json:"id"`
diff --git a/libfic/stats.go b/libfic/stats.go
index 774b74d6..7f41ef14 100644
--- a/libfic/stats.go
+++ b/libfic/stats.go
@@ -30,8 +30,8 @@ func exoptsQuery(whereExo string) string {
func teamptsQuery() string {
return exoptsQuery("") + ` UNION ALL
- SELECT D.id_team, D.time, H.cost AS points, -1.0 AS coeff, "Hint" AS reason, H.id_exercice FROM team_hints D INNER JOIN exercice_hints H ON H.id_hint = D.id_hint HAVING points != 0 UNION ALL
- SELECT W.id_team, W.time, F.choices_cost AS points, -1.0 AS coeff, "Display choices" AS reason, F.id_exercice FROM team_wchoices W INNER JOIN exercice_flags F ON F.id_flag = W.id_flag HAVING points != 0`
+ SELECT D.id_team, D.time, H.cost AS points, D.coefficient * -1 AS coeff, "Hint" AS reason, H.id_exercice FROM team_hints D INNER JOIN exercice_hints H ON H.id_hint = D.id_hint HAVING points != 0 UNION ALL
+ SELECT W.id_team, W.time, F.choices_cost AS points, W.coefficient * -1 AS coeff, "Display choices" AS reason, F.id_exercice FROM team_wchoices W INNER JOIN exercice_flags F ON F.id_flag = W.id_flag HAVING points != 0`
}
func rankQuery(whereTeam string) string {
diff --git a/libfic/team.go b/libfic/team.go
index d8611440..3f8b6c25 100644
--- a/libfic/team.go
+++ b/libfic/team.go
@@ -2,12 +2,16 @@ package fic
import (
"log"
+ "math"
"time"
)
// UnlockedChallenges disables dependancy requirement between challenges.
var UnlockedChallenges bool
+// WchoiceCoefficient is the current coefficient applied on the cost of changing flag into choices
+var WChoiceCoefficient = 1.0
+
// Team represents a group of players, come to solve our challenges.
type Team struct {
Id int64 `json:"id"`
@@ -174,7 +178,7 @@ func (t Team) HasHint(h EHint) (bool) {
// OpenHint registers to the database that the Team has now revealed.
func (t Team) OpenHint(h EHint) (error) {
- _, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time) VALUES (?, ?, ?)", t.Id, h.Id, time.Now())
+ _, err := DBExec("INSERT INTO team_hints (id_team, id_hint, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, h.Id, time.Now(), math.Max(HintCoefficient, 0.0))
return err
}
@@ -187,7 +191,7 @@ func (t Team) SeeChoices(k FlagKey) (bool) {
// DisplayChoices registers to the database that the Team has now revealed.
func (t Team) DisplayChoices(k FlagKey) (error) {
- _, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time) VALUES (?, ?, ?)", t.Id, k.Id, time.Now())
+ _, err := DBExec("INSERT INTO team_wchoices (id_team, id_flag, time, coefficient) VALUES (?, ?, ?, ?)", t.Id, k.Id, time.Now(), math.Max(WChoiceCoefficient, 0.0))
return err
}
diff --git a/libfic/team_my.go b/libfic/team_my.go
index 9cf71ae6..fedbbb8f 100644
--- a/libfic/team_my.go
+++ b/libfic/team_my.go
@@ -161,7 +161,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
return nil, err
} else {
for _, h := range hints {
- if t == nil || t.HasHint(h) {
+ if t == nil || HintCoefficient < 0 || t.HasHint(h) {
exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, h.Content, h.File, h.Cost})
} else {
exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, "", "", h.Cost})
@@ -210,7 +210,7 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
flag.Help = k.Help
if choices, err := k.GetChoices(); err != nil {
return nil, err
- } else if t == nil || k.ChoicesCost == 0 || t.SeeChoices(k) {
+ } else if t == nil || WChoiceCoefficient < 0 || k.ChoicesCost == 0 || t.SeeChoices(k) {
flag.Choices = map[string]string{}
for _, c := range choices {
flag.Choices[c.Value] = c.Label
diff --git a/settings/settings.go b/settings/settings.go
index 63f7a896..b29d5add 100644
--- a/settings/settings.go
+++ b/settings/settings.go
@@ -40,6 +40,10 @@ type FICSettings struct {
FirstBlood float64 `json:"firstBlood"`
// SubmissionCostBase is a complex number representing the cost of each attempts.
SubmissionCostBase float64 `json:"submissionCostBase"`
+ // HintCurrentCoefficient is the current coefficient applied to hint discovery.
+ HintCurCoefficient float64 `json:"hintCurrentCoefficient"`
+ // WChoiceCurCoefficient is the current coefficient applied to wanted choices.
+ WChoiceCurCoefficient float64 `json:"wchoiceCurrentCoefficient"`
// AllowRegistration permits unregistered Team to register themselves.
AllowRegistration bool `json:"allowRegistration"`