Create and enter room

This commit is contained in:
Notify-ctrl 2022-03-01 13:18:00 +08:00
parent 6fb0158d39
commit 5f175090c0
14 changed files with 232 additions and 62 deletions

View File

@ -21,5 +21,9 @@ 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()

View File

@ -15,12 +15,30 @@ function Server:initialize()
end
freekill.server_callback["create_room"] = function(json_data)
-- json_data: [ int id, string name, int capacity ]
-- json_data: [ int uid, string name, int capacity ]
local data = json.decode(json_data)
local owner = freekill.ServerInstance:findPlayer(data[1])
local owner = freekill.ServerInstance:findPlayer(tonumber(data[1]))
local roomName = data[2]
local capacity = data[3]
freekill.ServerInstance:createRoom(owner, roomName, capacity)
end
freekill.server_callback["enter_room"] = function(json_data)
-- json_data: [ int uid, int roomId ]
local data = json.decode(json_data)
local player = freekill.ServerInstance:findPlayer(tonumber(data[1]))
local room = freekill.ServerInstance:findRoom(tonumber(data[2]))
room:addPlayer(player)
end
freekill.server_callback["quit_room"] = function(json_data)
-- json_data: [ int uid ]
local data = json.decode(json_data)
local player = freekill.ServerInstance:findPlayer(tonumber(data[1]))
local room = player:getRoom()
if not room:isLobby() then
room:removePlayer(player)
end
end
ServerInstance = Server:new()

View File

@ -1,8 +0,0 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
Item {
id: root
}

63
qml/Pages/CreateRoom.qml Normal file
View File

@ -0,0 +1,63 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.15
Item {
id: root
Frame {
anchors.centerIn: parent
Column {
x: 32
y: 20
spacing: 20
RowLayout {
anchors.rightMargin: 8
spacing: 16
Text {
text: "Room Name"
}
TextField {
id: roomName
font.pixelSize: 18
text: "tmp's Room"
}
}
RowLayout {
anchors.rightMargin: 8
spacing: 16
Text {
text: "Player num"
}
SpinBox {
id: playerNum
from: 2
to: 8
}
}
RowLayout {
anchors.rightMargin: 8
spacing: 16
Button {
text: "OK"
onClicked: {
mainWindow.busy = true;
mainStack.pop();
Backend.notifyServer(
"create_room",
JSON.stringify([roomName.text, playerNum.value])
);
}
}
Button {
text: "Cancel"
onClicked: {
mainStack.pop();
}
}
}
}
}
}

View File

@ -1,6 +1,5 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
Item {
id: root
@ -20,16 +19,16 @@ Item {
Button {
text: "Join Server"
onClicked: {
mainWindow.state = "busy";
mainWindow.busyString = "Connecting to host...";
mainWindow.busy = true;
toast.show("Connecting to host...");
Backend.joinServer(server_addr.text);
}
}
Button {
text: "Console start"
onClicked: {
mainWindow.state = "busy";
mainWindow.busyString = "Connecting to host...";
mainWindow.busy = true;
toast.show("Connecting to host...");
Backend.startServer(9527);
Backend.joinServer("127.0.0.1");
}

View File

@ -40,7 +40,13 @@ Item {
hoverEnabled: true
onEntered: { parent.color = "blue" }
onExited: { parent.color = "black" }
onClicked: {}
onClicked: {
mainWindow.busy = true;
Backend.notifyServer(
"enter_room",
JSON.stringify([roomId])
);
}
}
}
}
@ -85,7 +91,9 @@ Item {
}
Button {
text: "Create Room"
onClicked: {}
onClicked: {
mainStack.push(createRoom);
}
}
Button {
text: "Generals Overview"
@ -101,12 +109,42 @@ Item {
}
Button {
text: "Exit Lobby"
onClicked: {
toast.show("Goodbye.");
Backend.quitLobby();
mainStack.pop();
}
}
}
}
Loader {
id: lobby_dialog
z: 1000
onSourceChanged: {
if (item === null)
return;
item.finished.connect(function(){
source = "";
});
item.widthChanged.connect(function(){
lobby_dialog.moveToCenter();
});
item.heightChanged.connect(function(){
lobby_dialog.moveToCenter();
});
moveToCenter();
}
function moveToCenter()
{
item.x = Math.round((root.width - item.width) / 2);
item.y = Math.round(root.height * 0.67 - item.height / 2);
}
}
Component.onCompleted: {
// toast.show("Welcome to FreeKill lobby!")
toast.show("Welcome to FreeKill lobby!");
}
}

18
qml/Pages/Room.qml Normal file
View File

@ -0,0 +1,18 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
Item {
id: root
Text {
anchors.centerIn: parent
text: "You are in room."
}
Button {
text: "quit"
onClicked: {
mainStack.pop();
Backend.notifyServer("quit_room", "[]");
}
}
}

View File

@ -1,6 +1,7 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import "Pages"
Window {
id: mainWindow
@ -10,46 +11,52 @@ Window {
property var callbacks: ({
"error_msg": function(json_data) {
toast.show(json_data);
if (mainWindow.state === "busy")
mainWindow.state = "init";
mainWindow.busy = false;
},
"enter_lobby": function(json_data) {
mainWindow.state = "lobby";
if (mainStack.depth === 1) {
mainStack.push(lobby);
}
mainWindow.busy = false;
},
"enter_room": function(json_data) {
mainStack.push(room);
mainWindow.busy = false;
}
})
Loader {
id: mainLoader
source: "Page/Init.qml"
StackView {
id: mainStack
visible: !mainWindow.busy
initialItem: init
anchors.fill: parent
}
property string state: "init"
onStateChanged: {
switch (state) {
case "init":
mainLoader.source = "Page/Init.qml";
break;
case "lobby":
mainLoader.source = "Page/Lobby.qml";
break;
case "room":
mainLoader.source = "Page/Room.qml";
break;
case "busy":
mainLoader.source = "";
break;
default: break;
}
Component {
id: init
Init {}
}
property string busyString: "Busy"
Component {
id: lobby
Lobby {}
}
Component {
id: room
Room {}
}
Component {
id: createRoom
CreateRoom {}
}
property bool busy: false
BusyIndicator {
running: true
anchors.centerIn: parent
visible: mainWindow.state === "busy"
visible: mainWindow.busy === true
}
Rectangle {
@ -83,14 +90,14 @@ Window {
ScriptAction {
script: {
toast.opacity = 0
toast.opacity = 0;
}
}
}
function show(text) {
opacity = 1
toast_text.text = text
opacity = 1;
toast_text.text = text;
}
}

View File

@ -23,6 +23,7 @@ Client::Client(QObject* parent)
Client::~Client()
{
ClientInstance = nullptr;
router->getSocket()->disconnectFromHost();
router->getSocket()->deleteLater();
}
@ -39,12 +40,12 @@ void Client::requestServer(const QString& command, const QString& json_data, int
void Client::replyToServer(const QString& command, const QString& json_data)
{
int type = Router::TYPE_REQUEST | Router::SRC_CLIENT | Router::DEST_SERVER;
int type = Router::TYPE_REPLY | Router::SRC_CLIENT | Router::DEST_SERVER;
router->reply(type, command, json_data);
}
void Client::notifyServer(const QString& command, const QString& json_data)
{
int type = Router::TYPE_REQUEST | Router::SRC_CLIENT | Router::DEST_SERVER;
int type = Router::TYPE_NOTIFICATION | Router::SRC_CLIENT | Router::DEST_SERVER;
router->notify(type, command, json_data);
}

View File

@ -3,6 +3,7 @@
#include "router.h"
#include "client.h"
#include "server.h"
#include "serverplayer.h"
Router::Router(QObject *parent, ClientSocket *socket, RouterType type)
: QObject(parent)
@ -153,9 +154,14 @@ void Router::handlePacket(const QByteArray& rawPacket)
if (type & TYPE_NOTIFICATION) {
if (type & DEST_CLIENT) {
qobject_cast<Client *>(parent())->callLua(command, json_data);
ClientInstance->callLua(command, json_data);
} else {
qDebug() << rawPacket << Qt::endl;
// Add the uid of sender to json_data
QJsonArray arr = QJsonDocument::fromJson(json_data.toUtf8()).array();
arr.prepend(
(int)qobject_cast<ServerPlayer *>(parent())->getUid()
);
ServerInstance->callLua(command, QJsonDocument(arr).toJson());
}
}
else if (type & TYPE_REQUEST) {
@ -165,7 +171,8 @@ void Router::handlePacket(const QByteArray& rawPacket)
if (type & DEST_CLIENT) {
qobject_cast<Client *>(parent())->callLua(command, json_data);
} else {
qDebug() << rawPacket << Qt::endl;
// requesting server is not allowed
Q_ASSERT(false);
}
}
else if (type & TYPE_REPLY) {

View File

@ -8,6 +8,10 @@ Room::Room(Server* server)
id = roomId;
roomId++;
this->server = server;
if (!isLobby()) {
connect(this, &Room::playerAdded, server->lobby(), &Room::removePlayer);
connect(this, &Room::playerRemoved, server->lobby(), &Room::addPlayer);
}
}
Room::~Room()
@ -72,7 +76,15 @@ void Room::setOwner(ServerPlayer *owner)
void Room::addPlayer(ServerPlayer *player)
{
players.insert(player->getId(), player);
if (!player) return;
players.insert(player->getUid(), player);
player->setRoom(this);
if (isLobby()) {
player->doNotify("enter_lobby", "{}");
} else {
player->doNotify("enter_room", "{}");
}
qDebug() << "Player #" << player->getUid() << " entered room";
emit playerAdded(player);
}

View File

@ -22,6 +22,7 @@ Server::Server(QObject* parent)
L = CreateLuaState();
DoLuaScript(L, "lua/freekill.lua");
DoLuaScript(L, "lua/server/server.lua");
}
Server::~Server()
@ -41,13 +42,11 @@ void Server::createRoom(ServerPlayer* owner, const QString &name, uint capacity)
room->setName(name);
room->setCapacity(capacity);
room->setOwner(owner);
// TODO
// room->addPlayer(owner);
room->addPlayer(owner);
rooms.insert(room->getId(), room);
#ifdef QT_DEBUG
qDebug() << "Room #" << room->getId() << " created.";
#endif
emit roomCreated(room);
}
Room *Server::findRoom(uint id) const
@ -75,13 +74,14 @@ void Server::processNewConnection(ClientSocket* client)
// version check, file check, ban IP, reconnect, etc
ServerPlayer *player = new ServerPlayer(lobby());
player->setSocket(client);
players.insert(player->getUid(), player);
#ifdef QT_DEBUG
qDebug() << "ServerPlayer #" << player->getUid() << "connected.";
qDebug() << "His address is " << client->peerAddress();
#endif
player->doNotify("enter_lobby", "{}");
//player->doNotify("enter_lobby", "{}");
lobby()->addPlayer(player);
}
void Server::onRoomAbandoned()

View File

@ -13,12 +13,15 @@ QmlBackend::QmlBackend(QObject* parent)
void QmlBackend::startServer(ushort port)
{
if (!ServerInstance) {
class Server *server = new class Server(this);
if (!server->listen(QHostAddress::Any, port)) {
server->deleteLater();
emit notifyUI("error_msg", tr("Cannot start server!"));
}
}
}
void QmlBackend::joinServer(QString address)
{
@ -50,3 +53,8 @@ void QmlBackend::notifyServer(const QString& command, const QString& json_data)
{
ClientInstance->notifyServer(command, json_data);
}
void QmlBackend::quitLobby()
{
delete ClientInstance;
}

View File

@ -31,6 +31,9 @@ public slots:
void replyToServer(const QString &command, const QString &json_data);
void notifyServer(const QString &command, const QString &json_data);
// Lobby
void quitLobby();
private:
WindowType type;
};