Skip to content

Commit

Permalink
Release v1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleYang0531 committed Mar 6, 2023
1 parent 48b4e43 commit e7dfd52
Show file tree
Hide file tree
Showing 22 changed files with 627 additions and 149 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<p align="center"><a href="./README_en.md">English</a>&nbsp; <a href="./README.md">简体中文</a></p>

使用 C++ 与 MySQL 开发的一个适用于 Sonolus 的 api 服务器,您可以用于测试您自己的引擎或自己构建一个 Sonolus 服务。
使用 C++ 与 MySQL/SQLite 开发的一个适用于 Sonolus 的 api 服务器,您可以用于测试您自己的引擎或自己构建一个 Sonolus 服务。

该项目可以被部署在任何 Linux 设备以及 Windows 设备,即使是一台手机也能轻松完成服务器的编译。

Expand Down Expand Up @@ -64,7 +64,7 @@ g++ main.cpp -o main -lpthread -lcrypto -lssl -ljsoncpp -lmysqlclient -g
./main import bandori.bin
```

我们提供各官方引擎的数据包下载: [Data Packages for v1.1.1+](https://github.com/LittleYang0531/sonolus-server-cpp/releases/tag/data)
我们提供各官方引擎的数据包下载: [Data Packages for v1.2.1+](https://github.com/LittleYang0531/sonolus-server-cpp/releases/tag/v1.2.1-data)

### 运行

Expand Down Expand Up @@ -136,7 +136,7 @@ g++ main.cpp -o main -lpthread -lcrypto -lssl -ljsoncpp -lmysqlclient -g

- `GET /`: 网站主页面。
- `GET /index`: 网站主页面。
- `GET /levels/create`: 创建一个关卡。
<!-- - `GET /levels/create`: 创建一个关卡。 -->
- `GET /levels/{name}`: 显示名为 {name} 的关卡信息。
- `GET /skins/{name}`: 显示名为 {name} 的皮肤信息。
- `GET /backgrounds/{name}`: 显示名为 {name} 的背景信息。
Expand Down Expand Up @@ -278,6 +278,14 @@ string levelSearch(map<string, string> $_GET) {
## 更新日志
### v1.2.1 2023.3.6
1. 新增对 SQLite 数据库的支持。
2. 修改了数据包格式,以为 SQLite 提供支持。
3. 重新对官方引擎进行打包,新的下载链接: [Data Packages for v1.2.1+](https://github.com/LittleYang0531/sonolus-server-cpp/releases/tag/v1.2.1-data)。
4. 新增了各组件创建接口,为下一版本创建组件提供支持。
5. 临时删除 `/levels/create` 接口,便于下一版本对 GUI 的重写。
### v1.2.0 2023.2.14
🎁 情人节特供 💝
Expand Down
10 changes: 9 additions & 1 deletion README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ Take the export level named `bandori-#1` as an example

- `GET /`: Website's index.
- `GET /index`: Website's index.
- `GET /levels/create`: Create a level.
<!-- - `GET /levels/create`: Create a level. -->
- `GET /levels/{name}`: Show information of level named {name}.
- `GET /skins/{name}`: Show information of skin named {name}.
- `GET /backgrounds/{name}`: Show information of background named {name}.
Expand Down Expand Up @@ -278,6 +278,14 @@ These days, the official wiki website has added an endpoint `/sonolus/authentica
## Upload Log
### v1.2.1 2023.3.6
1. New support for SQLite database.
2. The data package format has been modified to provide support for SQLite.
3. Re-package the official engine with a new download link: [Data Packages for v1.2.1+](https://github.com/LittleYang0531/sonolus-server-cpp/releases/tag/v1.2.1-data)。
4. New component creation interfaces are added to support the creation of components in the next version.
5. Temporarily delete the `/levels/create` interface to facilitate GUI rewriting in the next version.
### v1.2.0 2023.2.14
🎁 Happy Valentine's Day 💝
Expand Down
4 changes: 3 additions & 1 deletion config/config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"database": "mysql",
"mysql.hostname": "127.0.0.1",
"mysql.port": 3306,
"mysql.username": "root",
"mysql.password": "root",
"mysql.database": "sonolus",
"sqlite.dbfile": "sonolus.db",
"server.name": "Sonolus",
"server.title": "Sonolus Server for C++",
"server.description": "A Test Server for Sonolus",
Expand All @@ -16,7 +18,7 @@
"server.httpsCacert": "cert.pem",
"server.httpsPrivkey": "privkey.pem",
"server.threadNumber": 8,
"server.rootUrl": "//192.168.0.102:8080",
"server.rootUrl": "//127.0.0.1:8080",
"logSystem.debug": false,
"logSystem.target": 1,
"logSystem.targetFile": "./log.txt",
Expand Down
28 changes: 26 additions & 2 deletions items/BackgroundItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ class BackgroundItem {
SRL<BackgroundThumbnail> thumbnail, SRL<BackgroundData> data, SRL<BackgroundImage> image, SRL<BackgroundConfiguration> configuration):
id(id), name(name), title(title), subtitle(subtitle), author(author),
thumbnail(thumbnail), data(data), image(image), configuration(configuration){}
BackgroundItem(int background_id, Json::Value arr) {
id = background_id;
name = arr["name"].asString();
version = arr["version"].asInt();
title = arr["title"].asString();
subtitle = arr["subtitle"].asString();
author = arr["author"].asString();
thumbnail = SRL<BackgroundThumbnail>(arr["thumbnail"]);
data = SRL<BackgroundData>(arr["data"]);
image = SRL<BackgroundImage>(arr["image"]);
configuration = SRL<BackgroundConfiguration>(arr["configuration"]);
}

Json::Value toJsonObject() {
Json::Value res;
Expand Down Expand Up @@ -63,7 +75,7 @@ class BackgroundItem {
int backgroundNumber(string filter) {
string sql = "SELECT COUNT(*) AS sum FROM Background";
if (filter != "") sql += " WHERE (" + filter + ")";
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
return atoi(res[0]["sum"].c_str());
}

Expand All @@ -75,7 +87,7 @@ Section<BackgroundItem> backgroundList(string filter, int st = 1, int en = 20) {
string sql = "SELECT * FROM Background";
if (filter != "") sql += " WHERE (" + filter + ")";
sql += " ORDER BY id DESC LIMIT " + to_string(st - 1) + ", " + to_string(en - st + 1);
auto res = mysqli_query(mysql, sql.c_str());
auto res = (new DB_Controller)->query(sql.c_str());
Section<BackgroundItem> list = Section<BackgroundItem>(pageCount, BackgroundSearch);
for (int i = 0; i < res.size(); i++) {
BackgroundItem data = BackgroundItem(
Expand All @@ -98,4 +110,16 @@ string backgroundFilter(argvar arg) {
return filter;
}

int backgroundCreate(BackgroundItem item) {
stringstream sqlbuffer;
auto res = (new DB_Controller)->query("SELECT id FROM Background WHERE name = \"" + item.name + "\"");
if (res.size() != 0) return 0;
int id = atoi((new DB_Controller)->query("SELECT COUNT(*) AS sum FROM Background;")[0]["sum"].c_str()) + 1;
sqlbuffer << "INSERT INTO Background (id, name, version, title, subtitle, author, thumbnail, data, image, configuration) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", \"" << item.thumbnail.hash << "\", ";
sqlbuffer << "\"" << item.data.hash << "\", \"" << item.image.hash << "\", \"" << item.configuration.hash << "\");";
return (new DB_Controller)->execute(sqlbuffer.str());
}

#endif
27 changes: 25 additions & 2 deletions items/EffectItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ class EffectItem {
SRL<EffectThumbnail> thumbnail, SRL<EffectData> data, SRL<EffectAudio> audio):
id(id), name(name), title(title), subtitle(subtitle), author(author),
thumbnail(thumbnail), data(data), audio(audio){}
EffectItem(int effect_id, Json::Value arr) {
id = effect_id;
name = arr["name"].asString();
version = arr["version"].asInt();
title = arr["title"].asString();
subtitle = arr["subtitle"].asString();
author = arr["author"].asString();
thumbnail = SRL<EffectThumbnail>(arr["thumbnail"]);
data = SRL<EffectData>(arr["data"]);
audio = SRL<EffectAudio>(arr["audio"]);
}

Json::Value toJsonObject() {
Json::Value res;
Expand Down Expand Up @@ -60,7 +71,7 @@ class EffectItem {
int effectNumber(string filter) {
string sql = "SELECT COUNT(*) AS sum FROM Effect";
if (filter != "") sql += " WHERE (" + filter + ")";
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
return atoi(res[0]["sum"].c_str());
}

Expand All @@ -72,7 +83,7 @@ Section<EffectItem> effectList(string filter, int st = 1, int en = 20) {
string sql = "SELECT * FROM Effect";
if (filter != "") sql += " WHERE (" + filter + ")";
sql += " ORDER BY id DESC LIMIT " + to_string(st - 1) + ", " + to_string(en - st + 1);
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
Section<EffectItem> list = Section<EffectItem>(pageCount, EffectSearch);
for (int i = 0; i < res.size(); i++) {
EffectItem data = EffectItem(
Expand All @@ -94,4 +105,16 @@ string effectFilter(argvar arg) {
return filter;
}

int effectCreate(EffectItem item) {
stringstream sqlbuffer;
auto res = (new DB_Controller)->query("SELECT id FROM Effect WHERE name = \"" + item.name + "\"");
if (res.size() != 0) return 0;
int id = atoi((new DB_Controller)->query("SELECT COUNT(*) AS sum FROM Effect;")[0]["sum"].c_str()) + 1;
sqlbuffer << "INSERT INTO Effect (id, name, version, title, subtitle, author, thumbnail, data, audio) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", \"" << item.thumbnail.hash << "\", ";
sqlbuffer << "\"" << item.data.hash << "\", \"" << item.audio.hash << "\")";
return (new DB_Controller)->execute(sqlbuffer.str());
}

#endif
37 changes: 35 additions & 2 deletions items/EngineItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ class EngineItem {
id(id), name(name), title(title), subtitle(subtitle), author(author),
skin(skin), background(background), effect(effect), particle(particle),
thumbnail(thumbnail), data(data), configuration(configuration), rom(rom){}
EngineItem(int engine_id, Json::Value arr) {
id = engine_id;
name = arr["name"].asString();
version = arr["version"].asInt();
title = arr["title"].asString();
subtitle = arr["subtitle"].asString();
author = arr["author"].asString();
skin = SkinItem(-1, arr["skin"]);
background = BackgroundItem(-1, arr["background"]);
effect = EffectItem(-1, arr["effect"]);
particle = ParticleItem(-1, arr["particle"]);
thumbnail = SRL<EngineThumbnail>(arr["thumbnail"]);
data = SRL<EngineData>(arr["data"]);
configuration = SRL<EngineConfiguration>(arr["configuration"]);
rom = SRL<EngineRom>(arr["rom"]);
}

Json::Value toJsonObject() {
Json::Value res;
Expand Down Expand Up @@ -77,7 +93,7 @@ class EngineItem {
int engineNumber(string filter) {
string sql = "SELECT COUNT(*) AS sum FROM Engine";
if (filter != "") sql += " WHERE (" + filter + ")";
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
return atoi(res[0]["sum"].c_str());
}

Expand All @@ -89,7 +105,7 @@ Section<EngineItem> engineList(string filter, int st = 1, int en = 20) {
string sql = "SELECT * FROM Engine";
if (filter != "") sql += " WHERE (" + filter + ")";
sql += " ORDER BY id DESC LIMIT " + to_string(st - 1) + ", " + to_string(en - st + 1);
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
Section<EngineItem> list = Section<EngineItem>(pageCount, EngineSearch);
for (int i = 0; i < res.size(); i++) {
SkinItem skin = skinList("id = " + res[i]["skin"], 1, 1).items[0];
Expand Down Expand Up @@ -117,4 +133,21 @@ string engineFilter(argvar arg) {
return filter;
}

int engineCreate(EngineItem item) {
stringstream sqlbuffer;
auto res = (new DB_Controller)->query("SELECT id FROM Engine WHERE name = \"" + item.name + "\"");
if (res.size() != 0) return 0;
int id = atoi((new DB_Controller)->query("SELECT COUNT(*) AS sum FROM Engine;")[0]["sum"].c_str()) + 1;
int skinId = atoi((new DB_Controller)->query("SELECT id FROM Skin WHERE name = \"" + item.skin.name + "\";")[0]["id"].c_str());
int backgroundId = atoi((new DB_Controller)->query("SELECT id FROM Background WHERE name = \"" + item.background.name + "\";")[0]["id"].c_str());
int effectId = atoi((new DB_Controller)->query("SELECT id FROM Effect WHERE name = \"" + item.effect.name + "\";")[0]["id"].c_str());
int particleId = atoi((new DB_Controller)->query("SELECT id FROM Particle WHERE name = \"" + item.particle.name + "\";")[0]["id"].c_str());
sqlbuffer << "INSERT INTO Engine (id, name, version, title, subtitle, author, skin, background, effect, particle, thumbnail, data, configuration, rom) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.subtitle << "\", \"" << item.author << "\", " << skinId << ", " << backgroundId << ", " << effectId << ", " << particleId << ", ";
sqlbuffer << "\"" << item.thumbnail.hash << "\", \"" << item.data.hash << "\", \"" << item.configuration.hash << "\", ";
sqlbuffer << "\"" << item.rom.hash << "\");";
return (new DB_Controller)->execute(sqlbuffer.str());
}

#endif
50 changes: 47 additions & 3 deletions items/LevelItem.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef LEVELITEM_h
#ifndef LEVELITEM_H
#define LEVELITEM_H

using namespace std;
Expand All @@ -12,6 +12,10 @@ class UseItem {

UseItem(){}
UseItem(bool useDefault, T item = T()): useDefault(useDefault), item(item){}
UseItem(Json::Value arr) {
useDefault = arr["useDefault"].asInt();
item = T(-1, arr["item"]);
}

Json::Value toJsonObject() {
Json::Value res;
Expand Down Expand Up @@ -48,6 +52,24 @@ class LevelItem {
id(id), name(name), rating(rating), title(title), artists(artists), author(author), engine(engine),
useSkin(useSkin), useBackground(useBackground), useEffect(useEffect), useParticle(useParticle),
cover(cover), bgm(bgm), data(data), preview(preview){}
LevelItem(int level_id, Json::Value arr) {
id = level_id;
name = arr["name"].asString();
version = arr["version"].asInt();
rating = arr["rating"].asInt();
title = arr["title"].asString();
artists = arr["artists"].asString();
author = arr["author"].asString();
engine = EngineItem(-1, arr["engine"]);
useSkin = UseItem<SkinItem>(arr["useSkin"]);
useBackground = UseItem<BackgroundItem>(arr["useBackground"]);
useEffect = UseItem<EffectItem>(arr["useEffect"]);
useParticle = UseItem<ParticleItem>(arr["useParticle"]);
cover = SRL<LevelCover>(arr["cover"]);
bgm = SRL<LevelBgm>(arr["bgm"]);
data = SRL<LevelData>(arr["data"]);
preview = SRL<LevelPreview>(arr["preview"]);
}

Json::Value toJsonObject() {
Json::Value res;
Expand Down Expand Up @@ -102,7 +124,7 @@ int levelNumber(string filter) {
string sql = "SELECT COUNT(*) AS sum FROM Level";
if (filter != "") sql += " WHERE (" + filter + ")";
sql += " ORDER BY id";
mysqld res = mysqli_query(mysql, sql.c_str());
dbres res = (new DB_Controller)->query(sql.c_str());
return atoi(res[0]["sum"].c_str());
}

Expand All @@ -114,7 +136,7 @@ Section<LevelItem> levelList(string filter, int st = 1, int en = 20) {
string sql = "SELECT * FROM Level";
if (filter != "") sql += " WHERE (" + filter + ")";
sql += " ORDER BY id DESC LIMIT " + to_string(st - 1) + ", " + to_string(en - st + 1);
auto res = mysqli_query(mysql, sql.c_str());
auto res = (new DB_Controller)->query(sql.c_str());
Section<LevelItem> list = Section<LevelItem>(pageCount, LevelSearch);
for (int i = 0; i < res.size(); i++) {
EngineItem engine = engineList("id = " + res[i]["engine"], 1, 1).items[0];
Expand Down Expand Up @@ -156,4 +178,26 @@ string levelFilter(argvar arg) {
return filter;
}

int levelCreate(LevelItem item) {
stringstream sqlbuffer;
auto res = (new DB_Controller)->query("SELECT id FROM Level WHERE name = \"" + item.name + "\"");
if (res.size() != 0) return 0;
int id = atoi((new DB_Controller)->query("SELECT COUNT(*) AS sum FROM Level;")[0]["sum"].c_str()) + 1;
int skinId = 0, backgroundId = 0, effectId = 0, particleId = 0, engineId = 0;
if (item.useSkin.useDefault == false)
skinId = atoi((new DB_Controller)->query("SELECT id FROM Skin WHERE name = \"" + item.useSkin.item.name + "\";")[0]["id"].c_str());
if (item.useBackground.useDefault == false)
backgroundId = atoi((new DB_Controller)->query("SELECT id FROM Background WHERE name = \"" + item.useBackground.item.name + "\";")[0]["id"].c_str());
if (item.useEffect.useDefault == false)
effectId = atoi((new DB_Controller)->query("SELECT id FROM Effect WHERE name = \"" + item.useEffect.item.name + "\";")[0]["id"].c_str());
if (item.useParticle.useDefault == false)
particleId = atoi((new DB_Controller)->query("SELECT id FROM Particle WHERE name = \"" + item.useParticle.item.name + "\";")[0]["id"].c_str());
engineId = atoi((new DB_Controller)->query("SELECT id FROM Engine WHERE name = \"" + item.engine.name + "\";")[0]["id"].c_str());
sqlbuffer << "INSERT INTO Level (id, name, version, rating, title, artists, author, engine, skin, background, effect, particle, cover, bgm, data, preview) VALUES (";
sqlbuffer << id << ", \"" << item.name << "\", " << item.version << ", " << item.rating << ", \"" << item.title << "\", ";
sqlbuffer << "\"" << item.artists << "\", \"" << item.author << "\", " << engineId << ", " << skinId << ", " << backgroundId << ", " << effectId << ", " << particleId << ", ";
sqlbuffer << "\"" << item.cover.hash << "\", \"" << item.bgm.hash << "\", \"" << item.data.hash << "\", \"" << item.preview.hash << "\")";
return (new DB_Controller)->execute(sqlbuffer.str());
}

#endif
Loading

0 comments on commit e7dfd52

Please sign in to comment.