Version18.125

This commit is contained in:
Antonio Cañas Vargas 2019-05-29 01:14:56 +02:00
parent 930714e7c3
commit a9903731f4
5 changed files with 212 additions and 239 deletions

View File

@ -86,6 +86,7 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday,
writeLocalDateHMSFromUTC.lastd = d; // Update last date for the next call writeLocalDateHMSFromUTC.lastd = d; // Update last date for the next call
/* Set date */ /* Set date */
StrDate = '';
if (WriteDate) { if (WriteDate) {
WriteTodayStr = false; WriteTodayStr = false;
if (StrToday != null) if (StrToday != null)
@ -111,7 +112,6 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday,
StrDate = MonthsShort[Mon - 1] + ' ' + Day.toString() + ', ' + Yea.toString(); StrDate = MonthsShort[Mon - 1] + ' ' + Day.toString() + ', ' + Yea.toString();
break; break;
default: default:
StrDate = '';
break; break;
} }
@ -120,10 +120,10 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday,
DayOfWeek = (DayOfWeek == 0) ? 6 : DayOfWeek - 1; DayOfWeek = (DayOfWeek == 0) ? 6 : DayOfWeek - 1;
StrDate = StrDate + Separator + DAYS[DayOfWeek]; StrDate = StrDate + Separator + DAYS[DayOfWeek];
} }
StrDate = StrDate + Separator;
} }
else else if (WriteWeekDay)
StrDate = ''; StrDate = Separator;
StrDate = StrDate + Separator;
/* Set HH:MM:SS */ /* Set HH:MM:SS */
StrHou = ''; StrHou = '';

View File

@ -634,23 +634,17 @@ CREATE TABLE IF NOT EXISTS gam_grp (
CREATE TABLE IF NOT EXISTS gam_matches ( CREATE TABLE IF NOT EXISTS gam_matches (
MchCod INT NOT NULL AUTO_INCREMENT, MchCod INT NOT NULL AUTO_INCREMENT,
GamCod INT NOT NULL, GamCod INT NOT NULL,
UsrCod INT NOT NULL,
StartTime DATETIME NOT NULL, StartTime DATETIME NOT NULL,
EndTime DATETIME NOT NULL, EndTime DATETIME NOT NULL,
UsrCod INT NOT NULL,
Title VARCHAR(2047) NOT NULL, Title VARCHAR(2047) NOT NULL,
UNIQUE INDEX(MchCod),
INDEX(GamCod));
--
-- Table gam_playing: stores the matches (game instances) beeing played currently
--
CREATE TABLE IF NOT EXISTS gam_playing (
MchCod INT NOT NULL,
QstInd INT NOT NULL DEFAULT 0, QstInd INT NOT NULL DEFAULT 0,
QstCod INT NOT NULL DEFAULT -1, QstCod INT NOT NULL DEFAULT -1,
QstStartTime DATETIME NOT NULL,
ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N', ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',
MchStart DATETIME NOT NULL, Finished ENUM('N','Y') NOT NULL DEFAULT 'N',
QstStart DATETIME NOT NULL, UNIQUE INDEX(MchCod),
UNIQUE INDEX(MchCod)); INDEX(GamCod));
-- --
-- Table gam_questions: stores the questions in the games -- Table gam_questions: stores the questions in the games
-- --

View File

@ -451,15 +451,19 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 18.124 (2019-05-28)" #define Log_PLATFORM_VERSION "SWAD 18.125 (2019-05-29)"
#define CSS_FILE "swad18.123.css" #define CSS_FILE "swad18.123.css"
#define JS_FILE "swad18.123.js" #define JS_FILE "swad18.123.js"
/* /*
Version 18.125: May 29, 2019 Unification of tables of matches (saved and current) into one table. (243371 lines)
2 changes necessary in database:
DROP TABLE gam_matches;
CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,UsrCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,Title VARCHAR(2047) NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,QstStartTime DATETIME NOT NULL,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',Finished ENUM('N','Y') NOT NULL DEFAULT 'N',UNIQUE INDEX(MchCod),INDEX(GamCod));
Version 18.124: May 28, 2019 Every game can have several matches (game instances). (243400 lines) Version 18.124: May 28, 2019 Every game can have several matches (game instances). (243400 lines)
4 changes necessary in database: 3 changes necessary in database:
DROP TABLE gam_played,gam_playing,gam_grp; DROP TABLE gam_played,gam_matches,gam_grp;
CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,UsrCod INT NOT NULL,Title VARCHAR(2047) NOT NULL,UNIQUE INDEX(MchCod),INDEX(GamCod)); CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,UsrCod INT NOT NULL,Title VARCHAR(2047) NOT NULL,UNIQUE INDEX(MchCod),INDEX(GamCod));
CREATE TABLE IF NOT EXISTS gam_playing (MchCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',MchStart DATETIME NOT NULL,QstStart DATETIME NOT NULL,UNIQUE INDEX(MchCod));
CREATE TABLE IF NOT EXISTS gam_grp (MchCod INT NOT NULL,GrpCod INT NOT NULL,UNIQUE INDEX(MchCod,GrpCod)); CREATE TABLE IF NOT EXISTS gam_grp (MchCod INT NOT NULL,GrpCod INT NOT NULL,UNIQUE INDEX(MchCod,GrpCod));
Version 18.123.2: May 23, 2019 New table with games instances already played. (242829 lines) Version 18.123.2: May 23, 2019 New table with games instances already played. (242829 lines)
@ -481,9 +485,8 @@ sudo cp icon/flag-checkered.svg /var/www/html/swad/icon/
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1781','es','N','Finalizar juego'); INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1781','es','N','Finalizar juego');
Version 18.122.2: May 20, 2019 New action to show current question (in a game beeing played) to a student. (242378 lines) Version 18.122.2: May 20, 2019 New action to show current question (in a game beeing played) to a student. (242378 lines)
2 changes necessary in database: 1 change necessary in database:
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1780','es','N','Mostrar juego a estudiante'); INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1780','es','N','Mostrar juego a estudiante');
CREATE TABLE IF NOT EXISTS gam_playing (GamCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',GamStart DATETIME NOT NULL,QstStart DATETIME NOT NULL,UNIQUE INDEX(GamCod));
Version 18.122.1: May 20, 2019 New action to play game by a student. (242257 lines) Version 18.122.1: May 20, 2019 New action to play game by a student. (242257 lines)
2 changes necessary in database: 2 changes necessary in database:

View File

@ -1373,51 +1373,37 @@ mysql> DESCRIBE gam_grp;
/***** Table gam_matches *****/ /***** Table gam_matches *****/
/* /*
mysql> DESCRIBE gam_matches; mysql> DESCRIBE gam_matches;
+-----------+---------------+------+-----+---------+----------------+ +----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+----------------+ +----------------+---------------+------+-----+---------+----------------+
| MchCod | int(11) | NO | PRI | NULL | auto_increment | | MchCod | int(11) | NO | PRI | NULL | auto_increment |
| GamCod | int(11) | NO | MUL | NULL | | | GamCod | int(11) | NO | MUL | NULL | |
| StartTime | datetime | NO | | NULL | | | UsrCod | int(11) | NO | | NULL | |
| EndTime | datetime | NO | | NULL | | | StartTime | datetime | NO | | NULL | |
| UsrCod | int(11) | NO | | NULL | | | EndTime | datetime | NO | | NULL | |
| Title | varchar(2047) | NO | | NULL | | | Title | varchar(2047) | NO | | NULL | |
+-----------+---------------+------+-----+---------+----------------+ | QstInd | int(11) | NO | | 0 | |
6 rows in set (0.00 sec) | QstCod | int(11) | NO | | -1 | |
| QstStartTime | datetime | NO | | NULL | |
| ShowingAnswers | enum('N','Y') | NO | | N | |
| Finished | enum('N','Y') | NO | | N | |
+----------------+---------------+------+-----+---------+----------------+
11 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_matches (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_matches ("
"MchCod INT NOT NULL AUTO_INCREMENT," "MchCod INT NOT NULL AUTO_INCREMENT,"
"GamCod INT NOT NULL," "GamCod INT NOT NULL,"
"UsrCod INT NOT NULL,"
"StartTime DATETIME NOT NULL," "StartTime DATETIME NOT NULL,"
"EndTime DATETIME NOT NULL," "EndTime DATETIME NOT NULL,"
"UsrCod INT NOT NULL,"
"Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE
"UNIQUE INDEX(MchCod),"
"INDEX(GamCod)");
/***** Table gam_playing *****/
/*
mysql> DESCRIBE gam_playing;
+----------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+-------+
| MchCod | int(11) | NO | PRI | NULL | |
| QstInd | int(11) | NO | | 0 | |
| QstCod | int(11) | NO | | -1 | |
| ShowingAnswers | enum('N','Y') | NO | | N | |
| MchStart | datetime | NO | | NULL | |
| QstStart | datetime | NO | | NULL | |
+----------------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_playing ("
"MchCod INT NOT NULL,"
"QstInd INT NOT NULL DEFAULT 0," "QstInd INT NOT NULL DEFAULT 0,"
"QstCod INT NOT NULL DEFAULT -1," "QstCod INT NOT NULL DEFAULT -1,"
"QstStartTime DATETIME NOT NULL,"
"ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N'," "ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',"
"MchStart DATETIME NOT NULL," "Finished ENUM('N','Y') NOT NULL DEFAULT 'N',"
"QstStart DATETIME NOT NULL," "UNIQUE INDEX(MchCod),"
"UNIQUE INDEX(MchCod))"); "INDEX(GamCod)");
/***** Table gam_questions *****/ /***** Table gam_questions *****/
/* /*

View File

@ -84,8 +84,15 @@ struct Match
long GamCod; long GamCod;
long UsrCod; long UsrCod;
time_t TimeUTC[2]; time_t TimeUTC[2];
bool Open;
char Title[Gam_MAX_BYTES_TITLE + 1]; char Title[Gam_MAX_BYTES_TITLE + 1];
struct
{
int QstInd;
long QstCod;
time_t QstStartTimeUTC;
bool ShowAnswers;
bool Finished;
} Status;
}; };
/*****************************************************************************/ /*****************************************************************************/
@ -113,7 +120,6 @@ static void Gam_ShowOneGame (long GamCod,
bool PutFormNewMatch, bool PutFormNewMatch,
bool PutButtonToPlay); bool PutButtonToPlay);
static void Gam_WriteAuthor (struct Game *Game); static void Gam_WriteAuthor (struct Game *Game);
// static void Gam_WriteStatus (struct Game *Game);
static void Gam_GetParamGameOrder (void); static void Gam_GetParamGameOrder (void);
static void Gam_PutFormsToRemEditOneGame (const struct Game *Game, static void Gam_PutFormsToRemEditOneGame (const struct Game *Game,
@ -128,8 +134,6 @@ static void Gam_ShowLstGrpsToEditMatch (void);
static void Gam_CreateGame (struct Game *Game,const char *Txt); static void Gam_CreateGame (struct Game *Game,const char *Txt);
static void Gam_UpdateGame (struct Game *Game,const char *Txt); static void Gam_UpdateGame (struct Game *Game,const char *Txt);
// static bool Gam_CheckIfMatchIsAssociatedToGrps (long MchCod);
// Nstatic void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod);
static void Gam_CreateGrps (long MchCod); static void Gam_CreateGrps (long MchCod);
static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match); static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match);
static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod); static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod);
@ -144,8 +148,8 @@ static void Gam_RemAnswersOfAQuestion (long QstCod);
static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod); // TODO: Remove this function because a question code can be repeated static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod); // TODO: Remove this function because a question code can be repeated
static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd); static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd);
static int Gam_GetMaxQuestionIndexInGame (long GamCod); static int Gam_GetMaxQuestionIndexInGame (long GamCod);
static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd); static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd);
static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd); static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd);
static void Gam_ListGameQuestions (struct Game *Game); static void Gam_ListGameQuestions (struct Game *Game);
static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
MYSQL_RES *mysql_res); MYSQL_RES *mysql_res);
@ -176,9 +180,8 @@ static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game);
static void Gam_PutBigButtonToPlayMatchStd (long MchCod); static void Gam_PutBigButtonToPlayMatchStd (long MchCod);
static long Gam_CreateMatch (struct Match *Match); static long Gam_CreateMatch (struct Match *Match);
// static bool Gam_CheckIfGameIsBeingPlayed (long GamCod); static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers); bool ShowingAnswers);
static void Gam_RemoveMatchBeingPlayed (long MchCod);
static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
unsigned QstInd, unsigned QstInd,
@ -187,7 +190,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
long MchCod,unsigned QstInd); long MchCod,unsigned QstInd);
static void Gam_PutBigButtonToEnd (long GamCod); static void Gam_PutBigButtonToEnd (long GamCod);
static void Gam_ShowQuestionBeingPlayed (void); static void Gam_ShowQuestionBeingPlayed (struct Match *Match);
static void Gam_ReceiveAndStoreUserAnswersToAGame (long GamCod); static void Gam_ReceiveAndStoreUserAnswersToAGame (long GamCod);
static void Gam_IncreaseAnswerInDB (long QstCod,unsigned AnsInd); static void Gam_IncreaseAnswerInDB (long QstCod,unsigned AnsInd);
@ -1717,23 +1720,10 @@ bool Gam_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod)
MchCod,GrpCod) != 0); MchCod,GrpCod) != 0);
} }
/*****************************************************************************/
/******************** Remove groups in matches of a game *********************/
/*****************************************************************************/
/*
static void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod)
{
***** Remove groups of the game *****
DB_QueryDELETE ("can not remove the groups associated to matches of a game",
"DELETE FROM gam_grp USING gam_grp,gam_matches"
" WHERE gam_matches.GrpCod=%ld"
" AND gam_matches.MchCod=gam_grp.MchCod",
GamCod);
}
*/
/*****************************************************************************/ /*****************************************************************************/
/******************** Remove one group from all the games ********************/ /******************** Remove one group from all the games ********************/
/*****************************************************************************/ /*****************************************************************************/
// TODO: Check if this function should be called when removing group
void Gam_RemoveGroup (long GrpCod) void Gam_RemoveGroup (long GrpCod)
{ {
@ -1747,6 +1737,7 @@ void Gam_RemoveGroup (long GrpCod)
/*****************************************************************************/ /*****************************************************************************/
/**************** Remove groups of one type from all the games ***************/ /**************** Remove groups of one type from all the games ***************/
/*****************************************************************************/ /*****************************************************************************/
// TODO: Check if this function should be called when removing group type
void Gam_RemoveGroupsOfType (long GrpTypCod) void Gam_RemoveGroupsOfType (long GrpTypCod)
{ {
@ -2098,7 +2089,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod)
// Question index can be 0, 1, 2,... // Question index can be 0, 1, 2,...
// Return -1 if no previous question // Return -1 if no previous question
static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd) static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -2109,7 +2100,7 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
// ...this implementation works even with non continuous indexes // ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get previous question index", if (!DB_QuerySELECT (&mysql_res,"can not get previous question index",
"SELECT MAX(QstInd) FROM gam_questions" "SELECT MAX(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd<%u", " WHERE GamCod=%ld AND QstInd<%d",
GamCod,QstInd)) GamCod,QstInd))
Lay_ShowErrorAndExit ("Error: previous question index not found."); Lay_ShowErrorAndExit ("Error: previous question index not found.");
@ -2131,7 +2122,7 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
// Question index can be 0, 1, 2,... // Question index can be 0, 1, 2,...
// Return -1 if no next question // Return -1 if no next question
static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd) static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -2142,7 +2133,7 @@ static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
// ...this implementation works even with non continuous indexes // ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get next question index", if (!DB_QuerySELECT (&mysql_res,"can not get next question index",
"SELECT MIN(QstInd) FROM gam_questions" "SELECT MIN(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd>%u", " WHERE GamCod=%ld AND QstInd>%d",
GamCod,QstInd)) GamCod,QstInd))
Lay_ShowErrorAndExit ("Error: next question index not found."); Lay_ShowErrorAndExit ("Error: next question index not found.");
@ -2923,13 +2914,17 @@ static void Gam_ListPlayedMatches (struct Game *Game,bool PutFormNewMatch)
/* Make query */ /* Make query */
NumMatches = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", NumMatches = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches",
"SELECT MchCod," // row[0] "SELECT MchCod," // row[ 0]
"GamCod," // row[1] "GamCod," // row[ 1]
"UNIX_TIMESTAMP(StartTime)," // row[2] "UsrCod," // row[ 2]
"UNIX_TIMESTAMP(EndTime)," // row[3] "UNIX_TIMESTAMP(StartTime)," // row[ 3]
"NOW() BETWEEN StartTime AND EndTime,"// row[4] "UNIX_TIMESTAMP(EndTime)," // row[ 4]
"UsrCod," // row[5] "Title," // row[ 5]
"Title" // row[6] "QstInd," // row[ 6]
"QstCod," // row[ 7]
"UNIX_TIMESTAMP(QstStartTime)," // row[ 8]
"ShowingAnswers," // row[ 9]
"Finished" // row[10]
" FROM gam_matches" " FROM gam_matches"
" WHERE %s" " WHERE %s"
" ORDER BY MchCod", " ORDER BY MchCod",
@ -2971,13 +2966,17 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
/***** Get data of match from database *****/ /***** Get data of match from database *****/
NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches",
"SELECT MchCod," // row[0] "SELECT MchCod," // row[ 0]
"GamCod," // row[1] "GamCod," // row[ 1]
"UNIX_TIMESTAMP(StartTime)," // row[2] "UsrCod," // row[ 2]
"UNIX_TIMESTAMP(EndTime)," // row[3] "UNIX_TIMESTAMP(StartTime)," // row[ 3]
"NOW() BETWEEN StartTime AND EndTime," // row[4] "UNIX_TIMESTAMP(EndTime)," // row[ 4]
"UsrCod," // row[5] "Title," // row[ 5]
"Title" // row[6] "QstInd," // row[ 6]
"QstCod," // row[ 7]
"UNIX_TIMESTAMP(QstStartTime)," // row[ 8]
"ShowingAnswers," // row[ 9]
"Finished" // row[10]
" FROM gam_matches" " FROM gam_matches"
" WHERE MchCod=%ld" " WHERE MchCod=%ld"
" AND GamCod IN" // Extra check " AND GamCod IN" // Extra check
@ -2996,8 +2995,12 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
Match->UsrCod = -1L; Match->UsrCod = -1L;
Match->TimeUTC[Gam_START_TIME] = Match->TimeUTC[Gam_START_TIME] =
Match->TimeUTC[Gam_END_TIME ] = (time_t) 0; Match->TimeUTC[Gam_END_TIME ] = (time_t) 0;
Match->Open = false;
Match->Title[0] = '\0'; Match->Title[0] = '\0';
Match->Status.QstInd = -1;
Match->Status.QstCod = -1L;
Match->Status.QstStartTimeUTC = (time_t) 0;
Match->Status.ShowAnswers = false;
Match->Status.Finished = false;
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -3028,6 +3031,7 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
extern const char *Txt_Match; extern const char *Txt_Match;
extern const char *Txt_Continue;
extern const char *Txt_Today; extern const char *Txt_Today;
unsigned NumMatch; unsigned NumMatch;
unsigned UniqueId; unsigned UniqueId;
@ -3037,19 +3041,19 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
Tbl_StartTableWideMargin (2); Tbl_StartTableWideMargin (2);
fprintf (Gbl.F.Out,"<tr>" fprintf (Gbl.F.Out,"<tr>"
"<th></th>" "<th></th>"
"<th class=\"CENTER_TOP\">" "<th class=\"RIGHT_TOP\">"
"%s" "%s"
"</th>" "</th>"
"<th class=\"CENTER_TOP\">" "<th class=\"LEFT_TOP\">"
"%s" "%s"
"</th>" "</th>"
"<th class=\"CENTER_TOP\">" "<th class=\"LEFT_TOP\">"
"%s" "%s"
"</th>" "</th>"
"<th class=\"CENTER_TOP\">" "<th class=\"LEFT_TOP\">"
"%s" "%s"
"</th>" "</th>"
"<th class=\"CENTER_TOP\">" "<th class=\"LEFT_TOP\">"
"%s" "%s"
"</th>" "</th>"
"</tr>", "</tr>",
@ -3079,6 +3083,16 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
Ico_PutIconRemove (); Ico_PutIconRemove ();
Frm_EndForm (); Frm_EndForm ();
/* Put icon to continue playing the match */
if (!Match.Status.Finished)
{
Gam_CurrentMchCod = Match.MchCod;
Lay_PutContextualLinkOnlyIcon (ActGamTchNxtQst,NULL, // TODO: Continue on a new tab!!!!
Gam_PutParamCurrentMchCod,
"play.svg",
Txt_Continue);
}
fprintf (Gbl.F.Out,"</td>"); fprintf (Gbl.F.Out,"</td>");
/***** Number of match ******/ /***** Number of match ******/
@ -3098,8 +3112,8 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
fprintf (Gbl.F.Out,"<td id=\"mch_date_start_%u\"" fprintf (Gbl.F.Out,"<td id=\"mch_date_start_%u\""
" class=\"%s LEFT_TOP COLOR%u\">", " class=\"%s LEFT_TOP COLOR%u\">",
UniqueId, UniqueId,
Match.Open ? "DATE_GREEN" : Match.Status.Finished ? "DATE_RED" :
"DATE_RED", "DATE_GREEN",
Gbl.RowEvenOdd); Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">" fprintf (Gbl.F.Out,"<script type=\"text/javascript\">"
"writeLocalDateHMSFromUTC('mch_date_start_%u',%ld," "writeLocalDateHMSFromUTC('mch_date_start_%u',%ld,"
@ -3113,8 +3127,8 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
fprintf (Gbl.F.Out,"<td id=\"mch_date_end_%u\"" fprintf (Gbl.F.Out,"<td id=\"mch_date_end_%u\""
" class=\"%s LEFT_TOP COLOR%u\">", " class=\"%s LEFT_TOP COLOR%u\">",
UniqueId, UniqueId,
Match.Open ? "DATE_GREEN" : Match.Status.Finished ? "DATE_RED" :
"DATE_RED", "DATE_GREEN",
Gbl.RowEvenOdd); Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">" fprintf (Gbl.F.Out,"\">"
"<script type=\"text/javascript\">" "<script type=\"text/javascript\">"
@ -3126,9 +3140,10 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
(unsigned) Gbl.Prefs.DateFormat,Txt_Today); (unsigned) Gbl.Prefs.DateFormat,Txt_Today);
/***** Title and groups *****/ /***** Title and groups *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",Gbl.RowEvenOdd);
/* Title */ /* Title */
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">%s", fprintf (Gbl.F.Out,"<span class=\"ASG_TITLE\">%s</span>",Match.Title);
Gbl.RowEvenOdd,Match.Title);
/* Groups whose students can answer this match */ /* Groups whose students can answer this match */
if (Gbl.Crs.Grps.NumGrps) if (Gbl.Crs.Grps.NumGrps)
@ -3155,40 +3170,60 @@ static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res,
/***** Get match data *****/ /***** Get match data *****/
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
/* /*
row[0] MchCod row[ 0] MchCod
row[1] GamCod row[ 1] GamCod
row[2] UNIX_TIMESTAMP(StartTime) row[ 2] UsrCod
row[3] UNIX_TIMESTAMP(EndTime) row[ 3] UNIX_TIMESTAMP(StartTime)
row[4] NOW() BETWEEN StartTime AND EndTime row[ 4] UNIX_TIMESTAMP(EndTime)
row[5] UsrCod row[ 5] Title
row[6] Title
*/ */
/* row[0] holds the code of the match */ /***** Get match data *****/
/* Code of the match (row[0]) */
if ((Match->MchCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) if ((Match->MchCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Lay_ShowErrorAndExit ("Wrong code of match."); Lay_ShowErrorAndExit ("Wrong code of match.");
/* row[1] holds the code of the game */ /* Code of the game (row[1]) */
if ((Match->GamCod = Str_ConvertStrCodToLongCod (row[1])) <= 0) if ((Match->GamCod = Str_ConvertStrCodToLongCod (row[1])) <= 0)
Lay_ShowErrorAndExit ("Wrong code of game."); Lay_ShowErrorAndExit ("Wrong code of game.");
/* Get start date (row[2] holds the start UTC time) */ /* Get match teacher (row[2]) */
Match->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[2]); Match->UsrCod = Str_ConvertStrCodToLongCod (row[2]);
/* Get end date (row[3] holds the end UTC time) */ /* Get start date (row[3] holds the start UTC time) */
Match->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[3]); Match->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]);
/* Get whether the match is open or closed (row(4)) */ /* Get end date (row[4] holds the end UTC time) */
Match->Open = (row[4][0] == '1'); Match->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]);
/* Get match player (row[5]) */ /* Get the title of the game (row[5]) */
Match->UsrCod = Str_ConvertStrCodToLongCod (row[5]); if (row[5])
Str_Copy (Match->Title,row[5],
/* Get the title of the game (row[6]) */
if (row[6])
Str_Copy (Match->Title,row[6],
Gam_MAX_BYTES_TITLE); Gam_MAX_BYTES_TITLE);
else else
Match->Title[0] = '\0'; Match->Title[0] = '\0';
/***** Get current match status *****/
/*
row[ 6] QstInd
row[ 7] QstCod
row[ 8] UNIX_TIMESTAMP(QstStartTime)
row[ 9] ShowingAnswers
row[10] Finished
*/
/* Current question index (row[6]) */
Match->Status.QstInd = (int) Str_ConvertStrCodToLongCod (row[6]);
/* Current question code (row[7]) */
Match->Status.QstCod = Str_ConvertStrCodToLongCod (row[7]);
/* Get question start date (row[8] holds the start UTC time) */
Match->Status.QstStartTimeUTC = Dat_GetUNIXTimeFromStr (row[8]);
/* Get whether to show question answers or not (row(9)) */
Match->Status.ShowAnswers = (row[9][0] == 'Y');
/* Get whether the match is finished or not (row(10)) */
Match->Status.Finished = (row[10][0] == 'Y');
} }
/*****************************************************************************/ /*****************************************************************************/
@ -3474,12 +3509,14 @@ static long Gam_CreateMatch (struct Match *Match)
/***** Create a new match *****/ /***** Create a new match *****/
MchCod = DB_QueryINSERTandReturnCode ("can not create match", MchCod = DB_QueryINSERTandReturnCode ("can not create match",
"INSERT gam_matches" "INSERT gam_matches"
" (GamCod,StartTime,EndTime,UsrCod,Title)" " (GamCod,UsrCod,StartTime,EndTime,Title,"
"QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)"
" VALUES" " VALUES"
" (%ld,NOW(),NOW(),%ld,'%s')", " (%ld,%ld,NOW(),NOW(),'%s',"
"-1,-1,FROM_UNIXTIME(0),'N','N')",
Match->GamCod, Match->GamCod,
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Match->Title); Match->Title);
/***** Create groups associated to the match *****/ /***** Create groups associated to the match *****/
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
@ -3488,69 +3525,36 @@ static long Gam_CreateMatch (struct Match *Match)
return MchCod; return MchCod;
} }
/*****************************************************************************/
/******************** Check if I game is being played ************************/
/*****************************************************************************/
/*
static bool Gam_CheckIfGameIsBeingPlayed (long GamCod)
{
***** Get if game is being played from database *****
return (DB_QueryCOUNT ("can not check if game is being played",
"SELECT COUNT(*)"
" FROM gam_matches,gam_playing"
" WHERE gam_matches.GamCod=%ld"
" AND gam_matches.MchCod=gam_playing.MchCod",
GamCod) != 0);
}
*/
/*****************************************************************************/ /*****************************************************************************/
/***************** Insert/update a game match being played *******************/ /***************** Insert/update a game match being played *******************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers) static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,
bool ShowingAnswers)
{ {
/***** Update match in table of matches being played currently *****/ /***** Update match in table of matches being played currently *****/
if (ShowingAnswers) // Show a question previously shown and its answers if (ShowingAnswers) // Show a question previously shown and its answers
DB_QueryUPDATE ("can not update match beeing played", DB_QueryUPDATE ("can not update match being played",
"UPDATE gam_playing" "UPDATE gam_matches,games"
" SET ShowingAnswers='Y'" " SET gam_matches.EndTime=NOW(),"
" WHERE MchCod=%ld" "gam_matches.ShowingAnswers='Y'"
" AND QstInd=%u AND QstCod=%ld", // Extra checks, not necessary " WHERE gam_matches.MchCod=%ld"
MchCod,QstInd,QstCod); " AND gam_matches.GamCod=games.GamCod"
" AND games.CrsCod=%ld", // Extra check
MchCod,Gbl.Hierarchy.Crs.CrsCod);
else // Show a question without answers else // Show a question without answers
{ DB_QueryUPDATE ("can not update match being played",
if (QstInd == 0) // 1st question beeing shown "UPDATE gam_matches,games"
DB_QueryINSERT ("can not create match beeing played", " SET gam_matches.EndTime=NOW(),"
"INSERT gam_playing" "gam_matches.QstInd=%d,"
" (MchCod,QstInd,QstCod,ShowingAnswers,MchStart,QstStart)" "gam_matches.QstCod=%ld,"
" VALUES" "gam_matches.ShowingAnswers='N',"
" (%ld,0,%ld,'N',NOW(),NOW())", "gam_matches.QstStartTime=NOW()"
MchCod,QstCod); " WHERE gam_matches.MchCod=%ld"
else // 2nd, 3rd... question beeing shown " AND gam_matches.GamCod=games.GamCod"
DB_QueryUPDATE ("can not update match beeing played", " AND games.CrsCod=%ld", // Extra check
"UPDATE gam_playing" QstInd,QstCod,
" SET QstInd=%u,QstCod=%ld,ShowingAnswers='N',QstStart=NOW()" MchCod,Gbl.Hierarchy.Crs.CrsCod);
" WHERE MchCod=%ld",
QstInd,QstCod,MchCod);
}
/***** Update match end time in table of matches already played *****/
DB_QueryUPDATE ("can not update match end time",
"UPDATE gam_matches SET EndTime=NOW() WHERE MchCod=%ld",
MchCod);
}
/*****************************************************************************/
/****************** Remove match from matches being played *******************/
/*****************************************************************************/
static void Gam_RemoveMatchBeingPlayed (long MchCod)
{
/***** Remove game being played from database *****/
DB_QueryDELETE ("can not remove match being played",
"DELETE FROM gam_playing"
" WHERE MchCod=%ld",
MchCod);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -3673,7 +3677,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
if (ShowAnswers) if (ShowAnswers)
{ {
/* Get index of the next question */ /* Get index of the next question */
NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,QstInd); NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,Match.Status.QstInd);
if (NxtQstInd >= 0) // Not last question if (NxtQstInd >= 0) // Not last question
/* Put button to show next question */ /* Put button to show next question */
Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd); Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd);
@ -3773,8 +3777,15 @@ void Gam_MatchTchEnd (void)
if ((MchCod = Gam_GetParamMatchCod ()) == -1L) if ((MchCod = Gam_GetParamMatchCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of match is missing."); Lay_ShowErrorAndExit ("Code of match is missing.");
/***** Remove match being played *****/ /***** Update match being played *****/
Gam_RemoveMatchBeingPlayed (MchCod); DB_QueryUPDATE ("can not update match being played",
"UPDATE gam_matches,games"
" SET gam_matches.Finished='Y',"
"gam_matches.EndTime=NOW()"
" WHERE gam_matches.MchCod=%ld"
" AND gam_matches.GamCod=games.GamCod"
" AND games.CrsCod=%ld", // Extra check
MchCod,Gbl.Hierarchy.Crs.CrsCod);
/***** Show alert *****/ /***** Show alert *****/
Ale_ShowAlert (Ale_INFO,"Partida finalizada."); // TODO: Need translation!!!!! Ale_ShowAlert (Ale_INFO,"Partida finalizada."); // TODO: Need translation!!!!!
@ -3800,8 +3811,15 @@ void Gam_GetMatchBeingPlayed (void)
void Gam_ShowNewMatchToMeAsStd (void) void Gam_ShowNewMatchToMeAsStd (void)
{ {
struct Match Match;
/***** Get data of the match from database *****/
Match.MchCod = Gbl.Games.MchCodBeingPlayed;
Gam_GetDataOfMatchByCod (&Match);
/***** Show current question *****/
fprintf (Gbl.F.Out,"<div id=\"game\" class=\"GAM_PLAY_STD_CONTAINER\">"); fprintf (Gbl.F.Out,"<div id=\"game\" class=\"GAM_PLAY_STD_CONTAINER\">");
Gam_ShowQuestionBeingPlayed (); Gam_ShowQuestionBeingPlayed (&Match);
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
} }
@ -3811,83 +3829,55 @@ void Gam_ShowNewMatchToMeAsStd (void)
void Gam_RefreshCurrentMatchStd (void) void Gam_RefreshCurrentMatchStd (void)
{ {
if (Gbl.Session.IsOpen) // If session has been closed, do not write anything struct Match Match;
/***** Get and show current question *****/
Gam_ShowQuestionBeingPlayed (); if (!Gbl.Session.IsOpen) // If session has been closed, do not write anything
return;
/***** Get data of the match from database *****/
Match.MchCod = Gbl.Games.MchCodBeingPlayed;
Gam_GetDataOfMatchByCod (&Match);
/***** Show current question *****/
Gam_ShowQuestionBeingPlayed (&Match);
} }
/*****************************************************************************/ /*****************************************************************************/
/************ Show current question being played for a student ***************/ /************ Show current question being played for a student ***************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_ShowQuestionBeingPlayed (void) static void Gam_ShowQuestionBeingPlayed (struct Match *Match)
{ {
MYSQL_RES *mysql_res;
MYSQL_ROW row;
bool IBelongToGroups; bool IBelongToGroups;
unsigned QstInd;
long QstCod;
bool GameIsPlaying;
bool ShowAnswers;
unsigned NumOptions; unsigned NumOptions;
unsigned NumOpt; unsigned NumOpt;
/***** Do I belong to valid groups to play this match? *****/ /***** Do I belong to valid groups to play this match? *****/
IBelongToGroups = Gbl.Usrs.Me.IBelongToCurrentCrs && IBelongToGroups = Gbl.Usrs.Me.IBelongToCurrentCrs &&
Gam_CheckIfIPlayThisMatchBasedOnGrps (Gbl.Games.MchCodBeingPlayed); Gam_CheckIfIPlayThisMatchBasedOnGrps (Match->MchCod);
if (!IBelongToGroups) if (!IBelongToGroups)
Lay_ShowErrorAndExit ("You can not play this match!"); Lay_ShowErrorAndExit ("You can not play this match!");
/***** Get question being played from database *****/
GameIsPlaying = (DB_QuerySELECT (&mysql_res,"can not get question being played",
"SELECT QstInd," // row[0]
"QstCod," // row[1]
"ShowingAnswers," // row[2]
"GamStart," // row[3]
"QstStart" // row[4]
" FROM gam_playing"
" WHERE MchCod=%ld",
Gbl.Games.MchCodBeingPlayed) != 0);
if (GameIsPlaying)
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get question index (row[0]) */
if (sscanf (row[0],"%d",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting question index.");
/* Get question code (row[1]) */
if ((QstCod = Str_ConvertStrCodToLongCod (row[1])) <= 0)
Lay_ShowErrorAndExit ("Error: wrong question code.");
/* Get whether the answers are being shown (row[2]) */
ShowAnswers = (row[2][0] == 'Y');
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
/***** Show question *****/ /***** Show question *****/
if (GameIsPlaying) if (!Match->Status.Finished)
{ {
/***** Show question *****/ /***** Show question *****/
/* Write number of question */ /* Write number of question */
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_NUM_QST\">%u</div>", fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_NUM_QST\">%u</div>",
QstInd + 1); Match->Status.QstInd + 1);
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">");
/* Write answers? */ /* Write answers? */
if (ShowAnswers) if (Match->Status.ShowAnswers)
{ {
if (Tst_CheckIfQuestionIsValidForGame (QstCod)) if (Tst_CheckIfQuestionIsValidForGame (Match->Status.QstCod))
{ {
/***** Start table *****/ /***** Start table *****/
Tbl_StartTableWide (8); Tbl_StartTableWide (8);
/***** Write answers *****/ /***** Write answers *****/
NumOptions = Tst_GetNumAnswersQst (QstCod); NumOptions = Tst_GetNumAnswersQst (Match->Status.QstCod);
for (NumOpt = 0; for (NumOpt = 0;
NumOpt < NumOptions; NumOpt < NumOptions;
NumOpt++) NumOpt++)