forked from github/server
commit
0710fb796d
4 changed files with 99 additions and 25 deletions
|
@ -46,7 +46,7 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
|
||||||
st->level = effskill_study(u, st->sk);
|
st->level = effskill_study(u, st->sk);
|
||||||
st->learn = 0;
|
st->learn = 0;
|
||||||
st->u = u;
|
st->u = u;
|
||||||
if (++nscholars == max_scholars) {
|
if (++nscholars > max_scholars) {
|
||||||
log_fatal("you must increase MAXSCHOLARS");
|
log_fatal("you must increase MAXSCHOLARS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,6 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
|
||||||
u = u->next;
|
u = u->next;
|
||||||
}
|
}
|
||||||
*units = unext;
|
*units = unext;
|
||||||
scholars[nscholars].u = NULL;
|
|
||||||
if (nscholars > 0) {
|
if (nscholars > 0) {
|
||||||
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
|
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
|
||||||
}
|
}
|
||||||
|
@ -125,25 +124,20 @@ void autostudy_run(scholar scholars[], int nscholars)
|
||||||
n = scholars[s].u->number;
|
n = scholars[s].u->number;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* s gets partial credit and we need a new teacher */
|
/* a part of s gets credited and we need a new teacher: */
|
||||||
teaching(scholars + s, i);
|
teaching(scholars + s, i);
|
||||||
|
/* we still need to teach n students in this unit: */
|
||||||
/* we are done with this teacher. any remaining people are regular learners: */
|
n -= i;
|
||||||
if (scholars[t].u->number > 1) {
|
i = 0;
|
||||||
/* remain = number - ceil(taught/10); */
|
|
||||||
int remain = (STUDENTS_PER_TEACHER * scholars[t].u->number - i + STUDENTS_PER_TEACHER - 1) / STUDENTS_PER_TEACHER;
|
|
||||||
learning(scholars + t, remain);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we want a new teacher for s. if any exists, it's next in the sequence. */
|
/* we want a new teacher for s. if any exists, it's next in the sequence. */
|
||||||
if (++t == si) {
|
if (++t == si) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (scholars[t].level - TEACHDIFFERENCE < scholars[s].level) {
|
if (scholars[t].level - TEACHDIFFERENCE < scholars[s].level) {
|
||||||
/* next teacher cannot teach, we must skip students. */
|
/* no remaining teacher can teach this student, so we skip ahead */
|
||||||
do {
|
do {
|
||||||
learning(scholars + s, (n - i));
|
/* remaining students learn without a teacher: */
|
||||||
i = 0;
|
learning(scholars + s, n);
|
||||||
if (++s == se) {
|
if (++s == se) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,52 @@ static void test_autostudy_init(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].level);
|
CuAssertIntEquals(tc, 0, scholars[0].level);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk);
|
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk);
|
||||||
CuAssertPtrEquals(tc, NULL, scholars[1].u);
|
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reproduce Bug 2520
|
||||||
|
*/
|
||||||
|
static void test_autostudy_run_twoteachers(CuTest *tc) {
|
||||||
|
scholar scholars[4];
|
||||||
|
int nscholars;
|
||||||
|
unit *u1, *u2, *u3, *u4, *ulist;
|
||||||
|
faction *f;
|
||||||
|
region *r;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
r = test_create_plain(0, 0);
|
||||||
|
f = test_create_faction(NULL);
|
||||||
|
u1 = test_create_unit(f, r);
|
||||||
|
set_level(u1, SK_ENTERTAINMENT, 2);
|
||||||
|
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
u2 = test_create_unit(f, r);
|
||||||
|
set_level(u2, SK_ENTERTAINMENT, 2);
|
||||||
|
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
|
||||||
|
u3 = test_create_unit(f, r);
|
||||||
|
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
set_number(u3, 8);
|
||||||
|
u4 = test_create_unit(f, r);
|
||||||
|
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
set_number(u4, 12);
|
||||||
|
|
||||||
|
ulist = r->units;
|
||||||
|
CuAssertIntEquals(tc, 4, nscholars = autostudy_init(scholars, 4, &ulist));
|
||||||
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
|
autostudy_run(scholars, nscholars);
|
||||||
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
|
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
||||||
|
CuAssertIntEquals(tc, scholars[2].u->number * 2, scholars[2].learn);
|
||||||
|
CuAssertIntEquals(tc, scholars[3].u->number * 2, scholars[3].learn);
|
||||||
|
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
static void test_autostudy_run(CuTest *tc) {
|
static void test_autostudy_run(CuTest *tc) {
|
||||||
scholar scholars[4];
|
scholar scholars[4];
|
||||||
|
int nscholars;
|
||||||
unit *u1, *u2, *u3, *ulist;
|
unit *u1, *u2, *u3, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
@ -88,9 +127,9 @@ static void test_autostudy_run(CuTest *tc) {
|
||||||
set_number(u3, 15);
|
set_number(u3, 15);
|
||||||
scholars[3].u = NULL;
|
scholars[3].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, 3);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
||||||
|
@ -99,6 +138,7 @@ static void test_autostudy_run(CuTest *tc) {
|
||||||
|
|
||||||
static void test_autostudy_run_noteachers(CuTest *tc) {
|
static void test_autostudy_run_noteachers(CuTest *tc) {
|
||||||
scholar scholars[4];
|
scholar scholars[4];
|
||||||
|
int nscholars;
|
||||||
unit *u1, *u2, *u3, *ulist;
|
unit *u1, *u2, *u3, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
@ -118,20 +158,50 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
|
||||||
set_number(u3, 15);
|
set_number(u3, 15);
|
||||||
scholars[3].u = NULL;
|
scholars[3].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, 3);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 2, scholars[0].learn);
|
CuAssertIntEquals(tc, 2, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a teacher unit doesn't have enough students, the remaining members study.
|
||||||
|
*/
|
||||||
|
static void test_autostudy_run_teachers_learn(CuTest *tc) {
|
||||||
|
scholar scholars[4];
|
||||||
|
int nscholars;
|
||||||
|
unit *u1, *u2, *ulist;
|
||||||
|
faction *f;
|
||||||
|
region *r;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
r = test_create_plain(0, 0);
|
||||||
|
f = test_create_faction(NULL);
|
||||||
|
u1 = test_create_unit(f, r);
|
||||||
|
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
set_number(u1, 2);
|
||||||
|
set_level(u1, SK_ENTERTAINMENT, 2);
|
||||||
|
u2 = test_create_unit(f, r);
|
||||||
|
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
set_number(u2, 10);
|
||||||
|
ulist = r->units;
|
||||||
|
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist));
|
||||||
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
|
autostudy_run(scholars, nscholars);
|
||||||
|
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
||||||
|
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reproduce Bug 2514
|
* Reproduce Bug 2514
|
||||||
*/
|
*/
|
||||||
static void test_autostudy_run_skilldiff(CuTest *tc) {
|
static void test_autostudy_run_skilldiff(CuTest *tc) {
|
||||||
scholar scholars[4];
|
scholar scholars[4];
|
||||||
|
int nscholars;
|
||||||
unit *u1, *u2, *u3, *ulist;
|
unit *u1, *u2, *u3, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
@ -152,9 +222,9 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
|
||||||
set_number(u3, 10);
|
set_number(u3, 10);
|
||||||
scholars[3].u = NULL;
|
scholars[3].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, 3);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 20, scholars[2].learn);
|
CuAssertIntEquals(tc, 20, scholars[2].learn);
|
||||||
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
||||||
|
@ -167,6 +237,8 @@ CuSuite *get_automate_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_init);
|
SUITE_ADD_TEST(suite, test_autostudy_init);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run);
|
SUITE_ADD_TEST(suite, test_autostudy_run);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
||||||
|
SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn);
|
||||||
|
SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff);
|
SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
#include <util/path.h>
|
#include <util/path.h>
|
||||||
|
#include <util/password.h>
|
||||||
|
|
||||||
#include "eressea.h"
|
#include "eressea.h"
|
||||||
#ifdef USE_CURSES
|
#ifdef USE_CURSES
|
||||||
|
@ -231,6 +232,10 @@ static int parse_args(int argc, char **argv)
|
||||||
i = get_arg(argc, argv, 2, i, &arg, 0);
|
i = get_arg(argc, argv, 2, i, &arg, 0);
|
||||||
turn = atoi(arg);
|
turn = atoi(arg);
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
i = get_arg(argc, argv, 2, i, &arg, 0);
|
||||||
|
bcrypt_workfactor = arg ? atoi(arg) : 0xff;
|
||||||
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
verbosity = 0;
|
verbosity = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -17,7 +17,7 @@ bool password_is_implemented(cryptalgo_t algo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * password_hash(const char * passwd, cryptalgo_t algo) {
|
const char * password_hash(const char * passwd, cryptalgo_t algo) {
|
||||||
if (algo == PASSWORD_BCRYPT) {
|
if (algo == PASSWORD_BCRYPT && bcrypt_workfactor != 0) {
|
||||||
char salt[BCRYPT_HASHSIZE];
|
char salt[BCRYPT_HASHSIZE];
|
||||||
static char hash[BCRYPT_HASHSIZE];
|
static char hash[BCRYPT_HASHSIZE];
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -32,10 +32,13 @@ const char * password_hash(const char * passwd, cryptalgo_t algo) {
|
||||||
int password_verify(const char * pwhash, const char * passwd) {
|
int password_verify(const char * pwhash, const char * passwd) {
|
||||||
if (pwhash[0] == '$') {
|
if (pwhash[0] == '$') {
|
||||||
if (pwhash[1] == '2') {
|
if (pwhash[1] == '2') {
|
||||||
|
if (bcrypt_workfactor > 0) {
|
||||||
int ret = bcrypt_checkpw(passwd, pwhash);
|
int ret = bcrypt_checkpw(passwd, pwhash);
|
||||||
assert(ret != -1);
|
assert(ret != -1);
|
||||||
return (ret == 0) ? VERIFY_OK : VERIFY_FAIL;
|
return (ret == 0) ? VERIFY_OK : VERIFY_FAIL;
|
||||||
}
|
}
|
||||||
|
return VERIFY_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL;
|
return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue