Fixbug (#399)
Some checks are pending
Check Whitespace and New Line / check (push) Waiting to run
Deploy Doxygen to Pages / build (push) Waiting to run
Deploy Doxygen to Pages / deploy (push) Blocked by required conditions

* lua端的ob属性根本没同步,同步一下
* [需要C++] 让requestTimer的超时影响到Lua
* 修复windows没图标
* qmllint; remove modmaker
* 修理了选卡器
* 修理了确定取消消失
* 删除了已经不用的autoPending和respond_play
* 修复异常烧条(或许吧)
* 修复负数烧条时间,若为负数则无事发生
This commit is contained in:
notify 2024-10-24 16:41:06 +08:00 committed by GitHub
parent 30df075db2
commit 196e92f5d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 58 additions and 78 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@
/.cache/ /.cache/
/tags /tags
/.luarc.json /.luarc.json
/.qmllint.ini
# file produced by game # file produced by game
/FreeKill /FreeKill

View File

@ -4,7 +4,7 @@
# 2022-01-24 2023-02-21 v0.0.1 # 2022-01-24 2023-02-21 v0.0.1
# ------------------------------------------------------------ # ------------------------------------------------------------
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.22)
project(FreeKill VERSION 0.4.20) project(FreeKill VERSION 0.4.20)
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\") add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")

View File

@ -63,6 +63,9 @@ QtObject {
property list<string> blockedUsers: [] property list<string> blockedUsers: []
property int totalTime: 0 // FIXME: only for notifying property int totalTime: 0 // FIXME: only for notifying
onObservingChanged: lcall("SetObserving", observing);
//onReplayingChanged: lcall("SetReplaying", replaying);
// onDisabledGeneralsChanged: { // onDisabledGeneralsChanged: {
// disableGeneralSchemes[disableSchemeIdx] = disabledGenerals; // disableGeneralSchemes[disableSchemeIdx] = disabledGenerals;
// } // }

View File

@ -390,7 +390,6 @@ Item {
config.replaying = false; config.replaying = false;
if (playerNum < capacity) { if (playerNum < capacity) {
config.observing = false; config.observing = false;
lcall("SetObserving", false);
mainWindow.busy = true; mainWindow.busy = true;
ClientInstance.notifyServer( ClientInstance.notifyServer(
"EnterRoom", "EnterRoom",
@ -398,7 +397,6 @@ Item {
); );
} else { } else {
config.observing = true; config.observing = true;
lcall("SetObserving", true);
mainWindow.busy = true; mainWindow.busy = true;
ClientInstance.notifyServer( ClientInstance.notifyServer(
"ObserveRoom", "ObserveRoom",

View File

@ -1,3 +0,0 @@
import Fk.ModMaker as Md
Md.ModMaker {}

View File

@ -42,8 +42,6 @@ Item {
property var selected_targets: [] property var selected_targets: []
property string responding_card property string responding_card
property bool respond_play: false
property bool autoPending: false
property var extra_data: ({}) property var extra_data: ({})
property var skippedUseEventId: [] property var skippedUseEventId: []
@ -353,6 +351,11 @@ Item {
const total = dat["timeout"] * 1000; const total = dat["timeout"] * 1000;
const now = Date.now(); // ms const now = Date.now(); // ms
const elapsed = now - (dat["timestamp"] ?? now); const elapsed = now - (dat["timestamp"] ?? now);
if (total <= elapsd) {
roomScene.state = "notactive";
}
progressAnim.from = (1 - elapsed / total) * 100.0; progressAnim.from = (1 - elapsed / total) * 100.0;
progressAnim.duration = total - elapsed; progressAnim.duration = total - elapsed;
progress.visible = true; progress.visible = true;
@ -449,11 +452,12 @@ Item {
text: luatr("Choose one handcard") text: luatr("Choose one handcard")
textFont.pixelSize: 28 textFont.pixelSize: 28
visible: { visible: {
if (roomScene.state === "notactive") return false;
if (dashboard.handcardArea.length <= 15) { if (dashboard.handcardArea.length <= 15) {
return false; return false;
} }
const cards = dashboard.handcardArea.cards; const cards = dashboard.handcardArea.cards;
for (const card in cards) { for (const card of cards) {
if (card.selectable) return true; if (card.selectable) return true;
} }
return false; return false;
@ -1294,6 +1298,11 @@ Item {
return Logic.getPhoto(id); return Logic.getPhoto(id);
} }
function activate() {
if (state === "active") state = "notactive";
state = "active";
}
function applyChange(uiUpdate) { function applyChange(uiUpdate) {
uiUpdate["_delete"]?.forEach(data => { uiUpdate["_delete"]?.forEach(data => {
if (data.type == "Interaction") { if (data.type == "Interaction") {

View File

@ -809,7 +809,7 @@ callbacks["AskForGeneral"] = (data) => {
const convert = data[2]; const convert = data[2];
const heg = data[3]; const heg = data[3];
roomScene.setPrompt(luatr("#AskForGeneral"), true); roomScene.setPrompt(luatr("#AskForGeneral"), true);
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/ChooseGeneralBox.qml"); Qt.createComponent("../RoomElement/ChooseGeneralBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
@ -830,15 +830,15 @@ callbacks["AskForSkillInvoke"] = (data) => {
const prompt = data[1]; const prompt = data[1];
roomScene.promptText = prompt ? processPrompt(prompt) roomScene.promptText = prompt ? processPrompt(prompt)
: luatr("#AskForSkillInvoke").arg(luatr(skill)); : luatr("#AskForSkillInvoke").arg(luatr(skill));
// roomScene.state = "active"; // roomScene.activate();
// roomScene.okCancel.visible = true; // roomScene.okCancel.visible = true;
// roomScene.okButton.enabled = true; // roomScene.okButton.enabled = true;
// roomScene.cancelButton.enabled = true; // roomScene.cancelButton.enabled = true;
roomScene.state = "active"; roomScene.activate();
} }
callbacks["AskForArrangeCards"] = (data) => { callbacks["AskForArrangeCards"] = (data) => {
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/ArrangeCardsBox.qml"); Qt.createComponent("../RoomElement/ArrangeCardsBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
@ -869,7 +869,7 @@ callbacks["AskForGuanxing"] = (data) => {
const top_area_name = data.top_area_name; const top_area_name = data.top_area_name;
const bottom_area_name = data.bottom_area_name; const bottom_area_name = data.bottom_area_name;
const prompt = data.prompt; const prompt = data.prompt;
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/GuanxingBox.qml"); Qt.createComponent("../RoomElement/GuanxingBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
@ -905,7 +905,7 @@ callbacks["AskForExchange"] = (data) => {
const cards_name = []; const cards_name = [];
const capacities = []; const capacities = [];
const limits = []; const limits = [];
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/GuanxingBox.qml"); Qt.createComponent("../RoomElement/GuanxingBox.qml");
let for_i = 0; let for_i = 0;
@ -944,7 +944,7 @@ callbacks["AskForChoice"] = (data) => {
} else { } else {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
let qmlSrc; let qmlSrc;
if (!detailed) { if (!detailed) {
qmlSrc = "../RoomElement/ChoiceBox.qml"; qmlSrc = "../RoomElement/ChoiceBox.qml";
@ -978,7 +978,7 @@ callbacks["AskForChoices"] = (data) => {
} else { } else {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
let qmlSrc; let qmlSrc;
if (!detailed) { if (!detailed) {
qmlSrc = "../RoomElement/CheckBox.qml"; qmlSrc = "../RoomElement/CheckBox.qml";
@ -1013,7 +1013,7 @@ callbacks["AskForCardChosen"] = (data) => {
} else { } else {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/PlayerCardBox.qml"); Qt.createComponent("../RoomElement/PlayerCardBox.qml");
@ -1045,7 +1045,7 @@ callbacks["AskForCardsChosen"] = (data) => {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/PlayerCardBox.qml"); Qt.createComponent("../RoomElement/PlayerCardBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
@ -1070,7 +1070,7 @@ callbacks["AskForCardsChosen"] = (data) => {
callbacks["AskForPoxi"] = (dat) => { callbacks["AskForPoxi"] = (dat) => {
const { type, data, extra_data, cancelable } = dat; const { type, data, extra_data, cancelable } = dat;
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/PoxiBox.qml"); Qt.createComponent("../RoomElement/PoxiBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
@ -1096,7 +1096,7 @@ callbacks["AskForPoxi"] = (dat) => {
callbacks["AskForMoveCardInBoard"] = (data) => { callbacks["AskForMoveCardInBoard"] = (data) => {
const { cards, cardsPosition, generalNames, playerIds } = data; const { cards, cardsPosition, generalNames, playerIds } = data;
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/MoveCardInBoardBox.qml"); Qt.createComponent("../RoomElement/MoveCardInBoardBox.qml");
@ -1133,7 +1133,8 @@ callbacks["MoveCards"] = (moves) => {
// 切换状态 -> 向Lua询问UI情况 // 切换状态 -> 向Lua询问UI情况
// 所以Lua一开始就要设置好各种亮灭的值 而这个自然是通过update // 所以Lua一开始就要设置好各种亮灭的值 而这个自然是通过update
callbacks["PlayCard"] = () => { callbacks["PlayCard"] = () => {
roomScene.state = "active"; roomScene.activate();
roomScene.okCancel.visible = true;
} }
callbacks["LoseSkill"] = (data) => { callbacks["LoseSkill"] = (data) => {
@ -1176,18 +1177,8 @@ callbacks["AskForUseActiveSkill"] = (data) => {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.respond_play = false; roomScene.activate();
roomScene.state = "active"; roomScene.okCancel.visible = true;
// if (lcall('GetSkillData', skill_name).isViewAsSkill) {
// roomScene.responding_card = ".";
// }
// roomScene.autoPending = true;
// roomScene.extra_data = extra_data;
// // dashboard.startPending(skill_name);
// // roomScene.activateSkill(skill_name, true);
// cancelButton.enabled = cancelable;
} }
callbacks["CancelRequest"] = () => { callbacks["CancelRequest"] = () => {
@ -1212,7 +1203,8 @@ callbacks["AskForUseCard"] = (data) => {
} else { } else {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
roomScene.okCancel.visible = true;
if (extra_data != null) { if (extra_data != null) {
if (extra_data.effectTo !== Self.id && if (extra_data.effectTo !== Self.id &&
roomScene.skippedUseEventId.find(id => id === extra_data.useEventId)) { roomScene.skippedUseEventId.find(id => id === extra_data.useEventId)) {
@ -1223,7 +1215,6 @@ callbacks["AskForUseCard"] = (data) => {
} }
} }
// roomScene.responding_card = pattern; // roomScene.responding_card = pattern;
// roomScene.respond_play = false;
// disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames); // disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames);
// roomScene.state = "responding"; // roomScene.state = "responding";
// okButton.enabled = false; // okButton.enabled = false;
@ -1243,13 +1234,8 @@ callbacks["AskForResponseCard"] = (data) => {
} else { } else {
roomScene.setPrompt(processPrompt(prompt), true); roomScene.setPrompt(processPrompt(prompt), true);
} }
roomScene.state = "active"; roomScene.activate();
// roomScene.responding_card = pattern; roomScene.okCancel.visible = true;
// roomScene.respond_play = true;
// disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames);
// roomScene.state = "responding";
// okButton.enabled = false;
// cancelButton.enabled = true;
} }
callbacks["WaitForNullification"] = () => { callbacks["WaitForNullification"] = () => {
@ -1436,7 +1422,7 @@ callbacks["FillAG"] = (data) => {
} }
callbacks["AskForAG"] = (j) => { callbacks["AskForAG"] = (j) => {
roomScene.state = "active"; roomScene.activate();
roomScene.manualBox.item.interactive = true; roomScene.manualBox.item.interactive = true;
} }
@ -1456,7 +1442,7 @@ callbacks["CloseAG"] = () => roomScene.manualBox.item.close();
callbacks["CustomDialog"] = (data) => { callbacks["CustomDialog"] = (data) => {
const path = data.path; const path = data.path;
const dat = data.data; const dat = data.data;
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.source = AppPath + "/" + path; roomScene.popupBox.source = AppPath + "/" + path;
if (dat) { if (dat) {
roomScene.popupBox.item.loadData(dat); roomScene.popupBox.item.loadData(dat);
@ -1467,7 +1453,7 @@ callbacks["MiniGame"] = (data) => {
const game = data.type; const game = data.type;
const dat = data.data; const dat = data.data;
const gdata = lcall("GetMiniGame", game, Self.id, JSON.stringify(dat)); const gdata = lcall("GetMiniGame", game, Self.id, JSON.stringify(dat));
roomScene.state = "active"; roomScene.activate();
roomScene.popupBox.source = AppPath + "/" + gdata.qml_path + ".qml"; roomScene.popupBox.source = AppPath + "/" + gdata.qml_path + ".qml";
if (dat) { if (dat) {
roomScene.popupBox.item.loadData(dat); roomScene.popupBox.item.loadData(dat);
@ -1536,21 +1522,10 @@ callbacks["UpdateRequestUI"] = (uiUpdate) => {
roomScene.promptText = processPrompt(uiUpdate["_prompt"]); roomScene.promptText = processPrompt(uiUpdate["_prompt"]);
if (uiUpdate._type == "Room") { if (uiUpdate._type == "Room") {
// 需要判断是不是第一次收到这样的数据可以通过state判断
// 因为是先收到Lua的数据再切换状态的
// FIXME: 当然了 非常可能出现因为网络延迟过大导致在active状态收到新Request的情况
// if (roomScene.state === "notactive") {
// okCancel.visible = true;
// okButton.enabled = false;
// cancelButton.enabled = false;
// // endPhaseButton.visible = true;
// }
roomScene.applyChange(uiUpdate); roomScene.applyChange(uiUpdate);
} }
} }
// FIXME: 完全是因为ChangeSelf需要向服务器询问此人手牌信息导致不能直接暴力reply+设置notactive
// FIXME: 后面需要杀掉所有客户端未知牌
callbacks["ReplyToServer"] = (data) => { callbacks["ReplyToServer"] = (data) => {
replyToServer(data); replyToServer(data);
} }

View File

@ -12,4 +12,3 @@ PackageManage 1.0 PackageManage.qml
Room 1.0 Room.qml Room 1.0 Room.qml
Replay 1.0 Replay.qml Replay 1.0 Replay.qml
TileButton 1.0 TileButton.qml TileButton 1.0 TileButton.qml
ModMaker 1.0 ModMaker.qml

View File

@ -40,7 +40,7 @@ ColumnLayout {
for (let cd of clist) { for (let cd of clist) {
if (cd.cid == cid) { if (cd.cid == cid) {
cd.selected = !cd.selected; cd.selected = !cd.selected;
cd.clicked(); cd.clicked(cd);
finish(); finish();
} }
} }

View File

@ -16,6 +16,10 @@ add_custom_command(
${SWIG_SOURCE} ${SWIG_SOURCE}
) )
set(freekill_EXESRCS
"main.cpp"
)
set(freekill_SRCS set(freekill_SRCS
# "main.cpp" # "main.cpp"
"freekill.cpp" "freekill.cpp"
@ -69,7 +73,7 @@ if (WIN32)
set(CRYPTO_LIB OpenSSL::Crypto) set(CRYPTO_LIB OpenSSL::Crypto)
set(GIT_LIB ${PROJECT_SOURCE_DIR}/lib/win/libgit2.dll) set(GIT_LIB ${PROJECT_SOURCE_DIR}/lib/win/libgit2.dll)
set(app_icon_resource_windows "${PROJECT_SOURCE_DIR}/image/icon.rc") set(app_icon_resource_windows "${PROJECT_SOURCE_DIR}/image/icon.rc")
list(APPEND freekill_SRCS ${app_icon_resource_windows}) list(APPEND freekill_EXESRCS ${app_icon_resource_windows})
elseif (ANDROID) elseif (ANDROID)
set(LUA_LIB ${PROJECT_SOURCE_DIR}/lib/android/liblua54.so) set(LUA_LIB ${PROJECT_SOURCE_DIR}/lib/android/liblua54.so)
set(SQLITE3_LIB ${PROJECT_SOURCE_DIR}/lib/android/libsqlite3.so) set(SQLITE3_LIB ${PROJECT_SOURCE_DIR}/lib/android/libsqlite3.so)
@ -127,7 +131,7 @@ target_link_libraries(libFreeKill PRIVATE
${GIT_LIB} ${GIT_LIB}
${IDBFS_LIB} ${IDBFS_LIB}
) )
target_sources(FreeKill PRIVATE main.cpp) target_sources(FreeKill PRIVATE ${freekill_EXESRCS})
target_link_libraries(FreeKill PRIVATE target_link_libraries(FreeKill PRIVATE
libFreeKill libFreeKill
) )

View File

@ -186,7 +186,7 @@ void Router::handlePacket(const QByteArray &rawPacket) {
if (!_room->isLobby()) { if (!_room->isLobby()) {
auto room = qobject_cast<Room *>(_room); auto room = qobject_cast<Room *>(_room);
if (room->getThread()) { if (room->getThread()) {
room->getThread()->wakeUp(room->getId()); room->getThread()->wakeUp(room->getId(), "reply");
// TODO: signal // TODO: signal
} }
} }

View File

@ -608,7 +608,7 @@ void Room::setRequestTimer(int ms) {
request_timer->setSingleShot(true); request_timer->setSingleShot(true);
request_timer->setInterval(ms); request_timer->setInterval(ms);
connect(request_timer, &QTimer::timeout, this, [=](){ connect(request_timer, &QTimer::timeout, this, [=](){
m_thread->wakeUp(id); m_thread->wakeUp(id, "request_timer");
}); });
request_timer->start(); request_timer->start();
} }

View File

@ -37,7 +37,7 @@ class RoomThread : public QThread {
signals: signals:
void pushRequest(const QString &req); void pushRequest(const QString &req);
void delay(int roomId, int ms); void delay(int roomId, int ms);
void wakeUp(int roomId); void wakeUp(int roomId, const char *);
protected: protected:
virtual void run(); virtual void run();

View File

@ -36,16 +36,17 @@ void Scheduler::handleRequest(const QString &req) {
} }
void Scheduler::doDelay(int roomId, int ms) { void Scheduler::doDelay(int roomId, int ms) {
QTimer::singleShot(ms, [=](){ resumeRoom(roomId); }); QTimer::singleShot(ms, [=](){ resumeRoom(roomId, "delay_done"); });
} }
bool Scheduler::resumeRoom(int roomId) { bool Scheduler::resumeRoom(int roomId, const char *reason) {
lua_getglobal(L, "ResumeRoom"); lua_getglobal(L, "ResumeRoom");
lua_pushnumber(L, roomId); lua_pushnumber(L, roomId);
lua_pushstring(L, reason);
int err = lua_pcall(L, 1, 1, 0); int err = lua_pcall(L, 2, 1, 0);
const char *result = lua_tostring(L, -1);
if (err) { if (err) {
const char *result = lua_tostring(L, -1);
qCritical() << result; qCritical() << result;
lua_pop(L, 1); lua_pop(L, 1);
return true; return true;

View File

@ -18,7 +18,7 @@ class Scheduler : public QObject {
// 跨线程传递引用可能出问题! // 跨线程传递引用可能出问题!
void handleRequest(const QString &req); void handleRequest(const QString &req);
void doDelay(int roomId, int ms); void doDelay(int roomId, int ms);
bool resumeRoom(int roomId); bool resumeRoom(int roomId, const char *reason);
private: private:
RoomThread *m_thread; RoomThread *m_thread;

View File

@ -366,7 +366,7 @@ void Server::onRoomAbandoned() {
// FIXME: 但是这终归是内存泄漏!以后啥时候再改吧。 // FIXME: 但是这终归是内存泄漏!以后啥时候再改吧。
// room->deleteLater(); // room->deleteLater();
idle_rooms.push(room); idle_rooms.push(room);
room->getThread()->wakeUp(room->getId()); room->getThread()->wakeUp(room->getId(), "abandon");
room->getThread()->removeRoom(room); room->getThread()->removeRoom(room);
} }

View File

@ -201,7 +201,7 @@ void ServerPlayer::onDisconnected() {
} }
if (room->getThread()) { if (room->getThread()) {
// && thinking()) { // && thinking()) {
room->getThread()->wakeUp(room->getId()); room->getThread()->wakeUp(room->getId(), "player_disconnect");
} }
setState(Player::Offline); setState(Player::Offline);
setSocket(nullptr); setSocket(nullptr);

View File

@ -12,7 +12,6 @@
#include <QClipboard> #include <QClipboard>
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QMessageBox> #include <QMessageBox>
// #include "mod.h"
#endif #endif
#include <cstdlib> #include <cstdlib>
@ -481,10 +480,6 @@ void QmlBackend::installAESKey() {
ClientInstance->installAESKey(aes_key.toLatin1()); ClientInstance->installAESKey(aes_key.toLatin1());
} }
void QmlBackend::createModBackend() {
//engine->rootContext()->setContextProperty("ModBackend", new ModMaker);
}
void QmlBackend::detectServer() { void QmlBackend::detectServer() {
static const char *ask_str = "fkDetectServer"; static const char *ask_str = "fkDetectServer";

View File

@ -60,8 +60,6 @@ public:
Q_INVOKABLE QString getAESKey() const; Q_INVOKABLE QString getAESKey() const;
Q_INVOKABLE void installAESKey(); Q_INVOKABLE void installAESKey();
Q_INVOKABLE void createModBackend();
Q_INVOKABLE void detectServer(); Q_INVOKABLE void detectServer();
Q_INVOKABLE void getServerInfo(const QString &addr, ushort port = 9527u); Q_INVOKABLE void getServerInfo(const QString &addr, ushort port = 9527u);