From 957fefe88195ceb6d5508102c56b8800a07e24c2 Mon Sep 17 00:00:00 2001 From: Notify-ctrl <70358032+Notify-ctrl@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:29:23 +0800 Subject: [PATCH] Cards (#8) * more comment * create standard card pack * create card classes * freekill -> fk * fk_ex --- lua/client/client.lua | 22 ++++---- lua/core/card.lua | 80 +++++++++++++++++----------- lua/core/card_type/basic.lua | 9 ++++ lua/core/card_type/equip.lua | 9 ++++ lua/core/card_type/skill.lua | 9 ++++ lua/core/card_type/trick.lua | 9 ++++ lua/core/engine.lua | 15 +++--- lua/core/general.lua | 17 ++++-- lua/core/package.lua | 22 ++++++-- lua/core/player.lua | 10 ++-- lua/core/skill.lua | 12 ++--- lua/core/util.lua | 50 ++++++++--------- lua/fk_ex.lua | 38 +++++++++++++ lua/freekill.lua | 13 +++-- lua/server/gamelogic.lua | 5 ++ lua/server/room.lua | 34 +++++++++++- lua/server/server.lua | 40 +++++++------- lua/server/serverplayer.lua | 21 ++++++++ lua/vscode/freekill.lua | 22 ++++---- lua/vscode/lib.lua | 4 ++ lua/vscode/player.lua | 10 ++-- lua/vscode/qt.lua | 6 +-- lua/vscode/server.lua | 16 +++--- lua/vscode/sqlite.lua | 18 +++---- packages/standard/init.lua | 2 +- packages/standard_cards/init.lua | 8 +++ packages/standard_cards/metadata.lua | 14 +++++ src/core/util.cpp | 4 +- src/swig/freekill.i | 2 +- 29 files changed, 360 insertions(+), 161 deletions(-) create mode 100644 lua/core/card_type/basic.lua create mode 100644 lua/core/card_type/equip.lua create mode 100644 lua/core/card_type/skill.lua create mode 100644 lua/core/card_type/trick.lua create mode 100644 lua/fk_ex.lua create mode 100644 packages/standard_cards/init.lua create mode 100644 packages/standard_cards/metadata.lua diff --git a/lua/client/client.lua b/lua/client/client.lua index 8e2901be..c8aff3e9 100644 --- a/lua/client/client.lua +++ b/lua/client/client.lua @@ -3,15 +3,15 @@ Client = class('Client') -- load client classes ClientPlayer = require "client.clientplayer" -freekill.client_callback = {} +fk.client_callback = {} function Client:initialize() - self.client = freekill.ClientInstance + self.client = fk.ClientInstance self.notifyUI = function(self, command, jsonData) - freekill.Backend:emitNotifyUI(command, jsonData) + fk.Backend:emitNotifyUI(command, jsonData) end self.client.callback = function(_self, command, jsonData) - local cb = freekill.client_callback[command] + local cb = fk.client_callback[command] if (type(cb) == "function") then cb(jsonData) else @@ -22,31 +22,31 @@ function Client:initialize() self.players = {} -- ClientPlayer[] end -freekill.client_callback["Setup"] = function(jsonData) +fk.client_callback["Setup"] = function(jsonData) -- jsonData: [ int id, string screenName, string avatar ] local data = json.decode(jsonData) local id, name, avatar = data[1], data[2], data[3] - local self = freekill.Self + local self = fk.Self self:setId(id) self:setScreenName(name) self:setAvatar(avatar) end -freekill.client_callback["AddPlayer"] = function(jsonData) +fk.client_callback["AddPlayer"] = function(jsonData) -- jsonData: [ int id, string screenName, string avatar ] -- when other player enter the room, we create clientplayer(C and lua) for them local data = json.decode(jsonData) local id, name, avatar = data[1], data[2], data[3] - local player = freekill.ClientInstance:addPlayer(id, name, avatar) + local player = fk.ClientInstance:addPlayer(id, name, avatar) table.insert(ClientInstance.players, ClientPlayer:new(player)) ClientInstance:notifyUI("AddPlayer", jsonData) end -freekill.client_callback["RemovePlayer"] = function(jsonData) +fk.client_callback["RemovePlayer"] = function(jsonData) -- jsonData: [ int id ] local data = json.decode(jsonData) local id = data[1] - freekill.ClientInstance:removePlayer(id) + fk.ClientInstance:removePlayer(id) for _, p in ipairs(ClientInstance.players) do if p.player:getId() == id then table.removeOne(ClientInstance.players, p) @@ -56,7 +56,7 @@ freekill.client_callback["RemovePlayer"] = function(jsonData) ClientInstance:notifyUI("RemovePlayer", jsonData) end -freekill.client_callback["ArrangeSeats"] = function(jsonData) +fk.client_callback["ArrangeSeats"] = function(jsonData) local data = json.decode(jsonData) local n = #ClientInstance.players local players = {} diff --git a/lua/core/card.lua b/lua/core/card.lua index 408829b0..7d8e755f 100644 --- a/lua/core/card.lua +++ b/lua/core/card.lua @@ -1,37 +1,55 @@ -local SUITS = { - "Spade", - "Club", - "Diamond", - "Heart", - "NonSuit", -} - -CardSuit = Util:createEnum(SUITS) - -local COLOR = { - "Red", - "Black", - "NonColor", -} - -CardColor = Util:createEnum(COLOR) - +---@class Card : Object +---@field package Package +---@field name string +---@field suit number # enum suit +---@field number number +---@field color number # enum color +---@field id number +---@field type number # enum type local Card = class("Card") -function Card:initialize(name, suit, cardNumber) - self.name = name - self.suit = suit - self.cardNumber = cardNumber -end +-- enum Suit +fk.createEnum(Card, { + "Spade", + "Club", + "Heart", + "Diamond", + "NoSuit" +}) -function Card:getColor() - if self.suit == CardSuit.Spade or self.suit == CardSuit.Club then - return CardColor.Red - elseif self.suit == CardSuit.Diamond or self.suit == CardSuit.Heart then - return CardColor.Black - else - return CardColor.NonColor - end +-- enum Color +fk.createEnum(Card, { + "Black", + "Red", + "NoColor" +}) + +-- enum Type +fk.createEnum(Card, { + "TypeSkill", + "TypeBasic", + "TypeTrick", + "TypeEquip" +}) + +function Card:initialize(name, suit, number, color) + self.name = name + self.suit = suit or Card.NoSuit + self.number = number or 0 + + if suit == Card.Spade or suit == Card.Club then + self.color = Card.Black + elseif suit == Card.Heart or suit == Card.Diamond then + self.color = Card.Red + elseif color ~= nil then + self.color = color + else + self.color = Card.NoColor + end + + self.package = nil + self.id = 0 + self.type = 0 end return Card diff --git a/lua/core/card_type/basic.lua b/lua/core/card_type/basic.lua new file mode 100644 index 00000000..87dd0952 --- /dev/null +++ b/lua/core/card_type/basic.lua @@ -0,0 +1,9 @@ +---@class BasicCard : Card +local BasicCard = Card:subclass("BasicCard") + +function BasicCard:initialize(name, suit, number) + Card.initialize(self, name, suit, number) + self.type = Card.TypeBasic +end + +return BasicCard diff --git a/lua/core/card_type/equip.lua b/lua/core/card_type/equip.lua new file mode 100644 index 00000000..d971ddd4 --- /dev/null +++ b/lua/core/card_type/equip.lua @@ -0,0 +1,9 @@ +---@class EquipCard : Card +local EquipCard = Card:subclass("EquipCard") + +function EquipCard:initialize(name, suit, number) + Card.initialize(self, name, suit, number) + self.type = Card.TypeEquip +end + +return EquipCard diff --git a/lua/core/card_type/skill.lua b/lua/core/card_type/skill.lua new file mode 100644 index 00000000..a3064d13 --- /dev/null +++ b/lua/core/card_type/skill.lua @@ -0,0 +1,9 @@ +---@class SkillCard : Card +local SkillCard = Card:subclass("SkillCard") + +function SkillCard:initialize(name) + Card.initialize(self, name, Card.NoSuit, 0) + self.type = Card.TypeSkill +end + +return SkillCard diff --git a/lua/core/card_type/trick.lua b/lua/core/card_type/trick.lua new file mode 100644 index 00000000..ce91a5fd --- /dev/null +++ b/lua/core/card_type/trick.lua @@ -0,0 +1,9 @@ +---@class TrickCard : Card +local TrickCard = Card:subclass("TrickCard") + +function TrickCard:initialize(name, suit, number) + Card.initialize(self, name, suit, number) + self.type = Card.TypeTrick +end + +return TrickCard diff --git a/lua/core/engine.lua b/lua/core/engine.lua index eb88a399..1c41443d 100644 --- a/lua/core/engine.lua +++ b/lua/core/engine.lua @@ -46,14 +46,11 @@ function Engine:loadPackage(pack) end function Engine:loadPackages() - assert(FileIO.isDir("packages")) - FileIO.cd("packages") - for _, dir in ipairs(FileIO.ls()) do - if FileIO.isDir(dir) then - self:loadPackage(require(dir)) + for _, dir in ipairs(FileIO.ls("packages")) do + if FileIO.isDir("packages/" .. dir) then + self:loadPackage(require(string.format("packages.%s", dir))) end end - FileIO.cd("..") end ---@param t table @@ -98,13 +95,17 @@ function Engine:addGenerals(generals) end end +local cardId = 1 +---@param card Card function Engine:addCard(card) assert(card.class:isSubclassOf(Card)) + card.id = cardId + cardId = cardId + 1 table.insert(self.cards, card) end +---@param cards Card[] function Engine:addCards(cards) - assert(type(cards) == "table") for _, card in ipairs(cards) do self:addCard(card) end diff --git a/lua/core/general.lua b/lua/core/general.lua index 4c3f68b7..552bfa6d 100644 --- a/lua/core/general.lua +++ b/lua/core/general.lua @@ -1,9 +1,19 @@ ---- @class General : Object +---@class General : Object +---@field package Package +---@field name string +---@field kingdom string +---@field hp number +---@field maxHp number +---@field gender number +---@field skills table +---@field other_skills table General = class("General") -- enum Gender -General.Male = 0 -General.Female = 1 +fk.createEnum(General, { + "Male", + "Female" +}) function General:initialize(package, name, kingdom, hp, maxHp, gender, initialHp) self.package = package @@ -12,7 +22,6 @@ function General:initialize(package, name, kingdom, hp, maxHp, gender, initialHp self.hp = hp self.maxHp = maxHp or hp self.gender = gender or General.Male - self.initialHp = initialHp or maxHp self.skills = {} -- Skill[] -- skill belongs other general, e.g. "mashu" of pangde diff --git a/lua/core/package.lua b/lua/core/package.lua index aa1c5700..b131431b 100644 --- a/lua/core/package.lua +++ b/lua/core/package.lua @@ -8,9 +8,11 @@ local Package = class("Package") -- enum Type -Package.GeneralPack = 0 -Package.CardPack = 1 -Package.SpecialPack = 2 +fk.createEnum(Package, { + "GeneralPack", + "CardPack", + "SpecialPack" +}) function Package:initialize(name, _type) assert(type(name) == "string") @@ -45,4 +47,18 @@ function Package:addGeneral(general) table.insert(self.generals, general) end +---@param card Card +function Package:addCard(card) + assert(card.class and card:isInstanceOf(Card)) + card.package = self + table.insert(self.cards, card) +end + +---@param cards Card[] +function Package:addCards(cards) + for _, card in ipairs(cards) do + self:addCard(card) + end +end + return Package diff --git a/lua/core/player.lua b/lua/core/player.lua index d6c188fb..10ae4e0c 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -19,11 +19,14 @@ function Player:initialize() self.playerSkills = {} end +---@param general General +---@param setHp boolean +---@param addSkills boolean function Player:setGeneral(general, setHp, addSkills) self.general = general if setHp then self.maxHp = general.maxHp - self.hp = general.initialHp + self.hp = general.hp end if addSkills then @@ -31,9 +34,4 @@ function Player:setGeneral(general, setHp, addSkills) end end -function Player:setHp(maxHp, initialHp) - self.maxHp = maxHp - self.hp = initialHp or maxHp -end - return Player diff --git a/lua/core/skill.lua b/lua/core/skill.lua index 0f393a20..39814185 100644 --- a/lua/core/skill.lua +++ b/lua/core/skill.lua @@ -1,15 +1,13 @@ -local SKILL_TYPE = { +---@class Skill +local Skill = class("Skill") + +fk.createEnum(Skill, { "Common", "Frequent", "Compulsory", "Awaken", "Limit", - "Lord", -} - -SkillType = Util:createEnum(SKILL_TYPE) - -local Skill = class("Skill") +}) function Skill:initialize(name, skillType) self.name = name diff --git a/lua/core/util.lua b/lua/core/util.lua index fa9e27d3..55112469 100644 --- a/lua/core/util.lua +++ b/lua/core/util.lua @@ -5,7 +5,7 @@ local qlist_iterator = function(list, n) end end -function freekill.qlist(list) +function fk.qlist(list) return qlist_iterator, list, -1 end @@ -33,46 +33,47 @@ end Sql = { ---@param filename string open = function(filename) - return freekill.OpenDatabase(filename) + return fk.OpenDatabase(filename) end, - ---@param db freekill.SQLite3 + ---@param db fk.SQLite3 close = function(db) - freekill.CloseDatabase(db) + fk.CloseDatabase(db) end, --- Execute an SQL statement. - ---@param db freekill.SQLite3 + ---@param db fk.SQLite3 ---@param sql string exec = function(db, sql) - freekill.ExecSQL(db, sql) + fk.ExecSQL(db, sql) end, --- Execute a `SELECT` SQL statement. - ---@param db freekill.SQLite3 + ---@param db fk.SQLite3 ---@param sql string ---@return table data # { [columnName] --> result : string[] } exec_select = function(db, sql) - return json.decode(freekill.SelectFromDb(db, sql)) + return json.decode(fk.SelectFromDb(db, sql)) end, } FileIO = { - pwd = freekill.QmlBackend_pwd, + pwd = fk.QmlBackend_pwd, ls = function(filename) if filename == nil then - return freekill.QmlBackend_ls(".") + return fk.QmlBackend_ls(".") else - return freekill.QmlBackend_ls(filename) + return fk.QmlBackend_ls(filename) end end, - cd = freekill.QmlBackend_cd, - exists = freekill.QmlBackend_exists, - isDir = freekill.QmlBackend_isDir + cd = fk.QmlBackend_cd, + exists = fk.QmlBackend_exists, + isDir = fk.QmlBackend_isDir } -os.getms = freekill.GetMicroSecond +os.getms = fk.GetMicroSecond +---@class Stack : Object Stack = class("Stack") function Stack:initialize() self.t = {} @@ -106,16 +107,11 @@ function table:removeOne(element) return false end -local Util = class("Util") - -function Util.static:createEnum(tbl, index) - assert(type(tbl) == "table") - local enumtbl = {} - local enumindex = index or 0 - for i, v in ipairs(tbl) do - enumtbl[v] = enumindex + i - end - return enumtbl +--- convert a table to enum, e.g. core/card.lua +---@param table table # class to store the enum +---@param enum string[] +function fk.createEnum(table, enum) + for i, v in ipairs(enum) do + table[v] = i + end end - -return Util diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua new file mode 100644 index 00000000..4b7ab487 --- /dev/null +++ b/lua/fk_ex.lua @@ -0,0 +1,38 @@ +---@param spec table +---@return BasicCard +function fk.CreateBasicCard(spec) + assert(type(spec.name) == "string" or type(spec.class_name) == "string") + if not spec.name then spec.name = spec.class_name + elseif not spec.class_name then spec.class_name = spec.name end + if spec.suit then assert(type(spec.suit) == "number") end + if spec.number then assert(type(spec.number) == "number") end + + local card = BasicCard:new(spec.name, spec.suit, spec.number) + return card +end + +---@param spec table +---@return TrickCard +function fk.CreateTrickCard(spec) + assert(type(spec.name) == "string" or type(spec.class_name) == "string") + if not spec.name then spec.name = spec.class_name + elseif not spec.class_name then spec.class_name = spec.name end + if spec.suit then assert(type(spec.suit) == "number") end + if spec.number then assert(type(spec.number) == "number") end + + local card = TrickCard:new(spec.name, spec.suit, spec.number) + return card +end + +---@param spec table +---@return EquipCard +function fk.CreateEquipCard(spec) + assert(type(spec.name) == "string" or type(spec.class_name) == "string") + if not spec.name then spec.name = spec.class_name + elseif not spec.class_name then spec.class_name = spec.name end + if spec.suit then assert(type(spec.suit) == "number") end + if spec.number then assert(type(spec.number) == "number") end + + local card = EquipCard:new(spec.name, spec.suit, spec.number) + return card +end diff --git a/lua/freekill.lua b/lua/freekill.lua index faa7a3f9..b2f17c49 100644 --- a/lua/freekill.lua +++ b/lua/freekill.lua @@ -6,14 +6,12 @@ package.path = package.path .. ";./lua/lib/?.lua" -- load libraries ----@type class class = require "middleclass" - ----@type json json = require "json" -require "sha256" -Util = require "core.util" +dofile "lua/lib/sha256.lua" +dofile "lua/core/util.lua" + math.randomseed(os.time()) DebugMode = true @@ -29,8 +27,13 @@ Engine = require "core.engine" Package = require "core.package" General = require "core.general" Card = require "core.card" +SkillCard = require "core.card_type.skill" +BasicCard = require "core.card_type.basic" +TrickCard = require "core.card_type.trick" +EquipCard = require "core.card_type.equip" Skill = require "core.skill" Player = require "core.player" -- load packages +dofile "lua/fk_ex.lua" Fk = Engine:new() diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua index 551e6af2..f50921f0 100644 --- a/lua/server/gamelogic.lua +++ b/lua/server/gamelogic.lua @@ -1,4 +1,9 @@ ---@class GameLogic: Object +---@field room Room +---@field skill_table table +---@filed skills table +---@field event_stack Stack +---@field role_table table local GameLogic = class("GameLogic") function GameLogic:initialize(room) diff --git a/lua/server/room.lua b/lua/server/room.lua index 00718af8..82c84fdd 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -1,8 +1,15 @@ ---@class Room : Object +---@field room fk.Room +---@field server Server +---@field players table +---@field alive_players table +---@field game_finished boolean +---@field timeout number local Room = class("Room") function Room:initialize(_room) self.room = _room + self.server = nil self.players = {} -- ServerPlayer[] self.alive_players = {} self.game_finished = false @@ -11,7 +18,7 @@ end -- When this function returns, the Room(C++) thread stopped. function Room:run() - for _, p in freekill.qlist(self.room:getPlayers()) do + for _, p in fk.qlist(self.room:getPlayers()) do local player = ServerPlayer:new(p) player.state = p:getStateString() player.room = self @@ -23,12 +30,17 @@ function Room:run() self.logic:run() end +---@param player ServerPlayer +---@param property string function Room:broadcastProperty(player, property) for _, p in ipairs(self.players) do self:notifyProperty(p, player, property) end end +---@param p ServerPlayer +---@param player ServerPlayer +---@param property string function Room:notifyProperty(p, player, property) p:doNotify("PropertyUpdate", json.encode{ player:getId(), @@ -37,15 +49,23 @@ function Room:notifyProperty(p, player, property) }) end +---@param command string +---@param jsonData string +---@param players ServerPlayer[] # default all players function Room:doBroadcastNotify(command, jsonData, players) players = players or self.players - local tolist = freekill.SPlayerList() + local tolist = fk.SPlayerList() for _, p in ipairs(players) do tolist:append(p.serverplayer) end self.room:doBroadcastNotify(tolist, command, jsonData) end +---@param player ServerPlayer +---@param command string +---@param jsonData string +---@param wait boolean # default true +---@return string | nil function Room:doRequest(player, command, jsonData, wait) if wait == nil then wait = true end player:doRequest(command, jsonData, self.timeout) @@ -55,6 +75,8 @@ function Room:doRequest(player, command, jsonData, wait) end end +---@param command string +---@param players ServerPlayer[] function Room:doBroadcastRequest(command, players) players = players or self.players self:notifyMoveFocus(players, command) @@ -72,6 +94,8 @@ function Room:doBroadcastRequest(command, players) end end +---@param players ServerPlayer | ServerPlayer[] +---@param command string function Room:notifyMoveFocus(players, command) if (players.class) then players = {players} @@ -116,6 +140,7 @@ function Room:adjustSeats() self:doBroadcastNotify("ArrangeSeats", json.encode(player_circle)) end +---@return ServerPlayer | nil function Room:getLord() local lord = self.players[1] if lord.role == "lord" then return lord end @@ -126,12 +151,17 @@ function Room:getLord() return nil end +---@param expect ServerPlayer +---@return ServerPlayer[] function Room:getOtherPlayers(expect) local ret = {table.unpack(self.players)} table.removeOne(ret, expect) return ret end +---@param player ServerPlayer +---@param generals string[] +---@return string function Room:askForGeneral(player, generals) local command = "AskForGeneral" self:notifyMoveFocus(player, command) diff --git a/lua/server/server.lua b/lua/server/server.lua index 6c953b7d..50715f1b 100644 --- a/lua/server/server.lua +++ b/lua/server/server.lua @@ -1,4 +1,8 @@ ---@class Server : Object +---@field server fk.Server +---@field db fk.SQLite3 +---@field rooms table +---@field players table Server = class('Server') -- load server classes @@ -6,13 +10,13 @@ Room = require "server.room" GameLogic = require "server.gamelogic" ServerPlayer = require "server.serverplayer" -freekill.server_callback = {} +fk.server_callback = {} function Server:initialize() - self.server = freekill.ServerInstance - self.db = freekill.ServerInstance:getDatabase() + self.server = fk.ServerInstance + self.db = fk.ServerInstance:getDatabase() self.server.callback = function(_self, command, jsonData) - local cb = freekill.server_callback[command] + local cb = fk.server_callback[command] if (type(cb) == "function") then cb(jsonData) else @@ -37,18 +41,18 @@ function Server:initialize() self.players = {} -- id --> ServerPlayer end -freekill.server_callback["UpdateAvatar"] = function(jsonData) +fk.server_callback["UpdateAvatar"] = function(jsonData) -- jsonData: [ int uid, string newavatar ] local data = json.decode(jsonData) local id, avatar = data[1], data[2] local sql = "UPDATE userinfo SET avatar='%s' WHERE id=%d;" Sql.exec(ServerInstance.db, string.format(sql, avatar, id)) - local player = freekill.ServerInstance:findPlayer(id) + local player = fk.ServerInstance:findPlayer(id) player:setAvatar(avatar) player:doNotify("UpdateAvatar", avatar) end -freekill.server_callback["UpdatePassword"] = function(jsonData) +fk.server_callback["UpdatePassword"] = function(jsonData) -- jsonData: [ int uid, string oldpassword, int newpassword ] local data = json.decode(jsonData) local id, old, new = data[1], data[2], data[3] @@ -63,38 +67,38 @@ freekill.server_callback["UpdatePassword"] = function(jsonData) Sql.exec(db, string.format(sql_update, sha256(new), id)) end - local player = freekill.ServerInstance:findPlayer(tonumber(id)) + local player = fk.ServerInstance:findPlayer(tonumber(id)) player:doNotify("UpdatePassword", passed and "1" or "0") end -freekill.server_callback["CreateRoom"] = function(jsonData) +fk.server_callback["CreateRoom"] = function(jsonData) -- jsonData: [ int uid, string name, int capacity ] local data = json.decode(jsonData) - local owner = freekill.ServerInstance:findPlayer(tonumber(data[1])) + local owner = fk.ServerInstance:findPlayer(tonumber(data[1])) local roomName = data[2] local capacity = data[3] - freekill.ServerInstance:createRoom(owner, roomName, capacity) + fk.ServerInstance:createRoom(owner, roomName, capacity) end -freekill.server_callback["EnterRoom"] = function(jsonData) +fk.server_callback["EnterRoom"] = function(jsonData) -- jsonData: [ int uid, int roomId ] local data = json.decode(jsonData) - local player = freekill.ServerInstance:findPlayer(tonumber(data[1])) - local room = freekill.ServerInstance:findRoom(tonumber(data[2])) + local player = fk.ServerInstance:findPlayer(tonumber(data[1])) + local room = fk.ServerInstance:findRoom(tonumber(data[2])) room:addPlayer(player) end -freekill.server_callback["QuitRoom"] = function(jsonData) +fk.server_callback["QuitRoom"] = function(jsonData) -- jsonData: [ int uid ] local data = json.decode(jsonData) - local player = freekill.ServerInstance:findPlayer(tonumber(data[1])) + local player = fk.ServerInstance:findPlayer(tonumber(data[1])) local room = player:getRoom() if not room:isLobby() then room:removePlayer(player) end end -freekill.server_callback["DoLuaScript"] = function(jsonData) +fk.server_callback["DoLuaScript"] = function(jsonData) -- jsonData: [ int uid, string luaScript ] -- warning: only use this in debugging mode. if not DebugMode then return end @@ -102,7 +106,7 @@ freekill.server_callback["DoLuaScript"] = function(jsonData) assert(load(data[2]))() end -freekill.server_callback["PlayerStateChanged"] = function(jsonData) +fk.server_callback["PlayerStateChanged"] = function(jsonData) -- jsonData: [ int uid, string stateString ] -- note: this function is not called by Router. local data = json.decode(jsonData) diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index 3bf61cad..75d67483 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -1,4 +1,11 @@ ---@class ServerPlayer : Player +---@field serverplayer fk.ServerPlayer +---@field room Room +---@field next ServerPlayer +---@field request_data string +---@field client_reply string +---@field default_reply string +---@field reply_ready boolean local ServerPlayer = Player:subclass("ServerPlayer") function ServerPlayer:initialize(_self) @@ -15,14 +22,23 @@ function ServerPlayer:initialize(_self) self.reply_ready = false end +---@return number function ServerPlayer:getId() return self.serverplayer:getId() end +---@param command string +---@param jsonData string function ServerPlayer:doNotify(command, jsonData) self.serverplayer:doNotify(command, jsonData) end +--- Send a request to client, and allow client to reply within *timeout* seconds. +--- +--- *timeout* must not be negative. If nil, room.timeout is used. +---@param command string +---@param jsonData string +---@param timeout number function ServerPlayer:doRequest(command, jsonData, timeout) timeout = timeout or self.room.timeout self.client_reply = "" @@ -30,6 +46,11 @@ function ServerPlayer:doRequest(command, jsonData, timeout) self.serverplayer:doRequest(command, jsonData, timeout) end +--- Wait for at most *timeout* seconds for reply from client. +--- +--- If *timeout* is negative or **nil**, the function will wait forever until get reply. +---@param timeout number # seconds to wait +---@return string reply # JSON data function ServerPlayer:waitForReply(timeout) local result = "" if timeout == nil then diff --git a/lua/vscode/freekill.lua b/lua/vscode/freekill.lua index b2dd0aa2..ed8e0cef 100644 --- a/lua/vscode/freekill.lua +++ b/lua/vscode/freekill.lua @@ -3,23 +3,23 @@ -- Note: these files are not used by FreeKill. -- Just for convenience when using sumneko.lua ----@class freekill +---@class fk ---FreeKill's lua API -freekill = {} +fk = {} ----@class freekill.SPlayerList +---@class fk.SPlayerList SPlayerList = {} --- * get microsecond from Epoch ---@return number microsecond -function freekill:GetMicroSecond()end +function fk:GetMicroSecond()end --- construct a QList. ----@return freekill.SPlayerList -function freekill:SPlayerList()end +---@return fk.SPlayerList +function fk:SPlayerList()end -function freekill.QmlBackend_pwd()end -function freekill.QmlBackend_ls(filename)end -function freekill.QmlBackend_cd(dir)end -function freekill.QmlBackend_exists(file)end -function freekill.QmlBackend_isDir(file)end +function fk.QmlBackend_pwd()end +function fk.QmlBackend_ls(filename)end +function fk.QmlBackend_cd(dir)end +function fk.QmlBackend_exists(file)end +function fk.QmlBackend_isDir(file)end diff --git a/lua/vscode/lib.lua b/lua/vscode/lib.lua index 78d0549b..203a5cc2 100644 --- a/lua/vscode/lib.lua +++ b/lua/vscode/lib.lua @@ -20,6 +20,10 @@ function Object:subclass(name)end ---@return boolean function Object:isInstanceOf(class) end +---@param class class +---@return boolean +function Object:isSubclassOf(class) end + ---@class json json = {} diff --git a/lua/vscode/player.lua b/lua/vscode/player.lua index fd99c6d0..22f25b4c 100644 --- a/lua/vscode/player.lua +++ b/lua/vscode/player.lua @@ -1,6 +1,6 @@ ---@meta ----@class freekill.Player +---@class fk.Player FPlayer = {} ---@return number id @@ -27,16 +27,16 @@ function FPlayer:getStateString()end ---@param state string function FPlayer:setStateString(state)end ----@class freekill.ServerPlayer : freekill.Player +---@class fk.ServerPlayer : fk.Player FServerPlayer = {} ----@return freekill.Server +---@return fk.Server function FServerPlayer:getServer()end ----@return freekill.Room +---@return fk.Room function FServerPlayer:getRoom()end ----@param room freekill.Room +---@param room fk.Room function FServerPlayer:setRoom(room)end ---@param msg string diff --git a/lua/vscode/qt.lua b/lua/vscode/qt.lua index 3cc3b3ef..62a8bdda 100644 --- a/lua/vscode/qt.lua +++ b/lua/vscode/qt.lua @@ -3,15 +3,15 @@ ---@return number length function SPlayerList:length()end ----@param e freekill.ServerPlayer +---@param e fk.ServerPlayer function SPlayerList:append(e)end ----@param e freekill.ServerPlayer +---@param e fk.ServerPlayer ---@return boolean function SPlayerList:contains(e)end ---@param index number ----@return freekill.ServerPlayer | nil +---@return fk.ServerPlayer | nil function SPlayerList:at(index)end function SPlayerList:first()end diff --git a/lua/vscode/server.lua b/lua/vscode/server.lua index be029926..8c96da57 100644 --- a/lua/vscode/server.lua +++ b/lua/vscode/server.lua @@ -1,29 +1,29 @@ ---@meta ----@class freekill.Server +---@class fk.Server FServer = {} ----@type freekill.Server -freekill.ServerInstance = {} +---@type fk.Server +fk.ServerInstance = {} ----@class freekill.Room +---@class fk.Room --- Room (C++) FRoom = {} ----@param owner freekill.ServerPlayer +---@param owner fk.ServerPlayer ---@param name string ---@param capacity number function FServer:createRoom(owner,name,capacity)end ---@param id number ----@return freekill.Room room +---@return fk.Room room function FServer:findRoom(id)end ---@param id number ----@return freekill.ServerPlayer player +---@return fk.ServerPlayer player function FServer:findPlayer(id)end ----@return freekill.SQLite3 db +---@return fk.SQLite3 db function FServer:getDatabase()end function FRoom:getServer()end diff --git a/lua/vscode/sqlite.lua b/lua/vscode/sqlite.lua index a53edab7..4a5b39ce 100644 --- a/lua/vscode/sqlite.lua +++ b/lua/vscode/sqlite.lua @@ -1,20 +1,20 @@ ---@meta ----@class freekill.SQLite3 +---@class fk.SQLite3 SQLite3 = {} ---@param filename string ----@return freekill.SQLite3 -function freekill.OpenDatabase(filename)end +---@return fk.SQLite3 +function fk.OpenDatabase(filename)end ----@param db freekill.SQLite3 +---@param db fk.SQLite3 ---@param sql string ---@return string jsonData -function freekill.SelectFromDb(db, sql)end +function fk.SelectFromDb(db, sql)end ----@param db freekill.SQLite3 +---@param db fk.SQLite3 ---@param sql string -function freekill.ExecSQL(db, sql)end +function fk.ExecSQL(db, sql)end ----@param db freekill.SQLite3 -function freekill.CloseDatabase(db)end +---@param db fk.SQLite3 +function fk.CloseDatabase(db)end diff --git a/packages/standard/init.lua b/packages/standard/init.lua index bfeb7ecb..867a9710 100644 --- a/packages/standard/init.lua +++ b/packages/standard/init.lua @@ -1,5 +1,5 @@ local extension = Package:new("standard") -extension.metadata = require "standard.metadata" +extension.metadata = require "packages.standard.metadata" Fk:loadTranslationTable{ ["wei"] = "魏", diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua new file mode 100644 index 00000000..b3faa8e7 --- /dev/null +++ b/packages/standard_cards/init.lua @@ -0,0 +1,8 @@ +local extension = Package:new("standard_cards", Package.CardPack) +extension.metadata = require "packages.standard_cards.metadata" + +local slash = fk.CreateBasicCard{ + name = "slash", +} + +return extension diff --git a/packages/standard_cards/metadata.lua b/packages/standard_cards/metadata.lua new file mode 100644 index 00000000..bb56d252 --- /dev/null +++ b/packages/standard_cards/metadata.lua @@ -0,0 +1,14 @@ +return { + name = "standard_cards", + author = "official", + description = "", + collaborators = { + program = {}, + designer = {}, + cv = {}, + illustrator = {}, + }, + + dependencies = {}, + extra_files = {}, +} diff --git a/src/core/util.cpp b/src/core/util.cpp index c8602b76..9daffc9b 100644 --- a/src/core/util.cpp +++ b/src/core/util.cpp @@ -1,14 +1,14 @@ #include "util.h" extern "C" { - int luaopen_freekill(lua_State *); + int luaopen_fk(lua_State *); } lua_State *CreateLuaState() { lua_State *L = luaL_newstate(); luaL_openlibs(L); - luaopen_freekill(L); + luaopen_fk(L); return L; } diff --git a/src/swig/freekill.i b/src/swig/freekill.i index 95d87efe..80ff9c92 100644 --- a/src/swig/freekill.i +++ b/src/swig/freekill.i @@ -1,4 +1,4 @@ -%module freekill +%module fk %{ #include "client.h"