diff --git a/lua/client/client.lua b/lua/client/client.lua index 5fb8f608..d46ac0d4 100644 --- a/lua/client/client.lua +++ b/lua/client/client.lua @@ -12,18 +12,10 @@ function Client:initialize() if (type(cb) == "function") then cb(json_data) else - self:notifyUI("error_msg", "Unknown command " .. command); + self:notifyUI(command, json_data); end end end -freekill.client_callback["enter_lobby"] = function(json_data) - ClientInstance:notifyUI("enter_lobby", json_data) -end - -freekill.client_callback["enter_room"] = function(json_data) - ClientInstance:notifyUI("enter_room", json_data) -end - -- Create ClientInstance (used by Lua) ClientInstance = Client:new() diff --git a/qml/Pages/Lobby.qml b/qml/Pages/Lobby.qml index b548bc4a..e54a9f7d 100644 --- a/qml/Pages/Lobby.qml +++ b/qml/Pages/Lobby.qml @@ -5,7 +5,7 @@ import QtQuick.Layouts 1.15 Item { id: root - width: 640; height: 480 + property alias roomModel: roomModel Component { id: roomDelegate diff --git a/qml/main.qml b/qml/main.qml index e387798e..7e971460 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -22,6 +22,13 @@ Window { "enter_room": function(json_data) { mainStack.push(room); mainWindow.busy = false; + }, + "update_room_list": function(json_data) { + let current = mainStack.currentItem; // should be lobby + current.roomModel.clear(); + JSON.parse(json_data).forEach(function(room) { + current.roomModel.append(room); + }); } }) @@ -108,7 +115,7 @@ Window { if (typeof(cb) === "function") { cb(json_data); } else { - callbacks["error_msg"]("Unknown UI command " + command + "!"); + callbacks["error_msg"]("Unknown command " + command + "!"); } } } diff --git a/src/server/room.cpp b/src/server/room.cpp index 1137684b..fca5477a 100644 --- a/src/server/room.cpp +++ b/src/server/room.cpp @@ -77,7 +77,7 @@ void Room::setOwner(ServerPlayer *owner) void Room::addPlayer(ServerPlayer *player) { if (!player) return; - players.insert(player->getUid(), player); + players.append(player); player->setRoom(this); if (isLobby()) { player->doNotify("enter_lobby", "{}"); @@ -90,18 +90,31 @@ void Room::addPlayer(ServerPlayer *player) void Room::removePlayer(ServerPlayer *player) { - players.remove(player->getId()); + players.removeOne(player); emit playerRemoved(player); + + if (isLobby()) return; + + if (isAbandoned()) { + emit abandoned(); + } else if (player == owner) { + setOwner(players.first()); + owner->doNotify("room_owner", "{}"); + } } -QHash Room::getPlayers() const +QList Room::getPlayers() const { return players; } ServerPlayer *Room::findPlayer(uint id) const { - return players.value(id); + foreach (ServerPlayer *p, players) { + if (p->getId() == id) + return p; + } + return nullptr; } void Room::setGameLogic(GameLogic *logic) @@ -129,6 +142,15 @@ void Room::doNotify(const QList targets, int timeout) // TODO } +void Room::doBroadcastNotify(const QList targets, + const QString& command, const QString& json_data) +{ + foreach (ServerPlayer *p, targets) { + p->doNotify(command, json_data); + } +} + + void Room::run() { // TODO diff --git a/src/server/room.h b/src/server/room.h index 959c2241..40e366e4 100644 --- a/src/server/room.h +++ b/src/server/room.h @@ -2,7 +2,7 @@ #define _ROOM_H #include -#include +#include class Server; class ServerPlayer; class GameLogic; @@ -30,7 +30,7 @@ public: void addPlayer(ServerPlayer *player); void removePlayer(ServerPlayer *player); - QHash getPlayers() const; + QList getPlayers() const; ServerPlayer *findPlayer(uint id) const; void setGameLogic(GameLogic *logic); @@ -41,6 +41,12 @@ public: void doRequest(const QList targets, int timeout); void doNotify(const QList targets, int timeout); + void doBroadcastNotify( + const QList targets, + const QString &command, + const QString &json_data + ); + signals: void abandoned(); @@ -62,7 +68,7 @@ private: bool m_abandoned; // If room is empty, delete it ServerPlayer *owner; // who created this room? - QHash players; + QList players; GameLogic *logic; }; diff --git a/src/server/server.cpp b/src/server/server.cpp index 5ea9f5ac..4746befe 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -4,6 +4,9 @@ #include "room.h" #include "serverplayer.h" #include "global.h" +#include +#include +#include Server *ServerInstance; @@ -43,7 +46,10 @@ void Server::createRoom(ServerPlayer* owner, const QString &name, uint capacity) room->setCapacity(capacity); room->setOwner(owner); room->addPlayer(owner); - rooms.insert(room->getId(), room); + if (room->isLobby()) + m_lobby = room; + else + rooms.insert(room->getId(), room); #ifdef QT_DEBUG qDebug() << "Room #" << room->getId() << " created."; #endif @@ -56,7 +62,7 @@ Room *Server::findRoom(uint id) const Room *Server::lobby() const { - return findRoom(0); + return m_lobby; } ServerPlayer *Server::findPlayer(uint id) const @@ -64,9 +70,23 @@ ServerPlayer *Server::findPlayer(uint id) const return players.value(id); } -void Server::updateRoomList(ServerPlayer* user) +void Server::updateRoomList() { - // TODO + QJsonArray arr; + foreach (Room *room, rooms) { + QJsonObject obj; + obj["roomId"] = (int)room->getId(); + obj["roomName"] = room->getName(); + obj["gameMode"] = "Role"; + obj["playerNum"] = room->getPlayers().count(); + obj["capacity"] = (int)room->getCapacity(); + arr << obj; + } + lobby()->doBroadcastNotify( + lobby()->getPlayers(), + "update_room_list", + QJsonDocument(arr).toJson() + ); } void Server::processNewConnection(ClientSocket* client) @@ -86,7 +106,10 @@ void Server::processNewConnection(ClientSocket* client) void Server::onRoomAbandoned() { - // TODO + Room *room = qobject_cast(sender()); + rooms.remove(room->getId()); + updateRoomList(); + room->deleteLater(); } void Server::onUserDisconnected() diff --git a/src/server/server.h b/src/server/server.h index f6bf4f4d..4df06172 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -28,7 +29,7 @@ public: ServerPlayer *findPlayer(uint id) const; - void updateRoomList(ServerPlayer *user); + void updateRoomList(); void callLua(const QString &command, const QString &json_data); LuaFunction callback; @@ -47,7 +48,8 @@ public slots: private: ServerSocket *server; - QHash rooms; + Room *m_lobby; + QMap rooms; QHash players; lua_State *L; diff --git a/src/swig/freekill.i b/src/swig/freekill.i index 06d7e955..20340359 100644 --- a/src/swig/freekill.i +++ b/src/swig/freekill.i @@ -41,12 +41,13 @@ SWIG_arg ++; %{ lua_pushstring(L, $1.toUtf8()); SWIG_arg++; %} // const QString & +%typemap(arginit) QString const & + "QString $1_str;" + %typemap(in, checkfn = "lua_isstring") QString const & %{ - if (1) { // to avoid 'Jump bypasses variable initialization' error - QString $1_str = QString::fromUtf8(lua_tostring(L, $input)); - $1 = &$1_str; - } + $1_str = QString::fromUtf8(lua_tostring(L, $input)); + $1 = &$1_str; %} %typemap(out) QString const & @@ -114,7 +115,7 @@ public: ServerPlayer *findPlayer(unsigned int id) const; - void updateRoomList(ServerPlayer *user); + void updateRoomList(); LuaFunction callback; }; @@ -219,7 +220,7 @@ public: void addPlayer(ServerPlayer *player); void removePlayer(ServerPlayer *player); - QHash getPlayers() const; + QList getPlayers() const; ServerPlayer *findPlayer(unsigned int id) const; void setGameLogic(GameLogic *logic);