mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-17 03:37:08 -06:00
Compare commits
15 Commits
v2.3.0
...
chat-http-
| Author | SHA1 | Date | |
|---|---|---|---|
| 214626222c | |||
| ce5bd68067 | |||
| 9192dca4e6 | |||
| 06607c9b55 | |||
| c3ea448be0 | |||
| ff721ed49b | |||
| bce03ca08d | |||
| faee5b72e7 | |||
| 77143fc2cf | |||
| 5e16c13a58 | |||
| 29e759f793 | |||
| 63f9a9f9d4 | |||
| 850ad2aa15 | |||
| ed7b33d8ab | |||
| 55a52b6cc0 |
@@ -96,6 +96,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
find_package(MariaDB)
|
||||
find_package(JSON)
|
||||
|
||||
# Create a /resServer directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/resServer)
|
||||
@@ -284,7 +285,7 @@ add_subdirectory(dPhysics)
|
||||
add_subdirectory(dServer)
|
||||
|
||||
# Create a list of common libraries shared between all binaries
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "MariaDB::ConnCpp" "magic_enum")
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "MariaDB::ConnCpp" "magic_enum" "nlohmann_json::nlohmann_json")
|
||||
|
||||
# Add platform specific common libraries
|
||||
if(UNIX)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROJECT_VERSION_MAJOR=2
|
||||
PROJECT_VERSION_MINOR=3
|
||||
PROJECT_VERSION_PATCH=0
|
||||
PROJECT_VERSION_MAJOR=1
|
||||
PROJECT_VERSION_MINOR=1
|
||||
PROJECT_VERSION_PATCH=1
|
||||
|
||||
# Debugging
|
||||
# Set DYNAMIC to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
|
||||
|
||||
20
cmake/FindJSON.cmake
Normal file
20
cmake/FindJSON.cmake
Normal file
@@ -0,0 +1,20 @@
|
||||
include(FetchContent)
|
||||
|
||||
message(STATUS "Fetching json...")
|
||||
|
||||
FetchContent_Declare(
|
||||
json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json
|
||||
GIT_TAG v3.11.3
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(json)
|
||||
if(NOT json_POPULATED)
|
||||
FetchContent_Populate(json)
|
||||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
FetchContent_MakeAvailable(json)
|
||||
|
||||
message(STATUS "json fetched and is now ready.")
|
||||
set(JSON_FOUND TRUE)
|
||||
@@ -1,4 +1,5 @@
|
||||
set(DCHATSERVER_SOURCES
|
||||
"ChatWebApi.cpp"
|
||||
"ChatIgnoreList.cpp"
|
||||
"ChatPacketHandler.cpp"
|
||||
"PlayerContainer.cpp"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "eWorldMessageType.h"
|
||||
#include "ChatIgnoreList.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include "ChatWebApi.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "Server.h"
|
||||
@@ -36,7 +37,7 @@ namespace Game {
|
||||
AssetManager* assetManager = nullptr;
|
||||
Game::signal_t lastSignal = 0;
|
||||
std::mt19937 randomEngine;
|
||||
PlayerContainer playerContainer;
|
||||
PlayerContainer playerContainer;
|
||||
}
|
||||
|
||||
void HandlePacket(Packet* packet);
|
||||
@@ -122,6 +123,9 @@ int main(int argc, char** argv) {
|
||||
uint32_t framesSinceMasterDisconnect = 0;
|
||||
uint32_t framesSinceLastSQLPing = 0;
|
||||
|
||||
// start the web api thread
|
||||
std::thread webAPIThread(ChatWebApi::Listen, ourPort);
|
||||
|
||||
Game::logger->Flush(); // once immediately before main loop
|
||||
while (!Game::ShouldShutdown()) {
|
||||
//Check if we're still connected to master:
|
||||
@@ -174,6 +178,10 @@ int main(int argc, char** argv) {
|
||||
delete Game::server;
|
||||
delete Game::logger;
|
||||
delete Game::config;
|
||||
|
||||
// rejoin the web api thread
|
||||
ChatWebApi::Stop();
|
||||
webAPIThread.join();
|
||||
|
||||
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 "dNetCommon.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "dNetCommon.h"
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
#include "ChatPacketHandler.h"
|
||||
@@ -11,7 +13,24 @@
|
||||
#include "eConnectionType.h"
|
||||
#include "ChatPackets.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() {
|
||||
m_MaxNumberOfBestFriends =
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Game.h"
|
||||
#include "dServer.h"
|
||||
#include <unordered_map>
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
enum class eGameMasterLevel : uint8_t;
|
||||
|
||||
@@ -36,6 +37,8 @@ struct PlayerData {
|
||||
return muteExpire == 1 || muteExpire > time(NULL);
|
||||
}
|
||||
|
||||
const nlohmann::json to_json() const;
|
||||
|
||||
SystemAddress sysAddr{};
|
||||
LWOZONEID zoneID{};
|
||||
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||
@@ -88,6 +91,7 @@ public:
|
||||
LWOOBJID GetId(const std::u16string& playerName);
|
||||
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
|
||||
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
|
||||
const std::vector<TeamData*>& GetAllTeams() { return mTeams;};
|
||||
|
||||
private:
|
||||
LWOOBJID m_TeamIDCounter = 0;
|
||||
|
||||
@@ -1840,12 +1840,6 @@ const NiPoint3& Entity::GetPosition() const {
|
||||
return vehicel->GetPosition();
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
return rigidBodyPhantomPhysicsComponent->GetPosition();
|
||||
}
|
||||
|
||||
return NiPoint3Constant::ZERO;
|
||||
}
|
||||
|
||||
@@ -1874,12 +1868,6 @@ const NiQuaternion& Entity::GetRotation() const {
|
||||
return vehicel->GetRotation();
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
return rigidBodyPhantomPhysicsComponent->GetRotation();
|
||||
}
|
||||
|
||||
return NiQuaternionConstant::IDENTITY;
|
||||
}
|
||||
|
||||
@@ -1908,12 +1896,6 @@ void Entity::SetPosition(const NiPoint3& position) {
|
||||
vehicel->SetPosition(position);
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
rigidBodyPhantomPhysicsComponent->SetPosition(position);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(this);
|
||||
}
|
||||
|
||||
@@ -1942,12 +1924,6 @@ void Entity::SetRotation(const NiQuaternion& rotation) {
|
||||
vehicel->SetRotation(rotation);
|
||||
}
|
||||
|
||||
auto* rigidBodyPhantomPhysicsComponent = GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
|
||||
if (rigidBodyPhantomPhysicsComponent != nullptr) {
|
||||
rigidBodyPhantomPhysicsComponent->SetRotation(rotation);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
|
||||
m_Direction = NiPoint3(); // * m_DirectionalMultiplier
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
||||
m_dpEntity = CreatePhysicsLnv(m_Scale, ComponentType);
|
||||
CreatePhysics();
|
||||
}
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"respawnVol")) {
|
||||
@@ -89,9 +89,105 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
|
||||
m_RespawnRot = m_Rotation;
|
||||
}
|
||||
|
||||
if (!m_dpEntity) {
|
||||
m_dpEntity = CreatePhysicsEntity(ComponentType);
|
||||
if (!m_dpEntity) return;
|
||||
/*
|
||||
for (LDFBaseData* data : settings) {
|
||||
if (data) {
|
||||
if (data->GetKey() == u"create_physics") {
|
||||
if (bool(std::stoi(data->GetValueAsString()))) {
|
||||
CreatePhysics(settings);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->GetKey() == u"respawnVol") {
|
||||
if (bool(std::stoi(data->GetValueAsString()))) {
|
||||
m_IsRespawnVolume = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IsRespawnVolume) {
|
||||
if (data->GetKey() == u"rspPos") {
|
||||
//Joy, we get to split strings!
|
||||
std::stringstream test(data->GetValueAsString());
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(test, segment, '\x1f')) {
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
m_RespawnPos = NiPoint3(std::stof(seglist[0]), std::stof(seglist[1]), std::stof(seglist[2]));
|
||||
}
|
||||
|
||||
if (data->GetKey() == u"rspRot") {
|
||||
//Joy, we get to split strings!
|
||||
std::stringstream test(data->GetValueAsString());
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(test, segment, '\x1f')) {
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
m_RespawnRot = NiQuaternion(std::stof(seglist[0]), std::stof(seglist[1]), std::stof(seglist[2]), std::stof(seglist[3]));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Parent->GetLOT() == 4945) // HF - RespawnPoints
|
||||
{
|
||||
m_IsRespawnVolume = true;
|
||||
m_RespawnPos = m_Position;
|
||||
m_RespawnRot = m_Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!m_HasCreatedPhysics) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return;
|
||||
|
||||
auto* info = physComp->GetByID(componentID);
|
||||
if (info == nullptr || info->physicsAsset == "" || info->physicsAsset == "NO_PHYSICS") return;
|
||||
|
||||
//temp test
|
||||
if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
|
||||
// TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem...
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f);
|
||||
|
||||
// Move this down by 13.521004 units so it is still effectively at the same height as before
|
||||
m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f;
|
||||
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
|
||||
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 7.5f;
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 6.0f;
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f);
|
||||
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
|
||||
m_Position.y -= (111.467964f * m_Scale) / 2;
|
||||
} else {
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
|
||||
//add fallback cube:
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
|
||||
}
|
||||
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
@@ -105,6 +201,69 @@ PhantomPhysicsComponent::~PhantomPhysicsComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::CreatePhysics() {
|
||||
unsigned char alpha;
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
int type = -1;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float width = 0.0f; //aka "radius"
|
||||
float height = 0.0f;
|
||||
|
||||
if (m_Parent->HasVar(u"primitiveModelType")) {
|
||||
type = m_Parent->GetVar<int32_t>(u"primitiveModelType");
|
||||
x = m_Parent->GetVar<float>(u"primitiveModelValueX");
|
||||
y = m_Parent->GetVar<float>(u"primitiveModelValueY");
|
||||
z = m_Parent->GetVar<float>(u"primitiveModelValueZ");
|
||||
} else {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return;
|
||||
|
||||
auto info = physComp->GetByID(componentID);
|
||||
|
||||
if (info == nullptr) return;
|
||||
|
||||
type = info->pcShapeType;
|
||||
width = info->playerRadius;
|
||||
height = info->playerHeight;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1: { //Make a new box shape
|
||||
NiPoint3 boxSize(x, y, z);
|
||||
if (x == 0.0f) {
|
||||
//LU has some weird values, so I think it's best to scale them down a bit
|
||||
if (height < 0.5f) height = 2.0f;
|
||||
if (width < 0.5f) width = 2.0f;
|
||||
|
||||
//Scale them:
|
||||
width = width * m_Scale;
|
||||
height = height * m_Scale;
|
||||
|
||||
boxSize = NiPoint3(width, height, width);
|
||||
}
|
||||
|
||||
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), boxSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
m_dpEntity->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
|
||||
|
||||
dpWorld::AddEntity(m_dpEntity);
|
||||
|
||||
m_HasCreatedPhysics = true;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
|
||||
@@ -149,9 +308,8 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
controllablePhysicsComponent->SetGravityScale(effectScale);
|
||||
GameMessages::SendSetGravityScale(target, effectScale, targetEntity->GetSystemAddress());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The other types are not handled by the server
|
||||
case ePhysicsEffectType::ATTRACT:
|
||||
case ePhysicsEffectType::FRICTION:
|
||||
case ePhysicsEffectType::PUSH:
|
||||
@@ -159,7 +317,6 @@ void ApplyCollisionEffect(const LWOOBJID& target, const ePhysicsEffectType effec
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// The other types are not handled by the server and are here to handle all cases of the enum.
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Update(float deltaTime) {
|
||||
@@ -199,12 +356,24 @@ void PhantomPhysicsComponent::SetDirection(const NiPoint3& pos) {
|
||||
m_IsDirectional = true;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::SpawnVertices() const {
|
||||
if (!m_dpEntity) {
|
||||
LOG("No dpEntity to spawn vertices for %llu:%i", m_Parent->GetObjectID(), m_Parent->GetLOT());
|
||||
return;
|
||||
void PhantomPhysicsComponent::SpawnVertices() {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
LOG("%llu", m_Parent->GetObjectID());
|
||||
auto box = static_cast<dpShapeBox*>(m_dpEntity->GetShape());
|
||||
for (auto vert : box->GetVertices()) {
|
||||
LOG("%f, %f, %f", vert.x, vert.y, vert.z);
|
||||
|
||||
EntityInfo info;
|
||||
info.lot = 33;
|
||||
info.pos = vert;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
PhysicsComponent::SpawnVertices(m_dpEntity);
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) {
|
||||
|
||||
@@ -18,7 +18,6 @@ class LDFBaseData;
|
||||
class Entity;
|
||||
class dpEntity;
|
||||
enum class ePhysicsEffectType : uint32_t ;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
/**
|
||||
* Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be
|
||||
@@ -35,6 +34,11 @@ public:
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Creates the physics shape for this entity based on LDF data
|
||||
*/
|
||||
void CreatePhysics();
|
||||
|
||||
/**
|
||||
* Sets the direction this physics object is pointed at
|
||||
* @param pos the direction to set
|
||||
@@ -105,7 +109,7 @@ public:
|
||||
/**
|
||||
* Spawns an object at each of the vertices for debugging purposes
|
||||
*/
|
||||
void SpawnVertices() const;
|
||||
void SpawnVertices();
|
||||
|
||||
/**
|
||||
* Legacy stuff no clue what this does
|
||||
@@ -162,6 +166,11 @@ private:
|
||||
*/
|
||||
dpEntity* m_dpEntity;
|
||||
|
||||
/**
|
||||
* Whether or not the physics object has been created yet
|
||||
*/
|
||||
bool m_HasCreatedPhysics = false;
|
||||
|
||||
/**
|
||||
* Whether or not this physics object represents an object that updates the respawn pos of an entity that crosses it
|
||||
*/
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
#include "PhysicsComponent.h"
|
||||
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
|
||||
#include "dpEntity.h"
|
||||
#include "dpWorld.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
|
||||
#include "EntityInfo.h"
|
||||
|
||||
PhysicsComponent::PhysicsComponent(Entity* parent) : Component(parent) {
|
||||
m_Position = NiPoint3Constant::ZERO;
|
||||
m_Rotation = NiQuaternionConstant::IDENTITY;
|
||||
@@ -33,190 +19,3 @@ void PhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitia
|
||||
if (!bIsInitialUpdate) m_DirtyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
dpEntity* PhysicsComponent::CreatePhysicsEntity(eReplicaComponentType type) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), type);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return nullptr;
|
||||
|
||||
auto* info = physComp->GetByID(componentID);
|
||||
if (info == nullptr || info->physicsAsset == "" || info->physicsAsset == "NO_PHYSICS") return nullptr;
|
||||
|
||||
dpEntity* toReturn;
|
||||
if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
|
||||
// TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem...
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f);
|
||||
|
||||
// Move this down by 13.521004 units so it is still effectively at the same height as before
|
||||
m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f;
|
||||
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
|
||||
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
|
||||
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 7.5f;
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
|
||||
m_Position += m_Rotation.GetForwardVector() * 6.0f;
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 4.5f);
|
||||
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
|
||||
m_Position.y -= (111.467964f * m_Parent->GetDefaultScale()) / 2;
|
||||
} else {
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
|
||||
//add fallback cube:
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
dpEntity* PhysicsComponent::CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const {
|
||||
int pcShapeType = -1;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float width = 0.0f; //aka "radius"
|
||||
float height = 0.0f;
|
||||
dpEntity* toReturn = nullptr;
|
||||
|
||||
if (m_Parent->HasVar(u"primitiveModelType")) {
|
||||
pcShapeType = m_Parent->GetVar<int32_t>(u"primitiveModelType");
|
||||
x = m_Parent->GetVar<float>(u"primitiveModelValueX");
|
||||
y = m_Parent->GetVar<float>(u"primitiveModelValueY");
|
||||
z = m_Parent->GetVar<float>(u"primitiveModelValueZ");
|
||||
} else {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), type);
|
||||
|
||||
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
|
||||
if (physComp == nullptr) return nullptr;
|
||||
|
||||
auto info = physComp->GetByID(componentID);
|
||||
|
||||
if (info == nullptr) return nullptr;
|
||||
|
||||
pcShapeType = info->pcShapeType;
|
||||
width = info->playerRadius;
|
||||
height = info->playerHeight;
|
||||
}
|
||||
|
||||
switch (pcShapeType) {
|
||||
case 0: { // HKX type
|
||||
break;
|
||||
}
|
||||
case 1: { //Make a new box shape
|
||||
NiPoint3 boxSize(x, y, z);
|
||||
if (x == 0.0f) {
|
||||
//LU has some weird values, so I think it's best to scale them down a bit
|
||||
if (height < 0.5f) height = 2.0f;
|
||||
if (width < 0.5f) width = 2.0f;
|
||||
|
||||
//Scale them:
|
||||
width = width * scale;
|
||||
height = height * scale;
|
||||
|
||||
boxSize = NiPoint3(width, height, width);
|
||||
}
|
||||
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), boxSize);
|
||||
|
||||
toReturn->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
|
||||
break;
|
||||
}
|
||||
case 2: { //Make a new cylinder shape
|
||||
break;
|
||||
}
|
||||
case 3: { //Make a new sphere shape
|
||||
auto [x, y, z] = m_Position;
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), width);
|
||||
toReturn->SetPosition({ x, y, z });
|
||||
break;
|
||||
}
|
||||
case 4: { //Make a new capsule shape
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (toReturn) dpWorld::AddEntity(toReturn);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void PhysicsComponent::SpawnVertices(dpEntity* entity) const {
|
||||
if (!entity) return;
|
||||
|
||||
LOG("Spawning vertices for %llu", m_Parent->GetObjectID());
|
||||
EntityInfo info;
|
||||
info.lot = 33;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
// These don't use overloaded methods as dPhysics does not link with dGame at the moment.
|
||||
auto box = dynamic_cast<dpShapeBox*>(entity->GetShape());
|
||||
if (box) {
|
||||
for (auto vert : box->GetVertices()) {
|
||||
LOG("Vertex at %f, %f, %f", vert.x, vert.y, vert.z);
|
||||
|
||||
info.pos = vert;
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
auto sphere = dynamic_cast<dpShapeSphere*>(entity->GetShape());
|
||||
if (sphere) {
|
||||
auto [x, y, z] = entity->GetPosition(); // Use shapes position instead of the parent's position in case it's different
|
||||
float plusX = x + sphere->GetRadius();
|
||||
float minusX = x - sphere->GetRadius();
|
||||
float plusY = y + sphere->GetRadius();
|
||||
float minusY = y - sphere->GetRadius();
|
||||
float plusZ = z + sphere->GetRadius();
|
||||
float minusZ = z - sphere->GetRadius();
|
||||
|
||||
auto radius = sphere->GetRadius();
|
||||
LOG("Radius: %f", radius);
|
||||
LOG("Plus Vertices %f %f %f", plusX, plusY, plusZ);
|
||||
LOG("Minus Vertices %f %f %f", minusX, minusY, minusZ);
|
||||
|
||||
info.pos = NiPoint3{ x, plusY, z };
|
||||
Entity* newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, minusY, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ plusX, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ minusX, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, plusZ };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, minusZ };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
|
||||
info.pos = NiPoint3{ x, y, z };
|
||||
newEntity = Game::entityManager->CreateEntity(info);
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,6 @@ namespace Raknet {
|
||||
class BitStream;
|
||||
};
|
||||
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
class dpEntity;
|
||||
|
||||
class PhysicsComponent : public Component {
|
||||
public:
|
||||
PhysicsComponent(Entity* parent);
|
||||
@@ -26,12 +22,6 @@ public:
|
||||
const NiQuaternion& GetRotation() const { return m_Rotation; }
|
||||
virtual void SetRotation(const NiQuaternion& rot) { if (m_Rotation == rot) return; m_Rotation = rot; m_DirtyPosition = true; }
|
||||
protected:
|
||||
dpEntity* CreatePhysicsEntity(eReplicaComponentType type);
|
||||
|
||||
dpEntity* CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const;
|
||||
|
||||
void SpawnVertices(dpEntity* entity) const;
|
||||
|
||||
NiPoint3 m_Position;
|
||||
|
||||
NiQuaternion m_Rotation;
|
||||
|
||||
@@ -817,10 +817,8 @@ void RacingControlComponent::Update(float deltaTime) {
|
||||
|
||||
// Some offset up to make they don't fall through the terrain on a
|
||||
// respawn, seems to fix itself to the track anyhow
|
||||
if (waypoint.racing.isResetNode) {
|
||||
player.respawnPosition = position + NiPoint3Constant::UNIT_Y * 5;
|
||||
player.respawnRotation = vehicle->GetRotation();
|
||||
}
|
||||
player.respawnPosition = position + NiPoint3Constant::UNIT_Y * 5;
|
||||
player.respawnRotation = vehicle->GetRotation();
|
||||
player.respawnIndex = respawnIndex;
|
||||
|
||||
// Reached the start point, lapped
|
||||
|
||||
@@ -1,57 +1,16 @@
|
||||
// Darkflame Universe
|
||||
// Copyright 2024
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
*/
|
||||
|
||||
#include "RigidbodyPhantomPhysicsComponent.h"
|
||||
#include "Entity.h"
|
||||
|
||||
#include "dpEntity.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
#include "dpWorld.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
#include"EntityInfo.h"
|
||||
|
||||
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
m_Scale = m_Parent->GetDefaultScale();
|
||||
|
||||
if (m_Parent->GetVar<bool>(u"create_physics")) {
|
||||
m_dpEntity = CreatePhysicsLnv(m_Scale, ComponentType);
|
||||
if (!m_dpEntity) {
|
||||
m_dpEntity = CreatePhysicsEntity(ComponentType);
|
||||
if (!m_dpEntity) return;
|
||||
m_dpEntity->SetScale(m_Scale);
|
||||
m_dpEntity->SetRotation(m_Rotation);
|
||||
m_dpEntity->SetPosition(m_Position);
|
||||
dpWorld::AddEntity(m_dpEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Update(const float deltaTime) {
|
||||
if (!m_dpEntity) return;
|
||||
|
||||
//Process enter events
|
||||
for (const auto id : m_dpEntity->GetNewObjects()) {
|
||||
m_Parent->OnCollisionPhantom(id);
|
||||
}
|
||||
|
||||
//Process exit events
|
||||
for (const auto id : m_dpEntity->GetRemovedObjects()) {
|
||||
m_Parent->OnCollisionLeavePhantom(id);
|
||||
}
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::SpawnVertices() const {
|
||||
if (!m_dpEntity) {
|
||||
LOG("No dpEntity to spawn vertices for %llu:%i", m_Parent->GetObjectID(), m_Parent->GetLOT());
|
||||
return;
|
||||
}
|
||||
PhysicsComponent::SpawnVertices(m_dpEntity);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Darkflame Universe
|
||||
// Copyright 2024
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2023
|
||||
*/
|
||||
|
||||
#ifndef RIGIDBODYPHANTOMPHYSICS_H
|
||||
#define RIGIDBODYPHANTOMPHYSICS_H
|
||||
#ifndef __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
#define __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "dCommonVars.h"
|
||||
@@ -11,8 +13,6 @@
|
||||
#include "PhysicsComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
class dpEntity;
|
||||
|
||||
/**
|
||||
* Component that handles rigid bodies that can be interacted with, mostly client-side rendered. An example is the
|
||||
* bananas that fall from trees in GF.
|
||||
@@ -23,15 +23,7 @@ public:
|
||||
|
||||
RigidbodyPhantomPhysicsComponent(Entity* parent);
|
||||
|
||||
void Update(const float deltaTime) override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void SpawnVertices() const;
|
||||
private:
|
||||
float m_Scale{};
|
||||
|
||||
dpEntity* m_dpEntity{};
|
||||
};
|
||||
|
||||
#endif // RIGIDBODYPHANTOMPHYSICS_H
|
||||
#endif // __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
|
||||
@@ -369,8 +369,8 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd
|
||||
|
||||
const auto lot = entity->GetLOT();
|
||||
|
||||
if (lot == 12341 || lot == 5027 || lot == 5028 || lot == 14335 || lot == 14447 || lot == 14449 || lot == 11306 || lot == 11308) {
|
||||
iDesiredWaypointIndex = (lot == 11306 || lot == 11308) ? 1 : 0;
|
||||
if (lot == 12341 || lot == 5027 || lot == 5028 || lot == 14335 || lot == 14447 || lot == 14449) {
|
||||
iDesiredWaypointIndex = 0;
|
||||
iIndex = 0;
|
||||
nextIndex = 0;
|
||||
bStopAtDesiredWaypoint = true;
|
||||
|
||||
@@ -130,6 +130,12 @@ bool CheatDetection::VerifyLwoobjidIsSender(const LWOOBJID& id, const SystemAddr
|
||||
|
||||
// This will be true if the player does not possess the entity they are trying to send a packet as.
|
||||
// or if the user does not own the character they are trying to send a packet as.
|
||||
if (invalidPacket) {
|
||||
va_list args;
|
||||
va_start(args, messageIfNotSender);
|
||||
LogAndSaveFailedAntiCheatCheck(id, sysAddr, checkType, messageIfNotSender, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return !invalidPacket;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "ScriptedActivityComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "TriggerComponent.h"
|
||||
#include "RigidbodyPhantomPhysicsComponent.h"
|
||||
|
||||
// Enums
|
||||
#include "eGameMasterLevel.h"
|
||||
@@ -1130,13 +1129,8 @@ namespace DEVGMCommands {
|
||||
void SpawnPhysicsVerts(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||
//Go tell physics to spawn all the vertices:
|
||||
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS);
|
||||
for (const auto* en : entities) {
|
||||
const auto* phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
|
||||
if (phys)
|
||||
phys->SpawnVertices();
|
||||
}
|
||||
for (const auto* en : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS)) {
|
||||
const auto* phys = en->GetComponent<RigidbodyPhantomPhysicsComponent>();
|
||||
for (auto en : entities) {
|
||||
auto phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS));
|
||||
if (phys)
|
||||
phys->SpawnVertices();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c
|
||||
if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth);
|
||||
else if (serverType == ServerType::World) bitStream.Write(ServiceId::World);
|
||||
else bitStream.Write(ServiceId::General);
|
||||
bitStream.Write<uint64_t>(215523470896);
|
||||
bitStream.Write<uint64_t>(215523405360);
|
||||
|
||||
server->Send(bitStream, sysAddr, false);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_FV_RACING
|
||||
"RaceFireballs.cpp"
|
||||
"RaceMaelstromGeiser.cpp"
|
||||
"RaceShipLapColumnsServer.cpp"
|
||||
"FvRacingColumns.cpp"
|
||||
PARENT_SCOPE)
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "FvRacingColumns.h"
|
||||
#include "MovingPlatformComponent.h"
|
||||
|
||||
void FvRacingColumns::OnStartup(Entity* self) {
|
||||
auto* movingPlatformComponent = self->GetComponent<MovingPlatformComponent>();
|
||||
if (!movingPlatformComponent) return;
|
||||
|
||||
movingPlatformComponent->StopPathing();
|
||||
movingPlatformComponent->SetSerialized(true);
|
||||
int32_t pathStart = 0;
|
||||
if (self->HasVar(u"attached_path_start")) {
|
||||
pathStart = self->GetVar<uint32_t>(u"attached_path_start");
|
||||
}
|
||||
movingPlatformComponent->WarpToWaypoint(pathStart);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvRacingColumns : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "RaceFireballs.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void RaceFireballs::OnStartup(Entity* self) {
|
||||
self->AddTimer("fire", GeneralUtils::GenerateRandomNumber<float>(3.0f, 10.0f));
|
||||
}
|
||||
|
||||
void RaceFireballs::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "fire") {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
if (skillComponent) skillComponent->CastSkill(894);
|
||||
self->AddTimer("fire", GeneralUtils::GenerateRandomNumber<float>(3.0f, 10.0f));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class RaceFireballs : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
#include "RaceShipLapColumnsServer.h"
|
||||
|
||||
#include "RacingControlComponent.h"
|
||||
#include "MovingPlatformComponent.h"
|
||||
|
||||
void RaceShipLapColumnsServer::OnStartup(Entity* self) {
|
||||
self->SetVar(u"Lap2Complete", false);
|
||||
self->SetVar(u"Lap3Complete", false);
|
||||
}
|
||||
|
||||
void SetMovingToWaypoint(const int32_t waypointIndex, const std::string group) {
|
||||
const auto entities = Game::entityManager->GetEntitiesInGroup(group);
|
||||
if (entities.empty()) return;
|
||||
|
||||
auto* entity = entities[0];
|
||||
entity->SetIsGhostingCandidate(false);
|
||||
|
||||
auto* movingPlatfromComponent = entity->GetComponent<MovingPlatformComponent>();
|
||||
if (!movingPlatfromComponent) return;
|
||||
|
||||
movingPlatfromComponent->SetSerialized(true);
|
||||
movingPlatfromComponent->GotoWaypoint(waypointIndex);
|
||||
Game::entityManager->SerializeEntity(entity);
|
||||
}
|
||||
|
||||
void RaceShipLapColumnsServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target) return;
|
||||
|
||||
const auto racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
|
||||
if (racingControllers.empty()) return;
|
||||
|
||||
auto* racingControlComponent = racingControllers[0]->GetComponent<RacingControlComponent>();
|
||||
if (!racingControlComponent) return;
|
||||
|
||||
const auto* player = racingControlComponent->GetPlayerData(target->GetObjectID());
|
||||
if (!player) return;
|
||||
|
||||
if (player->lap == 1 && !self->GetVar<bool>(u"Lap2Complete")) {
|
||||
self->SetVar(u"Lap2Complete", true);
|
||||
SetMovingToWaypoint(1, "Lap2Column");
|
||||
SetMovingToWaypoint(0, "Lap2Ramp");
|
||||
} else if (player->lap == 2 && !self->GetVar<bool>(u"Lap3Complete")) {
|
||||
self->SetVar(u"Lap3Complete", true);
|
||||
SetMovingToWaypoint(1, "Lap3Column");
|
||||
SetMovingToWaypoint(0, "Lap3Ramp");
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class RaceShipLapColumnsServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
};
|
||||
@@ -154,11 +154,6 @@
|
||||
#include "FvBounceOverWall.h"
|
||||
#include "FvFong.h"
|
||||
#include "FvMaelstromGeyser.h"
|
||||
#include "FvRaceDragon.h"
|
||||
#include "FvRacePillarABCServer.h"
|
||||
#include "FvRacePillarDServer.h"
|
||||
#include "RaceFireballs.h"
|
||||
#include "RaceShipLapColumnsServer.h"
|
||||
|
||||
// FB Scripts
|
||||
#include "AgJetEffectServer.h"
|
||||
@@ -184,7 +179,6 @@
|
||||
#include "RaceMaelstromGeiser.h"
|
||||
#include "FvRaceSmashEggImagineServer.h"
|
||||
#include "RaceSmashServer.h"
|
||||
#include "FvRacingColumns.h"
|
||||
|
||||
// NT Scripts
|
||||
#include "NtSentinelWalkwayServer.h"
|
||||
@@ -628,25 +622,9 @@ CppScripts::Script* const CppScripts::GetScript(Entity* parent, const std::strin
|
||||
script = new FvBounceOverWall();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\FV\\L_NPC_FONG.lua")
|
||||
script = new FvFong();
|
||||
else if (scriptName == "scripts\\ai\\FV\\L_FV_MAELSTROM_GEYSER.lua")
|
||||
else if (scriptName == "scripts\\ai\\FV\\L_FV_MAELSTROM_GEYSER.lua") {
|
||||
script = new FvMaelstromGeyser();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\FV\\Racing\\RACE_SHIP_LAP_COLUMNS_SERVER.lua")
|
||||
script = new RaceShipLapColumnsServer();
|
||||
|
||||
// yes we know the lap numbers dont match the file name or anim. thats what they desgined it as.
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_DRAGON_LAP1_SERVER.lua")
|
||||
script = new FvRaceDragon("lap_01", 2);
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_DRAGON_LAP2_SERVER.lua")
|
||||
script = new FvRaceDragon("lap_02", 0);
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_DRAGON_LAP3_SERVER.lua")
|
||||
script = new FvRaceDragon("lap_03", 1);
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_PILLAR_ABC_SERVER.lua")
|
||||
script = new FvRacePillarABCServer();
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_PILLAR_D_SERVER.lua")
|
||||
script = new FvRacePillarDServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\FV\\Racing\\RACE_FIREBALLS.lua")
|
||||
script = new RaceFireballs();
|
||||
|
||||
}
|
||||
|
||||
//Misc:
|
||||
if (scriptName == "scripts\\02_server\\Map\\General\\L_EXPLODING_ASSET.lua")
|
||||
@@ -683,8 +661,6 @@ CppScripts::Script* const CppScripts::GetScript(Entity* parent, const std::strin
|
||||
script = new RaceMaelstromGeiser();
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\FV_RACE_SMASH_EGG_IMAGINE_SERVER.lua")
|
||||
script = new FvRaceSmashEggImagineServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\FV\\Racing\\FV_RACING_COLUMNS.lua")
|
||||
script = new FvRacingColumns();
|
||||
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\RACE_SMASH_SERVER.lua")
|
||||
script = new RaceSmashServer();
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
set(DSCRIPTS_SOURCES_AI_RACING_OBJECTS
|
||||
"RaceImagineCrateServer.cpp"
|
||||
"RaceImaginePowerup.cpp"
|
||||
"FvRaceDragon.cpp"
|
||||
"FvRacePillarServer.cpp"
|
||||
"FvRacePillarABCServer.cpp"
|
||||
"FvRacePillarDServer.cpp"
|
||||
"FvRaceSmashEggImagineServer.cpp"
|
||||
"RaceSmashServer.cpp"
|
||||
PARENT_SCOPE)
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#include "FvRaceDragon.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "RacingControlComponent.h"
|
||||
|
||||
void FvRaceDragon::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target) return;
|
||||
|
||||
const auto racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
|
||||
if (racingControllers.empty()) return;
|
||||
|
||||
auto* racingControlComponent = racingControllers[0]->GetComponent<RacingControlComponent>();
|
||||
if (!racingControlComponent) return;
|
||||
|
||||
const auto* player = racingControlComponent->GetPlayerData(target->GetObjectID());
|
||||
if (!player) return;
|
||||
|
||||
if (player->lap != m_Lap) return;
|
||||
|
||||
const auto dragons = Game::entityManager->GetEntitiesInGroup("dragon");
|
||||
for (const auto& dragon : dragons) {
|
||||
if (!dragon || dragon->GetLOT() != this->m_Dragon) continue;
|
||||
|
||||
auto* renderComponent = dragon->GetComponent<RenderComponent>();
|
||||
if (!renderComponent) continue;
|
||||
|
||||
renderComponent->PlayAnimation(dragon, m_LapAnimName);
|
||||
|
||||
}
|
||||
Game::entityManager->DestroyEntity(self);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class FvRaceDragon : public CppScripts::Script {
|
||||
public:
|
||||
FvRaceDragon(const std::string_view lapAnimName, const int32_t lap) : m_LapAnimName(lapAnimName), m_Lap(lap) {}
|
||||
private:
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
const std::string m_LapAnimName;
|
||||
const int32_t m_Lap;
|
||||
const LOT m_Dragon = 11898;
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
#include "FvRacePillarABCServer.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "RacingControlComponent.h"
|
||||
|
||||
void FvRacePillarABCServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target) return;
|
||||
|
||||
const auto racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
|
||||
if (racingControllers.empty()) return;
|
||||
|
||||
auto* racingControlComponent = racingControllers[0]->GetComponent<RacingControlComponent>();
|
||||
if (!racingControlComponent) return;
|
||||
|
||||
const auto* player = racingControlComponent->GetPlayerData(target->GetObjectID());
|
||||
if (!player || player->lap != 1) return;
|
||||
|
||||
PlayAnimation("crumble", "pillars", m_PillarA);
|
||||
PlayAnimation("roar", "dragon", m_Dragon);
|
||||
|
||||
self->AddTimer("PillarBFall", 2.5f);
|
||||
self->AddTimer("PillarCFall", 3.7f);
|
||||
self->AddTimer("DeleteObject", 3.8f);
|
||||
}
|
||||
|
||||
void FvRacePillarABCServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "PillarBFall") {
|
||||
PlayAnimation("crumble", "pillars", m_PillarB);
|
||||
} else if (timerName == "PillarCFall") {
|
||||
PlayAnimation("crumble", "pillars", m_PillarC);
|
||||
} else if (timerName == "DeleteObject") {
|
||||
Game::entityManager->DestroyEntity(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
#include "FvRacePillarServer.h"
|
||||
|
||||
class FvRacePillarABCServer : public FvRacePillarServer {
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
private:
|
||||
const LOT m_PillarA = 11946;
|
||||
const LOT m_PillarB = 11947;
|
||||
const LOT m_PillarC = 11948;
|
||||
const LOT m_Dragon = 11898;
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "FvRacePillarDServer.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "RacingControlComponent.h"
|
||||
|
||||
void FvRacePillarDServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target) return;
|
||||
|
||||
const auto racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
|
||||
if (racingControllers.empty()) return;
|
||||
|
||||
auto* racingControlComponent = racingControllers[0]->GetComponent<RacingControlComponent>();
|
||||
if (!racingControlComponent) return;
|
||||
|
||||
const auto* player = racingControlComponent->GetPlayerData(target->GetObjectID());
|
||||
if (!player) return;
|
||||
|
||||
if (player->lap == 2) {
|
||||
PlayAnimation("crumble", "pillars", m_PillarD);
|
||||
PlayAnimation("roar", "dragon", m_Dragon);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
#include "FvRacePillarServer.h"
|
||||
|
||||
class FvRacePillarDServer : public FvRacePillarServer {
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
private:
|
||||
const LOT m_PillarD = 11949;
|
||||
const LOT m_Dragon = 11898;
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "FvRacePillarServer.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "EntityManager.h"
|
||||
#include "RenderComponent.h"
|
||||
|
||||
void FvRacePillarServer::PlayAnimation(const std::string animName, const std::string group, const LOT lot) {
|
||||
const auto entities = Game::entityManager->GetEntitiesInGroup(group);
|
||||
for (const auto& entity : entities) {
|
||||
if (!entity || entity->GetLOT() != lot) continue;
|
||||
auto* renderComponent = entity->GetComponent<RenderComponent>();
|
||||
if (!renderComponent) continue;
|
||||
renderComponent->PlayAnimation(entity, animName);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef FVRACEPILLARSERVER__H
|
||||
#define FVRACEPILLARSERVER__H
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvRacePillarServer : public virtual CppScripts::Script {
|
||||
protected:
|
||||
// Plays an animation on all entities in a group with a specific LOT
|
||||
void PlayAnimation(const std::string animName, const std::string group, const LOT lot);
|
||||
};
|
||||
|
||||
#endif // FVRACEPILLARSERVER__H
|
||||
@@ -282,22 +282,24 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
const int32_t bufferSize = 1024;
|
||||
MD5 md5;
|
||||
MD5* md5 = new MD5();
|
||||
|
||||
char fileStreamBuffer[1024] = {};
|
||||
|
||||
while (!fileStream.eof()) {
|
||||
memset(fileStreamBuffer, 0, bufferSize);
|
||||
fileStream.read(fileStreamBuffer, bufferSize);
|
||||
md5.update(fileStreamBuffer, fileStream.gcount());
|
||||
md5->update(fileStreamBuffer, fileStream.gcount());
|
||||
}
|
||||
|
||||
fileStream.close();
|
||||
|
||||
const char* nullTerminateBuffer = "\0";
|
||||
md5.update(nullTerminateBuffer, 1); // null terminate the data
|
||||
md5.finalize();
|
||||
databaseChecksum = md5.hexdigest();
|
||||
md5->update(nullTerminateBuffer, 1); // null terminate the data
|
||||
md5->finalize();
|
||||
databaseChecksum = md5->hexdigest();
|
||||
|
||||
delete md5;
|
||||
|
||||
LOG("FDB Checksum calculated as: %s", databaseChecksum.c_str());
|
||||
}
|
||||
@@ -386,14 +388,14 @@ int main(int argc, char** argv) {
|
||||
//In world we'd update our other systems here.
|
||||
|
||||
if (zoneID != 0 && deltaTime > 0.0f) {
|
||||
Metrics::StartMeasurement(MetricVariable::UpdateEntities);
|
||||
Game::entityManager->UpdateEntities(deltaTime);
|
||||
Metrics::EndMeasurement(MetricVariable::UpdateEntities);
|
||||
|
||||
Metrics::StartMeasurement(MetricVariable::Physics);
|
||||
dpWorld::StepWorld(deltaTime);
|
||||
Metrics::EndMeasurement(MetricVariable::Physics);
|
||||
|
||||
Metrics::StartMeasurement(MetricVariable::UpdateEntities);
|
||||
Game::entityManager->UpdateEntities(deltaTime);
|
||||
Metrics::EndMeasurement(MetricVariable::UpdateEntities);
|
||||
|
||||
Metrics::StartMeasurement(MetricVariable::Ghosting);
|
||||
if (std::chrono::duration<float>(currentTime - ghostingLastTime).count() >= 1.0f) {
|
||||
Game::entityManager->UpdateGhosting();
|
||||
|
||||
@@ -7,7 +7,7 @@ services:
|
||||
- darkflame
|
||||
image: mariadb:latest
|
||||
volumes:
|
||||
- ${DB_DATA_DIR:-db-data}:/var/lib/mysql
|
||||
- ${DB_DATA_DIR:-./db/data}:/var/lib/mysql
|
||||
environment:
|
||||
- MARIADB_RANDOM_ROOT_PASSWORD=1
|
||||
- MARIADB_USER=${MARIADB_USER:-darkflame}
|
||||
@@ -79,6 +79,3 @@ services:
|
||||
|
||||
networks:
|
||||
darkflame:
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
|
||||
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)
|
||||
# going over 50 will be allowed in some secnarios, but proper handling will require client modding
|
||||
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
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
2.3 - Dragonmaw functional, new slash command system, vanity system overhaul
|
||||
2.2 - Code cleanup and QoL fixes
|
||||
2.1 - Bug and crash fixes
|
||||
2.0 - Whole lot of fixed bugs and implemented features
|
||||
1.0 - Final cleanup and bug fixing for public release
|
||||
0.9 - Includes BBB without the need for a UGC server, cannon cove minigame, and bug fixes.
|
||||
0.8 - Added Ninjago! and it's various features + frakjaw minigame. AG survival now works.
|
||||
@@ -11,4 +7,4 @@
|
||||
0.4 - Added Havok to replace Bullet, Instancing, Quickbuilds, rockets, and a ton more fixes and additions.
|
||||
0.3 - FrostBurgh, Snowdrift and Snowman's Land testing version. Includes bodged systems.
|
||||
0.2 - Transfer to VS2019 & Bullet
|
||||
0.1 - Initial transfer from NixLU, up until BehaviorManager inclusion
|
||||
0.1 - Initial transfer from NixLU, up until BehaviorManager inclusion
|
||||
Reference in New Issue
Block a user