Todo: disable sync (#14)

* lock room lua

* fixme

* add 'id' to lua Player

Co-authored-by: Notify-ctrl <notify-ctrl@qq.com>
This commit is contained in:
Notify-ctrl 2022-04-03 21:43:35 +08:00 committed by GitHub
parent 4c93c897b2
commit 9e09e6e50d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 12 deletions

View File

@ -1,4 +1,5 @@
---@class Player : Object
---@field id integer
---@field hp integer
---@field maxHp integer
---@field kingdom string
@ -31,6 +32,7 @@ Player.NotActive = 8
Player.PhaseNone = 9
function Player:initialize()
self.id = 114514
self.hp = 0
self.maxHp = 0
self.kingdom = "qun"

View File

@ -276,7 +276,8 @@ fk.room_callback["PlayerRunned"] = function(jsonData)
local robot = data[2]
for _, p in ipairs(RoomInstance.players) do
if p:getId() == runner then
p.serverplayer = RoomInstance:findPlayerById(robot)
p.serverplayer = RoomInstance.room:findPlayer(robot)
p.id = p.serverplayer:getId()
end
end
end
@ -291,6 +292,12 @@ fk.room_callback["PlayerStateChanged"] = function(jsonData)
RoomInstance:findPlayerById(id).state = stateString
end
fk.room_callback["RoomDeleted"] = function(jsonData)
debug.sethook(function ()
error("Room is deleted when running")
end, "l")
end
fk.room_callback["DoLuaScript"] = function(jsonData)
-- jsonData: [ int uid, string luaScript ]
-- warning: only use this in debugging mode.

View File

@ -11,6 +11,7 @@ local ServerPlayer = Player:subclass("ServerPlayer")
function ServerPlayer:initialize(_self)
Player.initialize(self)
self.serverplayer = _self
self.id = _self:getId()
self.room = nil
self.next = nil
@ -24,7 +25,7 @@ end
---@return integer
function ServerPlayer:getId()
return self.serverplayer:getId()
return self.id
end
---@param command string

View File

@ -159,7 +159,11 @@ void Router::handlePacket(const QByteArray& rawPacket)
// Add the uid of sender to jsonData
QJsonArray arr = QJsonDocument::fromJson(jsonData.toUtf8()).array();
arr.prepend(player->getId());
player->getRoom()->callLua(command, QJsonDocument(arr).toJson());
Room *room = player->getRoom();
room->lockLua(__FUNCTION__);
room->callLua(command, QJsonDocument(arr).toJson());
room->unlockLua(__FUNCTION__);
}
}
else if (type & TYPE_REQUEST) {

View File

@ -39,6 +39,7 @@ public:
int getTimeout() const;
void cancelRequest();
void abortRequest();
QString waitForReply();
QString waitForReply(int timeout);
@ -49,7 +50,6 @@ signals:
void replyReady();
protected:
void abortRequest();
void handlePacket(const QByteArray &rawPacket);
private:

View File

@ -32,10 +32,10 @@ Room::~Room()
{
// TODO
if (isRunning()) {
terminate();
callLua("RoomDeleted", "");
unlockLua(__FUNCTION__);
wait();
}
disconnect();
lua_close(L);
}
@ -180,6 +180,7 @@ void Room::removePlayer(ServerPlayer *player)
if (gameStarted) {
// TODO: if the player is died..
// create robot first
ServerPlayer *robot = new ServerPlayer(this);
robot->setState(Player::Robot);
@ -188,6 +189,8 @@ void Room::removePlayer(ServerPlayer *player)
robot->setScreenName(QString("COMP-%1").arg(robot_id));
robot_id--;
players.append(robot);
// tell lua & clients
QJsonArray jsonData;
jsonData << player->getId();
@ -195,6 +198,10 @@ void Room::removePlayer(ServerPlayer *player)
callLua("PlayerRunned", QJsonDocument(jsonData).toJson());
doBroadcastNotify(getPlayers(), "PlayerRunned", QJsonDocument(jsonData).toJson());
runned_players << player->getId();
// FIXME: abortRequest here will result crash
// but if dont abort and room is abandoned, the main thread will wait until replyed
// player->abortRequest();
} else {
QJsonArray jsonData;
jsonData << player->getId();
@ -202,6 +209,8 @@ void Room::removePlayer(ServerPlayer *player)
}
if (isAbandoned()) {
// FIXME: do not delete room here
// create a new thread and delete the room
emit abandoned();
} else if (player == owner) {
setOwner(players.first());
@ -274,8 +283,28 @@ void Room::gameOver()
}
}
void Room::lockLua(const QString &caller)
{
if (!gameStarted) return;
lua_mutex.lock();
#ifdef QT_DEBUG
//qDebug() << caller << "=> room->L is locked.";
#endif
}
void Room::unlockLua(const QString &caller)
{
if (!gameStarted) return;
lua_mutex.unlock();
#ifdef QT_DEBUG
//qDebug() << caller << "=> room->L is unlocked.";
#endif
}
void Room::run()
{
gameStarted = true;
lockLua(__FUNCTION__);
roomStart();
unlockLua(__FUNCTION__);
}

View File

@ -49,8 +49,6 @@ public:
void gameOver();
lua_State *getLuaState() const;
void initLua();
void callLua(const QString &command, const QString &jsonData);
LuaFunction callback;
@ -58,6 +56,9 @@ public:
void roomStart();
LuaFunction startGame;
void lockLua(const QString &caller);
void unlockLua(const QString &caller);
signals:
void abandoned();
@ -83,6 +84,7 @@ private:
int timeout;
lua_State *L;
QMutex lua_mutex;
};
#endif // _ROOM_H

View File

@ -69,22 +69,37 @@ void ServerPlayer::doRequest(const QString& command, const QString& jsonData, in
router->request(type, command, jsonData, timeout);
}
void ServerPlayer::abortRequest()
{
router->abortRequest();
}
QString ServerPlayer::waitForReply()
{
room->unlockLua(__FUNCTION__);
QString ret;
if (getState() != Player::Online) {
QThread::sleep(1);
return "";
ret = "";
} else {
ret = router->waitForReply();
}
return router->waitForReply();
room->lockLua(__FUNCTION__);
return ret;
}
QString ServerPlayer::waitForReply(int timeout)
{
room->unlockLua(__FUNCTION__);
QString ret;
if (getState() != Player::Online) {
QThread::sleep(1);
return "";
ret = "";
} else {
ret = router->waitForReply(timeout);
}
return router->waitForReply(timeout);
room->lockLua(__FUNCTION__);
return ret;
}
void ServerPlayer::doNotify(const QString& command, const QString& jsonData)

View File

@ -24,6 +24,7 @@ public:
void doRequest(const QString &command,
const QString &jsonData, int timeout = -1);
void abortRequest();
QString waitForReply(int timeout);
QString waitForReply();
void doNotify(const QString &command, const QString &jsonData);