changed code style, doc

This commit is contained in:
Notify-ctrl 2022-03-02 20:56:37 +08:00
parent 9ed3f1bf3f
commit 8fb08a8ece
23 changed files with 158 additions and 89 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
build/
.kdev4/
.vscode/
*.user
*-swp
*.kdev4

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# FreeKill
___
试图打造一个最适合diy玩家游玩的民间三国杀所有的一切都是为了更好的制作diy而设计的。
项目仍处于啥都没有的阶段。不过我为了整理思路,也写了点[文档](./doc/index.md)。

9
doc/dev/index.md Normal file
View File

@ -0,0 +1,9 @@
# FreeKill 开发文档
> dev
___
FreeKill采用Qt框架提供底层支持在上层使用lua语言开发。在UI方面使用的是Qt Quick。
- [通信](./protocol.md)

36
doc/dev/protocol.md Normal file
View File

@ -0,0 +1,36 @@
# FreeKill 的通信
> [dev](./index.md) > 通信
___
## 概述
FreeKill使用UTF-8文本进行通信。基本的通信格式为JSON数组
`[requestId, packetType, command, jsonData]`
其中:
- requestId用来在request型通信使用用来确保收到的回复和发出的请求相对应。
- packetType用来确定这条消息的类型以及发送的目的地。
- command用来表示消息的类型。使用首字母大写的驼峰式命名因为下划线命名会造成额外的网络开销。
- jsonData保存着这个消息的额外信息必须是一个JSON数组。数组中的具体内容详见源码及注释。
FreeKill通信有三大类型请求Request、回复Reply和通知Notification
___
## 从连接上到进入大厅
想要启动服务器,需要通过命令行终端:
```sh
$ ./FreeKill -s <port>
```
`<port>`是服务器运行的端口号如果不带任何参数则启动GUI界面在GUI界面里面只能加入服务器或者单机游戏。
服务器以TCP方式监听。在默认情况下比如单机启动服务器的端口号是9527。
每当任何一个客户端连接上了之后,客户端进入大厅。

5
doc/diy/index.md Normal file
View File

@ -0,0 +1,5 @@
# 如何用FreeKill实现diy武将
> diy
___

6
doc/index.md Normal file
View File

@ -0,0 +1,6 @@
# FreeKill 文档
___
- [开发者文档](./dev/index.md)
- [DIY玩家文档](./diy/index.md)

View File

@ -4,15 +4,15 @@ freekill.client_callback = {}
function Client:initialize()
self.client = freekill.ClientInstance
self.notifyUI = function(self, command, json_data)
freekill.Backend:emitNotifyUI(command, json_data)
self.notifyUI = function(self, command, jsonData)
freekill.Backend:emitNotifyUI(command, jsonData)
end
self.client.callback = function(_self, command, json_data)
self.client.callback = function(_self, command, jsonData)
local cb = freekill.client_callback[command]
if (type(cb) == "function") then
cb(json_data)
cb(jsonData)
else
self:notifyUI(command, json_data);
self:notifyUI(command, jsonData);
end
end
end

View File

@ -4,36 +4,36 @@ freekill.server_callback = {}
function Server:initialize()
self.server = freekill.ServerInstance
self.server.callback = function(_self, command, json_data)
self.server.callback = function(_self, command, jsonData)
local cb = freekill.server_callback[command]
if (type(cb) == "function") then
cb(json_data)
cb(jsonData)
else
print("Server error: Unknown command " .. command);
end
end
end
freekill.server_callback["create_room"] = function(json_data)
-- json_data: [ int uid, string name, int capacity ]
local data = json.decode(json_data)
freekill.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 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)
freekill.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]))
room:addPlayer(player)
end
freekill.server_callback["quit_room"] = function(json_data)
-- json_data: [ int uid ]
local data = json.decode(json_data)
freekill.server_callback["QuitRoom"] = function(jsonData)
-- jsonData: [ int uid ]
local data = json.decode(jsonData)
local player = freekill.ServerInstance:findPlayer(tonumber(data[1]))
local room = player:getRoom()
if not room:isLobby() then

View File

@ -46,7 +46,7 @@ Item {
mainWindow.busy = true;
mainStack.pop();
Backend.notifyServer(
"create_room",
"CreateRoom",
JSON.stringify([roomName.text, playerNum.value])
);
}

View File

@ -11,7 +11,7 @@ Item {
text: "quit"
onClicked: {
mainStack.pop();
Backend.notifyServer("quit_room", "[]");
Backend.notifyServer("QuitRoom", "[]");
}
}
}

View File

@ -9,25 +9,31 @@ Window {
width: 720
height: 480
property var callbacks: ({
"error_msg": function(json_data) {
toast.show(json_data);
"ErrorMsg": function(jsonData) {
toast.show(jsonData);
mainWindow.busy = false;
},
"enter_lobby": function(json_data) {
"EnterLobby": function(jsonData) {
if (mainStack.depth === 1) {
mainStack.push(lobby);
}
mainWindow.busy = false;
},
"enter_room": function(json_data) {
"EnterRoom": function(jsonData) {
mainStack.push(room);
mainWindow.busy = false;
},
"update_room_list": function(json_data) {
"UpdateRoomList": function(jsonData) {
let current = mainStack.currentItem; // should be lobby
current.roomModel.clear();
JSON.parse(json_data).forEach(function(room) {
current.roomModel.append(room);
JSON.parse(jsonData).forEach(function(room) {
current.roomModel.append({
roomId: room[0],
roomName: room[1],
gameMode: room[2],
playerNum: room[3],
capacity: room[4],
});
});
}
})
@ -110,12 +116,12 @@ Window {
Connections {
target: Backend
function onNotifyUI(command, json_data) {
function onNotifyUI(command, jsonData) {
let cb = callbacks[command]
if (typeof(cb) === "function") {
cb(json_data);
cb(jsonData);
} else {
callbacks["error_msg"]("Unknown command " + command + "!");
callbacks["ErrorMsg"]("Unknown command " + command + "!");
}
}
}

View File

@ -32,20 +32,20 @@ void Client::connectToHost(const QHostAddress& server, ushort port)
router->getSocket()->connectToHost(server, port);
}
void Client::requestServer(const QString& command, const QString& json_data, int timeout)
void Client::requestServer(const QString& command, const QString& jsonData, int timeout)
{
int type = Router::TYPE_REQUEST | Router::SRC_CLIENT | Router::DEST_SERVER;
router->request(type, command, json_data, timeout);
router->request(type, command, jsonData, timeout);
}
void Client::replyToServer(const QString& command, const QString& json_data)
void Client::replyToServer(const QString& command, const QString& jsonData)
{
int type = Router::TYPE_REPLY | Router::SRC_CLIENT | Router::DEST_SERVER;
router->reply(type, command, json_data);
router->reply(type, command, jsonData);
}
void Client::notifyServer(const QString& command, const QString& json_data)
void Client::notifyServer(const QString& command, const QString& jsonData)
{
int type = Router::TYPE_NOTIFICATION | Router::SRC_CLIENT | Router::DEST_SERVER;
router->notify(type, command, json_data);
router->notify(type, command, jsonData);
}

View File

@ -20,11 +20,11 @@ public:
// void login
void requestServer(const QString &command,
const QString &json_data, int timeout = -1);
void replyToServer(const QString &command, const QString &json_data);
void notifyServer(const QString &command, const QString &json_data);
const QString &jsonData, int timeout = -1);
void replyToServer(const QString &command, const QString &jsonData);
void notifyServer(const QString &command, const QString &jsonData);
void callLua(const QString &command, const QString &json_data);
void callLua(const QString &command, const QString &jsonData);
LuaFunction callback;
signals:

View File

@ -50,7 +50,7 @@ void Router::setReplyReadySemaphore(QSemaphore *semaphore)
}
void Router::request(int type, const QString& command,
const QString& json_data, int timeout)
const QString& jsonData, int timeout)
{
// In case a request is called without a following waitForReply call
if (replyReadySemaphore.available() > 0)
@ -70,30 +70,30 @@ void Router::request(int type, const QString& command,
body << requestId;
body << type;
body << command;
body << json_data;
body << jsonData;
body << timeout;
emit messageReady(QJsonDocument(body).toJson(QJsonDocument::Compact));
}
void Router::reply(int type, const QString& command, const QString& json_data)
void Router::reply(int type, const QString& command, const QString& jsonData)
{
QJsonArray body;
body << this->requestId;
body << type;
body << command;
body << json_data;
body << jsonData;
emit messageReady(QJsonDocument(body).toJson(QJsonDocument::Compact));
}
void Router::notify(int type, const QString& command, const QString& json_data)
void Router::notify(int type, const QString& command, const QString& jsonData)
{
QJsonArray body;
body << -2; // requestId = -2 mean this is for notification
body << type;
body << command;
body << json_data;
body << jsonData;
emit messageReady(QJsonDocument(body).toJson(QJsonDocument::Compact));
}
@ -150,14 +150,14 @@ void Router::handlePacket(const QByteArray& rawPacket)
int requestId = packet[0].toInt();
int type = packet[1].toInt();
QString command = packet[2].toString();
QString json_data = packet[3].toString();
QString jsonData = packet[3].toString();
if (type & TYPE_NOTIFICATION) {
if (type & DEST_CLIENT) {
ClientInstance->callLua(command, json_data);
ClientInstance->callLua(command, jsonData);
} else {
// Add the uid of sender to json_data
QJsonArray arr = QJsonDocument::fromJson(json_data.toUtf8()).array();
// Add the uid of sender to jsonData
QJsonArray arr = QJsonDocument::fromJson(jsonData.toUtf8()).array();
arr.prepend(
(int)qobject_cast<ServerPlayer *>(parent())->getUid()
);
@ -169,7 +169,7 @@ void Router::handlePacket(const QByteArray& rawPacket)
this->requestTimeout = packet[4].toInt();
if (type & DEST_CLIENT) {
qobject_cast<Client *>(parent())->callLua(command, json_data);
qobject_cast<Client *>(parent())->callLua(command, jsonData);
} else {
// requesting server is not allowed
Q_ASSERT(false);
@ -187,7 +187,7 @@ void Router::handlePacket(const QByteArray& rawPacket)
requestStartTime.secsTo(QDateTime::currentDateTime()))
return;
m_reply = json_data;
m_reply = jsonData;
// TODO: callback?
qDebug() << rawPacket << Qt::endl;

View File

@ -37,9 +37,9 @@ public:
void setReplyReadySemaphore(QSemaphore *semaphore);
void request(int type, const QString &command,
const QString &json_data, int timeout);
void reply(int type, const QString &command, const QString &json_data);
void notify(int type, const QString &command, const QString &json_data);
const QString &jsonData, int timeout);
void reply(int type, const QString &command, const QString &jsonData);
void notify(int type, const QString &command, const QString &jsonData);
int getTimeout() const;

View File

@ -80,9 +80,9 @@ void Room::addPlayer(ServerPlayer *player)
players.append(player);
player->setRoom(this);
if (isLobby()) {
player->doNotify("enter_lobby", "{}");
player->doNotify("EnterLobby", "[]");
} else {
player->doNotify("enter_room", "{}");
player->doNotify("EnterRoom", "[]");
}
qDebug() << "Player #" << player->getUid() << " entered room";
emit playerAdded(player);
@ -99,7 +99,7 @@ void Room::removePlayer(ServerPlayer *player)
emit abandoned();
} else if (player == owner) {
setOwner(players.first());
owner->doNotify("room_owner", "{}");
owner->doNotify("RoomOwner", "[]");
}
}
@ -143,10 +143,10 @@ void Room::doNotify(const QList<ServerPlayer *> targets, int timeout)
}
void Room::doBroadcastNotify(const QList<ServerPlayer *> targets,
const QString& command, const QString& json_data)
const QString& command, const QString& jsonData)
{
foreach (ServerPlayer *p, targets) {
p->doNotify(command, json_data);
p->doNotify(command, jsonData);
}
}

View File

@ -44,7 +44,7 @@ public:
void doBroadcastNotify(
const QList<ServerPlayer *> targets,
const QString &command,
const QString &json_data
const QString &jsonData
);
signals:

View File

@ -74,17 +74,17 @@ void Server::updateRoomList()
{
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();
QJsonArray obj;
obj << (int)room->getId(); // roomId
obj << room->getName(); // roomName
obj << "Role"; // gameMode
obj << room->getPlayers().count(); // playerNum
obj << (int)room->getCapacity(); // capacity
arr << obj;
}
lobby()->doBroadcastNotify(
lobby()->getPlayers(),
"update_room_list",
"UpdateRoomList",
QJsonDocument(arr).toJson()
);
}
@ -100,7 +100,6 @@ void Server::processNewConnection(ClientSocket* client)
qDebug() << "His address is " << client->peerAddress();
#endif
//player->doNotify("enter_lobby", "{}");
lobby()->addPlayer(player);
}
@ -114,7 +113,7 @@ void Server::onRoomAbandoned()
void Server::onUserDisconnected()
{
// TODO
qobject_cast<ServerPlayer *>(sender())->setStateString("offline");
}
void Server::onUserStateChanged()

View File

@ -31,7 +31,7 @@ public:
void updateRoomList();
void callLua(const QString &command, const QString &json_data);
void callLua(const QString &command, const QString &jsonData);
LuaFunction callback;
signals:

View File

@ -52,22 +52,22 @@ void ServerPlayer::speak(const QString& message)
;
}
void ServerPlayer::doRequest(const QString& command, const QString& json_data, int timeout)
void ServerPlayer::doRequest(const QString& command, const QString& jsonData, int timeout)
{
int type = Router::TYPE_REQUEST | Router::SRC_SERVER | Router::DEST_CLIENT;
router->request(type, command, json_data, timeout);
router->request(type, command, jsonData, timeout);
}
void ServerPlayer::doReply(const QString& command, const QString& json_data)
void ServerPlayer::doReply(const QString& command, const QString& jsonData)
{
int type = Router::TYPE_REPLY | Router::SRC_SERVER | Router::DEST_CLIENT;
router->reply(type, command, json_data);
router->reply(type, command, jsonData);
}
void ServerPlayer::doNotify(const QString& command, const QString& json_data)
void ServerPlayer::doNotify(const QString& command, const QString& jsonData)
{
int type = Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT;
router->notify(type, command, json_data);
router->notify(type, command, jsonData);
}
void ServerPlayer::prepareForRequest(const QString& command, const QVariant& data)

View File

@ -25,9 +25,9 @@ public:
void speak(const QString &message);
void doRequest(const QString &command,
const QString &json_data, int timeout = -1);
void doReply(const QString &command, const QString &json_data);
void doNotify(const QString &command, const QString &json_data);
const QString &jsonData, int timeout = -1);
void doReply(const QString &command, const QString &jsonData);
void doNotify(const QString &command, const QString &jsonData);
void prepareForRequest(const QString &command,
const QVariant &data = QVariant());

View File

@ -18,7 +18,7 @@ void QmlBackend::startServer(ushort port)
if (!server->listen(QHostAddress::Any, port)) {
server->deleteLater();
emit notifyUI("error_msg", tr("Cannot start server!"));
emit notifyUI("ErrorMsg", tr("Cannot start server!"));
}
}
}
@ -28,7 +28,7 @@ void QmlBackend::joinServer(QString address)
class Client *client = new class Client(this);
connect(client, &Client::error_message, [this, client](const QString &msg){
client->deleteLater();
emit notifyUI("error_msg", msg);
emit notifyUI("ErrorMsg", msg);
});
QString addr = "127.0.0.1";
ushort port = 9527u;
@ -44,14 +44,14 @@ void QmlBackend::joinServer(QString address)
client->connectToHost(QHostAddress(addr), port);
}
void QmlBackend::replyToServer(const QString& command, const QString& json_data)
void QmlBackend::replyToServer(const QString& command, const QString& jsonData)
{
ClientInstance->replyToServer(command, json_data);
ClientInstance->replyToServer(command, jsonData);
}
void QmlBackend::notifyServer(const QString& command, const QString& json_data)
void QmlBackend::notifyServer(const QString& command, const QString& jsonData)
{
ClientInstance->notifyServer(command, json_data);
ClientInstance->notifyServer(command, jsonData);
}
void QmlBackend::quitLobby()

View File

@ -18,18 +18,18 @@ public:
QmlBackend(QObject *parent = nullptr);
// For lua use
void emitNotifyUI(const char *command, const char *json_data) {
emit notifyUI(command, json_data);
void emitNotifyUI(const char *command, const char *jsonData) {
emit notifyUI(command, jsonData);
}
signals:
void notifyUI(const QString &command, const QString &json_data);
void notifyUI(const QString &command, const QString &jsonData);
public slots:
void startServer(ushort port);
void joinServer(QString address);
void replyToServer(const QString &command, const QString &json_data);
void notifyServer(const QString &command, const QString &json_data);
void replyToServer(const QString &command, const QString &jsonData);
void notifyServer(const QString &command, const QString &jsonData);
// Lobby
void quitLobby();