edit profile (#5)
This commit is contained in:
parent
a67175f8eb
commit
3e4080f2ad
|
@ -7,6 +7,7 @@ freekill.server_callback = {}
|
||||||
|
|
||||||
function Server:initialize()
|
function Server:initialize()
|
||||||
self.server = freekill.ServerInstance
|
self.server = freekill.ServerInstance
|
||||||
|
self.db = freekill.ServerInstance:getDatabase()
|
||||||
self.server.callback = function(_self, command, jsonData)
|
self.server.callback = function(_self, command, jsonData)
|
||||||
local cb = freekill.server_callback[command]
|
local cb = freekill.server_callback[command]
|
||||||
if (type(cb) == "function") then
|
if (type(cb) == "function") then
|
||||||
|
@ -33,6 +34,35 @@ function Server:initialize()
|
||||||
self.players = {}
|
self.players = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
freekill.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)
|
||||||
|
player:doNotify("UpdateAvatar", "[]")
|
||||||
|
end
|
||||||
|
|
||||||
|
freekill.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]
|
||||||
|
local sql_find = "SELECT password FROM userinfo WHERE id=%d;"
|
||||||
|
local sql_update = "UPDATE userinfo SET password='%s' WHERE id=%d;"
|
||||||
|
|
||||||
|
local db = ServerInstance.db
|
||||||
|
local passed = false
|
||||||
|
local result = Sql.exec_select(db, string.format(sql_find, id))
|
||||||
|
passed = (result["password"][1] == sha256(old))
|
||||||
|
if passed then
|
||||||
|
Sql.exec(db, string.format(sql_update, sha256(new), id))
|
||||||
|
end
|
||||||
|
|
||||||
|
local player = freekill.ServerInstance:findPlayer(tonumber(id))
|
||||||
|
player:doNotify("UpdatePassword", passed and "1" or "0")
|
||||||
|
end
|
||||||
|
|
||||||
freekill.server_callback["CreateRoom"] = function(jsonData)
|
freekill.server_callback["CreateRoom"] = function(jsonData)
|
||||||
-- jsonData: [ int uid, string name, int capacity ]
|
-- jsonData: [ int uid, string name, int capacity ]
|
||||||
local data = json.decode(jsonData)
|
local data = json.decode(jsonData)
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: childrenRect.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
signal finished()
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "Room Name"
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: roomName
|
||||||
|
font.pixelSize: 18
|
||||||
|
text: Self.screenName + "'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: {
|
||||||
|
root.finished();
|
||||||
|
mainWindow.busy = true;
|
||||||
|
ClientInstance.notifyServer(
|
||||||
|
"CreateRoom",
|
||||||
|
JSON.stringify([roomName.text, playerNum.value])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Cancel"
|
||||||
|
onClicked: {
|
||||||
|
root.finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: childrenRect.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
signal finished()
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "Username"
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: Self.screenName
|
||||||
|
font.pixelSize: 18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "Avatar"
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: avatarName
|
||||||
|
font.pixelSize: 18
|
||||||
|
text: Self.avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "Old Password"
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: oldPassword
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
passwordCharacter: "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
text: "New Password"
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: newPassword
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
passwordCharacter: "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
spacing: 16
|
||||||
|
Button {
|
||||||
|
text: "Update Avatar"
|
||||||
|
enabled: avatarName.text !== ""
|
||||||
|
onClicked: {
|
||||||
|
mainWindow.busy = true;
|
||||||
|
ClientInstance.notifyServer(
|
||||||
|
"UpdateAvatar",
|
||||||
|
JSON.stringify([avatarName.text])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Update Password"
|
||||||
|
enabled: oldPassword.text !== "" && newPassword.text !== ""
|
||||||
|
onClicked: {
|
||||||
|
mainWindow.busy = true;
|
||||||
|
ClientInstance.notifyServer(
|
||||||
|
"UpdatePassword",
|
||||||
|
JSON.stringify([oldPassword.text, newPassword.text])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Exit"
|
||||||
|
onClicked: {
|
||||||
|
root.finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "dsdsd"
|
||||||
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
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();
|
|
||||||
ClientInstance.notifyServer(
|
|
||||||
"CreateRoom",
|
|
||||||
JSON.stringify([roomName.text, playerNum.value])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
text: "Cancel"
|
|
||||||
onClicked: {
|
|
||||||
mainStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.0
|
import QtQuick.Controls 2.0
|
||||||
import QtQuick.Window 2.0
|
import QtQuick.Window 2.0
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
import "Logic.js" as Logic
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
@ -89,13 +90,15 @@ Item {
|
||||||
Button {
|
Button {
|
||||||
text: "Edit Profile"
|
text: "Edit Profile"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
globalPopup.source = "EditProfile.qml";
|
||||||
|
globalPopup.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
text: "Create Room"
|
text: "Create Room"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
mainStack.push(createRoom);
|
globalPopup.source = "CreateRoom.qml";
|
||||||
|
globalPopup.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
callbacks["UpdateAvatar"] = function(jsonData) {
|
||||||
|
mainWindow.busy = false;
|
||||||
|
self.avatar = avatarName.text;
|
||||||
|
toast.show("Update avatar done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks["UpdatePassword"] = function(jsonData) {
|
||||||
|
mainWindow.busy = false;
|
||||||
|
if (jsonData === "1")
|
||||||
|
toast.show("Update password done.");
|
||||||
|
else
|
||||||
|
toast.show("Old password wrong!", 5000);
|
||||||
|
}
|
72
qml/main.qml
72
qml/main.qml
|
@ -33,11 +33,6 @@ Window {
|
||||||
Room {}
|
Room {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: createRoom
|
|
||||||
CreateRoom {}
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool busy: false
|
property bool busy: false
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
running: true
|
running: true
|
||||||
|
@ -49,6 +44,73 @@ Window {
|
||||||
id: config
|
id: config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// global popup. it is modal and just lower than toast
|
||||||
|
Rectangle {
|
||||||
|
id: globalPopupDim
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
opacity: 0
|
||||||
|
visible: !mainWindow.busy
|
||||||
|
|
||||||
|
property bool stateVisible: false
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
when: globalPopupDim.stateVisible
|
||||||
|
PropertyChanges { target: globalPopupDim; opacity: 0.5 }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
when: !globalPopupDim.stateVisible
|
||||||
|
PropertyChanges { target: globalPopupDim; opacity: 0.0 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
transitions: Transition {
|
||||||
|
NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: globalPopup
|
||||||
|
property string source: ""
|
||||||
|
modal: true
|
||||||
|
dim: false // cannot animate the dim
|
||||||
|
focus: true
|
||||||
|
opacity: mainWindow.busy ? 0 : 1
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
globalPopupDim.stateVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
enter: Transition {
|
||||||
|
NumberAnimation { properties: "opacity"; from: 0; to: 1 }
|
||||||
|
NumberAnimation { properties: "scale"; from: 0.4; to: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToHide: {
|
||||||
|
globalPopupDim.stateVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: Transition {
|
||||||
|
NumberAnimation { properties: "opacity"; from: 1; to: 0 }
|
||||||
|
NumberAnimation { properties: "scale"; from: 1; to: 0.4 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
visible: !mainWindow.busy
|
||||||
|
source: globalPopup.source === "" ? "" : "GlobalPopups/" + globalPopup.source
|
||||||
|
onSourceChanged: {
|
||||||
|
if (item === null)
|
||||||
|
return;
|
||||||
|
item.finished.connect(() => {
|
||||||
|
globalPopup.close();
|
||||||
|
globalPopup.source = "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ToastManager {
|
ToastManager {
|
||||||
id: toast
|
id: toast
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,17 @@
|
||||||
class ClientPlayer : public Player {
|
class ClientPlayer : public Player {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(int id READ getId)
|
Q_PROPERTY(int id READ getId CONSTANT)
|
||||||
Q_PROPERTY(QString screenName READ getScreenName WRITE setScreenName)
|
Q_PROPERTY(QString screenName
|
||||||
Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar)
|
READ getScreenName
|
||||||
|
WRITE setScreenName
|
||||||
|
NOTIFY screenNameChanged
|
||||||
|
)
|
||||||
|
Q_PROPERTY(QString avatar
|
||||||
|
READ getAvatar
|
||||||
|
WRITE setAvatar
|
||||||
|
NOTIFY avatarChanged
|
||||||
|
)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClientPlayer(int id, QObject *parent = nullptr);
|
ClientPlayer(int id, QObject *parent = nullptr);
|
||||||
|
|
20
src/main.cpp
20
src/main.cpp
|
@ -29,20 +29,26 @@ int main(int argc, char *argv[])
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine *engine = new QQmlApplicationEngine;
|
||||||
|
|
||||||
QmlBackend backend;
|
QmlBackend backend;
|
||||||
backend.setEngine(&engine);
|
backend.setEngine(engine);
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("Backend", &backend);
|
engine->rootContext()->setContextProperty("Backend", &backend);
|
||||||
engine.rootContext()->setContextProperty("AppPath", QUrl::fromLocalFile(QDir::currentPath()));
|
engine->rootContext()->setContextProperty("AppPath", QUrl::fromLocalFile(QDir::currentPath()));
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
bool debugging = true;
|
bool debugging = true;
|
||||||
#else
|
#else
|
||||||
bool debugging = false;
|
bool debugging = false;
|
||||||
#endif
|
#endif
|
||||||
engine.rootContext()->setContextProperty("Debugging", debugging);
|
engine->rootContext()->setContextProperty("Debugging", debugging);
|
||||||
engine.load("qml/main.qml");
|
engine->load("qml/main.qml");
|
||||||
|
|
||||||
return app.exec();
|
int ret = app.exec();
|
||||||
|
|
||||||
|
// delete the engine first
|
||||||
|
// to avoid "TypeError: Cannot read property 'xxx' of null"
|
||||||
|
delete engine;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@ Server::Server(QObject* parent)
|
||||||
connect(lobby(), &Room::playerAdded, this, &Server::updateRoomList);
|
connect(lobby(), &Room::playerAdded, this, &Server::updateRoomList);
|
||||||
connect(lobby(), &Room::playerRemoved, this, &Server::updateRoomList);
|
connect(lobby(), &Room::playerRemoved, this, &Server::updateRoomList);
|
||||||
|
|
||||||
|
db = OpenDatabase();
|
||||||
|
|
||||||
L = CreateLuaState();
|
L = CreateLuaState();
|
||||||
DoLuaScript(L, "lua/freekill.lua");
|
DoLuaScript(L, "lua/freekill.lua");
|
||||||
DoLuaScript(L, "lua/server/server.lua");
|
DoLuaScript(L, "lua/server/server.lua");
|
||||||
|
|
||||||
db = OpenDatabase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
|
@ -95,6 +95,10 @@ void Server::updateRoomList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite3 *Server::getDatabase() {
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
void Server::processNewConnection(ClientSocket* client)
|
void Server::processNewConnection(ClientSocket* client)
|
||||||
{
|
{
|
||||||
qDebug() << client->peerAddress() << "connected";
|
qDebug() << client->peerAddress() << "connected";
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
|
|
||||||
void updateRoomList();
|
void updateRoomList();
|
||||||
|
|
||||||
|
sqlite3 *getDatabase();
|
||||||
|
|
||||||
void callLua(const QString &command, const QString &jsonData);
|
void callLua(const QString &command, const QString &jsonData);
|
||||||
LuaFunction callback;
|
LuaFunction callback;
|
||||||
|
|
||||||
|
@ -49,8 +51,8 @@ private:
|
||||||
QMap<int, Room *> rooms;
|
QMap<int, Room *> rooms;
|
||||||
QHash<int, ServerPlayer *> players;
|
QHash<int, ServerPlayer *> players;
|
||||||
|
|
||||||
lua_State *L;
|
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
|
lua_State *L;
|
||||||
|
|
||||||
void handleNameAndPassword(ClientSocket *client, const QString &name, const QString &password);
|
void handleNameAndPassword(ClientSocket *client, const QString &name, const QString &password);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,8 @@ public:
|
||||||
Room *findRoom(int id) const;
|
Room *findRoom(int id) const;
|
||||||
ServerPlayer *findPlayer(int id) const;
|
ServerPlayer *findPlayer(int id) const;
|
||||||
|
|
||||||
|
sqlite3 *getDatabase();
|
||||||
|
|
||||||
LuaFunction callback;
|
LuaFunction callback;
|
||||||
LuaFunction startRoom;
|
LuaFunction startRoom;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue