Skip to content

Commit cb02a5b

Browse files
committed
add stop listen
1 parent 3aa690d commit cb02a5b

10 files changed

Lines changed: 121 additions & 181 deletions

File tree

ARCHITECTURE.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,9 @@ Receives back one of:
777777
```json
778778
{
779779
"c": 10,
780-
"d": {}
780+
"d": {
781+
"l": []
782+
}
781783
}
782784
```
783785

@@ -964,6 +966,23 @@ Receives back one of:
964966
}
965967
```
966968

969+
#### COMMAND_STOP_LIST_LOBBY
970+
971+
Stop receveiving list lobbies responses.
972+
973+
Receives back one of:
974+
- RESPONSE_ERROR
975+
- RESPONSE_LOBBY_LIST
976+
977+
```json
978+
{
979+
"c": 22,
980+
"d": {
981+
"l": []
982+
}
983+
}
984+
```
985+
967986
### Errors
968987

969988
Possible errors from server:

Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ RUN apt-get update && apt-get install -y \
1515
COPY ./build/tiny_lobby /app/tiny_lobby
1616
COPY ./scripts /app/scripts
1717
COPY ./config.ini /app/config.ini
18-
COPY ./games.ini /app/games.ini
1918

2019
RUN chmod +x /app/tiny_lobby
2120
RUN mkdir /app/logs

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Tiny Lobby
22

3-
|[Website](https://appsinacup.com)|[Discord](https://discord.gg/56dMud8HYn)|[Documentation](https://github.com/appsinacup/documentation_lobby)|[Build Locally](./BUILD_LOCALLY.md)
4-
|-|-|-|-|
3+
|[Website](https://appsinacup.com)|[Discord](https://discord.gg/56dMud8HYn)|[Documentation](https://github.com/appsinacup/documentation_lobby)|[Build Locally](./BUILD_LOCALLY.md)|[Architecture](./ARCHITECTURE.md)
4+
|-|-|-|-|-|
55

66
![example](docs/example.gif)
77

config.ini

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ max_reconnection_time=360000
1919

2020
[database]
2121
enabled=false
22-
username=<username>
22+
username=postgres
2323
password=<password>
24-
host=<host>
25-
port=<port>
26-
database=<database>
24+
host=localhost
25+
port=5432
26+
database=tiny_lobby
File renamed without changes.

src/database/database.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ bool Database::ensure_connection() {
2727
void Database::connect_to_db() {
2828
try {
2929
INIReader config_reader(BasePath::instance().file("config.ini"));
30-
std::string database = config_reader.Get("database", "database", "");
30+
std::string database = config_reader.Get("database", "database", "tiny_lobby");
3131
if (database.empty()) {
3232
std::cerr << "Database name not found in config.ini" << std::endl;
3333
exit(1);
3434
}
35-
std::string user = config_reader.Get("database", "user", "");
35+
std::string user = config_reader.Get("database", "username", "postgres");
3636
if (user.empty()) {
3737
std::cerr << "Database user not found in config.ini" << std::endl;
3838
exit(1);
@@ -42,12 +42,12 @@ void Database::connect_to_db() {
4242
std::cerr << "Database password not found in config.ini" << std::endl;
4343
exit(1);
4444
}
45-
std::string host = config_reader.Get("database", "host", "");
45+
std::string host = config_reader.Get("database", "host", "localhost");
4646
if (host.empty()) {
4747
std::cerr << "Database host not found in config.ini" << std::endl;
4848
exit(1);
4949
}
50-
std::string port = config_reader.Get("database", "port", "");
50+
std::string port = config_reader.Get("database", "port", "5432");
5151
if (port.empty()) {
5252
std::cerr << "Database port not found in config.ini" << std::endl;
5353
exit(1);

src/game/game_thread.cpp

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -38,55 +38,67 @@ GameThread::GameThread(
3838

3939
void GameThread::load_games() {
4040
logger.debug_log("[GameThread] on_load_games");
41-
if (!std::filesystem::exists(BasePath::instance().file("games.ini"))) {
42-
logger.error_log("[GameThread] Cannot open games.ini file");
41+
if (!std::filesystem::exists(scripts_folder)) {
42+
logger.error_log("[GameThread] Scripts folder does not exist: ", scripts_folder);
4343
return;
4444
}
45-
INIReader config_reader(BasePath::instance().file("games.ini"));
46-
auto sections = config_reader.Sections();
4745
std::unordered_set<std::string> games_to_open;
48-
for (const auto &section : sections) {
49-
std::string folder_name = config_reader.GetString(section, "folder", section);
50-
int tickrate = config_reader.GetInteger(section, "tickrate", 0);
51-
if (tickrate < 16) {
52-
tickrate = 0;
53-
}
54-
int sendrate = config_reader.GetInteger(section, "sendrate", 0);
55-
int max_afk_time = config_reader.GetInteger(section, "max_afk_time", 0);
56-
bool seal = config_reader.GetBoolean(section, "seal", false);
57-
std::string lobby_control = config_reader.Get(section, "lobby_control", "lua");
58-
if (tickrate > 0) {
59-
check_time = std::min(check_time, tickrate);
60-
}
61-
if (sendrate > 0) {
62-
check_time = std::min(check_time, sendrate);
63-
}
64-
// Only add if new game
65-
if (games.find(section) != games.end()) {
66-
continue;
46+
// go through all folders inside scripts_folder
47+
for (const auto &entry : std::filesystem::directory_iterator(scripts_folder)) {
48+
if (entry.is_directory()) {
49+
std::string folder_name = entry.path().filename().string();
50+
if (folder_name.empty()) {
51+
continue;
52+
}
53+
std::string section = folder_name;
54+
std::string lobby_control = "relay";
55+
INIReader config_reader(
56+
BasePath::instance().file(scripts_folder + "/" + folder_name + "/config.ini"));
57+
int tickrate = config_reader.GetInteger("game", "tickrate", 0);
58+
if (tickrate < 16) {
59+
tickrate = 0;
60+
}
61+
int sendrate = config_reader.GetInteger("game", "sendrate", 0);
62+
int max_afk_time = config_reader.GetInteger("game", "max_afk_time", 0);
63+
bool seal = config_reader.GetBoolean("game", "seal", false);
64+
// if there is a main.lua file in the fulder, set lobby_control to lua
65+
if (std::filesystem::exists(scripts_folder + "/" + folder_name + "/main.lua")) {
66+
lobby_control = "lua";
67+
}
68+
if (tickrate > 0) {
69+
check_time = std::min(check_time, tickrate);
70+
}
71+
if (sendrate > 0) {
72+
check_time = std::min(check_time, sendrate);
73+
}
74+
// Only add if new game
75+
if (games.find(section) != games.end()) {
76+
continue;
77+
}
78+
if (folder_name.empty()) {
79+
logger.debug_log("[GameThread] on_load_game relay");
80+
} else {
81+
logger.debug_log("[GameThread] on_load_game ", folder_name);
82+
}
83+
std::cout << "Loading game from " << folder_name << " with id " << section
84+
<< " and control " << lobby_control << std::endl;
85+
games_to_open.insert(section);
86+
games.emplace(section, GameData{.id = section,
87+
.lobby_control = lobby_control,
88+
.tick_rate = tickrate,
89+
.send_rate = sendrate,
90+
.max_afk_time = max_afk_time,
91+
.seal = seal,
92+
.disband_on_leave = config_reader.GetBoolean(
93+
section, "disband_on_leave", false),
94+
.folder_name = folder_name,
95+
.lua = ScriptLua{.scripts_folder = scripts_folder,
96+
.folder_name = folder_name,
97+
.script_entrypoint = "main.lua",
98+
.logs_folder = logs_folder,
99+
.game_thread = this,
100+
.enabled = lobby_control == "lua"}});
67101
}
68-
if (folder_name.empty()) {
69-
logger.debug_log("[GameThread] on_load_game relay");
70-
} else {
71-
logger.debug_log("[GameThread] on_load_game ", folder_name);
72-
}
73-
std::cout << "Loading game from " << folder_name << " with id " << section << std::endl;
74-
games_to_open.insert(section);
75-
games.emplace(section, GameData{.id = section,
76-
.lobby_control = lobby_control,
77-
.tick_rate = tickrate,
78-
.send_rate = sendrate,
79-
.max_afk_time = max_afk_time,
80-
.seal = seal,
81-
.disband_on_leave = config_reader.GetBoolean(
82-
section, "disband_on_leave", false),
83-
.folder_name = folder_name,
84-
.lua = ScriptLua{.scripts_folder = scripts_folder,
85-
.folder_name = folder_name,
86-
.script_entrypoint = "main.lua",
87-
.logs_folder = logs_folder,
88-
.game_thread = this,
89-
.enabled = lobby_control == "lua"}});
90102
}
91103
for (auto &game : games) {
92104
if (!games_to_open.contains(game.first)) {
@@ -354,9 +366,11 @@ bool GameThread::handle_events() {
354366
}
355367
messages_received++;
356368
if (games.find(message.game_id) == games.end()) {
357-
auto fake_game = GameData{.send_rate = 0};
358-
on_error(fake_game, EMPTY_STRING, message.id, ERROR_GAME_NOT_FOUND, true);
359-
return true;
369+
// game not found, add relay game.
370+
games.emplace(message.game_id, GameData{.id = message.game_id, .lobby_control = "relay"});
371+
// auto fake_game = GameData{.send_rate = 0};
372+
// on_error(fake_game, EMPTY_STRING, message.id, ERROR_GAME_NOT_FOUND, true);
373+
// return true;
360374
}
361375
auto &game = games[message.game_id];
362376
switch (message.event) {
@@ -430,6 +444,9 @@ bool GameThread::handle_events() {
430444
case COMMAND_LIST_LOBBY: {
431445
on_list_lobby(game, command_id, peer, data_val);
432446
} break;
447+
case COMMAND_STOP_LISTING: {
448+
on_stop_list_lobby(game, command_id, peer, data_val);
449+
} break;
433450
case COMMAND_CHAT_LOBBY: {
434451
on_chat_lobby(game, command_id, peer, data_val);
435452
} break;
@@ -924,7 +941,6 @@ void GameThread::on_create_lobby(
924941
.sealed = decode_bool_or_default(data_val, "s", game.seal),
925942
.tags = lobby_tags});
926943
auto &lobby = game.lobbies[small_uuid];
927-
game.lobby_listing_peers.erase(peer.id);
928944
// SCRIPTED CALL
929945
if (game.enabled_callbacks.find("_can_create_lobby") != game.enabled_callbacks.end()) {
930946
bool has_error = false;
@@ -1003,7 +1019,6 @@ bool GameThread::on_join_lobby(GameData &game, std::string command_id, PeerData
10031019
}
10041020
}
10051021
// CHANGES
1006-
game.lobby_listing_peers.erase(peer.id);
10071022
if (reconnecting) {
10081023
peer.ready = false;
10091024
} else {
@@ -1112,6 +1127,21 @@ void GameThread::on_list_lobby(GameData &game, std::string command_id, PeerData
11121127
send(game, peer.id, notification, uWS::OpCode::TEXT);
11131128
}
11141129

1130+
void GameThread::on_stop_list_lobby(GameData &game, std::string command_id, PeerData &peer,
1131+
yyjson_val *data_val) {
1132+
logger.debug_log("[GameThread] on_stop_list_lobby ", command_id, " ", peer.id);
1133+
if (game.lobby_listing_peers.find(peer.id) == game.lobby_listing_peers.end()) {
1134+
std::string notification =
1135+
notification_lobby_list(AnyElement{boost::container::vector<AnyElement>{}}, command_id);
1136+
return send(game, peer.id, notification, uWS::OpCode::TEXT);
1137+
}
1138+
1139+
game.lobby_listing_peers.erase(peer.id);
1140+
1141+
std::string notification = notification_lobby_stop_listing(command_id);
1142+
send(game, peer.id, notification, uWS::OpCode::TEXT);
1143+
}
1144+
11151145
std::string strip_BBCode(const std::string &input) {
11161146
static const std::regex bbcode_regex(R"(\[.*?\])");
11171147
return std::regex_replace(input, bbcode_regex, "");

src/game/game_thread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class GameThread {
101101
yyjson_val *data_val);
102102
void on_list_lobby(GameData &game, std::string command_id, PeerData &peer,
103103
yyjson_val *data_val);
104+
void on_stop_list_lobby(GameData &game, std::string command_id, PeerData &peer,
105+
yyjson_val *data_val);
104106
void on_chat_lobby(GameData &game, std::string command_id, PeerData &peer,
105107
yyjson_val *data_val);
106108
void on_lobby_tags(GameData &game, std::string command_id, PeerData &peer,

src/game/game_thread_messages.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const int COMMAND_LOBBY_UNSEAL = 18;
8383
const int COMMAND_LOBBY_MAX_PLAYERS = 19;
8484
const int COMMAND_LOBBY_TITLE = 20;
8585
const int COMMAND_LOBBY_PASSWORD = 21;
86+
const int COMMAND_STOP_LISTING = 22;
8687

8788
// host_id = h
8889
// max_players = m
@@ -288,6 +289,14 @@ std::string notification_lobby_list(const AnyElement& lobbies, const std::string
288289
.to_string();
289290
}
290291

292+
std::string notification_lobby_stop_listing(const std::string& command_id) {
293+
return AnyElement{boost::container::flat_map<std::string, AnyElement>{
294+
{"c", AnyElement{RESPONSE_LOBBY_LIST}},
295+
{"d", AnyElement{boost::container::flat_map<std::string, AnyElement>{
296+
{"l", AnyElement{}}, {"id", AnyElement{command_id}}}}}}}
297+
.to_string();
298+
}
299+
291300
std::string notification_lobby_public_data(const AnyElement& lobby_data,
292301
const std::string& command_id) {
293302
return AnyElement{

0 commit comments

Comments
 (0)