Cards (#8)
* more comment * create standard card pack * create card classes * freekill -> fk * fk_ex
This commit is contained in:
parent
a85f510c98
commit
957fefe881
|
@ -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 = {}
|
||||
|
|
|
@ -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)
|
||||
-- enum Suit
|
||||
fk.createEnum(Card, {
|
||||
"Spade",
|
||||
"Club",
|
||||
"Heart",
|
||||
"Diamond",
|
||||
"NoSuit"
|
||||
})
|
||||
|
||||
-- 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
|
||||
self.cardNumber = cardNumber
|
||||
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
|
||||
|
||||
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
|
||||
self.package = nil
|
||||
self.id = 0
|
||||
self.type = 0
|
||||
end
|
||||
|
||||
return Card
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
---@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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
--- 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
|
||||
return enumtbl
|
||||
end
|
||||
|
||||
return Util
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<ServerPlayer *>.
|
||||
---@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
|
||||
|
|
|
@ -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 = {}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
local extension = Package:new("standard")
|
||||
extension.metadata = require "standard.metadata"
|
||||
extension.metadata = require "packages.standard.metadata"
|
||||
|
||||
Fk:loadTranslationTable{
|
||||
["wei"] = "魏",
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,14 @@
|
|||
return {
|
||||
name = "standard_cards",
|
||||
author = "official",
|
||||
description = "",
|
||||
collaborators = {
|
||||
program = {},
|
||||
designer = {},
|
||||
cv = {},
|
||||
illustrator = {},
|
||||
},
|
||||
|
||||
dependencies = {},
|
||||
extra_files = {},
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%module freekill
|
||||
%module fk
|
||||
|
||||
%{
|
||||
#include "client.h"
|
||||
|
|
Loading…
Reference in New Issue