Enhancement (#274)

- 修复录像负数时间bug
- 修复域名无法读取服务器信息bug
- 加入服务器界面的UI稍微优化
- 大厅聊天的UI稍微优化
- 添加时机“出牌阶段空闲时间点开始时”,可以在此时设置一些提示性标记
- 修复请求处理协程只要遇到error直接炸服的bug
- 添加手牌选择器,能在手牌非常多时帮助玩家选卡
This commit is contained in:
notify 2023-10-03 00:19:12 +08:00 committed by GitHub
parent 8eeb2fc900
commit f97df65ac6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 128 additions and 67 deletions

View File

@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.16) 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}\") add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
find_package(Qt6 REQUIRED COMPONENTS find_package(Qt6 REQUIRED COMPONENTS

View File

@ -12,53 +12,6 @@ Rectangle {
chatLogBox.append(chatter) 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() { function loadSkills() {
for (let i = 1; i <= 16; i++) { for (let i = 1; i <= 16; i++) {
skills.append({ name: "fastchat_m", idx: i }); skills.append({ name: "fastchat_m", idx: i });

View File

@ -37,7 +37,7 @@ Item {
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
text: serverIP text: serverIP + " " + misMatchMsg
font.bold: true font.bold: true
} }
@ -82,10 +82,10 @@ Item {
ScrollBar.vertical: ScrollBar {} ScrollBar.vertical: ScrollBar {}
clip: true clip: true
highlight: Rectangle { highlight: Rectangle {
color: "transparent"; radius: 5 color: "#AA9ABFEF"; radius: 5
border.color: "black"; border.width: 2 // border.color: "black"; border.width: 2
} }
highlightMoveDuration: 0 // highlightMoveDuration: 0
currentIndex: -1 currentIndex: -1
} }
@ -328,6 +328,7 @@ Item {
serverModel.append({ serverModel.append({
serverIP: addr, serverIP: addr,
misMatchMsg: "",
description: qsTr("Server not up"), description: qsTr("Server not up"),
online: "-", online: "-",
capacity: "-", capacity: "-",
@ -370,7 +371,8 @@ Item {
const item = serverModel.get(i); const item = serverModel.get(i);
const ip = item.serverIP; const ip = item.serverIP;
if (addr.endsWith(ip)) { // endsWithIPv6ip if (addr.endsWith(ip)) { // endsWithIPv6ip
item.description = FkVersion === ver ? desc : "Ver " + ver; item.misMatchMsg = FkVersion === ver ? "" : qsTr("@VersionMismatch").arg(ver);
item.description = desc;
item.favicon = icon; item.favicon = icon;
item.online = count.toString(); item.online = count.toString();
item.capacity = capacity.toString(); item.capacity = capacity.toString();
@ -385,6 +387,7 @@ Item {
for (let key in config.savedPassword) { for (let key in config.savedPassword) {
serverModel.append({ serverModel.append({
serverIP: key, serverIP: key,
misMatchMsg: "",
description: qsTr("Server not up"), description: qsTr("Server not up"),
online: "-", online: "-",
capacity: "-", capacity: "-",

View File

@ -315,13 +315,14 @@ Item {
Rectangle { Rectangle {
id: info id: info
color: "#88EEEEEE" color: "#88EEEEEE"
width: childrenRect.width + 8 width: root.width * 0.23 // childrenRect.width + 8
height: childrenRect.height + 4 height: childrenRect.height + 4
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
radius: 4 radius: 4
Text { Text {
anchors.horizontalCenter: parent.horizontalCenter
x: 4; y: 2 x: 4; y: 2
font.pixelSize: 16 font.pixelSize: 16
text: Backend.translate("$OnlineInfo") text: Backend.translate("$OnlineInfo")

View File

@ -472,6 +472,20 @@ Item {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 8 anchors.leftMargin: 8
ColumnLayout { 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 { MetroButton {
text: Backend.translate("Revert Selection") text: Backend.translate("Revert Selection")
textFont.pixelSize: 28 textFont.pixelSize: 28

View File

@ -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 }; });
}
}

View File

@ -24,6 +24,7 @@ Rectangle {
width: parent.width * 0.7 width: parent.width * 0.7
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText textFormat: Text.RichText
onLinkActivated: Qt.openUrlExternally(link);
} }
} }
} }

View File

@ -3,8 +3,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.notify.FreeKill" package="org.notify.FreeKill"
android:installLocation="preferExternal" android:installLocation="preferExternal"
android:versionCode="309" android:versionCode="310"
android:versionName="0.3.9"> android:versionName="0.3.10">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

View File

@ -188,6 +188,10 @@
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>@VersionMismatch</source>
<translation>&lt;font color="red" size="4">&lt;b>v%1&lt;/b>&lt;/font></translation>
</message>
<message> <message>
<source>Server not up</source> <source>Server not up</source>
<translation></translation> <translation></translation>
@ -493,7 +497,7 @@
<source>tutor_msg_6</source> <source>tutor_msg_6</source>
<translation>&lt;br> <translation>&lt;br>
&lt;br> &lt;br>
Discord群组https://discord.gg/tp35GrQR6v&lt;br> Discord群组&lt;a href="https://discord.gg/tp35GrQR6v">https://discord.gg/tp35GrQR6v&lt;/a>&lt;br>
QQ频道freekill01&lt;br> QQ频道freekill01&lt;br>
QQ群太容易满啦</translation> QQ群太容易满啦</translation>
</message> </message>

View File

@ -54,7 +54,9 @@ Fk:loadTranslationTable{
["General Packages"] = "武将拓展包", ["General Packages"] = "武将拓展包",
["Card Packages"] = "卡牌拓展包", ["Card Packages"] = "卡牌拓展包",
["Select All"] = "全选", ["Select All"] = "全选",
["Choose one handcard"] = "选卡",
["Revert Selection"] = "反选", ["Revert Selection"] = "反选",
["Handcard selector"] = "手牌选择器,只可选一张,代为点击这张手牌",
["Give Flower"] = "送花", ["Give Flower"] = "送花",
["Give Egg"] = "砸蛋", ["Give Egg"] = "砸蛋",

View File

@ -128,8 +128,10 @@ fk.AreaResumed = 88
fk.GeneralRevealed = 89 fk.GeneralRevealed = 89
fk.GeneralHidden = 90 fk.GeneralHidden = 90
fk.NumOfEvents = 91 fk.StartPlayCard = 91
fk.BeforePropertyChange = 92 fk.BeforePropertyChange = 92
fk.PropertyChange = 93 fk.PropertyChange = 93
fk.AfterPropertyChange = 94 fk.AfterPropertyChange = 94
fk.NumOfEvents = 95

View File

@ -300,6 +300,7 @@ GameEvent.functions[GameEvent.Phase] = function(self)
[Player.Play] = function() [Player.Play] = function()
player._play_phase_end = false player._play_phase_end = false
while not player.dead do while not player.dead do
logic:trigger(fk.StartPlayCard, player, nil, true)
room:notifyMoveFocus(player, "PlayCard") room:notifyMoveFocus(player, "PlayCard")
local result = room:doRequest(player, "PlayCard", player.id) local result = room:doRequest(player, "PlayCard", player.id)
if result == "" then break end if result == "" then break end

View File

@ -188,7 +188,7 @@ local function requestLoop(self)
RoomInstance = room RoomInstance = room
local id = tonumber(reqlist[1]) local id = tonumber(reqlist[1])
local command = reqlist[2] local command = reqlist[2]
request_handlers[command](room, id, reqlist) Pcall(request_handlers[command], room, id, reqlist)
RoomInstance = nil RoomInstance = nil
end end
end end

View File

@ -71,7 +71,7 @@ Replayer::~Replayer() {
} }
int Replayer::getDuration() const { 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; return (int)ret;
} }
@ -126,8 +126,8 @@ void Replayer::shutdown() {
} }
void Replayer::run() { void Replayer::run() {
long last = 0; qint64 last = 0;
long start = 0; qint64 start = 0;
if (roomSettings == "") { if (roomSettings == "") {
Backend->showToast("Invalid replay file."); Backend->showToast("Invalid replay file.");
@ -150,7 +150,7 @@ void Replayer::run() {
continue; continue;
} }
long delay = pair->elapsed - last; qint64 delay = pair->elapsed - last;
if (uniformRunning) { if (uniformRunning) {
delay = qMin(delay, 2000); delay = qMin(delay, 2000);
if (delay > 500) if (delay > 500)

View File

@ -41,7 +41,7 @@ private:
QSemaphore play_sem; QSemaphore play_sem;
struct Pair { struct Pair {
long elapsed; qint64 elapsed;
bool isRequest; bool isRequest;
QString cmd; QString cmd;
QString jsonData; QString jsonData;

View File

@ -46,7 +46,7 @@ public:
static int GetMicroSecond(lua_State *L) { static int GetMicroSecond(lua_State *L) {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, nullptr); 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); lua_pushnumber(L, microsecond);
return 1; return 1;
} }

View File

@ -362,8 +362,17 @@ void QmlBackend::getServerInfo(const QString &address) {
QByteArray ask(ask_str); QByteArray ask(ask_str);
ask.append(address.toLatin1()); ask.append(address.toLatin1());
udpSocket->writeDatagram(ask, ask.size(), if (QHostAddress(addr).isNull()) { // 不是ip考虑解析域名
QHostAddress(addr), port); 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() { void QmlBackend::readPendingDatagrams() {