From f97df65ac61448c747448d7e0a4a5e1170f7133d Mon Sep 17 00:00:00 2001 From: notify Date: Tue, 3 Oct 2023 00:19:12 +0800 Subject: [PATCH] Enhancement (#274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复录像负数时间bug - 修复域名无法读取服务器信息bug - 加入服务器界面的UI稍微优化 - 大厅聊天的UI稍微优化 - 添加时机“出牌阶段空闲时间点开始时”,可以在此时设置一些提示性标记 - 修复请求处理协程只要遇到error直接炸服的bug - 添加手牌选择器,能在手牌非常多时帮助玩家选卡 --- CMakeLists.txt | 2 +- Fk/Common/ChatBox.qml | 47 -------------------- Fk/Pages/JoinServer.qml | 13 +++--- Fk/Pages/Lobby.qml | 3 +- Fk/Pages/Room.qml | 14 ++++++ Fk/RoomElement/ChooseHandcard.qml | 71 +++++++++++++++++++++++++++++++ Fk/Tutorial.qml | 1 + android/AndroidManifest.xml | 4 +- lang/zh_CN.ts | 6 ++- lua/client/i18n/zh_CN.lua | 2 + lua/server/event.lua | 4 +- lua/server/events/gameflow.lua | 1 + lua/server/request.lua | 2 +- src/client/replayer.cpp | 8 ++-- src/client/replayer.h | 2 +- src/swig/qt.i | 2 +- src/ui/qmlbackend.cpp | 13 +++++- 17 files changed, 128 insertions(+), 67 deletions(-) create mode 100644 Fk/RoomElement/ChooseHandcard.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index 8311db87..4ee5a1ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16) -project(FreeKill VERSION 0.3.9) +project(FreeKill VERSION 0.3.10) add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\") find_package(Qt6 REQUIRED COMPONENTS diff --git a/Fk/Common/ChatBox.qml b/Fk/Common/ChatBox.qml index 8985cecd..0a3dd829 100644 --- a/Fk/Common/ChatBox.qml +++ b/Fk/Common/ChatBox.qml @@ -12,53 +12,6 @@ Rectangle { chatLogBox.append(chatter) } - /* - function loadSkills(pid) { - if (isLobby) return; - let gender = 0; - // let g = false; - // if (g) { - // const data = JSON.parse(Backend.callLuaFunction("GetGeneralDetail", [g])); - // const extension = data.extension; - // gender = data.gender; - // data.skill.forEach(t => { - // for (let i = 0; i < 999; i++) { - // const fname = AppPath + "/packages/" + extension + "/audio/skill/" + - // t.name + (i !== 0 ? i.toString() : "") + ".mp3"; - - // if (Backend.exists(fname)) { - // skills.append({ name: t.name, idx: i }); - // } else { - // if (i > 0) break; - // } - // } - // }); - // data.related_skill.forEach(t => { - // for (let i = 0; i < 999; i++) { - // const fname = AppPath + "/packages/" + extension + "/audio/skill/" + - // t.name + (i !== 0 ? i.toString() : "") + ".mp3"; - - // if (Backend.exists(fname)) { - // skills.append({ name: t.name, idx: i }); - // } else { - // if (i > 0) break; - // } - // } - // }); - // } - for (let i = 0; i < 999; i++) { - const name = "fastchat_" + (gender == 1 ? "f" : "m") - const fname = AppPath + "/packages/standard/audio/skill/" + - name + (i !== 0 ? i.toString() : "") + ".mp3"; - - if (Backend.exists(fname)) { - skills.append({ name: name, idx: i }); - } else { - if (i > 0) break; - } - } - } - */ function loadSkills() { for (let i = 1; i <= 16; i++) { skills.append({ name: "fastchat_m", idx: i }); diff --git a/Fk/Pages/JoinServer.qml b/Fk/Pages/JoinServer.qml index 7337c45a..70414668 100644 --- a/Fk/Pages/JoinServer.qml +++ b/Fk/Pages/JoinServer.qml @@ -37,7 +37,7 @@ Item { Text { Layout.fillWidth: true horizontalAlignment: Text.AlignLeft - text: serverIP + text: serverIP + " " + misMatchMsg font.bold: true } @@ -82,10 +82,10 @@ Item { ScrollBar.vertical: ScrollBar {} clip: true highlight: Rectangle { - color: "transparent"; radius: 5 - border.color: "black"; border.width: 2 + color: "#AA9ABFEF"; radius: 5 + // border.color: "black"; border.width: 2 } - highlightMoveDuration: 0 + // highlightMoveDuration: 0 currentIndex: -1 } @@ -328,6 +328,7 @@ Item { serverModel.append({ serverIP: addr, + misMatchMsg: "", description: qsTr("Server not up"), online: "-", capacity: "-", @@ -370,7 +371,8 @@ Item { const item = serverModel.get(i); const ip = item.serverIP; if (addr.endsWith(ip)) { // endsWith是为了应付IPv6格式的ip - item.description = FkVersion === ver ? desc : "Ver " + ver; + item.misMatchMsg = FkVersion === ver ? "" : qsTr("@VersionMismatch").arg(ver); + item.description = desc; item.favicon = icon; item.online = count.toString(); item.capacity = capacity.toString(); @@ -385,6 +387,7 @@ Item { for (let key in config.savedPassword) { serverModel.append({ serverIP: key, + misMatchMsg: "", description: qsTr("Server not up"), online: "-", capacity: "-", diff --git a/Fk/Pages/Lobby.qml b/Fk/Pages/Lobby.qml index 317acfdd..f313152f 100644 --- a/Fk/Pages/Lobby.qml +++ b/Fk/Pages/Lobby.qml @@ -315,13 +315,14 @@ Item { Rectangle { id: info color: "#88EEEEEE" - width: childrenRect.width + 8 + width: root.width * 0.23 // childrenRect.width + 8 height: childrenRect.height + 4 anchors.bottom: parent.bottom anchors.left: parent.left radius: 4 Text { + anchors.horizontalCenter: parent.horizontalCenter x: 4; y: 2 font.pixelSize: 16 text: Backend.translate("$OnlineInfo") diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml index 7a5977d9..1de80109 100644 --- a/Fk/Pages/Room.qml +++ b/Fk/Pages/Room.qml @@ -472,6 +472,20 @@ Item { anchors.left: parent.left anchors.leftMargin: 8 ColumnLayout { + MetroButton { + text: Backend.translate("Choose one handcard") + textFont.pixelSize: 28 + visible: { + if (dashboard.handcardArea.length <= 15) { + return false; + } + if (roomScene.state == "notactive" || roomScene.state == "replying") { + return false; + } + return true; + } + onClicked: roomScene.startCheat("../RoomElement/ChooseHandcard"); + } MetroButton { text: Backend.translate("Revert Selection") textFont.pixelSize: 28 diff --git a/Fk/RoomElement/ChooseHandcard.qml b/Fk/RoomElement/ChooseHandcard.qml new file mode 100644 index 00000000..94747891 --- /dev/null +++ b/Fk/RoomElement/ChooseHandcard.qml @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects + +Item { + id: root + anchors.fill: parent + property var extra_data: ({}) // unused + signal finish() + property var cards: [] + + Text { + text: Backend.translate("Handcard selector") + width: parent.width + anchors.topMargin: 6 + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 16 + } + + Flickable { + id: flickableContainer + ScrollBar.vertical: ScrollBar {} + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 40 + flickableDirection: Flickable.VerticalFlick + width: parent.width - 20 + height: parent.height - 40 + contentWidth: cardsList.width + contentHeight: cardsList.height + clip: true + + GridLayout { + id: cardsList + columns: Math.floor(flickableContainer.width / 90) + + Repeater { + model: cards + + CardItem { + width: 93 * 0.9 + height: 130 * 0.9 + chosenInBox: modelData.chosen + onClicked: { + const clist = roomScene.dashboard.handcardArea.cards; + for (let cd of clist) { + if (cd.cid == cid) { + cd.selected = !cd.selected; + cd.clicked(); + finish(); + } + } + } + Component.onCompleted: { + setData(JSON.parse(Backend.callLuaFunction("GetCardData", [modelData.cid]))); + } + } + } + } + } + + Component.onCompleted: { + cards = roomScene.dashboard.handcardArea.cards + .filter(c => c.selectable) + .map(c => { return { cid: c.cid, chosen: c.selected }; }); + } +} + diff --git a/Fk/Tutorial.qml b/Fk/Tutorial.qml index 0c0fcbd7..fa017706 100644 --- a/Fk/Tutorial.qml +++ b/Fk/Tutorial.qml @@ -24,6 +24,7 @@ Rectangle { width: parent.width * 0.7 horizontalAlignment: Text.AlignHCenter textFormat: Text.RichText + onLinkActivated: Qt.openUrlExternally(link); } } } diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 196018ce..a4735670 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,8 +3,8 @@ + android:versionCode="310" + android:versionName="0.3.10"> diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts index 983f457d..72bba804 100644 --- a/lang/zh_CN.ts +++ b/lang/zh_CN.ts @@ -188,6 +188,10 @@ 返回 + + @VersionMismatch + <font color="red" size="4"><b>版本不同:服务器为v%1</b></font> + Server not up 服务器似乎没有启动。 @@ -493,7 +497,7 @@ tutor_msg_6 如果想联系我们,可以用这些方式:<br> 百度贴吧:新月杀吧<br> - Discord群组:https://discord.gg/tp35GrQR6v<br> + Discord群组:<a href="https://discord.gg/tp35GrQR6v">https://discord.gg/tp35GrQR6v</a><br> QQ频道:freekill01<br> QQ群太容易满啦,就不发群号了 diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua index a052515d..6db9c0e8 100644 --- a/lua/client/i18n/zh_CN.lua +++ b/lua/client/i18n/zh_CN.lua @@ -54,7 +54,9 @@ Fk:loadTranslationTable{ ["General Packages"] = "武将拓展包", ["Card Packages"] = "卡牌拓展包", ["Select All"] = "全选", + ["Choose one handcard"] = "选卡", ["Revert Selection"] = "反选", + ["Handcard selector"] = "手牌选择器,只可选一张,代为点击这张手牌", ["Give Flower"] = "送花", ["Give Egg"] = "砸蛋", diff --git a/lua/server/event.lua b/lua/server/event.lua index 737b7dad..a1167b07 100644 --- a/lua/server/event.lua +++ b/lua/server/event.lua @@ -128,8 +128,10 @@ fk.AreaResumed = 88 fk.GeneralRevealed = 89 fk.GeneralHidden = 90 -fk.NumOfEvents = 91 +fk.StartPlayCard = 91 fk.BeforePropertyChange = 92 fk.PropertyChange = 93 fk.AfterPropertyChange = 94 + +fk.NumOfEvents = 95 diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua index 05e6f00e..835ba459 100644 --- a/lua/server/events/gameflow.lua +++ b/lua/server/events/gameflow.lua @@ -300,6 +300,7 @@ GameEvent.functions[GameEvent.Phase] = function(self) [Player.Play] = function() player._play_phase_end = false while not player.dead do + logic:trigger(fk.StartPlayCard, player, nil, true) room:notifyMoveFocus(player, "PlayCard") local result = room:doRequest(player, "PlayCard", player.id) if result == "" then break end diff --git a/lua/server/request.lua b/lua/server/request.lua index 54d20a2c..eaa6c270 100644 --- a/lua/server/request.lua +++ b/lua/server/request.lua @@ -188,7 +188,7 @@ local function requestLoop(self) RoomInstance = room local id = tonumber(reqlist[1]) local command = reqlist[2] - request_handlers[command](room, id, reqlist) + Pcall(request_handlers[command], room, id, reqlist) RoomInstance = nil end end diff --git a/src/client/replayer.cpp b/src/client/replayer.cpp index e7ca3647..d31800f3 100644 --- a/src/client/replayer.cpp +++ b/src/client/replayer.cpp @@ -71,7 +71,7 @@ Replayer::~Replayer() { } int Replayer::getDuration() const { - long ret = (pairs.last()->elapsed - pairs.first()->elapsed) / 1000.0; + qint64 ret = (pairs.last()->elapsed - pairs.first()->elapsed) / 1000.0; return (int)ret; } @@ -126,8 +126,8 @@ void Replayer::shutdown() { } void Replayer::run() { - long last = 0; - long start = 0; + qint64 last = 0; + qint64 start = 0; if (roomSettings == "") { Backend->showToast("Invalid replay file."); @@ -150,7 +150,7 @@ void Replayer::run() { continue; } - long delay = pair->elapsed - last; + qint64 delay = pair->elapsed - last; if (uniformRunning) { delay = qMin(delay, 2000); if (delay > 500) diff --git a/src/client/replayer.h b/src/client/replayer.h index cb1874bb..d9e55a7d 100644 --- a/src/client/replayer.h +++ b/src/client/replayer.h @@ -41,7 +41,7 @@ private: QSemaphore play_sem; struct Pair { - long elapsed; + qint64 elapsed; bool isRequest; QString cmd; QString jsonData; diff --git a/src/swig/qt.i b/src/swig/qt.i index 620395eb..366c6560 100644 --- a/src/swig/qt.i +++ b/src/swig/qt.i @@ -46,7 +46,7 @@ public: static int GetMicroSecond(lua_State *L) { struct timeval tv; gettimeofday(&tv, nullptr); - long microsecond = tv.tv_sec * 1000000 + tv.tv_usec; + long long microsecond = tv.tv_sec * 1000000 + tv.tv_usec; lua_pushnumber(L, microsecond); return 1; } diff --git a/src/ui/qmlbackend.cpp b/src/ui/qmlbackend.cpp index 525d02b7..8d52fe00 100644 --- a/src/ui/qmlbackend.cpp +++ b/src/ui/qmlbackend.cpp @@ -362,8 +362,17 @@ void QmlBackend::getServerInfo(const QString &address) { QByteArray ask(ask_str); ask.append(address.toLatin1()); - udpSocket->writeDatagram(ask, ask.size(), - QHostAddress(addr), port); + if (QHostAddress(addr).isNull()) { // 不是ip?考虑解析域名 + QHostInfo::lookupHost(addr, this, [=](const QHostInfo &host) { + if (host.error() == QHostInfo::NoError) { + udpSocket->writeDatagram(ask, ask.size(), + host.addresses().first(), port); + } + }); + } else { + udpSocket->writeDatagram(ask, ask.size(), + QHostAddress(addr), port); + } } void QmlBackend::readPendingDatagrams() {