mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-17 12:04:27 -06:00
Compare commits
15 Commits
script-stu
...
chat-http-
| Author | SHA1 | Date | |
|---|---|---|---|
| 214626222c | |||
| ce5bd68067 | |||
| 9192dca4e6 | |||
| 06607c9b55 | |||
| c3ea448be0 | |||
| ff721ed49b | |||
| bce03ca08d | |||
| faee5b72e7 | |||
| 77143fc2cf | |||
| 5e16c13a58 | |||
| 29e759f793 | |||
| 63f9a9f9d4 | |||
| 850ad2aa15 | |||
| ed7b33d8ab | |||
| 55a52b6cc0 |
@@ -1,4 +1,5 @@
|
|||||||
set(DCHATSERVER_SOURCES
|
set(DCHATSERVER_SOURCES
|
||||||
|
"ChatWebApi.cpp"
|
||||||
"ChatIgnoreList.cpp"
|
"ChatIgnoreList.cpp"
|
||||||
"ChatPacketHandler.cpp"
|
"ChatPacketHandler.cpp"
|
||||||
"PlayerContainer.cpp"
|
"PlayerContainer.cpp"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "eWorldMessageType.h"
|
#include "eWorldMessageType.h"
|
||||||
#include "ChatIgnoreList.h"
|
#include "ChatIgnoreList.h"
|
||||||
#include "StringifiedEnum.h"
|
#include "StringifiedEnum.h"
|
||||||
|
#include "ChatWebApi.h"
|
||||||
|
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
@@ -36,7 +37,7 @@ namespace Game {
|
|||||||
AssetManager* assetManager = nullptr;
|
AssetManager* assetManager = nullptr;
|
||||||
Game::signal_t lastSignal = 0;
|
Game::signal_t lastSignal = 0;
|
||||||
std::mt19937 randomEngine;
|
std::mt19937 randomEngine;
|
||||||
PlayerContainer playerContainer;
|
PlayerContainer playerContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlePacket(Packet* packet);
|
void HandlePacket(Packet* packet);
|
||||||
@@ -122,6 +123,9 @@ int main(int argc, char** argv) {
|
|||||||
uint32_t framesSinceMasterDisconnect = 0;
|
uint32_t framesSinceMasterDisconnect = 0;
|
||||||
uint32_t framesSinceLastSQLPing = 0;
|
uint32_t framesSinceLastSQLPing = 0;
|
||||||
|
|
||||||
|
// start the web api thread
|
||||||
|
std::thread webAPIThread(ChatWebApi::Listen, ourPort);
|
||||||
|
|
||||||
Game::logger->Flush(); // once immediately before main loop
|
Game::logger->Flush(); // once immediately before main loop
|
||||||
while (!Game::ShouldShutdown()) {
|
while (!Game::ShouldShutdown()) {
|
||||||
//Check if we're still connected to master:
|
//Check if we're still connected to master:
|
||||||
@@ -174,6 +178,10 @@ int main(int argc, char** argv) {
|
|||||||
delete Game::server;
|
delete Game::server;
|
||||||
delete Game::logger;
|
delete Game::logger;
|
||||||
delete Game::config;
|
delete Game::config;
|
||||||
|
|
||||||
|
// rejoin the web api thread
|
||||||
|
ChatWebApi::Stop();
|
||||||
|
webAPIThread.join();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
93
dChatServer/ChatWebApi.cpp
Normal file
93
dChatServer/ChatWebApi.cpp
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include "ChatWebApi.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "dCommonVars.h"
|
||||||
|
#include "eConnectionType.h"
|
||||||
|
#include "eChatMessageType.h"
|
||||||
|
#include "httplib.h"
|
||||||
|
#include "dServer.h"
|
||||||
|
#include "PlayerContainer.h"
|
||||||
|
#include "dConfig.h"
|
||||||
|
#include "httplib.h"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
httplib::Server m_APIServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWebApi::Listen(const uint32_t port) {
|
||||||
|
if (Game::config->GetValue("enable_chat_web_api") != "1") {
|
||||||
|
LOG("Chat Web API is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG("Chat Web API is enabled, starting web server...");
|
||||||
|
|
||||||
|
m_APIServer.Post("/announce", [](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
const json data = json::parse(req.body);
|
||||||
|
if (!data.contains("title")) {
|
||||||
|
res.set_content("{\"error\":\"Missing paramater: title\"}", "application/json");
|
||||||
|
res.status = 400;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string title = data["title"];
|
||||||
|
if (!data.contains("message")) {
|
||||||
|
res.set_content("{\"error\":\"Missing paramater: message\"}", "application/json");
|
||||||
|
res.status = 400;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string message = data["message"];
|
||||||
|
// build and send the packet to all world servers
|
||||||
|
CBITSTREAM;
|
||||||
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GM_ANNOUNCE);
|
||||||
|
bitStream.Write<uint32_t>(title.size());
|
||||||
|
bitStream.Write(title);
|
||||||
|
bitStream.Write<uint32_t>(message.size());
|
||||||
|
bitStream.Write(message);
|
||||||
|
Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_APIServer.Get("/players", [](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
auto data = json::array();
|
||||||
|
for (auto& [playerID, playerData ]: Game::playerContainer.GetAllPlayers()){
|
||||||
|
if (!playerData) continue;
|
||||||
|
data.push_back(playerData.to_json());
|
||||||
|
}
|
||||||
|
res.set_content(data.dump(), "application/json");
|
||||||
|
if (data.empty()) res.status = 204;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_APIServer.Get("/teams", [](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
auto data = json::array();
|
||||||
|
for (auto& teamData: Game::playerContainer.GetAllTeams()){
|
||||||
|
if (!teamData) continue;
|
||||||
|
json toInsert;
|
||||||
|
toInsert["id"] = teamData->teamID;
|
||||||
|
toInsert["loot_flag"] = teamData->lootFlag;
|
||||||
|
toInsert["local"] = teamData->local;
|
||||||
|
|
||||||
|
auto& leader = Game::playerContainer.GetPlayerData(teamData->leaderID);
|
||||||
|
toInsert["leader"] = leader.to_json();
|
||||||
|
|
||||||
|
json members;
|
||||||
|
for (auto& member : teamData->memberIDs){
|
||||||
|
auto playerData = Game::playerContainer.GetPlayerData(member);
|
||||||
|
if (!playerData) continue;
|
||||||
|
members.push_back(playerData.to_json());
|
||||||
|
}
|
||||||
|
toInsert["members"] = members;
|
||||||
|
data.push_back(toInsert);
|
||||||
|
}
|
||||||
|
res.set_content(data.dump(), "application/json");
|
||||||
|
if (data.empty()) res.status = 204;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_APIServer.listen(Game::config->GetValue("chat_web_api_listen_address").c_str(), port);
|
||||||
|
};
|
||||||
|
|
||||||
|
void ChatWebApi::Stop(){
|
||||||
|
LOG("Stopping Chat Web API server...");
|
||||||
|
m_APIServer.stop();
|
||||||
|
}
|
||||||
6
dChatServer/ChatWebApi.h
Normal file
6
dChatServer/ChatWebApi.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace ChatWebApi {
|
||||||
|
void Listen(const uint32_t port);
|
||||||
|
void Stop();
|
||||||
|
};
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
#include "PlayerContainer.h"
|
#include "PlayerContainer.h"
|
||||||
#include "dNetCommon.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "dNetCommon.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "ChatPacketHandler.h"
|
#include "ChatPacketHandler.h"
|
||||||
@@ -11,7 +13,24 @@
|
|||||||
#include "eConnectionType.h"
|
#include "eConnectionType.h"
|
||||||
#include "ChatPackets.h"
|
#include "ChatPackets.h"
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
#include "eChatMessageType.h"
|
#include "eChatMessageType.h"
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
const json PlayerData::to_json() const {
|
||||||
|
json data;
|
||||||
|
data["id"] = this->playerID;
|
||||||
|
data["name"] = this->playerName;
|
||||||
|
data["gm_level"] = this->gmLevel;
|
||||||
|
data["muted"] = this->GetIsMuted();
|
||||||
|
|
||||||
|
json zoneID;
|
||||||
|
zoneID["map_id"] = std::to_string(this->zoneID.GetMapID());
|
||||||
|
zoneID["instance_id"] = std::to_string(this->zoneID.GetInstanceID());
|
||||||
|
zoneID["clone_id"] = std::to_string(this->zoneID.GetCloneID());
|
||||||
|
data["zone_id"] = zoneID;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerContainer::Initialize() {
|
void PlayerContainer::Initialize() {
|
||||||
m_MaxNumberOfBestFriends =
|
m_MaxNumberOfBestFriends =
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "dServer.h"
|
#include "dServer.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
enum class eGameMasterLevel : uint8_t;
|
enum class eGameMasterLevel : uint8_t;
|
||||||
|
|
||||||
@@ -36,6 +37,8 @@ struct PlayerData {
|
|||||||
return muteExpire == 1 || muteExpire > time(NULL);
|
return muteExpire == 1 || muteExpire > time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nlohmann::json to_json() const;
|
||||||
|
|
||||||
SystemAddress sysAddr{};
|
SystemAddress sysAddr{};
|
||||||
LWOZONEID zoneID{};
|
LWOZONEID zoneID{};
|
||||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||||
@@ -88,6 +91,7 @@ public:
|
|||||||
LWOOBJID GetId(const std::u16string& playerName);
|
LWOOBJID GetId(const std::u16string& playerName);
|
||||||
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
|
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
|
||||||
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
|
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
|
||||||
|
const std::vector<TeamData*>& GetAllTeams() { return mTeams;};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LWOOBJID m_TeamIDCounter = 0;
|
LWOOBJID m_TeamIDCounter = 0;
|
||||||
|
|||||||
151
docs/ChatWebAPI.yaml
Normal file
151
docs/ChatWebAPI.yaml
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: DLU Chat Server API
|
||||||
|
description: |-
|
||||||
|
This documents the available api endpoints for the DLU Chat Server Web API
|
||||||
|
|
||||||
|
contact:
|
||||||
|
name: DarkflameUniverse Github
|
||||||
|
url: https://github.com/DarkflameUniverse/DarkflameServer/issues
|
||||||
|
license:
|
||||||
|
name: GNU AGPL v3.0
|
||||||
|
url: https://github.com/DarkflameUniverse/DarkflameServer/blob/main/LICENSE
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Swagger
|
||||||
|
url: http://swagger.io
|
||||||
|
|
||||||
|
servers:
|
||||||
|
- url: http://localhost:2005/
|
||||||
|
description: localhost
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- name: management
|
||||||
|
description: Server Management Utilities
|
||||||
|
- name: user
|
||||||
|
description: User Data Utilities
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/announce:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- management
|
||||||
|
summary: Send an announcement to the game server
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Announce"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful operation
|
||||||
|
"400":
|
||||||
|
description: Missing Parameter
|
||||||
|
|
||||||
|
/players:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get all online Players
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Player"
|
||||||
|
"204":
|
||||||
|
description: No Data
|
||||||
|
|
||||||
|
/teams:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get all active Teams
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Team"
|
||||||
|
"204":
|
||||||
|
description: No Data
|
||||||
|
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Player:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 1152921508901824000
|
||||||
|
gm_level:
|
||||||
|
type: integer
|
||||||
|
format: uint8
|
||||||
|
example: 0
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: thisisatestname
|
||||||
|
muted:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
zone_id:
|
||||||
|
$ref: "#/components/schemas/ZoneID"
|
||||||
|
|
||||||
|
ZoneID:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
map_id:
|
||||||
|
type: integer
|
||||||
|
format: uint16
|
||||||
|
example: 1200
|
||||||
|
instance_id:
|
||||||
|
type: integer
|
||||||
|
format: uint16
|
||||||
|
example: 2
|
||||||
|
clone_id:
|
||||||
|
type: integer
|
||||||
|
format: uint32
|
||||||
|
example: 0
|
||||||
|
|
||||||
|
Team:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 1152921508901824000
|
||||||
|
loot_flag:
|
||||||
|
type: integer
|
||||||
|
format: uint8
|
||||||
|
example: 1
|
||||||
|
local:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
leader:
|
||||||
|
$ref: "#/components/schemas/Player"
|
||||||
|
members:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Player"
|
||||||
|
|
||||||
|
Announce:
|
||||||
|
required:
|
||||||
|
- title
|
||||||
|
- message
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
example: A Mythran has taken Action against you!
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: Check your mailbox for details!
|
||||||
@@ -6,3 +6,11 @@ max_number_of_best_friends=5
|
|||||||
# Change the value below to what you would like this to be (50 is live accurate)
|
# Change the value below to what you would like this to be (50 is live accurate)
|
||||||
# going over 50 will be allowed in some secnarios, but proper handling will require client modding
|
# going over 50 will be allowed in some secnarios, but proper handling will require client modding
|
||||||
max_number_of_friends=50
|
max_number_of_friends=50
|
||||||
|
|
||||||
|
# Enable or disable the chat web API, disabled by default
|
||||||
|
# It will run on the same port the chat server is running on, defined in shardconfig.ini
|
||||||
|
enable_chat_web_api=0
|
||||||
|
|
||||||
|
# If that chat web api is enabled, it will only listen for connections on this ip address
|
||||||
|
# 127.0.0.1 is localhost
|
||||||
|
chat_web_api_listen_address=127.0.0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user