mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-28 11:53:11 -07:00
Turn Card, Deck_List, Protocol, RNG, Network (Client, Server), Settings and Utility into libraries and remove cockatrice_common. (#6212)
--------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> Co-authored-by: ebbit1q <ebbit1q@gmail.com>
This commit is contained in:
32
libcockatrice_utility/CMakeLists.txt
Normal file
32
libcockatrice_utility/CMakeLists.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(Utility VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(UTILITY_SOURCES
|
||||
libcockatrice/utility/expression.cpp libcockatrice/utility/key_signals.cpp libcockatrice/utility/levenshtein.cpp
|
||||
libcockatrice/utility/logger.cpp libcockatrice/utility/passwordhasher.cpp
|
||||
)
|
||||
|
||||
set(UTILITY_HEADERS
|
||||
libcockatrice/utility/color.h
|
||||
libcockatrice/utility/expression.h
|
||||
libcockatrice/utility/key_signals.h
|
||||
libcockatrice/utility/levenshtein.h
|
||||
libcockatrice/utility/logger.h
|
||||
libcockatrice/utility/macros.h
|
||||
libcockatrice/utility/passwordhasher.h
|
||||
libcockatrice/utility/trice_limits.h
|
||||
)
|
||||
|
||||
add_library(libcockatrice_utility STATIC ${UTILITY_SOURCES} ${UTILITY_HEADERS})
|
||||
|
||||
target_include_directories(libcockatrice_utility PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(libcockatrice_utility PUBLIC libcockatrice_rng ${COCKATRICE_QT_MODULES})
|
||||
|
||||
set(ORACLE_LIBS)
|
||||
|
||||
include_directories(${${COCKATRICE_QT_VERSION_NAME}Core_INCLUDE_DIRS})
|
||||
24
libcockatrice_utility/libcockatrice/utility/card_ref.h
Normal file
24
libcockatrice_utility/libcockatrice/utility/card_ref.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef CARD_REF_H
|
||||
#define CARD_REF_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
* The information passed over the server that is required to identify the exact card to display.
|
||||
*
|
||||
* @param name The name of the card. Should not be empty, unless to indicate the lack of a card.
|
||||
* @param providerId Determines which printing of the card to use. Can be empty, in which case Cockatrice should default
|
||||
* to using the preferred set.
|
||||
*/
|
||||
struct CardRef
|
||||
{
|
||||
QString name;
|
||||
QString providerId = QString();
|
||||
|
||||
bool operator==(const CardRef &other) const
|
||||
{
|
||||
return name == other.name && providerId == other.providerId;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CARD_REF_H
|
||||
35
libcockatrice_utility/libcockatrice/utility/color.h
Normal file
35
libcockatrice_utility/libcockatrice/utility/color.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
#ifdef QT_GUI_LIB
|
||||
#include <QColor>
|
||||
#endif
|
||||
|
||||
#include <libcockatrice/protocol/pb/color.pb.h>
|
||||
|
||||
#ifdef QT_GUI_LIB
|
||||
inline QColor convertColorToQColor(const color &c)
|
||||
{
|
||||
return QColor(c.r(), c.g(), c.b());
|
||||
}
|
||||
|
||||
inline color convertQColorToColor(const QColor &c)
|
||||
{
|
||||
color result;
|
||||
result.set_r(c.red());
|
||||
result.set_g(c.green());
|
||||
result.set_b(c.blue());
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline color makeColor(int r, int g, int b)
|
||||
{
|
||||
color result;
|
||||
result.set_r(r);
|
||||
result.set_g(g);
|
||||
result.set_b(b);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
107
libcockatrice_utility/libcockatrice/utility/expression.cpp
Normal file
107
libcockatrice_utility/libcockatrice/utility/expression.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "expression.h"
|
||||
|
||||
#include "peglib.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QtMath>
|
||||
#include <functional>
|
||||
|
||||
peg::parser math(R"(
|
||||
EXPRESSION <- P0
|
||||
P0 <- P1 (P1_OPERATOR P1)*
|
||||
P1 <- P2 (P2_OPERATOR P2)*
|
||||
P2 <- P3 (P3_OPERATOR P3)*
|
||||
P3 <- NUMBER / FUNCTION / VARIABLE / '(' P0 ')'
|
||||
|
||||
P1_OPERATOR <- < [-+] >
|
||||
P2_OPERATOR <- < [/*] >
|
||||
P3_OPERATOR <- < '^' >
|
||||
|
||||
NUMBER <- < '-'? [0-9]+ >
|
||||
NAME <- < [a-z][a-z0-9]* >
|
||||
VARIABLE <- < [x] >
|
||||
FUNCTION <- NAME '(' EXPRESSION ( [,\n] EXPRESSION )* ')'
|
||||
|
||||
%whitespace <- [ \t\r]*
|
||||
)");
|
||||
|
||||
QMap<QString, std::function<double(double)>> *default_functions = nullptr;
|
||||
|
||||
Expression::Expression(double initial) : value(initial)
|
||||
{
|
||||
if (default_functions == nullptr) {
|
||||
default_functions = new QMap<QString, std::function<double(double)>>();
|
||||
default_functions->insert("abs", [](double a) { return qFabs(a); });
|
||||
default_functions->insert("ceil", [](double a) { return qCeil(a); });
|
||||
default_functions->insert("cos", [](double a) { return qCos(a); });
|
||||
default_functions->insert("floor", [](double a) { return qFloor(a); });
|
||||
default_functions->insert("log", [](double a) { return qLn(a); });
|
||||
default_functions->insert("log10", [](double a) { return qLn(a); });
|
||||
default_functions->insert("round", [](double a) { return qRound(a); });
|
||||
default_functions->insert("sin", [](double a) { return qSin(a); });
|
||||
default_functions->insert("sqrt", [](double a) { return qSqrt(a); });
|
||||
default_functions->insert("tan", [](double a) { return qTan(a); });
|
||||
default_functions->insert("trunc", [](double a) { return std::trunc(a); });
|
||||
}
|
||||
fns = QMap<QString, std::function<double(double)>>(*default_functions);
|
||||
}
|
||||
|
||||
double Expression::eval(const peg::Ast &ast)
|
||||
{
|
||||
const auto &nodes = ast.nodes;
|
||||
if (ast.name == "NUMBER") {
|
||||
return stod(std::string(ast.token));
|
||||
} else if (ast.name == "FUNCTION") {
|
||||
QString name = QString::fromStdString(std::string(nodes[0]->token));
|
||||
if (!fns.contains(name))
|
||||
return 0;
|
||||
return fns[name](eval(*nodes[1]));
|
||||
} else if (ast.name == "VARIABLE") {
|
||||
return value;
|
||||
} else if (ast.name[0] == 'P') {
|
||||
double result = eval(*nodes[0]);
|
||||
for (unsigned int i = 1; i < nodes.size(); i += 2) {
|
||||
double arg = eval(*nodes[i + 1]);
|
||||
char operation = nodes[i]->token[0];
|
||||
switch (operation) {
|
||||
case '+':
|
||||
result += arg;
|
||||
break;
|
||||
case '-':
|
||||
result -= arg;
|
||||
break;
|
||||
case '*':
|
||||
result *= arg;
|
||||
break;
|
||||
case '/':
|
||||
result /= arg;
|
||||
break;
|
||||
case '^':
|
||||
result = qPow(result, arg);
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
double Expression::parse(const QString &expr)
|
||||
{
|
||||
QByteArray ba = expr.toUtf8();
|
||||
|
||||
math.enable_ast();
|
||||
|
||||
std::shared_ptr<peg::Ast> ast;
|
||||
if (math.parse(ba.data(), ast)) {
|
||||
ast = peg::AstOptimizer(true).optimize(ast);
|
||||
return eval(*ast);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
libcockatrice_utility/libcockatrice/utility/expression.h
Normal file
28
libcockatrice_utility/libcockatrice/utility/expression.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef EXPRESSION_H
|
||||
#define EXPRESSION_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
namespace peg
|
||||
{
|
||||
template <typename Annotation> struct AstBase;
|
||||
struct EmptyType;
|
||||
typedef AstBase<EmptyType> Ast;
|
||||
} // namespace peg
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
double value;
|
||||
|
||||
explicit Expression(double initial = 0);
|
||||
double parse(const QString &expr);
|
||||
|
||||
private:
|
||||
double eval(const peg::Ast &ast);
|
||||
QMap<QString, std::function<double(double)>> fns;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
libcockatrice_utility/libcockatrice/utility/key_signals.cpp
Normal file
74
libcockatrice_utility/libcockatrice/utility/key_signals.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "key_signals.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
bool KeySignals::eventFilter(QObject * /*object*/, QEvent *event)
|
||||
{
|
||||
QKeyEvent *kevent;
|
||||
|
||||
if (event->type() != QEvent::KeyPress)
|
||||
return false;
|
||||
|
||||
kevent = static_cast<QKeyEvent *>(event);
|
||||
switch (kevent->key()) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
|
||||
emit onCtrlAltEnter();
|
||||
else if (kevent->modifiers() & Qt::ControlModifier)
|
||||
emit onCtrlEnter();
|
||||
else
|
||||
emit onEnter();
|
||||
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
if (kevent->modifiers() & Qt::ShiftModifier)
|
||||
emit onShiftRight();
|
||||
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
if (kevent->modifiers() & Qt::ShiftModifier)
|
||||
emit onShiftLeft();
|
||||
|
||||
break;
|
||||
case Qt::Key_Delete:
|
||||
case Qt::Key_Backspace:
|
||||
emit onDelete();
|
||||
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
|
||||
emit onCtrlAltMinus();
|
||||
|
||||
break;
|
||||
case Qt::Key_Equal:
|
||||
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
|
||||
emit onCtrlAltEqual();
|
||||
|
||||
break;
|
||||
case Qt::Key_BracketLeft:
|
||||
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
|
||||
emit onCtrlAltLBracket();
|
||||
|
||||
break;
|
||||
case Qt::Key_BracketRight:
|
||||
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
|
||||
emit onCtrlAltRBracket();
|
||||
|
||||
break;
|
||||
case Qt::Key_S:
|
||||
if (kevent->modifiers() & Qt::ShiftModifier)
|
||||
emit onShiftS();
|
||||
|
||||
break;
|
||||
case Qt::Key_C:
|
||||
if (kevent->modifiers() & Qt::ControlModifier)
|
||||
emit onCtrlC();
|
||||
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
36
libcockatrice_utility/libcockatrice/utility/key_signals.h
Normal file
36
libcockatrice_utility/libcockatrice/utility/key_signals.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file key_signals.h
|
||||
* @ingroup Core
|
||||
* @ingroup UI
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef KEYSIGNALS_H
|
||||
#define KEYSIGNALS_H
|
||||
|
||||
#include <QEvent>
|
||||
#include <QObject>
|
||||
|
||||
class KeySignals : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void onEnter();
|
||||
void onCtrlEnter();
|
||||
void onCtrlAltEnter();
|
||||
void onShiftLeft();
|
||||
void onShiftRight();
|
||||
void onDelete();
|
||||
void onCtrlAltMinus();
|
||||
void onCtrlAltEqual();
|
||||
void onCtrlAltLBracket();
|
||||
void onCtrlAltRBracket();
|
||||
void onShiftS();
|
||||
void onCtrlC();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
25
libcockatrice_utility/libcockatrice/utility/levenshtein.cpp
Normal file
25
libcockatrice_utility/libcockatrice/utility/levenshtein.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "levenshtein.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
int levenshteinDistance(const QString &s1, const QString &s2)
|
||||
{
|
||||
int len1 = s1.size();
|
||||
int len2 = s2.size();
|
||||
std::vector<std::vector<int>> dp(len1 + 1, std::vector<int>(len2 + 1));
|
||||
|
||||
for (int i = 0; i <= len1; i++)
|
||||
dp[i][0] = i;
|
||||
for (int j = 0; j <= len2; j++)
|
||||
dp[0][j] = j;
|
||||
|
||||
for (int i = 1; i <= len1; i++) {
|
||||
for (int j = 1; j <= len2; j++) {
|
||||
int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
|
||||
dp[i][j] = std::min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost});
|
||||
}
|
||||
}
|
||||
|
||||
return dp[len1][len2];
|
||||
}
|
||||
14
libcockatrice_utility/libcockatrice/utility/levenshtein.h
Normal file
14
libcockatrice_utility/libcockatrice/utility/levenshtein.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @file levenshtein.h
|
||||
* @ingroup Core
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef LEVENSHTEIN_H
|
||||
#define LEVENSHTEIN_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
int levenshteinDistance(const QString &s1, const QString &s2);
|
||||
|
||||
#endif // LEVENSHTEIN_H
|
||||
142
libcockatrice_utility/libcockatrice/utility/logger.cpp
Normal file
142
libcockatrice_utility/libcockatrice/utility/logger.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "logger.h"
|
||||
|
||||
#include "version_string.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QLocale>
|
||||
#include <QSysInfo>
|
||||
#include <iostream>
|
||||
|
||||
#define LOGGER_MAX_ENTRIES 128
|
||||
#define LOGGER_FILENAME "qdebug.txt"
|
||||
|
||||
Logger::Logger() : logToFileEnabled(false)
|
||||
{
|
||||
logBuffer.append(getClientVersion());
|
||||
logBuffer.append(getSystemArchitecture());
|
||||
logBuffer.append(getSystemLocale());
|
||||
logBuffer.append(getClientInstallInfo());
|
||||
logBuffer.append(QString("-").repeated(75));
|
||||
std::cerr << getClientVersion().toStdString() << std::endl;
|
||||
std::cerr << getSystemArchitecture().toStdString() << std::endl;
|
||||
std::cerr << getSystemLocale().toStdString() << std::endl;
|
||||
std::cerr << getClientInstallInfo().toStdString() << std::endl;
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
closeLogfileSession();
|
||||
logBuffer.clear();
|
||||
}
|
||||
|
||||
void Logger::logToFile(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
openLogfileSession();
|
||||
} else {
|
||||
closeLogfileSession();
|
||||
}
|
||||
}
|
||||
|
||||
QString Logger::getClientVersion()
|
||||
{
|
||||
return "Client Version: " + QString::fromStdString(VERSION_STRING);
|
||||
}
|
||||
|
||||
void Logger::openLogfileSession()
|
||||
{
|
||||
if (logToFileEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileHandle.setFileName(LOGGER_FILENAME);
|
||||
fileHandle.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
|
||||
fileStream.setDevice(&fileHandle);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
fileStream << "Log session started at " << QDateTime::currentDateTime().toString() << Qt::endl;
|
||||
fileStream << getClientVersion() << Qt::endl;
|
||||
fileStream << getSystemArchitecture() << Qt::endl;
|
||||
fileStream << getClientInstallInfo() << Qt::endl;
|
||||
#else
|
||||
fileStream << "Log session started at " << QDateTime::currentDateTime().toString() << endl;
|
||||
fileStream << getClientVersion() << endl;
|
||||
fileStream << getSystemArchitecture() << endl;
|
||||
fileStream << getClientInstallInfo() << endl;
|
||||
#endif
|
||||
logToFileEnabled = true;
|
||||
}
|
||||
|
||||
void Logger::closeLogfileSession()
|
||||
{
|
||||
if (!logToFileEnabled)
|
||||
return;
|
||||
|
||||
logToFileEnabled = false;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
fileStream << "Log session closed at " << QDateTime::currentDateTime().toString() << Qt::endl;
|
||||
#else
|
||||
fileStream << "Log session closed at " << QDateTime::currentDateTime().toString() << endl;
|
||||
#endif
|
||||
fileHandle.close();
|
||||
}
|
||||
|
||||
void Logger::log(QtMsgType /* type */, const QMessageLogContext & /* ctx */, const QString &message)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "internalLog", Qt::QueuedConnection, Q_ARG(const QString &, message));
|
||||
}
|
||||
|
||||
void Logger::internalLog(const QString &message)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
logBuffer.append(message);
|
||||
if (logBuffer.size() > LOGGER_MAX_ENTRIES) {
|
||||
logBuffer.removeAt(1);
|
||||
}
|
||||
|
||||
emit logEntryAdded(message);
|
||||
std::cerr << message.toStdString() << std::endl; // Print to stdout
|
||||
|
||||
if (logToFileEnabled) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
fileStream << message << Qt::endl; // Print to fileStream
|
||||
#else
|
||||
fileStream << message << endl; // Print to fileStream
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
QString Logger::getSystemArchitecture()
|
||||
{
|
||||
QString result;
|
||||
|
||||
if (!getClientOperatingSystem().isEmpty()) {
|
||||
// We don't want translatable strings in the 'Debug Log' for easier troubleshooting
|
||||
result.append(QString("Client Operating System: ") + getClientOperatingSystem() + "\n");
|
||||
}
|
||||
|
||||
result.append(QString("Build Architecture: ") + QString::fromStdString(BUILD_ARCHITECTURE) + "\n");
|
||||
result.append(QString("Qt Version: ") + QT_VERSION_STR);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString Logger::getClientOperatingSystem()
|
||||
{
|
||||
return QSysInfo::prettyProductName();
|
||||
}
|
||||
|
||||
QString Logger::getSystemLocale()
|
||||
{
|
||||
QString result(QString("System Locale: ") + QLocale().name());
|
||||
return result;
|
||||
}
|
||||
|
||||
QString Logger::getClientInstallInfo()
|
||||
{
|
||||
// don't rely on settingsCache->getIsPortableBuild() since the logger is initialized earlier
|
||||
bool isPortable = QFile::exists(qApp->applicationDirPath() + "/portable.dat");
|
||||
QString result(QString("Install Mode: ") + (isPortable ? "Portable" : "Standard"));
|
||||
return result;
|
||||
}
|
||||
72
libcockatrice_utility/libcockatrice/utility/logger.h
Normal file
72
libcockatrice_utility/libcockatrice/utility/logger.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file logger.h
|
||||
* @ingroup Core
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
#include <QVector>
|
||||
|
||||
#if defined(Q_PROCESSOR_X86_32)
|
||||
#define BUILD_ARCHITECTURE "32-bit"
|
||||
#elif defined(Q_PROCESSOR_X86_64)
|
||||
#define BUILD_ARCHITECTURE "64-bit"
|
||||
#elif defined(Q_PROCESSOR_ARM)
|
||||
#define BUILD_ARCHITECTURE "ARM"
|
||||
#else
|
||||
#define BUILD_ARCHITECTURE "unknown"
|
||||
#endif
|
||||
|
||||
class Logger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Logger &getInstance()
|
||||
{
|
||||
static Logger instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void logToFile(bool enabled);
|
||||
void log(QtMsgType type, const QMessageLogContext &ctx, const QString &message);
|
||||
QString getClientVersion();
|
||||
QString getClientOperatingSystem();
|
||||
QString getSystemArchitecture();
|
||||
QString getSystemLocale();
|
||||
QString getClientInstallInfo();
|
||||
QList<QString> getLogBuffer()
|
||||
{
|
||||
return logBuffer;
|
||||
}
|
||||
|
||||
private:
|
||||
Logger();
|
||||
~Logger() override;
|
||||
// Singleton - Don't implement copy constructor and assign operator
|
||||
Logger(Logger const &);
|
||||
void operator=(Logger const &);
|
||||
|
||||
bool logToFileEnabled;
|
||||
QTextStream fileStream;
|
||||
QFile fileHandle;
|
||||
QList<QString> logBuffer;
|
||||
QMutex mutex;
|
||||
|
||||
protected:
|
||||
void openLogfileSession();
|
||||
void closeLogfileSession();
|
||||
|
||||
protected slots:
|
||||
void internalLog(const QString &message);
|
||||
|
||||
signals:
|
||||
void logEntryAdded(const QString &message);
|
||||
};
|
||||
|
||||
#endif
|
||||
17
libcockatrice_utility/libcockatrice/utility/macros.h
Normal file
17
libcockatrice_utility/libcockatrice/utility/macros.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef COCKATRICE_MACROS_H
|
||||
#define COCKATRICE_MACROS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
// Qt6.7 changed how stateChanged functionality
|
||||
// of QCheckBoxes work.
|
||||
// See https://doc.qt.io/qt-6/qcheckbox.html#checkStateChanged
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||
#define QT_STATE_CHANGED checkStateChanged
|
||||
#define QT_STATE_CHANGED_T Qt::CheckState
|
||||
#else
|
||||
#define QT_STATE_CHANGED stateChanged
|
||||
#define QT_STATE_CHANGED_T int
|
||||
#endif
|
||||
|
||||
#endif // COCKATRICE_MACROS_H
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "passwordhasher.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <libcockatrice/rng/rng_sfmt.h>
|
||||
|
||||
QString PasswordHasher::computeHash(const QString &password, const QString &salt)
|
||||
{
|
||||
QCryptographicHash::Algorithm algo = QCryptographicHash::Sha512;
|
||||
const int rounds = 1000;
|
||||
|
||||
QByteArray hash = (salt + password).toUtf8();
|
||||
for (int i = 0; i < rounds; ++i) {
|
||||
hash = QCryptographicHash::hash(hash, algo);
|
||||
}
|
||||
QString hashedPass = salt + QString(hash.toBase64());
|
||||
return hashedPass;
|
||||
}
|
||||
|
||||
QString PasswordHasher::generateRandomSalt(const int len)
|
||||
{
|
||||
static const char alphanum[] = "0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
QString ret;
|
||||
int size = sizeof(alphanum) - 1;
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
ret.append(alphanum[rng->rand(0, size)]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString PasswordHasher::generateActivationToken()
|
||||
{
|
||||
return QCryptographicHash::hash(generateRandomSalt().toUtf8(), QCryptographicHash::Md5).toBase64().left(16);
|
||||
}
|
||||
14
libcockatrice_utility/libcockatrice/utility/passwordhasher.h
Normal file
14
libcockatrice_utility/libcockatrice/utility/passwordhasher.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef PASSWORDHASHER_H
|
||||
#define PASSWORDHASHER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class PasswordHasher
|
||||
{
|
||||
public:
|
||||
static QString computeHash(const QString &password, const QString &salt);
|
||||
static QString generateRandomSalt(const int len = 16);
|
||||
static QString generateActivationToken();
|
||||
};
|
||||
|
||||
#endif
|
||||
4937
libcockatrice_utility/libcockatrice/utility/peglib.h
Normal file
4937
libcockatrice_utility/libcockatrice/utility/peglib.h
Normal file
File diff suppressed because it is too large
Load Diff
32
libcockatrice_utility/libcockatrice/utility/trice_limits.h
Normal file
32
libcockatrice_utility/libcockatrice/utility/trice_limits.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef TRICE_LIMITS_H
|
||||
#define TRICE_LIMITS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
// max size for short strings, like names and things that are generally a single phrase
|
||||
constexpr int MAX_NAME_LENGTH = 0xff;
|
||||
// max size for chat messages and text contents
|
||||
constexpr int MAX_TEXT_LENGTH = 0xfff;
|
||||
// max size for deck files and pictures
|
||||
constexpr int MAX_FILE_LENGTH = 0x1fffff; // about 2 megabytes
|
||||
|
||||
constexpr uint MINIMUM_DIE_SIDES = 2;
|
||||
constexpr uint MAXIMUM_DIE_SIDES = 1000000;
|
||||
constexpr uint MINIMUM_DICE_TO_ROLL = 1;
|
||||
constexpr uint MAXIMUM_DICE_TO_ROLL = 100;
|
||||
|
||||
// optimized functions to get qstrings that are at most that long
|
||||
static inline QString nameFromStdString(const std::string &_string)
|
||||
{
|
||||
return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_NAME_LENGTH));
|
||||
}
|
||||
static inline QString textFromStdString(const std::string &_string)
|
||||
{
|
||||
return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_TEXT_LENGTH));
|
||||
}
|
||||
static inline QString fileFromStdString(const std::string &_string)
|
||||
{
|
||||
return QString::fromUtf8(_string.data(), std::min(int(_string.size()), MAX_FILE_LENGTH));
|
||||
}
|
||||
|
||||
#endif // TRICE_LIMITS_H
|
||||
Reference in New Issue
Block a user