Merge pull request 'Update' (#7) from devel into main
|
@ -6,7 +6,7 @@
|
|||
<style type="text/css">
|
||||
body {
|
||||
color: $TEXT$;
|
||||
font-size: 23px;
|
||||
font-size: 19px;
|
||||
background-color: $BG$;
|
||||
}
|
||||
h1 {
|
||||
|
@ -24,7 +24,7 @@
|
|||
}
|
||||
code {
|
||||
color: $CODE$;
|
||||
font-size: 21px;
|
||||
font-size: 17px;
|
||||
padding-left:16px
|
||||
}
|
||||
i {
|
||||
|
@ -37,11 +37,14 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<br>
|
||||
<h1 align="center">Apache2</h1>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center"><br>Access logs format string</h2>
|
||||
<br>
|
||||
<h3>Configuration file</h3>
|
||||
<h3><br>Configuration file</h3>
|
||||
<br>
|
||||
<p>The configuration file should be located at:</p><br>
|
||||
<code>/etc/apache2/apache2.conf</code>
|
||||
|
@ -49,6 +52,7 @@
|
|||
<p>The line to configure access logs is the one starting with "<b>LogFormat</b>" followed by the list of fields codes.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Common logs formats</h3>
|
||||
<br>
|
||||
<p>Most commonly used format strings are:</p>
|
||||
|
@ -62,6 +66,7 @@
|
|||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Suggested logs formats</h3>
|
||||
<br>
|
||||
<p>A suggested format string, to allow using the complete set of functionalities of LogDoctor, is:</p><br>
|
||||
|
@ -71,12 +76,14 @@
|
|||
<code>LogFormat "%{sec}t \"%r\" %q %<s %I %O %D \"%{Referer}i\" \"%{Cookie}i\" \"%{User-agent}i\" %h" combined</code>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Note on custom format strings</h3>
|
||||
<br>
|
||||
<p>If you're using your own custom string, please keep in mind that parsing is not magic. When you define your own string, think about which characters can be there in a field and use separators accordingly to not conflict with the field itself.<br>
|
||||
As an example: an URI (<i>%U</i>) can't contain whitespaces, so it is safe to use a space to separe this field by the previous and next one. Instead, the User-Agent (*%{User-agent}i*) may contain spaces, as well as parenthesis, brackets, dashes, etc, so it's better to pick an appropriate separator (double-quotes are a good choice, since they get escaped while logging).</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Note on control-characters</h3>
|
||||
<br>
|
||||
<p>Although Apache2 does support some control-characters (<i>aka</i> escape sequences), it is reccomended to <b>not use them</b> inside format strings.<br>
|
||||
|
@ -86,9 +93,12 @@
|
|||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center"><br>Access logs format fields</h2>
|
||||
<br>
|
||||
<h3>Fields considered by LogDoctor</h3>
|
||||
<h3><br>Fields considered by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.</p>
|
||||
<br>
|
||||
|
@ -131,7 +141,8 @@
|
|||
<tr><td align="center" style="padding:10px">%X</td><td style="padding:10px">time representation</td></tr>
|
||||
<tr><td align="center" style="padding:10px">%y</td><td style="padding:10px">year, last two digits <i>(YY)</i></td></tr>
|
||||
<tr><td align="center" style="padding:10px">%Y</td><td style="padding:10px">year</td></tr>
|
||||
</table></td>
|
||||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<i>Note:</i> time formats <i>sec</i>, <i>msec</i> and <i>usec</i> can't be mixed together or with other formats.
|
||||
</tr>
|
||||
|
@ -216,6 +227,7 @@
|
|||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Fields discarded by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Any field than the ones above won't be considered by LogDoctor.<br>
|
||||
|
@ -223,6 +235,9 @@
|
|||
If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>References</h3>
|
||||
<br>
|
||||
<ul>
|
||||
|
|
|
@ -5,37 +5,46 @@
|
|||
<title>LogDoctor - Help</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
color: $TXT$;
|
||||
font-size: 23px;
|
||||
color: $TEXT$;
|
||||
font-size: 19px;
|
||||
background-color: $BG$;
|
||||
}
|
||||
h1 {
|
||||
color: $IP$;
|
||||
color: $H1$;
|
||||
}
|
||||
h2 {
|
||||
color: $BG$;
|
||||
background-color: $UA$;
|
||||
background-color: $H1$;
|
||||
}
|
||||
h3 {
|
||||
color: $T$;
|
||||
color: $H3$;
|
||||
}
|
||||
th,td {
|
||||
padding: 20px;
|
||||
}
|
||||
code {
|
||||
color: $PT$;
|
||||
font-size: 21px;
|
||||
color: $CODE$;
|
||||
font-size: 17px;
|
||||
padding-left:16px
|
||||
}
|
||||
i {
|
||||
color: $IT$;
|
||||
}
|
||||
a {
|
||||
color: $LINK$;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<br>
|
||||
<h1 align="center">IIS</h1>
|
||||
<br>
|
||||
<h2 align="center">Access logs format string</h2>
|
||||
<br>
|
||||
<h3>Configuration</h3>
|
||||
<br>
|
||||
<h2 align="center"><br>Access logs format string</h2>
|
||||
<br>
|
||||
<h3><br>Configuration</h3>
|
||||
<br>
|
||||
<p>The configuration file should be located at:</p><br>
|
||||
<code>C:\inetpub\logs\LogFiles\<YourSiteName></code>
|
||||
|
@ -45,22 +54,24 @@
|
|||
Once inside, click on <code>Logging</code> to edit the logs settings.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Logs format modules</h3>
|
||||
<br>
|
||||
<p>Available logs formats (supported by LogDoctor) are:</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li style="padding-bottom:10px"><i>IIS</i></li><br>
|
||||
<li style="padding-bottom:10px"><i>IIS</i></li>
|
||||
<p>Comma-separated values, can't be customized further. The file name is usually something like <code>u_in<DATE>.log</code></p>
|
||||
<br>
|
||||
<li style="padding-bottom:10px"><i>NCSA</i></li><br>
|
||||
<li style="padding-bottom:10px"><i>NCSA</i></li>
|
||||
<p>Whitespace-separated values, can't be customized further. The file name is usually something like <code>u_nc<DATE>.log</code></p>
|
||||
<br>
|
||||
<li style="padding-bottom:10px"><i>W3C</i></li><br>
|
||||
<li style="padding-bottom:10px"><i>W3C</i></li>
|
||||
<p>Whitespace-separated values, can be customized by selecting which fields to log. The file name is usually something like <code>u_ex<DATE>.log</code></p>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Suggested logs format</h3>
|
||||
<br>
|
||||
<p>The suggested logs module is the <i>W3C</i> format, which will allow using the complete set of functionalities of LogDoctor.</p>
|
||||
|
@ -68,6 +79,7 @@
|
|||
<code>date</code>, <code>time</code>, <code>cs-method</code>, <code>cs-uri-stem</code>, <code>cs-uri-query</code>, <code>c-ip</code>, <code>cs-version</code>, <code>cs(User-Agent)</code>, <code>cs(Cookie)</code>, <code>cs(Referer)</code>, <code>sc-status</code>, <code>sc-bytes</code>, <code>cs-bytes</code>, <code>time-taken</code>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Logs format strings</h3>
|
||||
<br>
|
||||
<p>Both the <i>IIS</i> and <i>NCSA</i> modules are standard, and thus LogDoctor doesn't need the <i>format string</i> to be specified.<br>
|
||||
|
@ -75,9 +87,12 @@
|
|||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center">W£C logs format fields</h2>
|
||||
<br>
|
||||
<h3>Fields considered by LogDoctor</h3>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center"><br>W3C logs format fields</h2>
|
||||
<br>
|
||||
<h3><br>Fields considered by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.</p>
|
||||
<br>
|
||||
|
@ -142,6 +157,7 @@
|
|||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Fields discarded by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Any field than the ones above won't be considered by LogDoctor.<br>
|
||||
|
@ -149,15 +165,17 @@
|
|||
If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>References</h3>
|
||||
<br>
|
||||
<ul>
|
||||
<li>Configure IIS logging:<br>
|
||||
<i style="color:$REQ$">https://docs.microsoft.com/en-us/iis/manage/provisioning-and-managing-iis/configure-logging-in-iis</i></li><br>
|
||||
<a style="color:$LINK$">https://docs.microsoft.com/en-us/iis/manage/provisioning-and-managing-iis/configure-logging-in-iis</a></li><br>
|
||||
<li>Logs format modules overview:<br>
|
||||
<i style="color:$REQ$">https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525807(v=vs.90)</i></li>
|
||||
<a style="color:$LINK$">https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525807(v=vs.90)</a></li><br>
|
||||
<li>The W3C log format:<br>
|
||||
<i style="color:$REQ$">https://docs.microsoft.com/en-us/windows/win32/http/w3c-logging</i></li>
|
||||
<a style="color:$LINK$">https://docs.microsoft.com/en-us/windows/win32/http/w3c-logging</a></li>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<style type="text/css">
|
||||
body {
|
||||
color: $TEXT$;
|
||||
font-size: 23px;
|
||||
font-size: 19px;
|
||||
background-color: $BG$;
|
||||
}
|
||||
h1 {
|
||||
|
@ -24,7 +24,7 @@
|
|||
}
|
||||
code {
|
||||
color: $CODE$;
|
||||
font-size: 21px;
|
||||
font-size: 17px;
|
||||
padding-left:16px
|
||||
}
|
||||
i {
|
||||
|
@ -37,11 +37,14 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<br>
|
||||
<h1 align="center">Nginx</h1>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center"><br>Access logs format string</h2>
|
||||
<br>
|
||||
<h3>Configuration file</h3>
|
||||
<h3><br>Configuration file</h3>
|
||||
<br>
|
||||
<p>The configuration file should be located at:</p><br>
|
||||
<code>/usr/local/etc/nginx/nginx.conf</code>
|
||||
|
@ -49,6 +52,7 @@
|
|||
<p>The line to configure access logs is the one starting with "<b>log_format main</b>" followed by the list of fields codes.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Default logs formats</h3>
|
||||
<br>
|
||||
<p>The default logs format string is:</p>
|
||||
|
@ -56,17 +60,20 @@
|
|||
<code>log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent"'</code>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Suggested logs format</h3>
|
||||
<br>
|
||||
<p>The suggested format string, to allow using the most of the functionalities of LogDoctor, is:</p><br>
|
||||
<code>log_format main '$time_iso8601 "$request" $status $request_length $bytes_sent $request_time "$http_referer" "$http_user_agent" $remote_addr'</code>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Note the format strings</h3>
|
||||
<br>
|
||||
<p>When copy-pasting the format string, please remove any identation (if present) and just paste the resulting format string only.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Note on control-characters</h3>
|
||||
<br>
|
||||
<p>Although Nginx does support some control-characters (<i>aka</i> escape sequences), it is reccomended to <b>not use them</b> inside format strings.<br>
|
||||
|
@ -76,9 +83,12 @@
|
|||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h2 align="center"><br>Access logs format fields</h2>
|
||||
<br>
|
||||
<h3>Fields considered by LogDoctor</h3>
|
||||
<h3><br>Fields considered by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.</p>
|
||||
<br>
|
||||
|
@ -159,6 +169,7 @@
|
|||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>Fields discarded by LogDoctor</h3>
|
||||
<br>
|
||||
<p>Any field than the ones above won't be considered by LogDoctor.<br>
|
||||
|
@ -166,6 +177,8 @@
|
|||
If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<h3>References</h3>
|
||||
<br>
|
||||
<ul>
|
||||
|
|
|
@ -101,6 +101,14 @@ set(PROJECT_SOURCES
|
|||
tools/crapnote/crapnote.h
|
||||
tools/crapnote/crapnote.cpp
|
||||
|
||||
games/crisscross.ui
|
||||
games/crisscross.h
|
||||
games/crisscross.cpp
|
||||
|
||||
games/snake.ui
|
||||
games/snake.h
|
||||
games/snake.cpp
|
||||
|
||||
resources/resources.qrc
|
||||
${TS_FILES}
|
||||
)
|
||||
|
|
347
logdoctor/games/crisscross.cpp
Normal file
|
@ -0,0 +1,347 @@
|
|||
|
||||
#include "crisscross.h"
|
||||
#include "ui_crisscross.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
CrissCross::CrissCross( const QPalette& style, QWidget* parent ) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::CrissCross)
|
||||
{
|
||||
this->ui->setupUi(this);
|
||||
this->setPalette( style );
|
||||
|
||||
// verify that one player is human and the other is not
|
||||
if ( !(p1_human^p2_human) ) {
|
||||
throw("Players identities error: "+std::to_string(p1_human)+" - "+std::to_string(p2_human));
|
||||
}
|
||||
|
||||
this->victory_sequence.reserve( 3 );
|
||||
|
||||
this->board_buttons[0] = this->ui->button_NW;
|
||||
this->board_buttons[1] = this->ui->button_N;
|
||||
this->board_buttons[2] = this->ui->button_NE;
|
||||
this->board_buttons[3] = this->ui->button_W;
|
||||
this->board_buttons[4] = this->ui->button_C;
|
||||
this->board_buttons[5] = this->ui->button_E;
|
||||
this->board_buttons[6] = this->ui->button_SW;
|
||||
this->board_buttons[7] = this->ui->button_S;
|
||||
this->board_buttons[8] = this->ui->button_SE;
|
||||
|
||||
if ( ! p1_human ) {
|
||||
// AI starts
|
||||
this->AI_playTurn();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CrissCross::~CrissCross()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
//// BOARD TILES ////
|
||||
void CrissCross::on_button_NW_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_NW->isFlat() ) {
|
||||
this->board[0] = this->p_turn;
|
||||
this->ui->button_NW->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_NW->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_N_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_N->isFlat() ) {
|
||||
this->board[1] = this->p_turn;
|
||||
this->ui->button_N->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_N->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_NE_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_NE->isFlat() ) {
|
||||
this->board[2] = this->p_turn;
|
||||
this->ui->button_NE->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_NE->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_W_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_W->isFlat() ) {
|
||||
this->board[3] = this->p_turn;
|
||||
this->ui->button_W->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_W->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_C_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_C->isFlat() ) {
|
||||
this->board[4] = this->p_turn;
|
||||
this->ui->button_C->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_C->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_E_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_E->isFlat() ) {
|
||||
this->board[5] = this->p_turn;
|
||||
this->ui->button_E->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_E->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_SW_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_SW->isFlat() ) {
|
||||
this->board[6] = this->p_turn;
|
||||
this->ui->button_SW->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_SW->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_S_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_S->isFlat() ) {
|
||||
this->board[7] = this->p_turn;
|
||||
this->ui->button_S->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_S->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::on_button_SE_clicked()
|
||||
{
|
||||
if ( ! this->ui->button_SE->isFlat() ) {
|
||||
this->board[8] = this->p_turn;
|
||||
this->ui->button_SE->setIcon( this->icons[ this->p_turn-1 ] );
|
||||
this->ui->button_SE->setFlat( true );
|
||||
this->endTurn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////
|
||||
//// TURN RELATED ////
|
||||
void CrissCross::endTurn()
|
||||
{
|
||||
if ( this->checkVictory() ) {
|
||||
// a player won!
|
||||
this->victory();
|
||||
} else {
|
||||
// nobody won yet
|
||||
if ( this->gameDraw() ) {
|
||||
// game is draw
|
||||
this->draw();
|
||||
} else {
|
||||
// change turn and keep playing
|
||||
this->nextTurn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrissCross::nextTurn()
|
||||
{
|
||||
switch ( this->p_turn ) {
|
||||
case 1:
|
||||
this->p_turn += 1;
|
||||
if ( ! this->p2_human ) {
|
||||
this->AI_playTurn();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
this->p_turn -= 1;
|
||||
if ( ! this->p1_human ) {
|
||||
this->AI_playTurn();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// wrong
|
||||
throw("Wrong turn: "+std::to_string(this->p_turn));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const bool CrissCross::checkVictory()
|
||||
{
|
||||
bool result = false;
|
||||
unsigned int streak;
|
||||
for ( const auto& sequence : this->sequences ) {
|
||||
streak = 0;
|
||||
for ( const auto& index : sequence ) {
|
||||
if ( this->board[ index ] == this->p_turn ) {
|
||||
streak ++;
|
||||
this->victory_sequence.push_back( index );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( streak == 3 ) {
|
||||
// victory
|
||||
result = true;
|
||||
break;
|
||||
} else {
|
||||
this->victory_sequence.clear();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CrissCross::victory()
|
||||
{
|
||||
// disable all buttons except the victory sequence ones
|
||||
bool disable;
|
||||
for ( unsigned int i=0; i<9; i++ ) {
|
||||
disable = true;
|
||||
for ( const auto& j : this->victory_sequence ) {
|
||||
if ( i == j ) {
|
||||
disable = false;
|
||||
break;
|
||||
} else if ( i < j ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->board_buttons[ i ]->setFlat( true );
|
||||
if ( disable ) {
|
||||
this->board_buttons[ i ]->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
// display a dialog
|
||||
QString message;
|
||||
if ( (this->p_turn == 1 && this->p1_human)
|
||||
|| (this->p_turn == 2 && this->p2_human) ) {
|
||||
// user won
|
||||
message = CrissCross::tr("You beated me!");
|
||||
} else {
|
||||
// AI won
|
||||
message = CrissCross::tr("This time you lost!");
|
||||
}
|
||||
QMessageBox::about(
|
||||
this,
|
||||
CrissCross::tr("Victory"),
|
||||
message );
|
||||
}
|
||||
|
||||
|
||||
const bool CrissCross::gameDraw()
|
||||
{
|
||||
bool result = false;
|
||||
unsigned int empty_tiles = 9;
|
||||
for ( const auto& tile : this->board ) {
|
||||
if ( tile > 0 ) {
|
||||
empty_tiles --;
|
||||
}
|
||||
}
|
||||
if ( empty_tiles == 0 ) {
|
||||
// no movement left
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CrissCross::draw()
|
||||
{
|
||||
// disable all buttons
|
||||
for ( const auto& button : this->board_buttons ) {
|
||||
button->setEnabled( false );
|
||||
}
|
||||
|
||||
// display a dialog
|
||||
QMessageBox::about(
|
||||
this,
|
||||
CrissCross::tr("Draw"),
|
||||
CrissCross::tr("Nice match") );
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
//// AI ////
|
||||
void CrissCross::AI_playTurn()
|
||||
{
|
||||
this->AI_updateWeights();
|
||||
emit this->board_buttons[ this->AI_makeChoice() ]->clicked();
|
||||
}
|
||||
|
||||
void CrissCross::AI_updateWeights()
|
||||
{
|
||||
// reset the weights
|
||||
for ( int i=0; i<9; i++ ) {
|
||||
this->board_weights[ i ] = 0;
|
||||
}
|
||||
// calculate the new weights
|
||||
unsigned int win_streak, lose_streak;
|
||||
std::vector<unsigned int> empty_tiles;
|
||||
for ( const auto& sequence : this->sequences ) {
|
||||
// reset data
|
||||
win_streak = lose_streak = 0;
|
||||
empty_tiles.clear();
|
||||
// check the tiles in the sequence
|
||||
for ( const auto& index : sequence ) {
|
||||
if ( this->board[ index ] == this->p_turn ) {
|
||||
win_streak ++;
|
||||
} else if ( this->board[ index ] > 0 ) {
|
||||
lose_streak ++;
|
||||
} else {
|
||||
empty_tiles.push_back( index );
|
||||
}
|
||||
}
|
||||
// set the new weight for the empty tiles
|
||||
const unsigned int new_weight = (win_streak>=lose_streak)
|
||||
? (win_streak==2) ? win_streak+2 : win_streak+1
|
||||
: lose_streak+1;
|
||||
for ( const auto& index : empty_tiles ) {
|
||||
if ( new_weight > this->board_weights[ index ] ) {
|
||||
this->board_weights[ index ] = new_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const unsigned int CrissCross::AI_makeChoice()
|
||||
{
|
||||
// get a list of the heaviest tiles
|
||||
std::vector<unsigned int> moves;
|
||||
unsigned int max_weight = 0;
|
||||
unsigned int index = 0;
|
||||
for ( const auto& weight : this->board_weights ) {
|
||||
if ( weight > max_weight ) {
|
||||
// heavier weight found
|
||||
max_weight = weight;
|
||||
moves.clear();
|
||||
moves.push_back( index );
|
||||
} else if ( weight == max_weight ) {
|
||||
// same weight
|
||||
moves.push_back( index );
|
||||
}/* else {
|
||||
// lighter weight
|
||||
;
|
||||
}*/
|
||||
index ++;
|
||||
}
|
||||
// decide the movement (or better, randomly pick one)
|
||||
unsigned int next_move;
|
||||
if ( max_weight == 0 ) {
|
||||
// first turn
|
||||
next_move = rand() % 9;
|
||||
} else {
|
||||
next_move = moves[ rand() % moves.size() ];
|
||||
}
|
||||
return next_move;
|
||||
}
|
96
logdoctor/games/crisscross.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
#ifndef CRISSCROSS_H
|
||||
#define CRISSCROSS_H
|
||||
|
||||
#include <QIcon>
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class CrissCross;
|
||||
}
|
||||
|
||||
class CrissCross : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CrissCross( const QPalette& style, QWidget* parent=nullptr );
|
||||
~CrissCross();
|
||||
|
||||
private slots:
|
||||
void on_button_NW_clicked();
|
||||
|
||||
void on_button_N_clicked();
|
||||
|
||||
void on_button_NE_clicked();
|
||||
|
||||
void on_button_W_clicked();
|
||||
|
||||
void on_button_C_clicked();
|
||||
|
||||
void on_button_E_clicked();
|
||||
|
||||
void on_button_SW_clicked();
|
||||
|
||||
void on_button_S_clicked();
|
||||
|
||||
void on_button_SE_clicked();
|
||||
|
||||
private:
|
||||
Ui::CrissCross *ui;
|
||||
|
||||
// player turn
|
||||
unsigned int p_turn = 1;
|
||||
|
||||
// players identity
|
||||
const bool p1_human = rand() %2;
|
||||
const bool p2_human = (p1_human) ? false : true;
|
||||
|
||||
// victory related
|
||||
std::vector<unsigned int> victory_sequence;
|
||||
|
||||
// game data
|
||||
unsigned int board[9] = {
|
||||
0,0,0,
|
||||
0,0,0,
|
||||
0,0,0
|
||||
};
|
||||
|
||||
QPushButton* board_buttons[9];
|
||||
|
||||
const QIcon icons[2] = {
|
||||
QIcon(":/games/games/o.png"),
|
||||
QIcon(":/games/games/x.png")
|
||||
};
|
||||
|
||||
const unsigned int sequences[8][3] = {
|
||||
{0,1,2},{3,4,5},{6,7,8}, // horizontal
|
||||
{0,3,6},{1,4,7},{2,5,8}, // vertical
|
||||
{0,4,8},{2,4,6} // diagonal
|
||||
};
|
||||
|
||||
// AI data
|
||||
unsigned int board_weights[9] = {
|
||||
1,1,1,
|
||||
1,1,1,
|
||||
1,1,1
|
||||
};
|
||||
|
||||
|
||||
// game methods
|
||||
void endTurn();
|
||||
void nextTurn();
|
||||
const bool isPlayerTurn();
|
||||
|
||||
const bool checkVictory();
|
||||
const bool gameDraw();
|
||||
void victory();
|
||||
void draw();
|
||||
|
||||
void AI_playTurn();
|
||||
void AI_updateWeights();
|
||||
const unsigned int AI_makeChoice();
|
||||
};
|
||||
|
||||
#endif // CRISSCROSS_H
|
535
logdoctor/games/crisscross.ui
Normal file
|
@ -0,0 +1,535 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CrissCross</class>
|
||||
<widget class="QWidget" name="CrissCross">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>512</width>
|
||||
<height>512</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>512</width>
|
||||
<height>512</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">LogDoctor - CrissCross</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources/resources.qrc">
|
||||
<normaloff>:/logo/logo/logdoctor.svg</normaloff>:/logo/logo/logdoctor.svg</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="button_NW">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="button_N">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="button_NE">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="Line" name="line_1">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="button_W">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Line" name="line_9">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="button_C">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="Line" name="line_10">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="button_E">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="Line" name="line_8">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="button_SW">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="Line" name="line_11">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QPushButton" name="button_S">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="Line" name="line_12">
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QPushButton" name="button_SE">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>104</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="spacer_Board_Right">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>38</width>
|
||||
<height>397</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="spacer_Board_Left">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>4</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="spacer_Board_Top">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>4</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="spacer_Board_Bottom">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>4</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
603
logdoctor/games/snake.cpp
Normal file
|
@ -0,0 +1,603 @@
|
|||
|
||||
#include "snake.h"
|
||||
#include "ui_snake.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
|
||||
Snake:: Snake(const QPalette& style, const QFont& term_font, QWidget* parent ) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::Snake)
|
||||
{
|
||||
this->ui->setupUi(this);
|
||||
|
||||
this->setPalette( style );
|
||||
QFont font = QFont( term_font );
|
||||
font.setPointSize( 64 );
|
||||
this->ui->button_Play->setFont( font );
|
||||
|
||||
this->field_scene = new QGraphicsScene( this );
|
||||
this->field_scene->setSceneRect( 0,0, 544, 544 );
|
||||
this->field_scene->setBackgroundBrush( Qt::black );
|
||||
// put water limits
|
||||
this->field_scene->addItem( new QGraphicsPixmapItem( this->img_water ) );
|
||||
// add the scene to the view
|
||||
this->ui->view_Field->setScene( this->field_scene );
|
||||
|
||||
// snake initial position
|
||||
const unsigned int head_x = (rand()%4)+6;
|
||||
const unsigned int head_y = (rand()%4)+6;
|
||||
if ( head_x > 15 || head_y > 15 ) {
|
||||
// should be unreachable
|
||||
throw("Unexpected initial position: ("+std::to_string(head_x)+","+std::to_string(head_y)+")");
|
||||
}
|
||||
|
||||
// snake initial direction
|
||||
const int rand_d = rand()%4;
|
||||
switch ( rand_d ) {
|
||||
case 0:
|
||||
this->head_direction = Direction::UP;
|
||||
break;
|
||||
case 1:
|
||||
this->head_direction = Direction::DOWN;
|
||||
break;
|
||||
case 2:
|
||||
this->head_direction = Direction::LEFT;
|
||||
break;
|
||||
case 3:
|
||||
this->head_direction = Direction::RIGHT;
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected initial direction: "+std::to_string(rand_d));
|
||||
}
|
||||
this->key_events.push( rand_d );
|
||||
|
||||
// build the body with a head
|
||||
this->snake.push_back(
|
||||
{ head_x, head_y,
|
||||
this->head_direction, this->head_direction,
|
||||
new QGraphicsPixmapItem( this->img_snakeHead ) }
|
||||
);
|
||||
this->field_scene->addItem( this->snake.front().image );
|
||||
this->snake.front().update( head_x, head_y, this->head_direction );
|
||||
// a body part
|
||||
this->increaseSnakeBody( true );
|
||||
// and a tail
|
||||
this->increaseSnakeBody( true );
|
||||
// et voila! a snake is born
|
||||
|
||||
// now put some food on the field for it to eat
|
||||
this->food = Food{ 0, 0, new QGraphicsPixmapItem( this->img_food ) };
|
||||
this->field_scene->addItem( this->food.image );
|
||||
this->spawnFood();
|
||||
|
||||
}
|
||||
|
||||
Snake::~Snake()
|
||||
{
|
||||
delete this->ui;
|
||||
delete this->field_scene;
|
||||
delete this->game_loop;
|
||||
}
|
||||
|
||||
|
||||
void Snake::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
// store the key pressed if needed
|
||||
if ( this->playing ) {
|
||||
switch ( event->key() ) {
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_W:
|
||||
if ( this->key_events.back() != 0 ) {
|
||||
this->key_events.push( 0 );
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
case Qt::Key_S:
|
||||
if ( this->key_events.back() != 1 ) {
|
||||
this->key_events.push( 1 );
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_A:
|
||||
if ( this->key_events.back() != 2 ) {
|
||||
this->key_events.push( 2 );
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_D:
|
||||
if ( this->key_events.back() != 3 ) {
|
||||
this->key_events.push( 3 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
//// MENU ////
|
||||
void Snake::on_button_Play_clicked()
|
||||
{
|
||||
// switch to game board
|
||||
this->ui->stackedWidget_GameDisplay->setCurrentIndex( 1 );
|
||||
// start playing
|
||||
this->game_loop = new QTimer(this);
|
||||
connect(this->game_loop, SIGNAL(timeout()), this, SLOT(processGameLogic()));
|
||||
this->game_loop->start(175);
|
||||
this->playing = true;
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
//// GAME ////
|
||||
void Snake::processGameLogic()
|
||||
{
|
||||
if ( game_over ) {
|
||||
this->game_loop->stop();
|
||||
this->playing = false;
|
||||
QMessageBox::about(
|
||||
this,
|
||||
Snake::tr("Game Over"),
|
||||
this->game_over_msg );
|
||||
} else {
|
||||
|
||||
|
||||
if ( this->key_events.size() > 0 ) {
|
||||
this->processNextKeyEvent();
|
||||
}
|
||||
// check for a possible collision of the head
|
||||
this->checkCollision();
|
||||
if ( ! this->game_over ) {
|
||||
// update snake position
|
||||
this->updateSnakePosition();
|
||||
if ( this->spawn_food ) {
|
||||
// increase the score
|
||||
this->increaseGameScore();
|
||||
// spawn food in a new position
|
||||
this->spawnFood();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Snake::processNextKeyEvent()
|
||||
{
|
||||
// update direction if needed
|
||||
switch ( this->key_events.front() ) {
|
||||
case 0: // up
|
||||
if ( this->head_direction != Direction::DOWN ) {
|
||||
this->head_direction = Direction::UP;
|
||||
}
|
||||
break;
|
||||
case 1: // down
|
||||
if ( this->head_direction != Direction::UP ) {
|
||||
this->head_direction = Direction::DOWN;
|
||||
}
|
||||
break;
|
||||
case 2: // left
|
||||
if ( this->head_direction != Direction::RIGHT ) {
|
||||
this->head_direction = Direction::LEFT;
|
||||
}
|
||||
break;
|
||||
case 3: // right
|
||||
if ( this->head_direction != Direction::LEFT ) {
|
||||
this->head_direction = Direction::RIGHT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this->key_events.pop();
|
||||
}
|
||||
|
||||
|
||||
void Snake::increaseGameScore()
|
||||
{
|
||||
this->game_score ++;
|
||||
this->ui->lcd_Score->setDigitCount( std::to_string(this->game_score).size() );
|
||||
this->ui->lcd_Score->display( this->game_score );
|
||||
}
|
||||
|
||||
|
||||
void Snake::spawnFood()
|
||||
{
|
||||
// pick a new random position
|
||||
unsigned int x, y;
|
||||
while (true) {
|
||||
x = rand() % 16;
|
||||
y = rand() % 16;
|
||||
// check it's actually inside the field
|
||||
if ( x < 16 && y < 16 ) {
|
||||
// check the tile is empty
|
||||
if ( x != this->food.x && y != food.y ) {
|
||||
if ( ! this->snakeInTile( x, y ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update to new position
|
||||
this->food.update( x, y );
|
||||
|
||||
// randomly rotate the image
|
||||
int rand_ = rand()%4;
|
||||
switch (rand_) {
|
||||
case 1:
|
||||
this->food.image->setPixmap(
|
||||
this->food.image->pixmap().transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
case 2:
|
||||
this->food.image->setPixmap(
|
||||
this->food.image->pixmap().transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
case 3:
|
||||
this->food.image->setPixmap(
|
||||
this->food.image->pixmap().transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// do not rotate
|
||||
break;
|
||||
}
|
||||
|
||||
this->spawn_food = false;
|
||||
}
|
||||
|
||||
|
||||
void Snake::updateSnakePosition( const bool& dry )
|
||||
{
|
||||
size_t i = 0,
|
||||
max_i = this->snake.size()-1;
|
||||
unsigned int new_x, prev_x, new_y, prev_y;
|
||||
Direction new_direction, prev_direction, prev_body_d;
|
||||
for ( BodyPart& bp : this->snake ) {
|
||||
if ( ! dry ) {
|
||||
// future position
|
||||
if ( i == 0 ) {
|
||||
// head doesn't follow any other part of the body
|
||||
switch ( this->head_direction ) {
|
||||
case Direction::UP:
|
||||
new_y = bp.y - 1;
|
||||
new_x = bp.x;
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
new_y = bp.y + 1;
|
||||
new_x = bp.x;
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
new_x = bp.x - 1;
|
||||
new_y = bp.y;
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
new_x = bp.x + 1;
|
||||
new_y = bp.y;
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(this->head_direction));
|
||||
}
|
||||
new_direction = this->head_direction;
|
||||
} else {
|
||||
// follow the previous part of the body
|
||||
new_x = prev_x;
|
||||
new_y = prev_y;
|
||||
new_direction = prev_direction;
|
||||
}
|
||||
// store for the next part
|
||||
prev_x = bp.x;
|
||||
prev_y = bp.y;
|
||||
prev_direction = bp.direction;
|
||||
|
||||
// update the body-part position
|
||||
bp.update( new_x, new_y, new_direction );
|
||||
}
|
||||
|
||||
// finally set the image to be shown
|
||||
switch ( bp.direction ) {
|
||||
|
||||
case Direction::UP:
|
||||
if ( i == 0 ) {
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeHead );
|
||||
} else if ( i == max_i ) {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail );
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
} else {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeBody );
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Direction::DOWN:
|
||||
if ( i == 0 ) {
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeHead.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
} else if ( i == max_i ) {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
} else {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeBody );
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Direction::LEFT:
|
||||
if ( i == 0 ) {
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeHead.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
} else if ( i == max_i ) {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail );
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
} else {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::LEFT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeBody.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( -90.0 ) ) );
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Direction::RIGHT:
|
||||
if ( i == 0 ) {
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeHead.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
} else if ( i == max_i ) {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail );
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeTail.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
} else {
|
||||
switch ( prev_body_d ) {
|
||||
case Direction::RIGHT:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeBody.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
case Direction::UP:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( 180.0 ) ) );
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
bp.image->setPixmap(
|
||||
this->img_snakeCurve.transformed(
|
||||
QTransform().rotate( 90.0 ) ) );
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(prev_body_d));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(bp.direction));
|
||||
}
|
||||
prev_body_d = bp.direction;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Snake::increaseSnakeBody( const bool& initial )
|
||||
{
|
||||
// build from the tail
|
||||
const BodyPart& tail = this->snake.back();
|
||||
unsigned int x = tail.x;
|
||||
unsigned int y = tail.y;
|
||||
const Direction d = tail.direction;
|
||||
const Direction ld = tail.prev_direction;
|
||||
if ( initial ) {
|
||||
// one tile back
|
||||
switch ( d ) {
|
||||
case Direction::UP:
|
||||
y ++;
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
y --;
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
x ++;
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
x --;
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(d));
|
||||
}
|
||||
}
|
||||
this->snake.push_back(
|
||||
{ x, y,
|
||||
d, ld,
|
||||
new QGraphicsPixmapItem( this->img_snakeTail ) }
|
||||
);
|
||||
this->updateSnakePosition( true );
|
||||
this->snake.back().update( x, y, d );
|
||||
this->field_scene->addItem( this->snake.back().image );
|
||||
}
|
||||
|
||||
|
||||
const bool Snake::snakeInTile( const unsigned int& x, const unsigned int& y )
|
||||
{
|
||||
bool result = false;
|
||||
for ( const BodyPart& bp : this->snake ) {
|
||||
if ( bp.x == x && bp.y == y ) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Snake::checkCollision()
|
||||
{
|
||||
unsigned int x = this->snake.front().x,
|
||||
y = this->snake.front().y;
|
||||
switch ( this->head_direction ) {
|
||||
case Direction::UP:
|
||||
y--;
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
y++;
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
x--;
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
x++;
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
throw("Unexpected direction: "+std::to_string(this->head_direction));
|
||||
}
|
||||
// check the upcoming movement
|
||||
if ( x > 15 || y > 15 ) {
|
||||
// collision with the field limits
|
||||
this->game_over = true;
|
||||
this->game_over_msg = Snake::tr("You fell in the water!");
|
||||
|
||||
} else if ( this->snakeInTile( x, y ) ) {
|
||||
// collision with another part of the snake
|
||||
this->game_over = true;
|
||||
this->game_over_msg = Snake::tr("You ate yourself!");
|
||||
|
||||
} else if ( x == this->food.x && y == this->food.y ) {
|
||||
// will eat
|
||||
if ( this->snake.size() < this->MAX_SNAKE_LENGTH ) {
|
||||
// below max size, increase the size
|
||||
this->increaseSnakeBody();
|
||||
} else {
|
||||
// max size reached, increase speed
|
||||
const int interval = this->game_loop->interval();
|
||||
if ( interval > 50 ) {
|
||||
this->game_loop->setInterval( interval - 5 );
|
||||
}
|
||||
}
|
||||
this->spawn_food = true;
|
||||
}
|
||||
}
|
119
logdoctor/games/snake.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
#ifndef SNAKE_H
|
||||
#define SNAKE_H
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Snake;
|
||||
}
|
||||
|
||||
class Snake : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Snake( const QPalette& style, const QFont& term_font, QWidget* parent=nullptr );
|
||||
~Snake();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_button_Play_clicked();
|
||||
|
||||
void processGameLogic();
|
||||
|
||||
private:
|
||||
Ui::Snake *ui;
|
||||
|
||||
void keyPressEvent( QKeyEvent* event ) override;
|
||||
std::queue<unsigned short> key_events;
|
||||
void processNextKeyEvent();
|
||||
|
||||
bool playing = false;
|
||||
QTimer* game_loop = new QTimer();
|
||||
bool game_over = false;
|
||||
QString game_over_msg;
|
||||
|
||||
// graphics
|
||||
QGraphicsScene* field_scene;
|
||||
|
||||
QPixmap img_water = QPixmap(":/games/games/water.png");
|
||||
|
||||
QPixmap img_food = QPixmap(":/games/games/food.png");
|
||||
|
||||
QPixmap img_snakeHead = QPixmap(":/games/games/head.png");
|
||||
QPixmap img_snakeTail = QPixmap(":/games/games/tail.png");
|
||||
QPixmap img_snakeBody = QPixmap(":/games/games/body_s.png");
|
||||
QPixmap img_snakeCurve = QPixmap(":/games/games/body_c.png");
|
||||
|
||||
|
||||
// snake
|
||||
const unsigned int MAX_SNAKE_LENGTH = 64;
|
||||
|
||||
enum Direction {
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
Direction head_direction;
|
||||
|
||||
struct BodyPart {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
Direction direction;
|
||||
Direction prev_direction;
|
||||
QGraphicsPixmapItem* image;
|
||||
void update( const unsigned int& new_x, const unsigned int& new_y, const Direction& new_direction ) {
|
||||
this->x = new_x;
|
||||
this->y = new_y;
|
||||
this->image->setOffset( 16+(new_x*32), 16+(new_y*32) );
|
||||
this->prev_direction = this->direction;
|
||||
this->direction = new_direction;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<BodyPart> snake;
|
||||
|
||||
const bool snakeInTile( const unsigned int& x, const unsigned int& y );
|
||||
|
||||
void increaseSnakeBody( const bool& initial=false );
|
||||
|
||||
void updateSnakePosition( const bool& dry=false );
|
||||
|
||||
void checkCollision();
|
||||
|
||||
|
||||
// food
|
||||
struct Food {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
QGraphicsPixmapItem* image;
|
||||
void update( const unsigned int& new_x, const unsigned int& new_y ) {
|
||||
this->x = new_x;
|
||||
this->y = new_y;
|
||||
this->image->setOffset( 16+(new_x*32), 16+(new_y*32) );
|
||||
}
|
||||
};
|
||||
|
||||
Food food;
|
||||
|
||||
void spawnFood();
|
||||
bool spawn_food = true;
|
||||
|
||||
|
||||
// score
|
||||
int game_score = 0;
|
||||
|
||||
void increaseGameScore();
|
||||
};
|
||||
|
||||
#endif // SNAKE_H
|
297
logdoctor/games/snake.ui
Normal file
|
@ -0,0 +1,297 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Snake</class>
|
||||
<widget class="QWidget" name="Snake">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>594</width>
|
||||
<height>666</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>594</width>
|
||||
<height>666</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">LogDoctor - Snake</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normalon>:/logo/logo/logdoctor.svg</normalon>
|
||||
</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>529</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>590</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>590</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>529</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QStackedWidget" name="stackedWidget_GameDisplay">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>564</width>
|
||||
<height>634</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>564</width>
|
||||
<height>634</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="stackedPage_GameMenu">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QPushButton" name="button_Play">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>256</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>64</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PLAY</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>253</width>
|
||||
<height>234</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>253</width>
|
||||
<height>234</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>135</width>
|
||||
<height>125</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>135</width>
|
||||
<height>125</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stackedPage_GameBoard">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_Score">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>544</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>544</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLCDNumber" name="lcd_Score">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="digitCount">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="intValue" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="view_Field">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>544</width>
|
||||
<height>544</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>544</width>
|
||||
<height>544</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
|
|
@ -2,9 +2,15 @@
|
|||
#include "mainwindow.h"
|
||||
#include "./ui_mainwindow.h"
|
||||
|
||||
#include "modules/exceptions.h"
|
||||
|
||||
#include "utilities/checks.h"
|
||||
#include "utilities/colors.h"
|
||||
#include "utilities/gzip.h"
|
||||
#include "utilities/io.h"
|
||||
#include "utilities/rtf.h"
|
||||
|
||||
#include "modules/dialogs.h"
|
||||
#include "modules/exceptions.h"
|
||||
#include "modules/shared.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -103,6 +109,9 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
// utilities
|
||||
connect( this->ui->actionInfos, &QAction::triggered, this, &MainWindow::menu_actionInfos_triggered );
|
||||
connect( this->ui->actionCheckUpdates, &QAction::triggered, this, &MainWindow::menu_actionCheckUpdates_triggered );
|
||||
// games
|
||||
connect( this->ui->actionCrissCross, &QAction::triggered, this, &MainWindow::menu_actionCrissCross_triggered );
|
||||
connect( this->ui->actionSnake, &QAction::triggered, this, &MainWindow::menu_actionSnake_triggered );
|
||||
|
||||
|
||||
/////////////////
|
||||
|
@ -239,7 +248,8 @@ MainWindow::~MainWindow()
|
|||
delete this->craphelp;
|
||||
delete this->crapnote;
|
||||
delete this->crapinfo;
|
||||
//delete this->translator;
|
||||
delete this->crisscross;
|
||||
delete this->snake;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent( QCloseEvent *event )
|
||||
|
@ -267,24 +277,24 @@ void MainWindow::defineOSspec()
|
|||
// unix-like
|
||||
/*this->configs_path = home_path + "/.config/LogDoctor/logdoctor.conf";
|
||||
this->logdoc_path = home_path + "/.local/share/LogDoctor";*/
|
||||
this->db_data_path = logdoc_path;
|
||||
this->db_hashes_path = logdoc_path;
|
||||
this->db_data_path = this->logdoc_path;
|
||||
this->db_hashes_path = this->logdoc_path;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// windows
|
||||
/*this->configs_path = home_path + "/AppData/Local/LogDoctor/logdoctor.conf";
|
||||
this->logdoc_path = home_path + "/AppData/Local/LogDoctor";*/
|
||||
this->db_data_path = logdoc_path;
|
||||
this->db_hashes_path = logdoc_path;
|
||||
this->db_data_path = this->logdoc_path;
|
||||
this->db_hashes_path = this->logdoc_path;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// darwin-based
|
||||
/*this->configs_path = home_path + "/Lybrary/Preferences/LogDoctor/logdoctor.conf";
|
||||
this->logdoc_path = home_path + "/Lybrary/Application Support/LogDoctor";*/
|
||||
this->db_data_path = logdoc_path;
|
||||
this->db_hashes_path = logdoc_path;
|
||||
this->db_data_path = this->logdoc_path;
|
||||
this->db_hashes_path = this->logdoc_path;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -599,13 +609,13 @@ void MainWindow::readConfigs()
|
|||
}*/
|
||||
}
|
||||
|
||||
} catch ( const std::ios_base::failure/*& err*/ ) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed reading
|
||||
proceed = false;
|
||||
err_msg = DialogSec::tr("An error occured while reading the configuration file");
|
||||
} catch ( const LogFormatException ) {
|
||||
} catch ( const LogFormatException& ) {
|
||||
proceed = false; // message already shown
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
proceed = false;
|
||||
err_msg = QString("%1:\n%2").arg(
|
||||
DialogSec::tr("One of the lists has an invalid item"),
|
||||
|
@ -804,7 +814,7 @@ void MainWindow::writeConfigs()
|
|||
try {
|
||||
IOutils::writeOnFile( this->configs_path, configs );
|
||||
|
||||
} catch (const std::ios_base::failure& err) {
|
||||
} catch ( const std::ios_base::failure&/* err*/ ) {
|
||||
// failed writing
|
||||
DialogSec::errGeneric( DialogSec::tr("An error occured while writing the configuration file") );
|
||||
} catch (...) {
|
||||
|
@ -1370,10 +1380,10 @@ const QString MainWindow::printableTime( const int& secs_ )
|
|||
//////////////
|
||||
//// HELP ////
|
||||
//////////////
|
||||
void MainWindow::showHelp( const std::string& filename )
|
||||
void MainWindow::showHelp( const std::string& file_name )
|
||||
{
|
||||
const std::string link = "https://github.com/elB4RTO/LogDoctor/tree/main/installation_stuff/logdocdata/help/";
|
||||
const std::string path = this->logdoc_path+"/help/"+this->language+"/"+filename+".html";
|
||||
const std::string path = this->logdoc_path+"/help/"+this->language+"/"+file_name+".html";
|
||||
if ( IOutils::exists( path ) ) {
|
||||
if ( IOutils::isFile( path ) ) {
|
||||
if ( IOutils::checkFile( path, true ) ) {
|
||||
|
@ -1469,18 +1479,18 @@ void MainWindow::menu_actionBlockNote_triggered()
|
|||
|
||||
void MainWindow::menu_actionInfos_triggered()
|
||||
{
|
||||
std::string version = std::to_string( this->version );
|
||||
size_t cut = version.find('.');
|
||||
std::string version_ = std::to_string( this->version );
|
||||
size_t cut = version_.find('.');
|
||||
if ( cut == std::string::npos ) {
|
||||
cut = version.find(',');
|
||||
cut = version_.find(',');
|
||||
if ( cut == std::string::npos ) {
|
||||
cut = version.size()-3;
|
||||
cut = version_.size()-3;
|
||||
}
|
||||
}
|
||||
version = version.substr( 0, cut+3 );
|
||||
version_ = version_.substr( 0, cut+3 );
|
||||
delete this->crapinfo;
|
||||
this->crapinfo = new Crapinfo(
|
||||
QString::fromStdString( version ),
|
||||
QString::fromStdString( version_ ),
|
||||
QString::fromStdString( this->resolvePath( "./" ) ),
|
||||
QString::fromStdString( this->logdoc_path ),
|
||||
QString::fromStdString( this->configs_path ) );
|
||||
|
@ -1492,6 +1502,31 @@ void MainWindow::menu_actionCheckUpdates_triggered()
|
|||
this->crapup.versionCheck( this->version, this->dialogs_level );
|
||||
}
|
||||
|
||||
// play a game
|
||||
void MainWindow::menu_actionCrissCross_triggered()
|
||||
{
|
||||
if ( this->crisscross->isVisible() ) {
|
||||
this->crisscross->activateWindow();
|
||||
|
||||
} else {
|
||||
delete this->crisscross;
|
||||
this->crisscross = new CrissCross( this->palette() );
|
||||
this->crisscross->show();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::menu_actionSnake_triggered()
|
||||
{
|
||||
if ( this->snake->isVisible() ) {
|
||||
this->snake->activateWindow();
|
||||
|
||||
} else {
|
||||
delete this->snake;
|
||||
this->snake = new Snake( this->palette(), this->FONTS.at("script") );
|
||||
this->snake->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
//// DB ////
|
||||
|
@ -1723,7 +1758,7 @@ void MainWindow::on_button_LogFiles_ViewFile_clicked()
|
|||
item = this->craplog.getLogFileItem(
|
||||
this->ui->listLogFiles->selectedItems().takeFirst()->text(0) );
|
||||
|
||||
} catch (const GenericException& e) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed to find file
|
||||
proceed = false;
|
||||
DialogSec::errFileNotFound( QString::fromStdString( item.path ), true );
|
||||
|
@ -1778,9 +1813,9 @@ void MainWindow::on_button_LogFiles_ViewFile_clicked()
|
|||
// try reading as gzip compressed file
|
||||
GZutils::readFile( item.path, content );
|
||||
|
||||
} catch (const GenericException& e) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing file pointer
|
||||
throw e;
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
// failed as gzip, try as text file
|
||||
|
@ -1790,7 +1825,7 @@ void MainWindow::on_button_LogFiles_ViewFile_clicked()
|
|||
IOutils::readFile( item.path, content );
|
||||
}
|
||||
|
||||
} catch (const GenericException/*& e*/) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing gzip file pointer
|
||||
proceed = false;
|
||||
// >> e.what() << //
|
||||
|
@ -1798,7 +1833,7 @@ void MainWindow::on_button_LogFiles_ViewFile_clicked()
|
|||
DialogSec::tr("Failed to read gzipped file"),
|
||||
item.name) );
|
||||
|
||||
/*} catch (const std::ios_base::failure& err) {
|
||||
/*} catch ( const std::ios_base::failure& err ) {
|
||||
// failed reading as text
|
||||
proceed = false;
|
||||
// >> err.what() << //
|
||||
|
@ -3501,7 +3536,7 @@ void MainWindow::on_button_ConfApache_Warnlist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfApache_Warnlist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -3639,7 +3674,7 @@ void MainWindow::on_button_ConfApache_Blacklist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfApache_Blacklist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -3850,7 +3885,7 @@ void MainWindow::on_button_ConfNginx_Warnlist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfNginx_Warnlist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -3988,7 +4023,7 @@ void MainWindow::on_button_ConfNginx_Blacklist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfNginx_Blacklist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -4251,7 +4286,7 @@ void MainWindow::on_button_ConfIis_Warnlist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfIis_Warnlist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -4389,7 +4424,7 @@ void MainWindow::on_button_ConfIis_Blacklist_Add_clicked()
|
|||
this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ),
|
||||
item.toStdString() );
|
||||
this->ui->list_ConfIis_Blacklist_List->addItem( item );
|
||||
} catch ( const BWlistException ) {
|
||||
} catch ( const BWlistException& ) {
|
||||
DialogSec::warnInvalidItemBW();
|
||||
return;
|
||||
}
|
||||
|
@ -4465,5 +4500,3 @@ void MainWindow::on_button_ConfIis_Blacklist_Down_clicked()
|
|||
this->ui->list_ConfIis_Blacklist_List->item( i )->setSelected( true );
|
||||
this->ui->list_ConfIis_Blacklist_List->setFocus();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,15 +12,8 @@
|
|||
#include <QTreeWidget>
|
||||
#include <QChartView>
|
||||
|
||||
#include "utilities/checks.h"
|
||||
#include "utilities/colors.h"
|
||||
#include "utilities/io.h"
|
||||
#include "utilities/rtf.h"
|
||||
#include "utilities/strings.h"
|
||||
#include "utilities/vectors.h"
|
||||
|
||||
#include "modules/shared.h"
|
||||
#include "modules/dialogs.h"
|
||||
#include "modules/tb.h"
|
||||
|
||||
#include "modules/craplog/craplog.h"
|
||||
|
@ -31,6 +24,9 @@
|
|||
|
||||
#include "tools/crapnote/crapnote.h"
|
||||
|
||||
#include "games/crisscross.h"
|
||||
#include "games/snake.h"
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
|
@ -458,6 +454,12 @@ private slots:
|
|||
|
||||
void menu_actionCheckUpdates_triggered();
|
||||
|
||||
//// TOOLS ////
|
||||
|
||||
void menu_actionCrissCross_triggered();
|
||||
|
||||
void menu_actionSnake_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
|
@ -471,21 +473,21 @@ private:
|
|||
// operating system
|
||||
const std::string home_path = StringOps::rstrip( QStandardPaths::locate( QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory ).toStdString(), "/" );
|
||||
// 1: linux, 2:windows, 3:mac
|
||||
#if defined( Q_OS_UNIX )
|
||||
// Unix-like systems: Linux, BSD and SysV
|
||||
const unsigned int OS = 1;
|
||||
const std::string configs_path = this->home_path + "/.config/LogDoctor/logdoctor.conf";
|
||||
const std::string logdoc_path = this->home_path + "/.local/share/LogDoctor";
|
||||
#if defined( Q_OS_DARWIN )
|
||||
// Darwin-based systems: macOS, iOS, watchOS and tvOS.
|
||||
const unsigned int OS = 3;
|
||||
const std::string configs_path = this->home_path + "/Lybrary/Preferences/LogDoctor/logdoctor.conf";
|
||||
const std::string logdoc_path = this->home_path + "/Lybrary/Application Support/LogDoctor";
|
||||
#elif defined( Q_OS_WIN )
|
||||
// Microsoft Windows systems
|
||||
const unsigned int OS = 2;
|
||||
const std::string configs_path = this->home_path + "/AppData/Local/LogDoctor/logdoctor.conf";
|
||||
const std::string logdoc_path = this->home_path + "/AppData/Local/LogDoctor";
|
||||
#elif defined( Q_OS_DARWIN )
|
||||
// Darwin-based systems: macOS, iOS, watchOS and tvOS.
|
||||
const unsigned int OS = 3;
|
||||
const std::string configs_path = this->home_path + "/Lybrary/Preferences/LogDoctor/logdoctor.conf";
|
||||
const std::string logdoc_path = this->home_path + "/Lybrary/Application Support/LogDoctor";
|
||||
#elif defined( Q_OS_UNIX )
|
||||
// Unix-like systems: Linux, BSD and SysV
|
||||
const unsigned int OS = 1;
|
||||
const std::string configs_path = this->home_path + "/.config/LogDoctor/logdoctor.conf";
|
||||
const std::string logdoc_path = this->home_path + "/.local/share/LogDoctor";
|
||||
#else
|
||||
#error "System not supported"
|
||||
#endif
|
||||
|
@ -665,5 +667,12 @@ private:
|
|||
//////////////////
|
||||
Crapinfo* crapinfo = new Crapinfo("","","","");
|
||||
|
||||
|
||||
///////////////////
|
||||
//// CRAPGAMES ////
|
||||
///////////////////
|
||||
CrissCross* crisscross = new CrissCross( QPalette() );
|
||||
Snake* snake = new Snake( QPalette(), QFont() );
|
||||
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
@ -232,6 +232,8 @@
|
|||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'Noto Sans'; font-size:16pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</property>
|
||||
|
@ -2516,7 +2518,7 @@ Use '!', '=','<' or '>' to declare what to use</string>
|
|||
<widget class="QWidget" name="scrollAreaContent_StatsCount">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<x>13</x>
|
||||
<y>0</y>
|
||||
<width>263</width>
|
||||
<height>402</height>
|
||||
|
@ -6139,6 +6141,8 @@ With numbers, use '!', '=','<' or '>' to declare what to use</string>
|
|||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'Noto Sans'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</property>
|
||||
|
@ -7246,7 +7250,7 @@ hr { height: 1px; border-width: 0; }
|
|||
</font>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
|
@ -7525,7 +7529,7 @@ Any field not considered by LogDoctor will apear as 'DISCARDED'</string>
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<width>62</width>
|
||||
<height>54</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -8526,7 +8530,7 @@ Any field not considered by LogDoctor will apear as 'DISCARDED'</string>
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<width>62</width>
|
||||
<height>54</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -9605,7 +9609,7 @@ Any field not considered by LogDoctor will apear as 'DISCARDED'</string>
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<width>62</width>
|
||||
<height>54</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -10364,9 +10368,18 @@ Fields marked as 'DISCARDED' got parsed correctly, but are not considered by Log
|
|||
</property>
|
||||
<addaction name="actionBlockNote"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuGames">
|
||||
<property name="title">
|
||||
<string>Games</string>
|
||||
</property>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCrissCross"/>
|
||||
<addaction name="actionSnake"/>
|
||||
</widget>
|
||||
<addaction name="menuLanguage"/>
|
||||
<addaction name="menuTools"/>
|
||||
<addaction name="menuUtilities"/>
|
||||
<addaction name="menuGames"/>
|
||||
</widget>
|
||||
<action name="actionCrapnote">
|
||||
<property name="text">
|
||||
|
@ -10457,6 +10470,22 @@ Fields marked as 'DISCARDED' got parsed correctly, but are not considered by Log
|
|||
<string>Open a block-note like window to write temporary text</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCrissCross">
|
||||
<property name="text">
|
||||
<string>CrissCross</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Play CrissCross</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSnake">
|
||||
<property name="text">
|
||||
<string>Snake</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Play Snake</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Craphelp;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Crapinfo;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "utilities/checks.h"
|
||||
#include "utilities/gzip.h"
|
||||
#include "utilities/io.h"
|
||||
#include "utilities/strings.h"
|
||||
|
||||
#include "modules/dialogs.h"
|
||||
#include "modules/exceptions.h"
|
||||
|
@ -446,18 +447,6 @@ const Craplog::LogFile& Craplog::getLogFileItem( const QString& file_name )
|
|||
}
|
||||
|
||||
|
||||
// return the path of the file matching the given name
|
||||
/*const std::string& Craplog::getLogFilePath( const QString& file_name )
|
||||
{
|
||||
for ( const Craplog::LogFile& item : this->logs_list ) {
|
||||
if ( item.name == file_name ) {
|
||||
return item.path;
|
||||
}
|
||||
}
|
||||
// should be unreachable
|
||||
throw GenericException("File item not found");
|
||||
}*/
|
||||
|
||||
// set a file as selected
|
||||
const bool Craplog::setLogFileSelected( const QString& file_name )
|
||||
{
|
||||
|
@ -924,9 +913,9 @@ void Craplog::joinLogLines()
|
|||
// try as gzip compressed archive first
|
||||
GZutils::readFile( file.path, aux );
|
||||
|
||||
} catch ( const GenericException& e ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing file pointer
|
||||
throw e;
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
// fallback on reading as normal file
|
||||
|
@ -941,14 +930,14 @@ void Craplog::joinLogLines()
|
|||
}
|
||||
|
||||
// re-catched in run()
|
||||
} catch ( const GenericException ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing gzip file pointer
|
||||
throw GenericException( QString("%1:\n%2").arg(
|
||||
DialogSec::tr("An error accured while reading the gzipped file"),
|
||||
QString::fromStdString( file.path )
|
||||
).toStdString() );
|
||||
|
||||
} catch (const std::ios_base::failure& err) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed reading as text
|
||||
throw GenericException( QString("%1:\n%2").arg(
|
||||
DialogSec::tr("An error accured while reading the file"),
|
||||
|
@ -1127,23 +1116,6 @@ const QString Craplog::printableSize( const unsigned& bytes )
|
|||
}
|
||||
|
||||
|
||||
/*const std::vector<int> Craplog::calcDayTraffic()
|
||||
{
|
||||
std::vector<int> traffic = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
if ( this->data_collection.size() > 0 ) {
|
||||
for ( const auto& data : this->data_collection ) {
|
||||
if ( data.find( 4 ) != data.end() ) {
|
||||
try {
|
||||
traffic.at( std::stoi(data.at(4)) ) ++;
|
||||
} catch (...) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return traffic;
|
||||
}*/
|
||||
|
||||
void Craplog::makeCharts( const QChart::ChartTheme& theme, const std::unordered_map<std::string, QFont>& fonts, QChartView* size_chart )
|
||||
{
|
||||
const QString
|
||||
|
@ -1151,9 +1123,7 @@ void Craplog::makeCharts( const QChart::ChartTheme& theme, const std::unordered_
|
|||
ignored_slice_name = TR::tr("Ignored"),
|
||||
parsed_slice_name = TR::tr("Parsed"),
|
||||
warning_slice_name = TR::tr("Warnings"),
|
||||
blacklisted_slice_name = TR::tr("Blacklisted");/*,
|
||||
traffic_chart_name = TR::tr("Time of Day Logs Traffic Ensemble"),
|
||||
access_bar_name = TR::tr("Access Logs");*/
|
||||
blacklisted_slice_name = TR::tr("Blacklisted");
|
||||
|
||||
// logs size donut chart
|
||||
QPieSeries *parsedSize_donut = new QPieSeries();
|
||||
|
@ -1186,10 +1156,6 @@ void Craplog::makeCharts( const QChart::ChartTheme& theme, const std::unordered_
|
|||
sizeBreakdown->addBreakdownSeries( parsedSize_donut, Qt::GlobalColor::darkCyan, fonts.at("main_small") );
|
||||
sizeBreakdown->addBreakdownSeries( ignoredSize_donut, Qt::GlobalColor::gray, fonts.at("main_small") );
|
||||
} else {
|
||||
/*sizeBreakdown->addBreakdownSeries( parsedSize_donut, Qt::GlobalColor::white, fonts.at("main_small") );
|
||||
parsedSize_donut->setVisible( false );
|
||||
sizeBreakdown->addBreakdownSeries( ignoredSize_donut, Qt::GlobalColor::white, fonts.at("main_small") );
|
||||
ignoredSize_donut->setVisible( false );*/
|
||||
sizeBreakdown->legend()->setVisible( false );
|
||||
sizeBreakdown->setTitle("");
|
||||
}
|
||||
|
@ -1197,56 +1163,4 @@ void Craplog::makeCharts( const QChart::ChartTheme& theme, const std::unordered_
|
|||
|
||||
size_chart->setChart( sizeBreakdown );
|
||||
size_chart->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
|
||||
// logs traffic bars chart
|
||||
/*QColor col;
|
||||
QBarSet *access_bars = new QBarSet( access_bar_name );
|
||||
col = Qt::GlobalColor::darkCyan;
|
||||
access_bars->setColor( col.lighter( 130 ) );
|
||||
|
||||
int max_traf = 0;
|
||||
for ( const int& tfc : this->calcDayTraffic() ) {
|
||||
*access_bars << tfc;
|
||||
if ( tfc > max_traf ) {
|
||||
max_traf = tfc;
|
||||
}
|
||||
}
|
||||
|
||||
QBarSeries *bars = new QBarSeries();
|
||||
bars->append( access_bars );
|
||||
|
||||
QChart *t_chart = new QChart();
|
||||
t_chart->setTheme( theme );
|
||||
t_chart->addSeries( bars );
|
||||
t_chart->setTitle( traffic_chart_name );
|
||||
t_chart->setTitleFont( fonts.at("main") );
|
||||
t_chart->legend()->setFont( fonts.at("main_small") );
|
||||
t_chart->setAnimationOptions( QChart::SeriesAnimations );
|
||||
//t_chart->setBackgroundBrush( Qt::darkGray );
|
||||
|
||||
QStringList categories;
|
||||
categories << "00" << "01" << "02" << "03" << "04" << "05" << "06" << "07" << "08" << "09" << "10" << "11"
|
||||
<< "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20" << "21" << "22" << "23";
|
||||
|
||||
QBarCategoryAxis *axisX = new QBarCategoryAxis();
|
||||
axisX->append( categories );
|
||||
axisX->setLabelsFont( fonts.at( "main_small" ) );
|
||||
t_chart->addAxis( axisX, Qt::AlignBottom );
|
||||
bars->attachAxis( axisX );
|
||||
|
||||
QValueAxis *axisY = new QValueAxis();
|
||||
axisY->setLabelFormat( "%d" );
|
||||
axisY->setRange( 0, max_traf );
|
||||
axisY->setLabelsFont( fonts.at( "main_small" ) );
|
||||
t_chart->addAxis( axisY, Qt::AlignLeft );
|
||||
bars->attachAxis( axisY) ;
|
||||
|
||||
t_chart->legend()->setVisible( true );
|
||||
t_chart->legend()->setAlignment( Qt::AlignBottom );
|
||||
|
||||
traf_chart->setChart( t_chart );
|
||||
traf_chart->setRenderHint( QPainter::Antialiasing );*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
setWarnlist( const int& web_server_id, const int& log_field_id, const std::vector<std::string>& new_list );
|
||||
void blacklistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ),
|
||||
warnlistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ),
|
||||
blacklistRemove( const int& web_server_id, const int& log_field_id, const std::string& new_item ),
|
||||
blacklistRemove( const int& web_server_id, const int& log_field_id, const std::string& item ),
|
||||
warnlistRemove( const int& web_server_id, const int& log_field_id, const std::string& item );
|
||||
const int
|
||||
blacklistMoveUp( const int& web_server_id, const int& log_field_id, const std::string& item ),
|
||||
|
|
|
@ -125,12 +125,6 @@ const std::vector<std::string> DateTimeOps::processDateTime( const std::string&
|
|||
QDateTime e = QDateTime::fromSecsSinceEpoch( std::stoi( datetime ) );
|
||||
datetime = e.toString( "yyyy-MM-dd HH:mm:ss" ).toStdString();
|
||||
|
||||
/*const char* c = datetime.c_str();
|
||||
struct tm t;
|
||||
char d[32];
|
||||
strptime( c, "%s", &t );
|
||||
strftime( d, sizeof(d), "%Y-%m-%d %H:%M:%S", &t);
|
||||
datetime = std::string( d );*/
|
||||
// parse
|
||||
year = datetime.substr( 0, 4 );
|
||||
month = datetime.substr( 5, 2 );
|
||||
|
@ -151,22 +145,22 @@ const std::vector<std::string> DateTimeOps::processDateTime( const std::string&
|
|||
year = "20" + datetime.substr( 6, 2 );
|
||||
|
||||
} else if ( format == "MDYY" ) {
|
||||
int aux;
|
||||
int aux_;
|
||||
if ( datetime.at(2) == '/' ) {
|
||||
month = datetime.substr( 0, 2 );
|
||||
aux = 3;
|
||||
aux_ = 3;
|
||||
} else {
|
||||
month = "0" + datetime.substr( 0, 1 );
|
||||
aux = 2;
|
||||
aux_ = 2;
|
||||
}
|
||||
if ( datetime.at(aux+2) == '/' ) {
|
||||
day = datetime.substr( aux, 2 );
|
||||
aux += 3;
|
||||
if ( datetime.at(aux_+2) == '/' ) {
|
||||
day = datetime.substr( aux_, 2 );
|
||||
aux_ += 3;
|
||||
} else {
|
||||
day = "0" + datetime.substr( aux, 1 );
|
||||
aux = +2;
|
||||
day = "0" + datetime.substr( aux_, 1 );
|
||||
aux_ = +2;
|
||||
}
|
||||
year = "20" + datetime.substr( aux );
|
||||
year = "20" + datetime.substr( aux_ );
|
||||
|
||||
} else if ( StringOps::startsWith( format, "year" ) ) {
|
||||
year = datetime;
|
||||
|
|
|
@ -211,7 +211,7 @@ const FormatOps::LogsFormat FormatOps::processApacheFormatString( const std::str
|
|||
int n_fld=0;
|
||||
size_t start, stop=0, aux, aux_start, aux_stop;
|
||||
const size_t max=f_str.size()-1;
|
||||
std::string aux_fld, aux_fld_v, cur_fld, cur_sep="";
|
||||
std::string aux_fld, aux_fld_v, cur_fld, cur_sep;
|
||||
// find and convert any field
|
||||
while (true) {
|
||||
// start after the last found field
|
||||
|
@ -285,7 +285,6 @@ const FormatOps::LogsFormat FormatOps::processApacheFormatString( const std::str
|
|||
} else {
|
||||
// stop
|
||||
aux = aux_aux;
|
||||
aux_fld = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -385,8 +384,8 @@ const FormatOps::LogsFormat FormatOps::processApacheFormatString( const std::str
|
|||
// check if false positive
|
||||
if ( aux_aux != std::string::npos ) {
|
||||
// same escape rules as before, but single percent-signs are considered valid and treated as text
|
||||
const char c = aux_fld.at( aux_aux+1 );
|
||||
if ( c == '%' || c == 'n' || c == 't' ) {
|
||||
const char c_ = aux_fld.at( aux_aux+1 );
|
||||
if ( c_ == '%' || c_ == 'n' || c_ == 't' ) {
|
||||
// control characters, will be used as separator, skip
|
||||
aux_aux_stop = aux_aux + 2;
|
||||
continue;
|
||||
|
|
|
@ -36,7 +36,7 @@ private:
|
|||
const std::string parseApacheEscapes( const std::string& string, const bool& strftime=false );
|
||||
const std::string parseNginxEscapes( const std::string& string );
|
||||
|
||||
const int countNewLines( const std::string& initial, const std::string& final, const std::vector<std::string>& separatprs );
|
||||
const int countNewLines( const std::string& initial, const std::string& final, const std::vector<std::string>& separators );
|
||||
|
||||
const size_t findNginxFieldEnd( const std::string& string, const int& start );
|
||||
void checkIisString( const std::string& string );
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
#include "hash.h"
|
||||
|
||||
|
||||
#include "utilities/gzip.h"
|
||||
#include "utilities/io.h"
|
||||
#include "utilities/vectors.h"
|
||||
|
@ -10,6 +9,7 @@
|
|||
#include "modules/exceptions.h"
|
||||
#include "modules/craplog/modules/sha256.h"
|
||||
|
||||
#include <ios>
|
||||
|
||||
|
||||
HashOps::HashOps()
|
||||
|
@ -82,9 +82,9 @@ std::string HashOps::digestFile( const std::string& file_path )
|
|||
// try reading as gzip compressed file
|
||||
GZutils::readFile( file_path, content );
|
||||
|
||||
} catch ( const GenericException& e ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing file pointer
|
||||
throw e;
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
// failed as gzip, try as text file
|
||||
|
@ -95,14 +95,14 @@ std::string HashOps::digestFile( const std::string& file_path )
|
|||
}
|
||||
|
||||
// re-catched in craplog
|
||||
} catch ( const GenericException ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing gzip file pointer
|
||||
throw GenericException( QString("%1:\n%2").arg(
|
||||
DialogSec::tr("An error accured while reading the gzipped file"),
|
||||
QString::fromStdString( file_path )
|
||||
).toStdString() );
|
||||
|
||||
} catch (const std::ios_base::failure& err) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed reading as text
|
||||
throw GenericException( QString("%1:\n%2").arg(
|
||||
DialogSec::tr("An error accured while reading the file"),
|
||||
|
@ -269,4 +269,3 @@ bool HashOps::insertUsedHashes( const std::string& db_path, const std::vector<st
|
|||
db.close();
|
||||
return proceed;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "modules/exceptions.h"
|
||||
#include "modules/craplog/modules/datetime.h"
|
||||
|
||||
#include "utilities/strings.h"
|
||||
|
||||
|
||||
LogOps::LogOps()
|
||||
{
|
||||
|
@ -154,7 +156,7 @@ const std::unordered_map<int, std::string> LogOps::parseLine( const std::string&
|
|||
{
|
||||
std::unordered_map<int, std::string> data;
|
||||
std::string sep, fld, fld_str;
|
||||
bool missing=false, add_pm=false;
|
||||
bool add_pm=false;
|
||||
size_t start, stop=0, aux_start, aux_stop,
|
||||
line_size = line.size()-1;
|
||||
int i=0, n_sep=format.separators.size()-1;
|
||||
|
@ -389,13 +391,8 @@ const std::unordered_map<int, std::string> LogOps::parseLine( const std::string&
|
|||
|
||||
|
||||
// update the stop for the next start
|
||||
if ( missing ) {
|
||||
missing = false;
|
||||
stop = aux_stop;
|
||||
} else {
|
||||
stop = stop + sep.size();
|
||||
i++;
|
||||
}
|
||||
stop += sep.size();
|
||||
i++;
|
||||
if ( stop > line_size ) {
|
||||
// this was the final separator
|
||||
break;
|
||||
|
@ -466,4 +463,3 @@ const unsigned LogOps::getParsedLines()
|
|||
{
|
||||
return this->parsed_lines;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "utilities/strings.h"
|
||||
#include "modules/craplog/modules/formats.h"
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "modules/dialogs.h"
|
||||
#include "modules/exceptions.h"
|
||||
|
||||
#include "utilities/strings.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
|
@ -33,7 +35,7 @@ bool StoreOps::storeData( QSqlDatabase& db, Craplog& craplog, const std::vector<
|
|||
check_wl_req = craplog.isWarnlistUsed( wsID, 12 );
|
||||
check_wl_cli = craplog.isWarnlistUsed( wsID, 20 );
|
||||
check_wl_ua = craplog.isWarnlistUsed( wsID, 21 );
|
||||
std::vector<std::string> bl_cli_list, bl_err_list, wl_cli_list, wl_ua_list, wl_met_list, wl_req_list, wl_err_list;
|
||||
std::vector<std::string> bl_cli_list, wl_cli_list, wl_ua_list, wl_met_list, wl_req_list;
|
||||
if ( check_bl_cli ) {
|
||||
bl_cli_list = craplog.getBlacklist( wsID, 20 );
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class StoreOps
|
|||
public:
|
||||
StoreOps();
|
||||
|
||||
static bool storeData( QSqlDatabase& db, Craplog& caplog, const std::vector<std::unordered_map<int, std::string>>& data );
|
||||
static bool storeData( QSqlDatabase& db, Craplog& craplog, const std::vector<std::unordered_map<int, std::string>>& data );
|
||||
};
|
||||
|
||||
#endif // STORE_H
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
|
||||
#include "modules/dialogs.h"
|
||||
|
||||
#include "utilities/io.h"
|
||||
#include "utilities/strings.h"
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
|
@ -79,7 +77,7 @@ void Crapup::versionCheck( const float& v, const int& dialog_level )
|
|||
successful = true;
|
||||
break;
|
||||
|
||||
} catch (std::invalid_argument& e) {
|
||||
} catch ( const std::invalid_argument&/*& e*/ ) {
|
||||
// failed to convert string to float
|
||||
err = 11;
|
||||
}
|
||||
|
@ -110,8 +108,10 @@ void Crapup::versionCheck( const float& v, const int& dialog_level )
|
|||
} else {
|
||||
// something went wrong, can't be successful if version is less than 0
|
||||
successful = false;
|
||||
err = 20;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if ( ! successful ) {
|
||||
DialogSec::errVersionCheckFailed( err );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class Crapup : public QObject
|
||||
{
|
||||
|
|
|
@ -327,7 +327,7 @@ void Crapview::drawWarn( QTableWidget* table, QtCharts::QChartView* chart, const
|
|||
}
|
||||
for ( int h=0; h<24; h++ ) {
|
||||
for ( int m=0; m<6; m++ ) {
|
||||
auto& data = items.at( h ).at( m );
|
||||
const auto& data = items.at( h ).at( m );
|
||||
norm_count = warn_count = 0;
|
||||
for ( const std::vector<QString>& line : data ) {
|
||||
aux = table->rowCount();
|
||||
|
@ -368,7 +368,7 @@ void Crapview::drawWarn( QTableWidget* table, QtCharts::QChartView* chart, const
|
|||
}
|
||||
for ( int g=0; g<6; g++ ) {
|
||||
for ( int m=0; m<10; m++ ) {
|
||||
auto& data = items.at( g ).at( m );
|
||||
const auto& data = items.at( g ).at( m );
|
||||
norm_count = warn_count = 0;
|
||||
for ( const std::vector<QString>& line : data ) {
|
||||
aux = table->rowCount();
|
||||
|
@ -428,8 +428,7 @@ void Crapview::drawWarn( QTableWidget* table, QtCharts::QChartView* chart, const
|
|||
foreach ( auto& bars, b_series ) {
|
||||
b_chart->addSeries( bars );
|
||||
}
|
||||
//b_chart->setTitle( QString("%1: %2").arg( this->TITLE_WARN ) );
|
||||
b_chart->setTitle( TR::tr( this->TITLE_WARN.c_str() ) );
|
||||
b_chart->setTitle( TR::tr( "Log Lines Marked as Warning" ) );
|
||||
b_chart->setTitleFont( fonts.at("main") );
|
||||
//b_chart->legend()->setVisible( false );
|
||||
b_chart->legend()->setFont( fonts.at("main_small") );
|
||||
|
@ -587,7 +586,7 @@ void Crapview::drawSpeed( QTableWidget* table, QtCharts::QChartView* chart, cons
|
|||
l_chart->setTheme( theme );
|
||||
l_chart->addSeries( line );
|
||||
l_chart->addSeries( line_ );
|
||||
l_chart->setTitle( TR::tr( this->TITLE_SPEED.c_str() ) );
|
||||
l_chart->setTitle( TR::tr( "Time Taken to Serve Requests" ) );
|
||||
l_chart->setTitleFont( fonts.at("main") );
|
||||
l_chart->legend()->setFont( fonts.at( "main_small" ) );
|
||||
l_chart->legend()->setAlignment( Qt::AlignBottom );
|
||||
|
@ -647,7 +646,6 @@ void Crapview::drawCount( QTableWidget* table, QtCharts::QChartView* chart, cons
|
|||
oth_count += count;
|
||||
} else {
|
||||
pie->append( item, count );
|
||||
//items.push_back( aux_items.at( i ) );
|
||||
}
|
||||
aux = table->rowCount();
|
||||
table->insertRow( aux );
|
||||
|
@ -658,7 +656,7 @@ void Crapview::drawCount( QTableWidget* table, QtCharts::QChartView* chart, cons
|
|||
aux_items.clear();
|
||||
|
||||
if ( oth_count > 0 ) {
|
||||
pie->append( TR::tr( this->TEXT_COUNT_OTHERS.c_str() ), oth_count );
|
||||
pie->append( TR::tr( "Others" ), oth_count );
|
||||
QPieSlice *slice = pie->slices().at( pie->count()-1 );
|
||||
slice->setBrush( Qt::gray );
|
||||
}
|
||||
|
@ -703,9 +701,9 @@ void Crapview::drawDay( QtCharts::QChartView* chart, const QChart::ChartTheme& t
|
|||
b_30->setLabel( this->printableDate( from_year, this->getMonthNumber(from_month), from_day ) );
|
||||
} else {
|
||||
b_30->setLabel( QString("%1 %2 %3 %4")
|
||||
.arg( TR::tr( this->LEGEND_FROM.c_str() ),
|
||||
.arg( TR::tr( "from" ),
|
||||
this->printableDate( from_year, this->getMonthNumber(from_month), from_day ),
|
||||
TR::tr( this->LEGEND_TO.c_str() ),
|
||||
TR::tr( "to" ),
|
||||
this->printableDate( to_year, this->getMonthNumber(to_month), to_day ) ));
|
||||
}
|
||||
b_30->setColor( col );
|
||||
|
@ -762,7 +760,7 @@ void Crapview::drawDay( QtCharts::QChartView* chart, const QChart::ChartTheme& t
|
|||
QChart *b_chart = new QChart();
|
||||
b_chart->setTheme( theme );
|
||||
b_chart->addSeries( bars );
|
||||
b_chart->setTitle( QString("%1: %2").arg( TR::tr( this->TITLE_DAY.c_str() ), field ) );
|
||||
b_chart->setTitle( QString("%1: %2").arg( TR::tr( "Time of Day Count" ), field ) );
|
||||
b_chart->setTitleFont( fonts.at("main") );
|
||||
b_chart->legend()->setFont( fonts.at("main_small") );
|
||||
//b_chart->legend()->setVisible( true );
|
||||
|
@ -838,7 +836,6 @@ void Crapview::drawRelat( QtCharts::QChartView* chart, const QChart::ChartTheme&
|
|||
time = std::get<0>(item);
|
||||
count = std::get<1>(item);
|
||||
line->append( time, (double)count );
|
||||
//*line << QPoint( time, (double)count );
|
||||
if ( count > max_count ) {
|
||||
max_count = count;
|
||||
}
|
||||
|
@ -850,9 +847,9 @@ void Crapview::drawRelat( QtCharts::QChartView* chart, const QChart::ChartTheme&
|
|||
area->setName( this->printableDate( from_year, this->getMonthNumber(from_month), from_day ));
|
||||
} else {
|
||||
area->setName(QString("%1 %2 %3 %4")
|
||||
.arg( TR::tr( this->LEGEND_FROM.c_str() ),
|
||||
.arg( TR::tr( "from" ),
|
||||
this->printableDate( from_year, this->getMonthNumber(from_month), from_day ),
|
||||
TR::tr( this->LEGEND_TO.c_str() ),
|
||||
TR::tr( "to" ),
|
||||
this->printableDate( to_year, this->getMonthNumber(to_month), to_day )) );
|
||||
}
|
||||
|
||||
|
@ -879,7 +876,7 @@ void Crapview::drawRelat( QtCharts::QChartView* chart, const QChart::ChartTheme&
|
|||
a_chart->setTheme( theme );
|
||||
a_chart->addSeries( area );
|
||||
a_chart->addSeries( area_ );
|
||||
a_chart->setTitle( QString("%1: %2 -> %3").arg( TR::tr( this->TITLE_RELAT.c_str() ), field_1, field_2) );
|
||||
a_chart->setTitle( QString("%1: %2 -> %3").arg( TR::tr( "Time of Day Count" ), field_1, field_2) );
|
||||
a_chart->setTitleFont( fonts.at("main") );
|
||||
a_chart->legend()->setFont( fonts.at( "main_small" ) );
|
||||
a_chart->legend()->setAlignment( Qt::AlignBottom );
|
||||
|
@ -961,7 +958,7 @@ const bool Crapview::calcGlobals( std::vector<std::tuple<QString,QString>>& recu
|
|||
for ( int i=0; i<4; i++ ) {
|
||||
int max=0;
|
||||
QString max_str="";
|
||||
std::unordered_map<QString, int>& aux = recurs.at( i );
|
||||
const auto& aux = recurs.at( i );
|
||||
for ( const auto& [s,c] : aux ) {
|
||||
if ( c > max ) {
|
||||
max = c;
|
||||
|
|
|
@ -102,14 +102,6 @@ private:
|
|||
|
||||
DbQuery dbQuery;
|
||||
|
||||
const std::string TITLE_WARN = TR::tr("Log Lines Marked as Warning").toStdString();
|
||||
const std::string TITLE_SPEED = TR::tr("Time Taken to Serve Requests").toStdString();
|
||||
const std::string TEXT_COUNT_OTHERS = TR::tr("Others").toStdString();
|
||||
const std::string TITLE_DAY = TR::tr("Time of Day Count").toStdString();
|
||||
const std::string TITLE_RELAT = TR::tr("Relational Count").toStdString();
|
||||
const std::string LEGEND_FROM = TR::tr("from").toStdString();
|
||||
const std::string LEGEND_TO = TR::tr("to").toStdString();
|
||||
|
||||
// collection of available dates
|
||||
// { web_server_id : { year : { month_str : [ days ] } } }
|
||||
std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, std::vector<int>>>> dates;
|
||||
|
|
|
@ -2125,7 +2125,7 @@ const bool DbQuery::getGlobalCounts( const QString& web_server, const std::unord
|
|||
|
||||
// process the day of the week
|
||||
for ( int i=1; i<8; i++ ) {
|
||||
int &x = num_day_count.at( i );
|
||||
const int &x = num_day_count.at( i );
|
||||
if ( x > 0 ) {
|
||||
traf_day.at( i ) /= x;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ DialogSec::DialogSec()
|
|||
}
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
//// LANGUAGE ////
|
||||
//////////////////
|
||||
|
@ -136,6 +135,12 @@ void DialogSec::errVersionCheckFailed( const int& err_code, QWidget *parent )
|
|||
case 11:
|
||||
msg = DialogSec::tr("An error occured while parsing:\nmalformed version");
|
||||
break;
|
||||
case 20:
|
||||
msg = DialogSec::tr("An error occured while comparing:\nversion lesser than 0");
|
||||
break;
|
||||
default:
|
||||
throw("Unexpected err_code in VersionCheck dialog: "+std::to_string(err_code));
|
||||
break;
|
||||
}
|
||||
|
||||
DialogMsg dialog = DialogMsg(
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <QWidget>
|
||||
#include <QString>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class DialogSec : public QObject
|
||||
{
|
||||
|
@ -87,13 +85,8 @@ public:
|
|||
// files
|
||||
static void errFileNotFound( const QString& file, const bool& report=false, QWidget *parent=nullptr );
|
||||
// files permissions
|
||||
/*static void errFileNotExists( QWidget *parent=nullptr );
|
||||
static void errFileNotReadable( QWidget *parent=nullptr );
|
||||
static void errFileNotWritable( QWidget *parent=nullptr );*/
|
||||
static void warnFileNotReadable( const QString& file, QWidget *parent=nullptr );
|
||||
/*static const bool choiceFileNotExists( QWidget *parent=nullptr );
|
||||
static const bool choiceFileNotReadable( QWidget *parent=nullptr );
|
||||
static const bool choiceFileNotWritable( QWidget *parent=nullptr );*/
|
||||
|
||||
// files actions
|
||||
static void warnEmptyFile( const QString& file, QWidget *parent=nullptr );
|
||||
static void errFailedReadFile( const QString& file, const bool& skipping=false, QWidget *parent=nullptr );
|
||||
|
@ -106,16 +99,12 @@ public:
|
|||
static void errDirNotWritable( const QString& dir, QWidget *parent=nullptr );
|
||||
static void warnDirNotReadable( QWidget *parent=nullptr );
|
||||
static void warnDirNotWritable( QWidget *parent=nullptr );
|
||||
/*static void choiceDirNotReadable( QWidget *parent=nullptr );
|
||||
static void choiceDirNotWritable( QWidget *parent=nullptr );*/
|
||||
// folders actions
|
||||
static void errFailedMakeDir( const QString& msg, QWidget *parent=nullptr );
|
||||
|
||||
// generic choices
|
||||
static const bool choiceDirNotDir( const QString& path, QWidget *parent=nullptr );
|
||||
static const bool choiceFileNotFile( const QString& path, QWidget *parent=nullptr );
|
||||
/*static void choiceYesNo( QWidget *parent=nullptr );
|
||||
static const bool choiceIgnoreAbort( QWidget *parent=nullptr );*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "dialogbool.h"
|
||||
#include "ui_dialogbool.h"
|
||||
|
||||
|
||||
DialogBool::DialogBool( const QString& title, const QString& text, QWidget *parent ) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DialogBool)
|
||||
|
@ -26,9 +28,7 @@ void DialogBool::on_button_NO_clicked()
|
|||
this->done( 0 );
|
||||
}
|
||||
|
||||
|
||||
void DialogBool::on_button_YES_clicked()
|
||||
{
|
||||
this->done( 1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DialogBool;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "dialogdia.h"
|
||||
#include "ui_dialogdia.h"
|
||||
|
||||
|
||||
DialogDia::DialogDia( const QString& title, const QString& text, const bool& ignore, const bool& discard, const bool& abort, QWidget *parent ) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DialogDia)
|
||||
|
@ -39,15 +41,12 @@ void DialogDia::on_button_IGNORE_clicked()
|
|||
this->done( 2 );
|
||||
}
|
||||
|
||||
|
||||
void DialogDia::on_button_DISCARD_clicked()
|
||||
{
|
||||
this->done( 1 );
|
||||
}
|
||||
|
||||
|
||||
void DialogDia::on_button_ABORT_clicked()
|
||||
{
|
||||
this->done( 0 );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DialogDia;
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ DialogMsg::DialogMsg(const QString& title, const QString& text, const QString& a
|
|||
this->ui->label_Icon->setPixmap( QPixmap(":/icons/icons/dialog_warn.png") );
|
||||
break;
|
||||
case 2:
|
||||
// error message, change the icon
|
||||
// error message
|
||||
this->ui->label_Icon->setPixmap( QPixmap(":/icons/icons/dialog_err.png") );
|
||||
break;
|
||||
default:
|
||||
// shouldn't be here
|
||||
throw GenericException("Unexpected dialog type: "+ type);
|
||||
throw GenericException("Unexpected dialog type: "+ std::to_string(type));
|
||||
}
|
||||
|
||||
// insert the given text
|
||||
|
@ -86,4 +86,3 @@ void DialogMsg::on_button_Ok_clicked()
|
|||
{
|
||||
this->done( 1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DialogMsg;
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
class TR : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TR(QObject *parent = nullptr);
|
||||
explicit TR(QObject *parent=nullptr);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <QFont>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
class TextBrowser
|
||||
{
|
||||
|
|
BIN
logdoctor/resources/games/body_c.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
logdoctor/resources/games/body_s.png
Normal file
After Width: | Height: | Size: 115 B |
BIN
logdoctor/resources/games/food.png
Normal file
After Width: | Height: | Size: 216 B |
BIN
logdoctor/resources/games/head.png
Normal file
After Width: | Height: | Size: 187 B |
BIN
logdoctor/resources/games/o.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
logdoctor/resources/games/tail.png
Normal file
After Width: | Height: | Size: 186 B |
BIN
logdoctor/resources/games/water.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
logdoctor/resources/games/x.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
|
@ -1,8 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" version="1">
|
||||
<path fill="#64db2d" fill-rule="evenodd" d="m23.947 4.0004c-0.946 0.0134-1.85 0.3953-2.519 1.0644l-16.362 16.362c-1.4211 1.4203-1.4211 3.724 0 5.1443l16.362 16.363c1.4203 1.4211 3.7239 1.4211 5.1442 0l16.362-16.363c1.4211-1.4203 1.4211-3.724 0-5.1443l-16.362-16.362c-0.695-0.6952-1.642-1.0791-2.625-1.0646z"/>
|
||||
<path opacity=".2" d="m26 39h-4v-4h4zm4.14-15.5-1.8 1.84c-1.44 1.46-2.34 2.66-2.34 5.66h-4v-1c0-2.2 0.9-4.2 2.34-5.66l2.48-2.52c0.74-0.72 1.18-1.72 1.18-2.82 0-2.2-1.8-4-4-4s-4 1.8-4 4h-4c0-4.42 3.58-8 8-8s8 3.58 8 8c0 1.76-0.72 3.36-1.86 4.5z"/>
|
||||
<path fill="#fff" d="m26 38h-4v-4h4zm4.14-15.5-1.8 1.84c-1.44 1.46-2.34 2.66-2.34 5.66h-4v-1c0-2.2 0.9-4.2 2.34-5.66l2.48-2.52c0.74-0.72 1.18-1.72 1.18-2.82 0-2.2-1.8-4-4-4s-4 1.8-4 4h-4c0-4.42 3.58-8 8-8s8 3.58 8 8c0 1.76-0.72 3.36-1.86 4.5z"/>
|
||||
<rect fill="none" width="32" height="32" x="8" y="7.99"/>
|
||||
<path fill="#fff" fill-rule="evenodd" opacity=".2" d="m23.947 4c-0.946 0.0134-1.85 0.3953-2.519 1.0645l-16.362 16.364c-0.8382 0.838-1.1703 1.982-1.0191 3.072 0.1047-0.758 0.4367-1.49 1.0195-2.072l16.362-16.364c0.669-0.6687 1.573-1.0506 2.519-1.064 0.98283-0.01453 1.9299 0.36948 2.625 1.0645l16.362 16.364c0.58282 0.58252 0.91477 1.3145 1.0195 2.0723 0.15116-1.0903-0.18093-2.2341-1.0195-3.0723l-16.362-16.364c-0.695-0.6945-1.642-1.0785-2.625-1.064z"/>
|
||||
<path fill-rule="evenodd" opacity=".2" d="m4.0469 24.5c-0.15067 1.0899 0.18128 2.2344 1.0195 3.0723l16.362 16.362c1.4203 1.4211 3.7242 1.4211 5.1445 0l16.362-16.362c0.838-0.838 1.17-1.982 1.019-3.072-0.10499 0.7573-0.43707 1.4901-1.0195 2.0723l-16.362 16.362c-1.4203 1.4211-3.7242 1.4211-5.1445 0l-16.362-16.362c-0.5821-0.582-0.9141-1.315-1.0191-2.072z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
|
@ -49,4 +49,14 @@
|
|||
<file>flags/fr.png</file>
|
||||
<file>flags/it.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/games">
|
||||
<file>games/o.png</file>
|
||||
<file>games/x.png</file>
|
||||
<file>games/body_c.png</file>
|
||||
<file>games/body_s.png</file>
|
||||
<file>games/head.png</file>
|
||||
<file>games/tail.png</file>
|
||||
<file>games/food.png</file>
|
||||
<file>games/water.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -25,11 +25,11 @@ void Crapnote::setTextFont( const QFont& font )
|
|||
this->ui->textEdit->setFont( f );
|
||||
}
|
||||
|
||||
void Crapnote::setColorScheme( const int& scheme_id )
|
||||
void Crapnote::setColorScheme( const int& color_scheme_id )
|
||||
{
|
||||
QColor b, t;
|
||||
// update the colors palette
|
||||
switch ( scheme_id ) {
|
||||
switch ( color_scheme_id ) {
|
||||
case 0:
|
||||
this->ui->textEdit->setPalette( QPalette() );
|
||||
break;
|
||||
|
@ -53,7 +53,7 @@ void Crapnote::setColorScheme( const int& scheme_id )
|
|||
break;
|
||||
default:
|
||||
// wrong
|
||||
throw GenericException( "Unexpected ColorScheme ID for Crapnote: "+std::to_string( scheme_id ), true ); // leave un-catched
|
||||
throw GenericException( "Unexpected ColorScheme ID for Crapnote: "+std::to_string( color_scheme_id ), true ); // leave un-catched
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,4 +75,3 @@ void Crapnote::on_button_FontSize_Plus_clicked()
|
|||
{
|
||||
this->ui->spinBox_FontSize->setValue( this->font_size+1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Crapnote;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,29 @@
|
|||
<translation>Increase the font size</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CrissCross</name>
|
||||
<message>
|
||||
<source>You beated me!</source>
|
||||
<translation>You beated me!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This time you lost!</source>
|
||||
<translation>This time you lost!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Victory</source>
|
||||
<translation>Victory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Draw</source>
|
||||
<translation>Draw</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nice match</source>
|
||||
<translation>Nice match</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogBool</name>
|
||||
<message>
|
||||
|
@ -648,6 +671,12 @@ please follow the instruction on the repository page</source>
|
|||
<translation>If you'd like to have this locale in LogDoctor,
|
||||
please follow the instruction on the repository page</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error occured while comparing:
|
||||
version lesser than 0</source>
|
||||
<translation>An error occured while comparing:
|
||||
version lesser than 0</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
|
@ -1441,6 +1470,26 @@ Time of day counts for a single date, entire days counts in a period.</translati
|
|||
<source>Ash</source>
|
||||
<translation>Ash</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Games</source>
|
||||
<translation>Games</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CrissCross</source>
|
||||
<translation>CrissCross</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play CrissCross</source>
|
||||
<translation>Play CrissCross</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Snake</source>
|
||||
<translation>Snake</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Snake</source>
|
||||
<translation>Play Snake</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RichText</name>
|
||||
|
@ -1457,6 +1506,25 @@ Time of day counts for a single date, entire days counts in a period.</translati
|
|||
<translation>Failed to read</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Snake</name>
|
||||
<message>
|
||||
<source>PLAY</source>
|
||||
<translation>PLAY</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game Over</source>
|
||||
<translation>Game Over</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You fell in the water!</source>
|
||||
<translation>You fell in the water!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You ate yourself!</source>
|
||||
<translation>You ate yourself!</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TR</name>
|
||||
<message>
|
||||
|
@ -1503,10 +1571,6 @@ Time of day counts for a single date, entire days counts in a period.</translati
|
|||
<source>Time of Day Count</source>
|
||||
<translation>Time of Day Count</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relational Count</source>
|
||||
<translation>Relational Count</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>from</source>
|
||||
<translation>from</translation>
|
||||
|
|
|
@ -59,6 +59,29 @@
|
|||
<translation>Aumenta la dimensione dei caratteri</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CrissCross</name>
|
||||
<message>
|
||||
<source>You beated me!</source>
|
||||
<translation>Mi hai battuto!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This time you lost!</source>
|
||||
<translation>Stavolta hai perso!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Victory</source>
|
||||
<translation>Vittoria</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Draw</source>
|
||||
<translation>Pareggio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nice match</source>
|
||||
<translation>Bella partita</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogBool</name>
|
||||
<message>
|
||||
|
@ -648,6 +671,12 @@ please follow the instruction on the repository page</source>
|
|||
<translation>Se desideri avere questa lingua in LogDoctor,
|
||||
per favore segui le istruzioni nella pagina del repository</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error occured while comparing:
|
||||
version lesser than 0</source>
|
||||
<translation>È avvenuto un errore durante il confronto:
|
||||
la versione è minore di 0</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
|
@ -1442,6 +1471,26 @@ Conto negli orari del giorno per una singola data, o totali delle giornate per u
|
|||
<source>Ash</source>
|
||||
<translation>Cenere</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Games</source>
|
||||
<translation>Giochi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CrissCross</source>
|
||||
<translation>Tris</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play CrissCross</source>
|
||||
<translation>Gioca a Tris</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Snake</source>
|
||||
<translation>Snake</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Snake</source>
|
||||
<translation>Gioca a Snake</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RichText</name>
|
||||
|
@ -1458,6 +1507,25 @@ Conto negli orari del giorno per una singola data, o totali delle giornate per u
|
|||
<translation>Lettura fallita</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Snake</name>
|
||||
<message>
|
||||
<source>PLAY</source>
|
||||
<translation>GIOCA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Game Over</source>
|
||||
<translation>Game Over</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You fell in the water!</source>
|
||||
<translation>Sei caduto nell'acqua!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You ate yourself!</source>
|
||||
<translation>Ti sei mangiato da solo!</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TR</name>
|
||||
<message>
|
||||
|
@ -1504,10 +1572,6 @@ Conto negli orari del giorno per una singola data, o totali delle giornate per u
|
|||
<source>Time of Day Count</source>
|
||||
<translation>Conteggio dei Momenti del Giorno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Relational Count</source>
|
||||
<translation>Conteggio relazionale</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>from</source>
|
||||
<translation>da</translation>
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QSqlError>
|
||||
#include <QVariant>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
CheckSec::CheckSec()
|
||||
{
|
||||
|
|
|
@ -94,16 +94,13 @@ const QPalette ColorSec::getPalette( const int&theme )
|
|||
case 2:
|
||||
// candy
|
||||
p = QPalette( QBrush(QColor( 45, 0, 30 )), /* window text */
|
||||
//QBrush(QColor( 215, 110, 111 )), /* button */
|
||||
QBrush(QColor( 225, 120, 121 )), /* button */
|
||||
QBrush(QColor( 255, 170, 171 )), /* light */
|
||||
QBrush(QColor( 195, 80, 81 )), /* dark */
|
||||
QBrush(QColor( 235, 120, 121 )), /* mid */
|
||||
QBrush(QColor( 45, 0, 30 )), /* text */
|
||||
QBrush(QColor( 145, 100, 130 )), /* bright text */
|
||||
//QBrush(QColor( 255, 180, 181 )), /* base */
|
||||
QBrush(QColor( 194, 255, 195 )), /* base */
|
||||
//QBrush(QColor( 195, 80, 81 )) /* window */
|
||||
QBrush(QColor( 255, 204, 143 )) /* window */ );
|
||||
p.setBrush( QPalette::ColorRole::Highlight, QBrush(QColor(195,80,81)) );
|
||||
break;
|
||||
|
|
|
@ -66,7 +66,7 @@ void GZutils::readFile( const std::string& path, std::string& content )
|
|||
if ( ferror( file ) ) {
|
||||
// error reading
|
||||
(void)inflateEnd( &strm );
|
||||
successful = false;
|
||||
/*successful = false;*/
|
||||
break;
|
||||
}
|
||||
if ( strm.avail_in == 0 ) {
|
||||
|
|
|
@ -138,9 +138,9 @@ void IOutils::randomLines(const std::string& path, std::vector<std::string>& lin
|
|||
// try reading a gzipped file
|
||||
GZutils::readFile( path, aux );
|
||||
|
||||
} catch ( const GenericException& e ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing file pointer
|
||||
throw e;
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
// fallback in reading as text file
|
||||
|
@ -179,7 +179,7 @@ void IOutils::randomLines(const std::string& path, std::vector<std::string>& lin
|
|||
lines.push_back( line );
|
||||
}
|
||||
// add the first and last lines, to double check for file integrity
|
||||
for ( int& index : std::vector<int>({0,max-1}) ) {
|
||||
for ( const int& index : std::vector<int>({0,max-1}) ) {
|
||||
if ( ! VecOps::contains( picked_indexes, index ) ) {
|
||||
line = aux_lines.at( index );
|
||||
if ( strip_lines ) {
|
||||
|
@ -196,7 +196,7 @@ void IOutils::randomLines(const std::string& path, std::vector<std::string>& lin
|
|||
aux_lines.clear();
|
||||
|
||||
// re-catched in craplog
|
||||
} catch ( const GenericException ) {
|
||||
} catch ( const GenericException& ) {
|
||||
// failed closing gzip file pointer
|
||||
lines.clear(); aux_lines.clear();
|
||||
if ( file.is_open() ) {
|
||||
|
@ -204,7 +204,7 @@ void IOutils::randomLines(const std::string& path, std::vector<std::string>& lin
|
|||
}
|
||||
throw GenericException( "An error accured while reading the gzipped file" );
|
||||
|
||||
} catch (const std::ios_base::failure) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed reading
|
||||
lines.clear(); aux_lines.clear();
|
||||
if ( file.is_open() ) {
|
||||
|
@ -247,12 +247,12 @@ void IOutils::readFile( const std::string& path , std::string& content )
|
|||
(std::istreambuf_iterator<char>( file )),
|
||||
std::istreambuf_iterator<char>() );
|
||||
|
||||
} catch (const std::ios_base::failure& err) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed reading
|
||||
if ( file.is_open() ) {
|
||||
file.close();
|
||||
}
|
||||
throw err;
|
||||
throw;
|
||||
} catch (...) {
|
||||
if ( file.is_open() ) {
|
||||
file.close();
|
||||
|
@ -283,12 +283,12 @@ void IOutils::writeOnFile( const std::string& path, const std::string& content )
|
|||
// write the content
|
||||
file << content << std::endl;
|
||||
|
||||
} catch (const std::ios_base::failure& err) {
|
||||
} catch ( const std::ios_base::failure& ) {
|
||||
// failed writing
|
||||
if ( file.is_open() ) {
|
||||
file.close();
|
||||
}
|
||||
throw err;
|
||||
throw;
|
||||
} catch (...) {
|
||||
if ( file.is_open() ) {
|
||||
file.close();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "rtf.h"
|
||||
|
||||
#include "utilities/strings.h"
|
||||
|
||||
|
||||
RichText::RichText()
|
||||
{
|
||||
|
@ -25,7 +27,7 @@ void RichText::enrichLogs( QString &rich_content, const std::string& content, co
|
|||
rich_content += "<br/>";
|
||||
}
|
||||
QString rich_line="", class_name="";
|
||||
std::string sep, fld, fld_str, aux_sep1, aux_sep2, aux_fld_str;
|
||||
std::string sep, fld, fld_str, aux_sep2;
|
||||
bool missing=false;
|
||||
size_t start, stop, i, aux_start, aux_stop,
|
||||
line_size, sep_size;
|
||||
|
@ -209,7 +211,6 @@ void RichText::enrichLogs( QString &rich_content, const std::string& content, co
|
|||
|
||||
|
||||
|
||||
|
||||
void RichText::richLogsDefault( QString& rich_str )
|
||||
{
|
||||
rich_str.clear();
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <QFont>
|
||||
#include <QString>
|
||||
|
||||
#include "utilities/strings.h"
|
||||
|
||||
#include "modules/tb.h"
|
||||
#include "modules/craplog/modules/formats.h"
|
||||
|
||||
|
|
|
@ -264,9 +264,9 @@ std::string StringOps::rstrip( const std::string& str, const std::string& chars
|
|||
std::string StringOps::lstripUntil( const std::string& str, const std::string& chr, const bool& inclusive, const bool& consecutives )
|
||||
{
|
||||
size_t start, aux_start, aux;
|
||||
const size_t max_size = str.size()-1;
|
||||
const size_t max_size = str.size();
|
||||
std::string stripped = "";
|
||||
if ( max_size >= 0 ) {
|
||||
if ( max_size > 0 ) {
|
||||
start = str.find( chr );
|
||||
if ( inclusive == true ) {
|
||||
start += chr.size();
|
||||
|
@ -286,17 +286,13 @@ std::string StringOps::lstripUntil( const std::string& str, const std::string& c
|
|||
}
|
||||
aux_start = aux;
|
||||
}
|
||||
if ( aux_start == max_size+1 ) {
|
||||
stripped = "";
|
||||
} else {
|
||||
if ( aux_start < max_size ) {
|
||||
stripped = str.substr( aux_start );
|
||||
}
|
||||
} else {
|
||||
if ( start == std::string::npos ) {
|
||||
stripped = str;
|
||||
} else if ( start == max_size+1 ) {
|
||||
stripped = "";
|
||||
} else {
|
||||
} else if ( start < max_size ) {
|
||||
stripped = str.substr( start );
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +306,7 @@ void StringOps::split( std::vector<std::string>& list, const std::string& target
|
|||
{
|
||||
std::string slice;
|
||||
size_t start=0, stop;
|
||||
if ( target_str.size()-1 >= 0 ) {
|
||||
if ( target_str.size() > 0 ) {
|
||||
while (true) {
|
||||
stop = target_str.find( separator, start );
|
||||
if ( stop == std::string::npos ) {
|
||||
|
@ -350,18 +346,23 @@ void StringOps::splitrip( std::vector<std::string>& list, const std::string& tar
|
|||
const std::string StringOps::replace( const std::string& str, const std::string& target, const std::string& replace )
|
||||
{
|
||||
size_t start=0, stop;
|
||||
const int size = target.size();
|
||||
const size_t size = target.size();
|
||||
std::string string = "";
|
||||
if ( str.size()-1 >= 0 ) {
|
||||
while ( true ) {
|
||||
stop = str.find( target, start );
|
||||
if ( stop == std::string::npos ) {
|
||||
string += str.substr( start );
|
||||
break;
|
||||
} else {
|
||||
string += str.substr( start, stop-start );
|
||||
string += replace;
|
||||
start = stop+size;
|
||||
if ( str.size() > 0 ) {
|
||||
if ( size == 0 ) {
|
||||
// target is empty, nothing to replace
|
||||
string = str;
|
||||
} else {
|
||||
while ( true ) {
|
||||
stop = str.find( target, start );
|
||||
if ( stop == std::string::npos ) {
|
||||
string += str.substr( start );
|
||||
break;
|
||||
} else {
|
||||
string += str.substr( start, stop-start );
|
||||
string += replace;
|
||||
start = stop+size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ VecOps::VecOps()
|
|||
}
|
||||
|
||||
|
||||
|
||||
const bool VecOps::contains( const std::vector<int>& list, const int& flag )
|
||||
{
|
||||
bool result = false;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class VecOps
|
||||
{
|
||||
public:
|
||||
|
|