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
/* Set date */
StrDate = '';
if (WriteDate) {
WriteTodayStr = false;
if (StrToday != null)
@ -111,7 +112,6 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday,
StrDate = MonthsShort[Mon - 1] + ' ' + Day.toString() + ', ' + Yea.toString();
break;
default:
StrDate = '';
break;
}
@ -120,10 +120,10 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday,
DayOfWeek = (DayOfWeek == 0) ? 6 : DayOfWeek - 1;
StrDate = StrDate + Separator + DAYS[DayOfWeek];
}
StrDate = StrDate + Separator;
}
else
StrDate = '';
else if (WriteWeekDay)
StrDate = Separator;
StrDate = StrDate + Separator;
/* Set HH:MM:SS */
StrHou = '';

View File

@ -634,23 +634,17 @@ CREATE TABLE IF NOT EXISTS gam_grp (
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,
UsrCod INT 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,
QstCod INT NOT NULL DEFAULT -1,
QstStartTime DATETIME NOT NULL,
ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',
MchStart DATETIME NOT NULL,
QstStart DATETIME NOT NULL,
UNIQUE INDEX(MchCod));
Finished ENUM('N','Y') NOT NULL DEFAULT 'N',
UNIQUE INDEX(MchCod),
INDEX(GamCod));
--
-- Table gam_questions: stores the questions in the games
--

View File

@ -451,15 +451,19 @@ En OpenSWAD:
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 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)
4 changes necessary in database:
DROP TABLE gam_played,gam_playing,gam_grp;
3 changes necessary in database:
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_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));
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');
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');
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)
2 changes necessary in database:

View File

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

View File

@ -84,8 +84,15 @@ struct Match
long GamCod;
long UsrCod;
time_t TimeUTC[2];
bool Open;
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 PutButtonToPlay);
static void Gam_WriteAuthor (struct Game *Game);
// static void Gam_WriteStatus (struct Game *Game);
static void Gam_GetParamGameOrder (void);
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_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_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match);
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 long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd);
static int Gam_GetMaxQuestionIndexInGame (long GamCod);
static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd);
static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd);
static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd);
static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd);
static void Gam_ListGameQuestions (struct Game *Game);
static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
MYSQL_RES *mysql_res);
@ -176,9 +180,8 @@ static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game);
static void Gam_PutBigButtonToPlayMatchStd (long MchCod);
static long Gam_CreateMatch (struct Match *Match);
// static bool Gam_CheckIfGameIsBeingPlayed (long GamCod);
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers);
static void Gam_RemoveMatchBeingPlayed (long MchCod);
static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,
bool ShowingAnswers);
static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
unsigned QstInd,
@ -187,7 +190,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
long MchCod,unsigned QstInd);
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_IncreaseAnswerInDB (long QstCod,unsigned AnsInd);
@ -1717,23 +1720,10 @@ bool Gam_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod)
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 ********************/
/*****************************************************************************/
// TODO: Check if this function should be called when removing group
void Gam_RemoveGroup (long GrpCod)
{
@ -1747,6 +1737,7 @@ void Gam_RemoveGroup (long GrpCod)
/*****************************************************************************/
/**************** 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)
{
@ -2098,7 +2089,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod)
// Question index can be 0, 1, 2,...
// 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_ROW row;
@ -2109,7 +2100,7 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
// ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get previous question index",
"SELECT MAX(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd<%u",
" WHERE GamCod=%ld AND QstInd<%d",
GamCod,QstInd))
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,...
// 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_ROW row;
@ -2142,7 +2133,7 @@ static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
// ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get next question index",
"SELECT MIN(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd>%u",
" WHERE GamCod=%ld AND QstInd>%d",
GamCod,QstInd))
Lay_ShowErrorAndExit ("Error: next question index not found.");
@ -2923,13 +2914,17 @@ static void Gam_ListPlayedMatches (struct Game *Game,bool PutFormNewMatch)
/* Make query */
NumMatches = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches",
"SELECT MchCod," // row[0]
"GamCod," // row[1]
"UNIX_TIMESTAMP(StartTime)," // row[2]
"UNIX_TIMESTAMP(EndTime)," // row[3]
"NOW() BETWEEN StartTime AND EndTime,"// row[4]
"UsrCod," // row[5]
"Title" // row[6]
"SELECT MchCod," // row[ 0]
"GamCod," // row[ 1]
"UsrCod," // row[ 2]
"UNIX_TIMESTAMP(StartTime)," // row[ 3]
"UNIX_TIMESTAMP(EndTime)," // row[ 4]
"Title," // row[ 5]
"QstInd," // row[ 6]
"QstCod," // row[ 7]
"UNIX_TIMESTAMP(QstStartTime)," // row[ 8]
"ShowingAnswers," // row[ 9]
"Finished" // row[10]
" FROM gam_matches"
" WHERE %s"
" ORDER BY MchCod",
@ -2971,13 +2966,17 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
/***** Get data of match from database *****/
NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches",
"SELECT MchCod," // row[0]
"GamCod," // row[1]
"UNIX_TIMESTAMP(StartTime)," // row[2]
"UNIX_TIMESTAMP(EndTime)," // row[3]
"NOW() BETWEEN StartTime AND EndTime," // row[4]
"UsrCod," // row[5]
"Title" // row[6]
"SELECT MchCod," // row[ 0]
"GamCod," // row[ 1]
"UsrCod," // row[ 2]
"UNIX_TIMESTAMP(StartTime)," // row[ 3]
"UNIX_TIMESTAMP(EndTime)," // row[ 4]
"Title," // row[ 5]
"QstInd," // row[ 6]
"QstCod," // row[ 7]
"UNIX_TIMESTAMP(QstStartTime)," // row[ 8]
"ShowingAnswers," // row[ 9]
"Finished" // row[10]
" FROM gam_matches"
" WHERE MchCod=%ld"
" AND GamCod IN" // Extra check
@ -2996,8 +2995,12 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
Match->UsrCod = -1L;
Match->TimeUTC[Gam_START_TIME] =
Match->TimeUTC[Gam_END_TIME ] = (time_t) 0;
Match->Open = false;
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 *****/
@ -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_START_END_TIME[Dat_NUM_START_END_TIME];
extern const char *Txt_Match;
extern const char *Txt_Continue;
extern const char *Txt_Today;
unsigned NumMatch;
unsigned UniqueId;
@ -3037,19 +3041,19 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
Tbl_StartTableWideMargin (2);
fprintf (Gbl.F.Out,"<tr>"
"<th></th>"
"<th class=\"CENTER_TOP\">"
"<th class=\"RIGHT_TOP\">"
"%s"
"</th>"
"<th class=\"CENTER_TOP\">"
"<th class=\"LEFT_TOP\">"
"%s"
"</th>"
"<th class=\"CENTER_TOP\">"
"<th class=\"LEFT_TOP\">"
"%s"
"</th>"
"<th class=\"CENTER_TOP\">"
"<th class=\"LEFT_TOP\">"
"%s"
"</th>"
"<th class=\"CENTER_TOP\">"
"<th class=\"LEFT_TOP\">"
"%s"
"</th>"
"</tr>",
@ -3079,6 +3083,16 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
Ico_PutIconRemove ();
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>");
/***** Number of match ******/
@ -3098,8 +3112,8 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
fprintf (Gbl.F.Out,"<td id=\"mch_date_start_%u\""
" class=\"%s LEFT_TOP COLOR%u\">",
UniqueId,
Match.Open ? "DATE_GREEN" :
"DATE_RED",
Match.Status.Finished ? "DATE_RED" :
"DATE_GREEN",
Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">"
"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\""
" class=\"%s LEFT_TOP COLOR%u\">",
UniqueId,
Match.Open ? "DATE_GREEN" :
"DATE_RED",
Match.Status.Finished ? "DATE_RED" :
"DATE_GREEN",
Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">"
"<script type=\"text/javascript\">"
@ -3126,9 +3140,10 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
(unsigned) Gbl.Prefs.DateFormat,Txt_Today);
/***** Title and groups *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",Gbl.RowEvenOdd);
/* Title */
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">%s",
Gbl.RowEvenOdd,Match.Title);
fprintf (Gbl.F.Out,"<span class=\"ASG_TITLE\">%s</span>",Match.Title);
/* Groups whose students can answer this match */
if (Gbl.Crs.Grps.NumGrps)
@ -3155,40 +3170,60 @@ static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res,
/***** Get match data *****/
row = mysql_fetch_row (mysql_res);
/*
row[0] MchCod
row[1] GamCod
row[2] UNIX_TIMESTAMP(StartTime)
row[3] UNIX_TIMESTAMP(EndTime)
row[4] NOW() BETWEEN StartTime AND EndTime
row[5] UsrCod
row[6] Title
row[ 0] MchCod
row[ 1] GamCod
row[ 2] UsrCod
row[ 3] UNIX_TIMESTAMP(StartTime)
row[ 4] UNIX_TIMESTAMP(EndTime)
row[ 5] 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)
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)
Lay_ShowErrorAndExit ("Wrong code of game.");
/* Get start date (row[2] holds the start UTC time) */
Match->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[2]);
/* Get match teacher (row[2]) */
Match->UsrCod = Str_ConvertStrCodToLongCod (row[2]);
/* Get end date (row[3] holds the end UTC time) */
Match->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[3]);
/* Get start date (row[3] holds the start UTC time) */
Match->TimeUTC[Gam_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]);
/* Get whether the match is open or closed (row(4)) */
Match->Open = (row[4][0] == '1');
/* Get end date (row[4] holds the end UTC time) */
Match->TimeUTC[Gam_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]);
/* Get match player (row[5]) */
Match->UsrCod = Str_ConvertStrCodToLongCod (row[5]);
/* Get the title of the game (row[6]) */
if (row[6])
Str_Copy (Match->Title,row[6],
/* Get the title of the game (row[5]) */
if (row[5])
Str_Copy (Match->Title,row[5],
Gam_MAX_BYTES_TITLE);
else
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 *****/
MchCod = DB_QueryINSERTandReturnCode ("can not create match",
"INSERT gam_matches"
" (GamCod,StartTime,EndTime,UsrCod,Title)"
" (GamCod,UsrCod,StartTime,EndTime,Title,"
"QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)"
" VALUES"
" (%ld,NOW(),NOW(),%ld,'%s')",
" (%ld,%ld,NOW(),NOW(),'%s',"
"-1,-1,FROM_UNIXTIME(0),'N','N')",
Match->GamCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
Match->Title);
Match->Title);
/***** Create groups associated to the match *****/
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
@ -3488,69 +3525,36 @@ static long Gam_CreateMatch (struct Match *Match)
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 *******************/
/*****************************************************************************/
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 *****/
if (ShowingAnswers) // Show a question previously shown and its answers
DB_QueryUPDATE ("can not update match beeing played",
"UPDATE gam_playing"
" SET ShowingAnswers='Y'"
" WHERE MchCod=%ld"
" AND QstInd=%u AND QstCod=%ld", // Extra checks, not necessary
MchCod,QstInd,QstCod);
DB_QueryUPDATE ("can not update match being played",
"UPDATE gam_matches,games"
" SET gam_matches.EndTime=NOW(),"
"gam_matches.ShowingAnswers='Y'"
" WHERE gam_matches.MchCod=%ld"
" AND gam_matches.GamCod=games.GamCod"
" AND games.CrsCod=%ld", // Extra check
MchCod,Gbl.Hierarchy.Crs.CrsCod);
else // Show a question without answers
{
if (QstInd == 0) // 1st question beeing shown
DB_QueryINSERT ("can not create match beeing played",
"INSERT gam_playing"
" (MchCod,QstInd,QstCod,ShowingAnswers,MchStart,QstStart)"
" VALUES"
" (%ld,0,%ld,'N',NOW(),NOW())",
MchCod,QstCod);
else // 2nd, 3rd... question beeing shown
DB_QueryUPDATE ("can not update match beeing played",
"UPDATE gam_playing"
" SET QstInd=%u,QstCod=%ld,ShowingAnswers='N',QstStart=NOW()"
" 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);
DB_QueryUPDATE ("can not update match being played",
"UPDATE gam_matches,games"
" SET gam_matches.EndTime=NOW(),"
"gam_matches.QstInd=%d,"
"gam_matches.QstCod=%ld,"
"gam_matches.ShowingAnswers='N',"
"gam_matches.QstStartTime=NOW()"
" WHERE gam_matches.MchCod=%ld"
" AND gam_matches.GamCod=games.GamCod"
" AND games.CrsCod=%ld", // Extra check
QstInd,QstCod,
MchCod,Gbl.Hierarchy.Crs.CrsCod);
}
/*****************************************************************************/
@ -3673,7 +3677,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
if (ShowAnswers)
{
/* 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
/* Put button to show next question */
Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd);
@ -3773,8 +3777,15 @@ void Gam_MatchTchEnd (void)
if ((MchCod = Gam_GetParamMatchCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of match is missing.");
/***** Remove match being played *****/
Gam_RemoveMatchBeingPlayed (MchCod);
/***** Update match being played *****/
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 *****/
Ale_ShowAlert (Ale_INFO,"Partida finalizada."); // TODO: Need translation!!!!!
@ -3800,8 +3811,15 @@ void Gam_GetMatchBeingPlayed (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\">");
Gam_ShowQuestionBeingPlayed ();
Gam_ShowQuestionBeingPlayed (&Match);
fprintf (Gbl.F.Out,"</div>");
}
@ -3811,83 +3829,55 @@ void Gam_ShowNewMatchToMeAsStd (void)
void Gam_RefreshCurrentMatchStd (void)
{
if (Gbl.Session.IsOpen) // If session has been closed, do not write anything
/***** Get and show current question *****/
Gam_ShowQuestionBeingPlayed ();
struct Match Match;
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 ***************/
/*****************************************************************************/
static void Gam_ShowQuestionBeingPlayed (void)
static void Gam_ShowQuestionBeingPlayed (struct Match *Match)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
bool IBelongToGroups;
unsigned QstInd;
long QstCod;
bool GameIsPlaying;
bool ShowAnswers;
unsigned NumOptions;
unsigned NumOpt;
/***** Do I belong to valid groups to play this match? *****/
IBelongToGroups = Gbl.Usrs.Me.IBelongToCurrentCrs &&
Gam_CheckIfIPlayThisMatchBasedOnGrps (Gbl.Games.MchCodBeingPlayed);
Gam_CheckIfIPlayThisMatchBasedOnGrps (Match->MchCod);
if (!IBelongToGroups)
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 *****/
if (GameIsPlaying)
if (!Match->Status.Finished)
{
/***** Show question *****/
/* Write number of question */
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\">");
/* Write answers? */
if (ShowAnswers)
if (Match->Status.ShowAnswers)
{
if (Tst_CheckIfQuestionIsValidForGame (QstCod))
if (Tst_CheckIfQuestionIsValidForGame (Match->Status.QstCod))
{
/***** Start table *****/
Tbl_StartTableWide (8);
/***** Write answers *****/
NumOptions = Tst_GetNumAnswersQst (QstCod);
NumOptions = Tst_GetNumAnswersQst (Match->Status.QstCod);
for (NumOpt = 0;
NumOpt < NumOptions;
NumOpt++)