Skip to content

Commit

Permalink
Merge pull request #164 from cavoke-project/feature/game-submit
Browse files Browse the repository at this point in the history
[server] add basic game submissions
  • Loading branch information
waleko authored May 31, 2022
2 parents 998bb62 + d3aa9b8 commit 12c69f9
Show file tree
Hide file tree
Showing 9 changed files with 1,607 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,4 @@ local_server/
# Drogon logs
*.log
/games/codenames/client/client.zip
uploads/
2 changes: 1 addition & 1 deletion server/.gcp/gcsfuse_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -eo pipefail
mkdir -p "$MNT_DIR"

echo "Mounting GCS Fuse."
gcsfuse --debug_gcs --debug_fuse --file-mode=005 "$BUCKET" "$MNT_DIR"
gcsfuse --debug_gcs --debug_fuse --file-mode=777 "$BUCKET" "$MNT_DIR"
echo "Mounting completed."

# Run the web service on container startup.
Expand Down
1 change: 1 addition & 0 deletions server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_executable(${PROJECT_NAME}
model/sessions/game_session.cpp
model/statistics/statistics_manager.cpp
controllers/statistics_controller.cpp
controllers/gamesubmissions_controller.cpp
)
install(TARGETS ${PROJECT_NAME})

Expand Down
56 changes: 56 additions & 0 deletions server/controllers/gamesubmissions_controller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "gamesubmissions_controller.h"
#include "filters/AuthFilter.h"

namespace cavoke::server::controllers {

void GameSubmissionsController::submit_game(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback) {
// TODO: Auth. Currently problems with authenticating the form request.
// parse web form
drogon::MultiPartParser mpp;
int res = mpp.parse(req);
if (res == -1) {
return CALLBACK_STATUS_CODE(k400BadRequest);
}
// form files
auto files = mpp.getFilesMap();
// form params
nlohmann::json j = mpp.getParameters();
if (!j.contains("git_repo")) {
j["git_repo"] = "<empty>";
}
// serialize
GameSubmissionReq req_data;
try {
req_data = j.get<GameSubmissionReq>();
} catch (...) {
return CALLBACK_STATUS_CODE(k400BadRequest);
}
// validation
if (req_data.package_type != "Git Repository" &&
req_data.package_type != "Zip Archive") {
return CALLBACK_STATUS_CODE(k400BadRequest);
}

auto id = drogon::utils::getUuid();
auto submission = req_data.to_orm(id);
if (req_data.package_type == "Zip Archive") {
try {
files.at("client_zip").saveAs(id + "-client.zip");
files.at("server_zip").saveAs(id + "-server.zip");
} catch (...) {
return CALLBACK_STATUS_CODE(k400BadRequest);
}
}
// save to db
mp_submissions.insert(submission);

LOG_INFO << "New game submission! Game: " << req_data.display_name;
auto resp = newStatusCodeResponse(drogon::k200OK);
resp->setBody(
"Thanks for your game submission! We will review it and publish your "
"game shortly.");
return callback(resp);
}
} // namespace cavoke::server::controllers
58 changes: 58 additions & 0 deletions server/controllers/gamesubmissions_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef CAVOKE_GAMESUBMISSIONS_CONTROLLER_H
#define CAVOKE_GAMESUBMISSIONS_CONTROLLER_H

#include <drogon/HttpController.h>
#include <nlohmann/json.hpp>
#include "sql-models/Gamesubmissions.h"
#include "utils.h"

namespace cavoke::server::controllers {

class GameSubmissionsController
: public drogon::HttpController<GameSubmissionsController, true> {
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(GameSubmissionsController::submit_game,
"/submit_game",
drogon::Post,
drogon::Options);
METHOD_LIST_END

struct GameSubmissionReq {
std::string game_id;
std::string display_name;
std::string description;
std::string package_type;
std::string git_repo;

auto to_orm(const std::string &id) {
drogon_model::cavoke_orm::Gamesubmissions res;
res.setId(id);
res.setGameId(game_id);
res.setPackageType(package_type);
res.setGitRepo(git_repo);
res.setDisplayName(display_name);
return res;
}
};

protected:
void submit_game(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);

private:
MAPPER_TYPE(drogon_model::cavoke_orm::Gamesubmissions)
mp_submissions = MAPPER_FOR(drogon_model::cavoke_orm::Gamesubmissions);
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GameSubmissionsController::GameSubmissionReq,
game_id,
display_name,
description,
package_type,
git_repo);

} // namespace cavoke::server::controllers

#endif // CAVOKE_GAMESUBMISSIONS_CONTROLLER_H
16 changes: 16 additions & 0 deletions server/db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ create table globalstates
saved_on timestamp default current_timestamp
);

create table gamesubmissions
(
id uuid default gen_random_uuid() not null
constraint gamesubmissions_pk
primary key,
game_id varchar,
package_type varchar,
git_repo varchar,
review_status integer default 0,
submitted_at timestamp default CURRENT_TIMESTAMP,
display_name varchar
);

create unique index gamesubmissions_id_uindex
on gamesubmissions (id);

create or replace function leave_session(m_session_id uuid, m_user_id varchar) returns void as
$$
declare
Expand Down
3 changes: 2 additions & 1 deletion server/example_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
//number_of_threads: The number of IO threads, 1 by default, if the value is set to 0, the number of threads
//is the number of CPU cores
"number_of_threads": 1,
"upload_path": "uploads",
//enable_session: False by default
"enable_session": false,
"session_timeout": 0,
Expand Down Expand Up @@ -146,7 +147,7 @@
"br_static": true,
//client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M".
//One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
"client_max_body_size": "1M",
"client_max_body_size": "128M",
//max_memory_body_size: Set the maximum body size in memory of HTTP requests received by drogon. The default value is "64K" bytes.
//If the body size of an HTTP request exceeds this limit, the body is stored to a temporary file for processing.
//Setting it to "" means no limit.
Expand Down
Loading

0 comments on commit 12c69f9

Please sign in to comment.