Cppfix (#142)
修了一些需要重新编译的bug 修大厅卡死尸体 修“已经有人登入” 修服务端翻译文件 增加出牌时间设置 修Linux下复制文件bug 再次尝试wasm
This commit is contained in:
parent
3dfff72836
commit
34ce4c9859
|
@ -5,10 +5,8 @@ cmake_minimum_required(VERSION 3.16)
|
||||||
project(FreeKill VERSION 0.1.6)
|
project(FreeKill VERSION 0.1.6)
|
||||||
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
|
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
|
||||||
|
|
||||||
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
include_directories(fkparse/src)
|
||||||
include_directories(fkparse/src)
|
add_subdirectory(fkparse)
|
||||||
add_subdirectory(fkparse)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS
|
find_package(Qt6 REQUIRED COMPONENTS
|
||||||
Network
|
Network
|
||||||
|
@ -86,14 +84,53 @@ add_custom_command(
|
||||||
)
|
)
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||||
file(GLOB_RECURSE FK_RESOURCE_FILES
|
|
||||||
RELATIVE ${PROJECT_SOURCE_DIR}
|
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS}
|
||||||
*.lua *.qml *.js *.png *.jpg *.mp3
|
"-s INITIAL_MEMORY=64MB"
|
||||||
)
|
)
|
||||||
list(APPEND FK_RESOURCE_FILES "fonts/FZLBGBK.ttf")
|
|
||||||
qt_add_resources(FreeKill "qrc"
|
file(GLOB_RECURSE FK_SCRIPT_FILES
|
||||||
PREFIX "/"
|
RELATIVE ${PROJECT_SOURCE_DIR}
|
||||||
FILES ${FK_RESOURCE_FILES}
|
*.lua *.qml *.js *.fkp *.sql zh_CN.qm
|
||||||
)
|
)
|
||||||
|
qt_add_resources(FreeKill "scripts_qrc"
|
||||||
|
PREFIX "/"
|
||||||
|
FILES ${FK_SCRIPT_FILES}
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_resources(FreeKill "font_qrc"
|
||||||
|
PREFIX "/"
|
||||||
|
FILES "fonts/FZLBGBK.ttf"
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE FK_IMG_FILES
|
||||||
|
RELATIVE ${PROJECT_SOURCE_DIR}
|
||||||
|
${PROJECT_SOURCE_DIR}/image/*.jpg
|
||||||
|
${PROJECT_SOURCE_DIR}/image/*.png
|
||||||
|
)
|
||||||
|
qt_add_resources(FreeKill "img_qrc"
|
||||||
|
PREFIX "/"
|
||||||
|
FILES ${FK_IMG_FILES}
|
||||||
|
)
|
||||||
|
file(GLOB_RECURSE FK_AUDIO_FILES
|
||||||
|
RELATIVE ${PROJECT_SOURCE_DIR}
|
||||||
|
${PROJECT_SOURCE_DIR}/audio/*.mp3
|
||||||
|
)
|
||||||
|
qt_add_resources(FreeKill "audio_qrc"
|
||||||
|
PREFIX "/"
|
||||||
|
FILES ${FK_AUDIO_FILES}
|
||||||
|
)
|
||||||
|
file(GLOB_RECURSE FK_PKG_FILES
|
||||||
|
RELATIVE ${PROJECT_SOURCE_DIR}
|
||||||
|
${PROJECT_SOURCE_DIR}/packages/*.mp3
|
||||||
|
${PROJECT_SOURCE_DIR}/packages/*.jpg
|
||||||
|
${PROJECT_SOURCE_DIR}/packages/*.png
|
||||||
|
)
|
||||||
|
qt_add_resources(FreeKill "pkg_qrc"
|
||||||
|
PREFIX "/"
|
||||||
|
FILES ${FK_PKG_FILES}
|
||||||
|
)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
2
fkparse
2
fkparse
|
@ -1 +1 @@
|
||||||
Subproject commit 64481662879765f5631a291d512f7a74125051f3
|
Subproject commit fd7023f0752bfaa6fc5230ef1b1835eb4dfefe2f
|
|
@ -30,6 +30,7 @@ Fk:loadTranslationTable{
|
||||||
["$RoomName"] = "%1的房间",
|
["$RoomName"] = "%1的房间",
|
||||||
["Player num"] = "玩家数目",
|
["Player num"] = "玩家数目",
|
||||||
["Select general num"] = "选将数目",
|
["Select general num"] = "选将数目",
|
||||||
|
["Operation timeout"] = "操作时长(秒)",
|
||||||
["Game Mode"] = "游戏模式",
|
["Game Mode"] = "游戏模式",
|
||||||
["Enable free assign"] = "自由选将",
|
["Enable free assign"] = "自由选将",
|
||||||
["Enable deputy general"] = "启用副将机制",
|
["Enable deputy general"] = "启用副将机制",
|
||||||
|
|
|
@ -23,6 +23,8 @@ QtObject {
|
||||||
property real bgmVolume
|
property real bgmVolume
|
||||||
property bool disableMsgAudio
|
property bool disableMsgAudio
|
||||||
|
|
||||||
|
property int preferredTimeout
|
||||||
|
|
||||||
// Player property of client
|
// Player property of client
|
||||||
property string serverAddr
|
property string serverAddr
|
||||||
property string screenName: ""
|
property string screenName: ""
|
||||||
|
@ -56,6 +58,7 @@ QtObject {
|
||||||
Backend.volume = conf.effectVolume ?? 50.;
|
Backend.volume = conf.effectVolume ?? 50.;
|
||||||
bgmVolume = conf.bgmVolume ?? 50.;
|
bgmVolume = conf.bgmVolume ?? 50.;
|
||||||
disableMsgAudio = conf.disableMsgAudio ?? false;
|
disableMsgAudio = conf.disableMsgAudio ?? false;
|
||||||
|
preferredTimeout = conf.preferredTimeout ?? 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveConf() {
|
function saveConf() {
|
||||||
|
@ -77,6 +80,7 @@ QtObject {
|
||||||
conf.effectVolume = Backend.volume;
|
conf.effectVolume = Backend.volume;
|
||||||
conf.bgmVolume = bgmVolume;
|
conf.bgmVolume = bgmVolume;
|
||||||
conf.disableMsgAudio = disableMsgAudio;
|
conf.disableMsgAudio = disableMsgAudio;
|
||||||
|
conf.preferredTimeout = preferredTimeout;
|
||||||
|
|
||||||
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 20
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
@ -80,6 +78,24 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: Backend.translate("Operation timeout")
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
from: 10
|
||||||
|
to: 60
|
||||||
|
editable: true
|
||||||
|
value: config.preferredTimeout
|
||||||
|
|
||||||
|
onValueChanged: {
|
||||||
|
config.preferredTimeout = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
id: freeAssignCheck
|
id: freeAssignCheck
|
||||||
checked: Debugging ? true : false
|
checked: Debugging ? true : false
|
||||||
|
@ -102,7 +118,7 @@ ColumnLayout {
|
||||||
mainWindow.busy = true;
|
mainWindow.busy = true;
|
||||||
ClientInstance.notifyServer(
|
ClientInstance.notifyServer(
|
||||||
"CreateRoom",
|
"CreateRoom",
|
||||||
JSON.stringify([roomName.text, playerNum.value, {
|
JSON.stringify([roomName.text, playerNum.value, config.preferredTimeout, {
|
||||||
enableFreeAssign: freeAssignCheck.checked,
|
enableFreeAssign: freeAssignCheck.checked,
|
||||||
enableDeputy: deputyCheck.checked,
|
enableDeputy: deputyCheck.checked,
|
||||||
gameMode: config.preferedMode,
|
gameMode: config.preferedMode,
|
||||||
|
|
|
@ -1,65 +1,187 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
scale: 2
|
|
||||||
|
|
||||||
// Change this to your server's IP or domain name
|
Item {
|
||||||
property string server_addr: ServerAddr
|
width: 960 * 0.8
|
||||||
|
height: 540 * 0.8
|
||||||
Frame {
|
|
||||||
id: join_server
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
background: Rectangle {
|
|
||||||
color: "#88888888"
|
Item {
|
||||||
radius: 2
|
id: left
|
||||||
|
width: 300
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: lady
|
||||||
|
width: parent.width + 20
|
||||||
|
height: parent.height
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 12
|
||||||
|
width: parent.width
|
||||||
|
source: AppPath + "/image/widelogo"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Rectangle {
|
||||||
spacing: 8
|
id: right
|
||||||
TextField {
|
anchors.left: left.right
|
||||||
id: screenNameEdit
|
width: parent.width - left.width
|
||||||
maximumLength: 32
|
height: parent.height
|
||||||
text: "player"
|
color: "#88EEEEEE"
|
||||||
onTextChanged: {
|
radius: 16
|
||||||
passwordEdit.text = "";
|
|
||||||
let data = config.savedPassword[server_addr.editText];
|
ColumnLayout {
|
||||||
if (data) {
|
width: parent.width * 0.8
|
||||||
if (text === data.username) {
|
height: parent.height * 0.8
|
||||||
passwordEdit.text = data.shorten_password;
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 40
|
||||||
|
//spacing
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Welcome back!")
|
||||||
|
font.pixelSize: 28
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 20
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Server Addr")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
id: server_addr
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: []
|
||||||
|
editable: true
|
||||||
|
|
||||||
|
onEditTextChanged: {
|
||||||
|
if (model.indexOf(editText) === -1) {
|
||||||
|
passwordEdit.text = "";
|
||||||
|
} else {
|
||||||
|
let data = config.savedPassword[editText];
|
||||||
|
screenNameEdit.text = data.username;
|
||||||
|
passwordEdit.text = data.shorten_password;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Username")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: screenNameEdit
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("Username")
|
||||||
|
text: ""
|
||||||
|
onTextChanged: {
|
||||||
|
passwordEdit.text = "";
|
||||||
|
let data = config.savedPassword[server_addr.editText];
|
||||||
|
if (data) {
|
||||||
|
if (text === data.username) {
|
||||||
|
passwordEdit.text = data.shorten_password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: showPasswordCheck
|
||||||
|
text: qsTr("Show Password")
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: passwordEdit
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: qsTr("Password")
|
||||||
|
text: ""
|
||||||
|
echoMode: showPasswordCheck.checked ? TextInput.Normal : TextInput.Password
|
||||||
|
passwordCharacter: "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Join Server")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
display: AbstractButton.TextBesideIcon
|
||||||
|
icon.name: "go-next"
|
||||||
|
enabled: passwordEdit.text !== ""
|
||||||
|
onClicked: {
|
||||||
|
config.serverAddr = server_addr.editText;
|
||||||
|
config.screenName = screenNameEdit.text;
|
||||||
|
config.password = passwordEdit.text;
|
||||||
|
mainWindow.busy = true;
|
||||||
|
Backend.joinServer(server_addr.editText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("PackageManage")
|
||||||
|
onClicked: {
|
||||||
|
mainStack.push(packageManage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextField {
|
|
||||||
id: passwordEdit
|
Text {
|
||||||
maximumLength: 64
|
anchors.left: parent.left
|
||||||
text: ""
|
anchors.bottom: parent.bottom
|
||||||
echoMode: TextInput.Password
|
anchors.leftMargin: 12
|
||||||
passwordCharacter: "*"
|
anchors.bottomMargin: 12
|
||||||
|
text: "FreeKill " + FkVersion
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
}
|
}
|
||||||
Button {
|
|
||||||
text: "Login"
|
Text {
|
||||||
enabled: passwordEdit.text !== ""
|
anchors.right: parent.right
|
||||||
onClicked: {
|
anchors.bottom: parent.bottom
|
||||||
config.serverAddr = server_addr;
|
anchors.rightMargin: 8
|
||||||
config.screenName = screenNameEdit.text;
|
anchors.bottomMargin: 8
|
||||||
config.password = passwordEdit.text;
|
text: qsTr("FAQ")
|
||||||
mainWindow.busy = true;
|
color: "blue"
|
||||||
Backend.joinServer(server_addr);
|
font.pixelSize: 24
|
||||||
|
font.underline: true
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
onTapped: {
|
||||||
|
errDialog.txt = qsTr("$LoginFAQ");
|
||||||
|
errDialog.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function downloadComplete() {
|
||||||
|
toast.show(qsTr("updated packages for md5"));
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
config.loadConf();
|
config.loadConf();
|
||||||
|
|
||||||
|
lady.source = config.ladyImg;
|
||||||
|
|
||||||
|
server_addr.model = Object.keys(config.savedPassword);
|
||||||
|
server_addr.onModelChanged();
|
||||||
|
server_addr.currentIndex = server_addr.model.indexOf(config.lastLoginServer);
|
||||||
|
|
||||||
let data = config.savedPassword[config.lastLoginServer];
|
let data = config.savedPassword[config.lastLoginServer];
|
||||||
screenNameEdit.text = data.username;
|
if (data) {
|
||||||
passwordEdit.text = data.shorten_password;
|
screenNameEdit.text = data.username;
|
||||||
|
passwordEdit.text = data.shorten_password;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ set(freekill_SRCS
|
||||||
"server/server.cpp"
|
"server/server.cpp"
|
||||||
"server/serverplayer.cpp"
|
"server/serverplayer.cpp"
|
||||||
"server/room.cpp"
|
"server/room.cpp"
|
||||||
|
"ui/qmlbackend.cpp"
|
||||||
"swig/freekill-wrap.cxx"
|
"swig/freekill-wrap.cxx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,7 +20,6 @@ if (NOT DEFINED FK_SERVER_ONLY)
|
||||||
list(APPEND freekill_SRCS
|
list(APPEND freekill_SRCS
|
||||||
"client/client.cpp"
|
"client/client.cpp"
|
||||||
"client/clientplayer.cpp"
|
"client/clientplayer.cpp"
|
||||||
"ui/qmlbackend.cpp"
|
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
@ -66,9 +66,11 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||||
"server/serverplayer.cpp"
|
"server/serverplayer.cpp"
|
||||||
"server/room.cpp"
|
"server/room.cpp"
|
||||||
)
|
)
|
||||||
set(FKP_LIB "")
|
# set(LUA_LIB ${PROJECT_SOURCE_DIR}/lib/wasm/liblua.a)
|
||||||
set(LUA_LIB ${PROJECT_SOURCE_DIR}/lib/wasm/liblua.a)
|
# set(CRYPTO_LIB ${PROJECT_SOURCE_DIR}/lib/wasm/libcrypto.a)
|
||||||
set(CRYPTO_LIB ${PROJECT_SOURCE_DIR}/lib/wasm/libcrypto.a)
|
# set other libs by yourself
|
||||||
|
set(IDBFS_LIB idbfs.js)
|
||||||
|
include(${FK_WASM_TOOLCHAIN})
|
||||||
else ()
|
else ()
|
||||||
set(LUA_LIB lua5.4)
|
set(LUA_LIB lua5.4)
|
||||||
set(SQLITE3_LIB sqlite3)
|
set(SQLITE3_LIB sqlite3)
|
||||||
|
@ -89,6 +91,7 @@ target_link_libraries(FreeKill PRIVATE
|
||||||
${FKP_LIB}
|
${FKP_LIB}
|
||||||
${QT_LIB}
|
${QT_LIB}
|
||||||
${GIT_LIB}
|
${GIT_LIB}
|
||||||
|
${IDBFS_LIB}
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS FreeKill DESTINATION bin)
|
install(TARGETS FreeKill DESTINATION bin)
|
||||||
|
|
|
@ -60,7 +60,6 @@ void Dumpstack(lua_State *L) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_WASM
|
|
||||||
sqlite3 *OpenDatabase(const QString &filename, const QString &initSql) {
|
sqlite3 *OpenDatabase(const QString &filename, const QString &initSql) {
|
||||||
sqlite3 *ret;
|
sqlite3 *ret;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -123,6 +122,7 @@ void ExecSQL(sqlite3 *db, const QString &sql) {
|
||||||
|
|
||||||
void CloseDatabase(sqlite3 *db) { sqlite3_close(db); }
|
void CloseDatabase(sqlite3 *db) { sqlite3_close(db); }
|
||||||
|
|
||||||
|
#ifndef Q_OS_WASM
|
||||||
RSA *InitServerRSA() {
|
RSA *InitServerRSA() {
|
||||||
RSA *rsa = RSA_new();
|
RSA *rsa = RSA_new();
|
||||||
if (!QFile::exists("server/rsa_pub")) {
|
if (!QFile::exists("server/rsa_pub")) {
|
||||||
|
@ -222,7 +222,7 @@ QJsonDocument String2Json(const QString &str) {
|
||||||
|
|
||||||
QString Color(const QString &raw, fkShell::TextColor color,
|
QString Color(const QString &raw, fkShell::TextColor color,
|
||||||
fkShell::TextType type) {
|
fkShell::TextType type) {
|
||||||
#ifndef Q_OS_WIN32
|
#ifdef Q_OS_LINUX
|
||||||
static const char *suffix = "\e[0;0m";
|
static const char *suffix = "\e[0;0m";
|
||||||
int col = 30 + color;
|
int col = 30 + color;
|
||||||
int t = type == fkShell::Bold ? 1 : 0;
|
int t = type == fkShell::Bold ? 1 : 0;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
lua_State *CreateLuaState();
|
lua_State *CreateLuaState();
|
||||||
bool DoLuaScript(lua_State *L, const char *script);
|
bool DoLuaScript(lua_State *L, const char *script);
|
||||||
|
|
||||||
#ifndef Q_OS_WASM
|
|
||||||
sqlite3 *OpenDatabase(const QString &filename = "./server/users.db", const QString &initSql = "./server/init.sql");
|
sqlite3 *OpenDatabase(const QString &filename = "./server/users.db", const QString &initSql = "./server/init.sql");
|
||||||
QJsonArray SelectFromDatabase(sqlite3 *db, const QString &sql);
|
QJsonArray SelectFromDatabase(sqlite3 *db, const QString &sql);
|
||||||
// For Lua
|
// For Lua
|
||||||
|
@ -16,6 +15,7 @@ QString SelectFromDb(sqlite3 *db, const QString &sql);
|
||||||
void ExecSQL(sqlite3 *db, const QString &sql);
|
void ExecSQL(sqlite3 *db, const QString &sql);
|
||||||
void CloseDatabase(sqlite3 *db);
|
void CloseDatabase(sqlite3 *db);
|
||||||
|
|
||||||
|
#ifndef Q_OS_WASM
|
||||||
RSA *InitServerRSA();
|
RSA *InitServerRSA();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
34
src/main.cpp
34
src/main.cpp
|
@ -4,9 +4,11 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
using namespace fkShell;
|
using namespace fkShell;
|
||||||
|
|
||||||
#ifndef Q_OS_WASM
|
|
||||||
#include "packman.h"
|
#include "packman.h"
|
||||||
|
#ifndef Q_OS_WASM
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
#else
|
||||||
|
#include <emscripten.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
||||||
|
@ -80,15 +82,16 @@ static void prepareForLinux() {
|
||||||
// TODO: AppImage
|
// TODO: AppImage
|
||||||
char buf[256] = {0};
|
char buf[256] = {0};
|
||||||
int len = readlink("/proc/self/exe", buf, 256);
|
int len = readlink("/proc/self/exe", buf, 256);
|
||||||
|
const char *home = getenv("HOME");
|
||||||
if (!strcmp(buf, "/usr/bin/FreeKill")) {
|
if (!strcmp(buf, "/usr/bin/FreeKill")) {
|
||||||
system("mkdir -p ~/.local/share/FreeKill");
|
system("mkdir -p ~/.local/share/FreeKill");
|
||||||
installFkAssets("/usr/share/FreeKill", "~/.local/share");
|
installFkAssets("/usr/share/FreeKill", QString("%1/.local/share").arg(home));
|
||||||
chdir(getenv("HOME"));
|
chdir(home);
|
||||||
chdir(".local/share/FreeKill");
|
chdir(".local/share/FreeKill");
|
||||||
} else if (!strcmp(buf, "/usr/local/bin/FreeKill")) {
|
} else if (!strcmp(buf, "/usr/local/bin/FreeKill")) {
|
||||||
system("mkdir -p ~/.local/share/FreeKill");
|
system("mkdir -p ~/.local/share/FreeKill");
|
||||||
installFkAssets("/usr/local/share/FreeKill", "~/.local/share");
|
installFkAssets("/usr/local/share/FreeKill", QString("%1/.local/share").arg(home));
|
||||||
chdir(getenv("HOME"));
|
chdir(home);
|
||||||
chdir(".local/share/FreeKill");
|
chdir(".local/share/FreeKill");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,6 +170,10 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (startServer) {
|
if (startServer) {
|
||||||
app = new QCoreApplication(argc, argv);
|
app = new QCoreApplication(argc, argv);
|
||||||
|
QTranslator translator;
|
||||||
|
Q_UNUSED(translator.load("zh_CN.qm"));
|
||||||
|
QCoreApplication::installTranslator(&translator);
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (parser.value("server").toInt(&ok) && ok)
|
if (parser.value("server").toInt(&ok) && ok)
|
||||||
serverPort = parser.value("server").toInt();
|
serverPort = parser.value("server").toInt();
|
||||||
|
@ -194,6 +201,13 @@ int main(int argc, char *argv[]) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef Q_OS_WASM
|
#ifdef Q_OS_WASM
|
||||||
|
EM_ASM (
|
||||||
|
FS.mkdir('/assets');
|
||||||
|
FS.mount(IDBFS, {}, '/assets');
|
||||||
|
FS.chdir('/assets');
|
||||||
|
FS.syncfs(true, function(err) {
|
||||||
|
});
|
||||||
|
);
|
||||||
copyPath(":/", QDir::currentPath());
|
copyPath(":/", QDir::currentPath());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -234,8 +248,6 @@ int main(int argc, char *argv[]) {
|
||||||
QQuickStyle::setStyle("Material");
|
QQuickStyle::setStyle("Material");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 加载 zh_CN.qm 翻译文件
|
|
||||||
// TODO: i18n
|
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
Q_UNUSED(translator.load("zh_CN.qm"));
|
Q_UNUSED(translator.load("zh_CN.qm"));
|
||||||
QCoreApplication::installTranslator(&translator);
|
QCoreApplication::installTranslator(&translator);
|
||||||
|
@ -243,9 +255,7 @@ int main(int argc, char *argv[]) {
|
||||||
QmlBackend backend;
|
QmlBackend backend;
|
||||||
backend.setEngine(engine);
|
backend.setEngine(engine);
|
||||||
|
|
||||||
#ifndef Q_OS_WASM
|
|
||||||
Pacman = new PackMan;
|
Pacman = new PackMan;
|
||||||
#endif
|
|
||||||
|
|
||||||
// 向 Qml 中先定义几个全局变量
|
// 向 Qml 中先定义几个全局变量
|
||||||
engine->rootContext()->setContextProperty("FkVersion", FK_VERSION);
|
engine->rootContext()->setContextProperty("FkVersion", FK_VERSION);
|
||||||
|
@ -294,6 +304,12 @@ int main(int argc, char *argv[]) {
|
||||||
delete engine;
|
delete engine;
|
||||||
delete Pacman;
|
delete Pacman;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WASM
|
||||||
|
EM_ASM (
|
||||||
|
FS.syncfs(function(err) {});
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ void Router::setSocket(ClientSocket *socket) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Router::removeSocket() {
|
||||||
|
socket->disconnect(this);
|
||||||
|
socket = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Router::installAESKey(const QByteArray &key) {
|
void Router::installAESKey(const QByteArray &key) {
|
||||||
socket->installAESKey(key);
|
socket->installAESKey(key);
|
||||||
}
|
}
|
||||||
|
@ -195,9 +200,10 @@ void Router::handlePacket(const QByteArray &rawPacket) {
|
||||||
auto arr = String2Json(jsonData).array();
|
auto arr = String2Json(jsonData).array();
|
||||||
auto name = arr[0].toString();
|
auto name = arr[0].toString();
|
||||||
auto capacity = arr[1].toInt();
|
auto capacity = arr[1].toInt();
|
||||||
|
auto timeout = arr[2].toInt();
|
||||||
auto settings =
|
auto settings =
|
||||||
QJsonDocument(arr[2].toObject()).toJson(QJsonDocument::Compact);
|
QJsonDocument(arr[3].toObject()).toJson(QJsonDocument::Compact);
|
||||||
ServerInstance->createRoom(sender, name, capacity, settings);
|
ServerInstance->createRoom(sender, name, capacity, timeout, settings);
|
||||||
};
|
};
|
||||||
lobby_actions["EnterRoom"] = [](ServerPlayer *sender,
|
lobby_actions["EnterRoom"] = [](ServerPlayer *sender,
|
||||||
const QString &jsonData) {
|
const QString &jsonData) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
ClientSocket *getSocket() const;
|
ClientSocket *getSocket() const;
|
||||||
void setSocket(ClientSocket *socket);
|
void setSocket(ClientSocket *socket);
|
||||||
|
void removeSocket();
|
||||||
void installAESKey(const QByteArray &key);
|
void installAESKey(const QByteArray &key);
|
||||||
|
|
||||||
#ifndef FK_CLIENT_ONLY
|
#ifndef FK_CLIENT_ONLY
|
||||||
|
|
|
@ -87,7 +87,7 @@ bool Server::listen(const QHostAddress &address, ushort port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
||||||
const QByteArray &settings) {
|
int timeout, const QByteArray &settings) {
|
||||||
Room *room;
|
Room *room;
|
||||||
if (!idle_rooms.isEmpty()) {
|
if (!idle_rooms.isEmpty()) {
|
||||||
room = idle_rooms.pop();
|
room = idle_rooms.pop();
|
||||||
|
@ -106,6 +106,7 @@ void Server::createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
||||||
|
|
||||||
room->setName(name);
|
room->setName(name);
|
||||||
room->setCapacity(capacity);
|
room->setCapacity(capacity);
|
||||||
|
room->setTimeout(timeout);
|
||||||
room->setSettings(settings);
|
room->setSettings(settings);
|
||||||
room->addPlayer(owner);
|
room->addPlayer(owner);
|
||||||
if (!room->isLobby())
|
if (!room->isLobby())
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
ushort port = 9527u);
|
ushort port = 9527u);
|
||||||
|
|
||||||
void createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
void createRoom(ServerPlayer *owner, const QString &name, int capacity,
|
||||||
const QByteArray &settings = "{}");
|
int timeout = 15, const QByteArray &settings = "{}");
|
||||||
|
|
||||||
Room *findRoom(int id) const;
|
Room *findRoom(int id) const;
|
||||||
Room *lobby() const;
|
Room *lobby() const;
|
||||||
|
|
|
@ -52,7 +52,9 @@ ClientSocket *ServerPlayer::getSocket() const { return socket; }
|
||||||
// 处理跑路玩家专用,就单纯把socket置为null
|
// 处理跑路玩家专用,就单纯把socket置为null
|
||||||
// 因为后面还会用到socket所以不删除
|
// 因为后面还会用到socket所以不删除
|
||||||
void ServerPlayer::removeSocket() {
|
void ServerPlayer::removeSocket() {
|
||||||
this->socket = nullptr;
|
socket->disconnect(this);
|
||||||
|
socket = nullptr;
|
||||||
|
router->removeSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
Server *ServerPlayer::getServer() const { return server; }
|
Server *ServerPlayer::getServer() const { return server; }
|
||||||
|
|
|
@ -8,11 +8,13 @@
|
||||||
#include "clientplayer.h"
|
#include "clientplayer.h"
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "qmlbackend.h"
|
||||||
class ClientPlayer *Self = nullptr;
|
class ClientPlayer *Self = nullptr;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "naturalvar.i"
|
%include "naturalvar.i"
|
||||||
%include "qt.i"
|
%include "qt.i"
|
||||||
|
%include "qml-nogui.i"
|
||||||
%include "player.i"
|
%include "player.i"
|
||||||
%include "server.i"
|
%include "server.i"
|
||||||
%include "sqlite3.i"
|
%include "sqlite3.i"
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
%nodefaultctor QmlBackend;
|
||||||
|
%nodefaultdtor QmlBackend;
|
||||||
|
class QmlBackend : public QObject {
|
||||||
|
public:
|
||||||
|
static void cd(const QString &path);
|
||||||
|
static QStringList ls(const QString &dir);
|
||||||
|
static QString pwd();
|
||||||
|
static bool exists(const QString &file);
|
||||||
|
static bool isDir(const QString &file);
|
||||||
|
};
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
#include "qmlbackend.h"
|
#include "qmlbackend.h"
|
||||||
|
|
||||||
|
#ifndef FK_SERVER_ONLY
|
||||||
#include <qaudiooutput.h>
|
#include <qaudiooutput.h>
|
||||||
#include <qmediaplayer.h>
|
#include <qmediaplayer.h>
|
||||||
#include <qrandom.h>
|
#include <qrandom.h>
|
||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QMediaPlayer>
|
#include <QMediaPlayer>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#ifndef Q_OS_WASM
|
#ifndef Q_OS_WASM
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
@ -19,15 +22,48 @@ QmlBackend *Backend = nullptr;
|
||||||
|
|
||||||
QmlBackend::QmlBackend(QObject *parent) : QObject(parent) {
|
QmlBackend::QmlBackend(QObject *parent) : QObject(parent) {
|
||||||
Backend = this;
|
Backend = this;
|
||||||
|
#ifndef FK_SERVER_ONLY
|
||||||
engine = nullptr;
|
engine = nullptr;
|
||||||
rsa = RSA_new();
|
rsa = RSA_new();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlBackend::~QmlBackend() {
|
QmlBackend::~QmlBackend() {
|
||||||
Backend = nullptr;
|
Backend = nullptr;
|
||||||
|
#ifndef FK_SERVER_ONLY
|
||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlBackend::cd(const QString &path) { QDir::setCurrent(path); }
|
||||||
|
|
||||||
|
QStringList QmlBackend::ls(const QString &dir) {
|
||||||
|
QString d = dir;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (d.startsWith("file:///"))
|
||||||
|
d.replace(0, 8, "file://");
|
||||||
|
#endif
|
||||||
|
return QDir(QUrl(d).path())
|
||||||
|
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlBackend::pwd() { return QDir::currentPath(); }
|
||||||
|
|
||||||
|
bool QmlBackend::exists(const QString &file) {
|
||||||
|
QString s = file;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (s.startsWith("file:///"))
|
||||||
|
s.replace(0, 8, "file://");
|
||||||
|
#endif
|
||||||
|
return QFile::exists(QUrl(s).path());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlBackend::isDir(const QString &file) {
|
||||||
|
return QFileInfo(QUrl(file).path()).isDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef FK_SERVER_ONLY
|
||||||
|
|
||||||
QQmlApplicationEngine *QmlBackend::getEngine() const { return engine; }
|
QQmlApplicationEngine *QmlBackend::getEngine() const { return engine; }
|
||||||
|
|
||||||
void QmlBackend::setEngine(QQmlApplicationEngine *engine) {
|
void QmlBackend::setEngine(QQmlApplicationEngine *engine) {
|
||||||
|
@ -81,33 +117,6 @@ void QmlBackend::emitNotifyUI(const QString &command, const QString &jsonData) {
|
||||||
emit notifyUI(command, jsonData);
|
emit notifyUI(command, jsonData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlBackend::cd(const QString &path) { QDir::setCurrent(path); }
|
|
||||||
|
|
||||||
QStringList QmlBackend::ls(const QString &dir) {
|
|
||||||
QString d = dir;
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (d.startsWith("file:///"))
|
|
||||||
d.replace(0, 8, "file://");
|
|
||||||
#endif
|
|
||||||
return QDir(QUrl(d).path())
|
|
||||||
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QmlBackend::pwd() { return QDir::currentPath(); }
|
|
||||||
|
|
||||||
bool QmlBackend::exists(const QString &file) {
|
|
||||||
QString s = file;
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (s.startsWith("file:///"))
|
|
||||||
s.replace(0, 8, "file://");
|
|
||||||
#endif
|
|
||||||
return QFile::exists(QUrl(s).path());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QmlBackend::isDir(const QString &file) {
|
|
||||||
return QFileInfo(QUrl(file).path()).isDir();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QmlBackend::translate(const QString &src) {
|
QString QmlBackend::translate(const QString &src) {
|
||||||
if (!ClientInstance)
|
if (!ClientInstance)
|
||||||
return src;
|
return src;
|
||||||
|
@ -284,3 +293,5 @@ QString QmlBackend::getAESKey() const { return aes_key; }
|
||||||
void QmlBackend::installAESKey() {
|
void QmlBackend::installAESKey() {
|
||||||
ClientInstance->installAESKey(aes_key.toLatin1());
|
ClientInstance->installAESKey(aes_key.toLatin1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,12 +6,19 @@
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
class QmlBackend : public QObject {
|
class QmlBackend : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QmlBackend(QObject *parent = nullptr);
|
QmlBackend(QObject *parent = nullptr);
|
||||||
~QmlBackend();
|
~QmlBackend();
|
||||||
|
|
||||||
|
// File used by both Lua and Qml
|
||||||
|
static Q_INVOKABLE void cd(const QString &path);
|
||||||
|
static Q_INVOKABLE QStringList ls(const QString &dir = "");
|
||||||
|
static Q_INVOKABLE QString pwd();
|
||||||
|
static Q_INVOKABLE bool exists(const QString &file);
|
||||||
|
static Q_INVOKABLE bool isDir(const QString &file);
|
||||||
|
|
||||||
|
#ifndef FK_SERVER_ONLY
|
||||||
QQmlApplicationEngine *getEngine() const;
|
QQmlApplicationEngine *getEngine() const;
|
||||||
void setEngine(QQmlApplicationEngine *engine);
|
void setEngine(QQmlApplicationEngine *engine);
|
||||||
|
|
||||||
|
@ -24,13 +31,6 @@ public:
|
||||||
// lua --> qml
|
// lua --> qml
|
||||||
void emitNotifyUI(const QString &command, const QString &jsonData);
|
void emitNotifyUI(const QString &command, const QString &jsonData);
|
||||||
|
|
||||||
// File used by both Lua and Qml
|
|
||||||
static Q_INVOKABLE void cd(const QString &path);
|
|
||||||
static Q_INVOKABLE QStringList ls(const QString &dir = "");
|
|
||||||
static Q_INVOKABLE QString pwd();
|
|
||||||
static Q_INVOKABLE bool exists(const QString &file);
|
|
||||||
static Q_INVOKABLE bool isDir(const QString &file);
|
|
||||||
|
|
||||||
// read data from lua, call lua functions
|
// read data from lua, call lua functions
|
||||||
Q_INVOKABLE QString translate(const QString &src);
|
Q_INVOKABLE QString translate(const QString &src);
|
||||||
Q_INVOKABLE QString callLuaFunction(const QString &func_name,
|
Q_INVOKABLE QString callLuaFunction(const QString &func_name,
|
||||||
|
@ -57,12 +57,15 @@ signals:
|
||||||
void volumeChanged(qreal);
|
void volumeChanged(qreal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||||
|
|
||||||
QQmlApplicationEngine *engine;
|
QQmlApplicationEngine *engine;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
QString aes_key;
|
QString aes_key;
|
||||||
qreal m_volume;
|
qreal m_volume;
|
||||||
|
|
||||||
void pushLuaValue(lua_State *L, QVariant v);
|
void pushLuaValue(lua_State *L, QVariant v);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern QmlBackend *Backend;
|
extern QmlBackend *Backend;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# NGINX conf file for testing wasm build
|
||||||
|
|
||||||
|
worker_processes 1;
|
||||||
|
pid nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
gzip on;
|
||||||
|
|
||||||
|
error_log error.log;
|
||||||
|
access_log access.log;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 9580;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root .;
|
||||||
|
index index.html FreeKill.html;
|
||||||
|
|
||||||
|
add_header Cross-Origin-Opener-Policy same-origin;
|
||||||
|
add_header Cross-Origin-Embedder-Policy require-corp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue