mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-15 19:22:25 +08:00
Bugfix (#206)
* 修cost_data * 修cardMark,仍需自动清理措施 * 修锁视技( **重要!使用牌之前会根据锁视技重新决定使用的卡牌!!**)
This commit is contained in:
parent
6c0d5433c6
commit
c3fd8fc9a5
|
@ -159,6 +159,7 @@ Item {
|
|||
|
||||
if (dashboard.pending_skill !== "")
|
||||
dashboard.stopPending();
|
||||
dashboard.updateHandcards();
|
||||
dashboard.disableAllCards();
|
||||
dashboard.disableSkills();
|
||||
dashboard.retractAllPiles();
|
||||
|
@ -176,6 +177,7 @@ Item {
|
|||
ScriptAction {
|
||||
script: {
|
||||
skillInteraction.sourceComponent = undefined;
|
||||
dashboard.updateHandcards();
|
||||
dashboard.enableCards();
|
||||
dashboard.enableSkills();
|
||||
progress.visible = true;
|
||||
|
@ -191,6 +193,7 @@ Item {
|
|||
ScriptAction {
|
||||
script: {
|
||||
skillInteraction.sourceComponent = undefined;
|
||||
dashboard.updateHandcards();
|
||||
dashboard.enableCards(responding_card);
|
||||
dashboard.enableSkills(responding_card, respond_play);
|
||||
autoPending = false;
|
||||
|
@ -205,6 +208,7 @@ Item {
|
|||
ScriptAction {
|
||||
script: {
|
||||
skillInteraction.sourceComponent = undefined;
|
||||
dashboard.updateHandcards();
|
||||
dashboard.disableAllCards();
|
||||
dashboard.disableSkills();
|
||||
progress.visible = true;
|
||||
|
|
|
@ -622,6 +622,33 @@ callbacks["PropertyUpdate"] = (jsonData) => {
|
|||
}
|
||||
}
|
||||
|
||||
callbacks["UpdateCard"] = (j) => {
|
||||
const id = parseInt(j);
|
||||
let card;
|
||||
roomScene.tableCards.forEach((v) => {
|
||||
if (v.cid === id) {
|
||||
card = v;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!card) {
|
||||
roomScene.dashboard.handcardArea.cards.forEach((v) => {
|
||||
if (v.cid === id) {
|
||||
card = v;
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!card) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = JSON.parse(Backend.callLuaFunction("GetCardData", [id]));
|
||||
card.setData(data);
|
||||
}
|
||||
|
||||
callbacks["StartGame"] = (jsonData) => {
|
||||
roomScene.isStarted = true;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Fk
|
||||
|
||||
|
@ -33,6 +34,7 @@ Item {
|
|||
property bool enabled: true // if false the card will be grey
|
||||
property alias card: cardItem
|
||||
property alias glow: glowItem
|
||||
property var mark: ({})
|
||||
|
||||
function getColor() {
|
||||
if (suit != "")
|
||||
|
@ -161,6 +163,57 @@ Item {
|
|||
//glow.samples: 12
|
||||
}
|
||||
|
||||
Component {
|
||||
id: cardMarkDelegate
|
||||
Item {
|
||||
width: root.width / 2
|
||||
height: 16
|
||||
Rectangle {
|
||||
id: mark_rect
|
||||
width: mark_text.width + 12
|
||||
height: 16
|
||||
// color: "#A50330"
|
||||
radius: 4
|
||||
// border.color: "snow"
|
||||
// border.width: 1
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.7; color: "#A50330" }
|
||||
GradientStop { position: 1.0; color: "transparent" }
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: mark_text
|
||||
x: 2
|
||||
font.pixelSize: 16
|
||||
font.family: fontLibian.name
|
||||
font.letterSpacing: -0.6
|
||||
text: {
|
||||
let ret = Backend.translate(modelData.k);
|
||||
if (!modelData.k.startsWith("@@")) {
|
||||
ret += modelData.v.toString();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
color: "white"
|
||||
style: Text.Outline
|
||||
styleColor: "purple"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
width: root.width
|
||||
y: 60
|
||||
columns: 2
|
||||
rowSpacing: 1
|
||||
columnSpacing: 0
|
||||
Repeater {
|
||||
model: mark
|
||||
delegate: cardMarkDelegate
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: !root.selectable
|
||||
anchors.fill: parent
|
||||
|
@ -266,6 +319,7 @@ Item {
|
|||
color = data.color;
|
||||
subtype = data.subtype ? data.subtype : "";
|
||||
virt_name = data.virt_name ? data.virt_name : "";
|
||||
mark = data.mark ?? {};
|
||||
}
|
||||
|
||||
function toData()
|
||||
|
@ -278,6 +332,7 @@ Item {
|
|||
color: color,
|
||||
subtype: subtype,
|
||||
virt_name: virt_name,
|
||||
mark: mark,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -405,6 +405,14 @@ RowLayout {
|
|||
self.tremble();
|
||||
}
|
||||
|
||||
function updateHandcards() {
|
||||
Backend.callLuaFunction("FilterMyHandcards", []);
|
||||
handcardAreaItem.cards.forEach(v => {
|
||||
const data = JSON.parse(Backend.callLuaFunction("GetCardData", [v.cid]));
|
||||
v.setData(data);
|
||||
});
|
||||
}
|
||||
|
||||
function update() {
|
||||
unSelectAll();
|
||||
disableSkills();
|
||||
|
|
|
@ -52,6 +52,9 @@ function Client:initialize()
|
|||
self.status_skills[class] = {table.unpack(skills)}
|
||||
end
|
||||
|
||||
self.skill_costs = {}
|
||||
self.card_marks = {}
|
||||
self.filtered_cards = {}
|
||||
self.disabled_packs = {}
|
||||
self.disabled_generals = {}
|
||||
end
|
||||
|
@ -657,11 +660,9 @@ fk.client_callback["SetCardMark"] = function(jsonData)
|
|||
-- jsonData: [ int id, string mark, int value ]
|
||||
local data = json.decode(jsonData)
|
||||
local card, mark, value = data[1], data[2], data[3]
|
||||
ClientInstance:getCardById(card):setMark(mark, value)
|
||||
Fk:getCardById(card):setMark(mark, value)
|
||||
|
||||
if string.sub(mark, 1, 1) == "@" then
|
||||
ClientInstance:notifyUI("SetCardMark", jsonData)
|
||||
end
|
||||
ClientInstance:notifyUI("UpdateCard", tostring(card))
|
||||
end
|
||||
|
||||
fk.client_callback["Chat"] = function(jsonData)
|
||||
|
|
|
@ -81,6 +81,14 @@ function GetCardData(id)
|
|||
cid = id,
|
||||
known = false
|
||||
} end
|
||||
local mark = {}
|
||||
for k, v in pairs(card.mark) do
|
||||
if k and k:startsWith("@") and v and v ~= 0 then
|
||||
table.insert(mark, {
|
||||
k = k, v = v,
|
||||
})
|
||||
end
|
||||
end
|
||||
local ret = {
|
||||
cid = id,
|
||||
name = card.name,
|
||||
|
@ -88,6 +96,7 @@ function GetCardData(id)
|
|||
number = card.number,
|
||||
suit = card:getSuitString(),
|
||||
color = card:getColorString(),
|
||||
mark = mark,
|
||||
subtype = cardSubtypeStrings[card.sub_type]
|
||||
}
|
||||
if card.skillName ~= "" then
|
||||
|
@ -605,4 +614,8 @@ function SetPlayerGameData(pid, data)
|
|||
p.player:setGameData(table.unpack(data))
|
||||
end
|
||||
|
||||
function FilterMyHandcards()
|
||||
Self:filterHandcards()
|
||||
end
|
||||
|
||||
dofile "lua/client/i18n/init.lua"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
---@field public mark table<string, integer> @ 当前拥有的所有标记,用烂了
|
||||
---@field public subcards integer[] @ 子卡ID表
|
||||
---@field public skillName string @ 虚拟牌的技能名 for virtual cards
|
||||
---@field private _skillName string
|
||||
---@field public skillNames string[] @ 虚拟牌的技能名们(一张虚拟牌可能有多个技能名,如芳魂、龙胆、朱雀羽扇)
|
||||
---@field public skill Skill @ 技能(用于实现卡牌效果)
|
||||
---@field public special_skills string[] | nil @ 衍生技能,如重铸
|
||||
|
@ -94,18 +95,27 @@ function Card:initialize(name, suit, number, color)
|
|||
-- self.package = nil
|
||||
self.id = 0
|
||||
self.type = 0
|
||||
self.sub_type = Card.SubTypeNone
|
||||
self.sub_type = Card.SubtypeNone
|
||||
-- self.skill = nil
|
||||
self.subcards = {}
|
||||
-- self.skillName = nil
|
||||
self._skillName = ""
|
||||
self.skillNames = {}
|
||||
self.mark = {}
|
||||
-- self.mark = {} -- 这个视情况了,只有虚拟牌才有真正的self.mark,真牌的话挂在currentRoom
|
||||
end
|
||||
|
||||
function Card:__index(k)
|
||||
if k == "skillName" then
|
||||
return self._skillName
|
||||
elseif k == "mark" then
|
||||
if not self:isVirtual() then
|
||||
local mark_tab = Fk:currentRoom().card_marks
|
||||
mark_tab[self.id] = mark_tab[self.id] or {}
|
||||
return mark_tab[self.id]
|
||||
else
|
||||
self.mark = {}
|
||||
return self.mark
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -322,6 +332,15 @@ function Card:removeMark(mark, count)
|
|||
end
|
||||
|
||||
--- 为卡牌设置Mark至指定数量。
|
||||
---
|
||||
--- 关于标记的说明:
|
||||
---
|
||||
--- * @开头的为可见标记,其余为隐藏标记。
|
||||
--- * -turn结尾、-phase结尾、-round结尾的如同玩家标记一样在这个时机自动清理。
|
||||
--- * -noclear结尾的表示不要自动清理。
|
||||
--- * 默认的自动清理策略是当卡牌离开手牌区后清除所有的标记。
|
||||
--- * -turn之类的后缀会覆盖默认清理的方式。
|
||||
--- * (TODO: 以上皆为画饼)
|
||||
---@param mark string @ 标记
|
||||
---@param count integer @ 为标记删除的数量
|
||||
function Card:setMark(mark, count)
|
||||
|
@ -335,7 +354,11 @@ end
|
|||
---@param mark string @ 标记
|
||||
---@return integer
|
||||
function Card:getMark(mark)
|
||||
return (self.mark[mark] or 0)
|
||||
local ret = (self.mark[mark] or 0)
|
||||
if (not self:isVirtual()) and next(self.mark) == nil then
|
||||
self.mark = nil
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- 判定卡牌是否拥有对应的Mark。
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
---@field public game_modes table<string, GameMode> @ 所有游戏模式
|
||||
---@field public currentResponsePattern string @ 要求用牌的种类(如要求用特定花色的桃···)
|
||||
---@field public currentResponseReason string @ 要求用牌的原因(如濒死,被特定牌指定,使用特定技能···)
|
||||
---@field public filtered_cards table<integer, Card> @ 被锁视技影响的卡牌
|
||||
local Engine = class("Engine")
|
||||
|
||||
--- Engine的构造函数。
|
||||
|
@ -57,6 +58,7 @@ end
|
|||
local _foreign_keys = {
|
||||
"currentResponsePattern",
|
||||
"currentResponseReason",
|
||||
"filtered_cards",
|
||||
}
|
||||
|
||||
function Engine:__index(k)
|
||||
|
@ -381,8 +383,6 @@ function Engine:getAllCardIds(except)
|
|||
return result
|
||||
end
|
||||
|
||||
local filtered_cards = {}
|
||||
|
||||
--- 根据id返回相应的卡牌。
|
||||
---@param id integer @ 牌的id
|
||||
---@param ignoreFilter boolean @ 是否要无视掉锁定视为技,直接获得真牌
|
||||
|
@ -390,7 +390,7 @@ local filtered_cards = {}
|
|||
function Engine:getCardById(id, ignoreFilter)
|
||||
local ret = self.cards[id]
|
||||
if not ignoreFilter then
|
||||
ret = filtered_cards[id] or self.cards[id]
|
||||
ret = self.filtered_cards[id] or self.cards[id]
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
@ -402,14 +402,14 @@ end
|
|||
function Engine:filterCard(id, player, data)
|
||||
local card = self:getCardById(id, true)
|
||||
if player == nil then
|
||||
filtered_cards[id] = nil
|
||||
self.filtered_cards[id] = nil
|
||||
return
|
||||
end
|
||||
local skills = player:getAllSkills()
|
||||
local filters = self:currentRoom().status_skills[FilterSkill] or Util.DummyTable
|
||||
|
||||
if #filters == 0 then
|
||||
filtered_cards[id] = nil
|
||||
self.filtered_cards[id] = nil
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -446,11 +446,11 @@ function Engine:filterCard(id, player, data)
|
|||
if card == nil then
|
||||
card = self:getCardById(id)
|
||||
end
|
||||
filtered_cards[id] = card
|
||||
self.filtered_cards[id] = card
|
||||
end
|
||||
|
||||
if modify then
|
||||
filtered_cards[id] = nil
|
||||
self.filtered_cards[id] = nil
|
||||
data.card = card
|
||||
return
|
||||
end
|
||||
|
|
|
@ -344,6 +344,12 @@ function Player:getHandcardNum()
|
|||
return #self:getCardIds(Player.Hand)
|
||||
end
|
||||
|
||||
function Player:filterHandcards()
|
||||
for _, id in ipairs(self:getCardIds(Player.Hand)) do
|
||||
Fk:filterCard(id, self)
|
||||
end
|
||||
end
|
||||
|
||||
--- 检索玩家装备区是否存在对应类型的装备。
|
||||
---@param cardSubtype CardSubtype @ 卡牌子类
|
||||
---@return integer|null @ 返回卡牌ID或nil
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
-- Note: these files are not used by FreeKill.
|
||||
-- Just for convenience when using sumneko.lua
|
||||
|
||||
---@alias null nil
|
||||
|
||||
---@class fk
|
||||
---FreeKill's lua API
|
||||
fk = {}
|
||||
|
@ -35,3 +37,8 @@ function fk.QmlBackend_exists(file)end
|
|||
|
||||
---@return boolean
|
||||
function fk.QmlBackend_isDir(file)end
|
||||
|
||||
function fk.qCritical(msg) end
|
||||
function fk.qInfo(msg) end
|
||||
function fk.qDebug(msg) end
|
||||
function fk.qWarning(msg) end
|
||||
|
|
|
@ -14,6 +14,9 @@ function FPlayer:getScreenName()end
|
|||
---@return string avatar
|
||||
function FPlayer:getAvatar()end
|
||||
|
||||
---@class fk.ServerPlayer : fk.Player
|
||||
FServerPlayer = {}
|
||||
|
||||
--- Send a request to client, and allow client to reply within *timeout* seconds.
|
||||
---
|
||||
--- *timeout* must not be negative or **nil**.
|
||||
|
@ -34,3 +37,9 @@ function FServerPlayer:waitForReply(timeout)end
|
|||
---@param command string
|
||||
---@param jsonData string
|
||||
function FServerPlayer:doNotify(command,jsonData)end
|
||||
|
||||
function FServerPlayer:setBusy(_) end
|
||||
function FServerPlayer:isBusy(_) end
|
||||
function FServerPlayer:setThinking(_) end
|
||||
|
||||
function FServerPlayer:getState() end
|
||||
|
|
|
@ -119,7 +119,9 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
|||
self:doBroadcastNotify("UpdateDrawPile", #self.draw_pile)
|
||||
end
|
||||
|
||||
Fk:filterCard(info.cardId, self:getPlayerById(data.to))
|
||||
if not (data.to and data.toArea ~= Card.PlayerHand) then
|
||||
Fk:filterCard(info.cardId, self:getPlayerById(data.to))
|
||||
end
|
||||
|
||||
local currentCard = Fk:getCardById(info.cardId)
|
||||
if
|
||||
|
|
|
@ -52,6 +52,7 @@ local sendCardEmotionAndLog = function(room, cardUseEvent)
|
|||
Fk:filterCard(_card.id, room:getPlayerById(from), temp)
|
||||
card = temp.card
|
||||
end
|
||||
cardUseEvent.card = card
|
||||
|
||||
playCardEmotionAndSound(room, room:getPlayerById(from), card)
|
||||
room:doAnimate("Indicate", {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
---@field public request_queue table<userdata, table>
|
||||
---@field public request_self table<integer, integer>
|
||||
---@field public skill_costs table<string, any> @ 存放skill.cost_data用
|
||||
---@field public card_marks table<integer, any> @ 存放card.mark之用
|
||||
local Room = class("Room")
|
||||
|
||||
-- load classes used by the game
|
||||
|
@ -88,6 +89,8 @@ function Room:initialize(_room)
|
|||
self.request_queue = {}
|
||||
self.request_self = {}
|
||||
self.skill_costs = {}
|
||||
self.card_marks = {}
|
||||
self.filtered_cards = {}
|
||||
|
||||
self.settings = json.decode(self.room:settings())
|
||||
self.disabled_packs = self.settings.disabledPack
|
||||
|
@ -465,11 +468,13 @@ end
|
|||
---@param value integer @ 要设为的值,其实也可以设为字符串
|
||||
function Room:setCardMark(card, mark, value)
|
||||
card:setMark(mark, value)
|
||||
self:doBroadcastNotify("SetCardMark", json.encode{
|
||||
card.id,
|
||||
mark,
|
||||
value
|
||||
})
|
||||
if not card:isVirtual() then
|
||||
self:doBroadcastNotify("SetCardMark", json.encode{
|
||||
card.id,
|
||||
mark,
|
||||
value
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
--- 将一张卡牌的mark标记增加count个。
|
||||
|
@ -1168,7 +1173,7 @@ function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancel
|
|||
if includeEquip then
|
||||
table.insertTable(hands, player:getCardIds(Player.Equip))
|
||||
end
|
||||
for i = 1, minNum do
|
||||
for _ = 1, minNum do
|
||||
local randomId = hands[math.random(1, #hands)]
|
||||
table.insert(chosenCards, randomId)
|
||||
table.removeOne(hands, randomId)
|
||||
|
@ -1371,7 +1376,7 @@ end
|
|||
---@param prompt string|null @ 观星框的标题(暂时雪藏)
|
||||
---@param noPut boolean|null @ 是否进行放置牌操作
|
||||
---@param areaNames string[]|null @ 左侧提示信息
|
||||
---@return table<top|bottom, cardId[]>
|
||||
---@return table<"top"|"bottom", integer[]>
|
||||
function Room:askForGuanxing(player, cards, top_limit, bottom_limit, customNotify, noPut, areaNames)
|
||||
-- 这一大堆都是来提前报错的
|
||||
top_limit = top_limit or Util.DummyTable
|
||||
|
@ -1441,10 +1446,10 @@ end
|
|||
--- 询问玩家任意交换几堆牌堆。
|
||||
---
|
||||
---@param player ServerPlayer @ 要询问的玩家
|
||||
---@param piles table<cardIds, cardId[]> @ 卡牌id列表的列表,也就是……几堆牌堆的集合
|
||||
---@param piles table<cardIds, integer[]> @ 卡牌id列表的列表,也就是……几堆牌堆的集合
|
||||
---@param piles_name string[] @ 牌堆名,必须一一对应,否则统一替换为“牌堆X”
|
||||
---@param customNotify string|null @ 自定义读条操作提示
|
||||
---@return table<cardIds, cardId[]>
|
||||
---@return table<cardIds, integer[]>
|
||||
function Room:askForExchange(player, piles, piles_name, customNotify)
|
||||
local command = "AskForExchange"
|
||||
piles_name = piles_name or Util.DummyTable
|
||||
|
@ -1775,7 +1780,7 @@ end
|
|||
---@param skillName string @ 技能名
|
||||
---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’
|
||||
---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2
|
||||
---@return cardId
|
||||
---@return integer
|
||||
function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom)
|
||||
if flag then
|
||||
assert(flag == "e" or flag == "j")
|
||||
|
|
23
test/lua/lib/fk.lua
Normal file
23
test/lua/lib/fk.lua
Normal file
|
@ -0,0 +1,23 @@
|
|||
-- 为纯lua的测试环境捏一个虚拟的fk以便于测试
|
||||
|
||||
local fk = {}
|
||||
|
||||
local os, io = os, io
|
||||
|
||||
-- 这下Linux专用了
|
||||
function fk.QmlBackend_ls(dir)
|
||||
local f = io.popen("ls " .. dir)
|
||||
return f:read("*a"):split("\n")
|
||||
end
|
||||
|
||||
function fk.QmlBackend_isDir(dir)
|
||||
local f = io.popen("if [ -d " .. dir .. " ]; then echo OK; fi")
|
||||
return f:read("*a"):startsWith("OK")
|
||||
end
|
||||
|
||||
function fk.QmlBackend_exists(dir)
|
||||
local f = io.popen("if [ -e " .. dir .. " ]; then echo OK; fi")
|
||||
return f:read("*a"):startsWith("OK")
|
||||
end
|
||||
|
||||
return fk
|
3454
test/lua/lib/luaunit.lua
Normal file
3454
test/lua/lib/luaunit.lua
Normal file
File diff suppressed because it is too large
Load Diff
22
test/lua/pattern.lua
Normal file
22
test/lua/pattern.lua
Normal file
|
@ -0,0 +1,22 @@
|
|||
local exp1 = Exppattern:Parse("slash,jink")
|
||||
local exp2 = Exppattern:Parse("peach,jink")
|
||||
local exp3 = Exppattern:Parse(".|.|.|.|.|trick")
|
||||
local exp4 = Exppattern:Parse("peach,ex_nihilo")
|
||||
|
||||
local slash = Fk:cloneCard("slash")
|
||||
|
||||
TestExppattern = {
|
||||
testMatchExp = function()
|
||||
assert(exp1:matchExp(exp2))
|
||||
end,
|
||||
|
||||
testEasyMatchCard = function()
|
||||
assert(exp1:match(slash))
|
||||
assert(not exp2:match(slash))
|
||||
end,
|
||||
|
||||
testMatchWithType = function()
|
||||
assert(not exp3:matchExp(exp1))
|
||||
assert(exp3:matchExp(exp4))
|
||||
end,
|
||||
}
|
14
test/lua/run.lua
Normal file
14
test/lua/run.lua
Normal file
|
@ -0,0 +1,14 @@
|
|||
-- Run tests with `lua5.4 test/lua/run.lua`
|
||||
|
||||
---@diagnostic disable: lowercase-global
|
||||
|
||||
package.path = package.path .. ";./test/lua/lib/?.lua"
|
||||
|
||||
lu = require('luaunit')
|
||||
local os = os
|
||||
fk = require('fk')
|
||||
|
||||
dofile 'lua/freekill.lua'
|
||||
dofile 'test/lua/pattern.lua'
|
||||
|
||||
os.exit( lu.LuaUnit.run() )
|
Loading…
Reference in New Issue
Block a user