From fdd4e3cc8052d2a99b77d19e110575508fb14534 Mon Sep 17 00:00:00 2001 From: Stefan Heinz <31664665+StefanH-AT@users.noreply.github.com> Date: Wed, 8 Dec 2021 18:22:05 +0100 Subject: [PATCH 01/16] Add note to readme for troubleshooting tips with script editing --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c8afb9f0..f3cb6cd7 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,8 @@ The client script for the survival minigame has a bug in it which can cause the * Change `PlayerReady(self)` to `onPlayerReady(self)` * Save the file, overriding readonly mode if required +If you still experience the bug, try deleting/renaming `res/pack/scripts.pak`. + ### Brick-By-Brick building Brick-By-Brick building requires `PATCHSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be achieved by pointing it to `localhost` while having `sudo python -m http.server 80` running in the background. From bd609dfc905dbf094b611a7ee7fc0a2d5e660482 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Thu, 9 Dec 2021 13:09:12 +0000 Subject: [PATCH 02/16] Add ship shake to not log about being missing This log was causing confusion and issues when in reality there was no problem present. --- dScripts/CppScripts.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 99702805..cca8a728 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -781,6 +781,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = invalidToReturn; else if (scriptName == "scripts\\02_server\\Enemy\\General\\L_BASE_ENEMY_SPIDERLING.lua") script = invalidToReturn; + else if (scriptName == "scripts\\ai\\AG\\L_AG_SHIP_SHAKE.lua") + script = invalidToReturn; //Set ship shake to not log it is missing, it is implemented in AgSpaceStuff else if (script == invalidToReturn) { if (scriptName.length() > 0) Game::logger->Log("CppScripts", "Attempted to load CppScript for '" + scriptName + "', but returned InvalidScript.\n"); From e4de42659eb0859e87b0eec1244740eac45b8cff Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Thu, 9 Dec 2021 13:56:07 +0000 Subject: [PATCH 03/16] Update Entity.cpp --- dGame/Entity.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c98323a9..4b8aadb8 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -775,6 +775,15 @@ void Entity::Initialize() TriggerEvent("OnCreate"); + // so basically unless you leave and reenter the moonbase bubble (not something you can do), the physics effect will not trigger on the client + // one solution of this was change the OnEnter event to a OnCreate event + // but this required changing client files so instead that solution we can bodge + if (m_Trigger && Game::server->GetZoneID() == 1603) { + if (m_Trigger->id == 11) { + TriggerEvent("OnEnter"); + } + } + if (m_Character) { auto* controllablePhysicsComponent = GetComponent(); auto* characterComponent = GetComponent(); From a9dc0e0daccebb6fba283df0fb8f0f25803f85eb Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Thu, 9 Dec 2021 21:06:01 +0000 Subject: [PATCH 04/16] to improve (broken) --- dGame/Entity.cpp | 9 --------- dGame/dComponents/ControllablePhysicsComponent.cpp | 12 ++++++++++++ dGame/dComponents/ControllablePhysicsComponent.h | 9 +++++++++ dGame/dComponents/PhantomPhysicsComponent.h | 7 +++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 4b8aadb8..c98323a9 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -775,15 +775,6 @@ void Entity::Initialize() TriggerEvent("OnCreate"); - // so basically unless you leave and reenter the moonbase bubble (not something you can do), the physics effect will not trigger on the client - // one solution of this was change the OnEnter event to a OnCreate event - // but this required changing client files so instead that solution we can bodge - if (m_Trigger && Game::server->GetZoneID() == 1603) { - if (m_Trigger->id == 11) { - TriggerEvent("OnEnter"); - } - } - if (m_Character) { auto* controllablePhysicsComponent = GetComponent(); auto* characterComponent = GetComponent(); diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 922ae55d..7fe19acc 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -40,6 +40,18 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com m_dpEntity = new dpEntity(m_Parent->GetObjectID(), radius, false); m_dpEntity->SetCollisionGroup(COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_FRIENDLY); dpWorld::Instance().AddEntity(m_dpEntity); + + auto triggers = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PHANTOM_PHYSICS); + + for (auto* trigger : triggers) { + for (const auto* event : trigger->GetTrigger()->events) { + if (event->eventID == "OnEnter") { + if (dpCollisionChecks::AreColliding(trigger->GetComponent()->GetdpEntity(), this->m_dpEntity)) { + trigger->TriggerEvent("OnEnter", this->m_Parent); + } + } + } + } } } diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index 50ec4f26..1c1a4f44 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -7,6 +7,8 @@ #include "NiQuaternion.h" #include "tinyxml2.h" #include "Component.h" +#include "dpCollisionChecks.h" +#include "PhantomPhysicsComponent.h" class Entity; class dpEntity; @@ -218,6 +220,13 @@ public: */ bool GetStatic() const { return m_Static; } + /** + * Returns the Physics entity for the component + * @return Physics entity for the component + */ + + dpEntity* GetdpEntity() const { return m_dpEntity; } + private: /** * The entity that owns this component diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index fe1ee242..faf6362f 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -110,6 +110,13 @@ public: */ void SetEffectType(uint32_t type); + /** + * Returns the Physics entity for the component + * @return Physics entity for the component + */ + + dpEntity* GetdpEntity() const { return m_dpEntity; } + /** * Spawns an object at each of the vertices for debugging purposes */ From 6500b62c521ac644d6132fb29ab0e9aad743b812 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 02:02:02 +0000 Subject: [PATCH 05/16] Minifig editing --- dGame/Character.h | 162 ++++++++++++++++------- dGame/dComponents/CharacterComponent.cpp | 20 +++ dGame/dComponents/CharacterComponent.h | 5 +- dGame/dUtilities/SlashCommandHandler.cpp | 48 +++++++ 4 files changed, 183 insertions(+), 52 deletions(-) diff --git a/dGame/Character.h b/dGame/Character.h index 161b9eab..57da8640 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -74,65 +74,127 @@ public: */ uint64_t GetLastLogin() const { return m_LastLogin; } - /** - * Gets the default shirt color for this character - * @return the default shirt color ID - */ - uint32_t GetShirtColor() const { return m_ShirtColor; } + + /** + * Gets the default shirt color for this character + * @return the default shirt color ID + */ + uint32_t GetShirtColor() const { return m_ShirtColor; } - /** - * Gets the default hair style for this character - * @return the default hair style ID - */ - uint32_t GetShirtStyle() const { return m_ShirtStyle; } + /** + * Gets the default hair style for this character + * @return the default hair style ID + */ + uint32_t GetShirtStyle() const { return m_ShirtStyle; } - /** - * Gets the default pants color for this character - * @return the default pants color ID - */ - uint32_t GetPantsColor() const { return m_PantsColor; } + /** + * Gets the default pants color for this character + * @return the default pants color ID + */ + uint32_t GetPantsColor() const { return m_PantsColor; } - /** - * Gets the default hair color for this character - * @return the default hair color ID - */ - uint32_t GetHairColor() const { return m_HairColor; } + /** + * Gets the default hair color for this character + * @return the default hair color ID + */ + uint32_t GetHairColor() const { return m_HairColor; } - /** - * Gets the default hair style of this character - * @return the default hair style ID - */ - uint32_t GetHairStyle() const { return m_HairStyle; } + /** + * Gets the default hair style of this character + * @return the default hair style ID + */ + uint32_t GetHairStyle() const { return m_HairStyle; } - /** - * Gets the eyes config for this character - * @return the eyes config ID - */ - uint32_t GetEyes() const { return m_Eyes; } + /** + * Gets the eyes config for this character + * @return the eyes config ID + */ + uint32_t GetEyes() const { return m_Eyes; } - /** - * Gets the eyebrows config for this character - * @return the eyebrow config ID - */ - uint32_t GetEyebrows() const { return m_Eyebrows; } + /** + * Gets the eyebrows config for this character + * @return the eyebrow config ID + */ + uint32_t GetEyebrows() const { return m_Eyebrows; } - /** - * Get the mouth of this character - * @return the mouth ID - */ - uint32_t GetMouth() const { return m_Mouth; } + /** + * Get the mouth of this character + * @return the mouth ID + */ + uint32_t GetMouth() const { return m_Mouth; } - /** - * Gets the left hand color of this character - * @return the left hand color ID - */ - uint32_t GetLeftHand() const { return m_LeftHand; } + /** + * Gets the left hand color of this character + * @return the left hand color ID + */ + uint32_t GetLeftHand() const { return m_LeftHand; } + + /** + * Gets the right hand color of this character + * @return the right hand color ID + */ + uint32_t GetRightHand() const { return m_RightHand; } + + /** + * Sets the default shirt color for this character + * @param color the shirt color ID to set + */ + void SetShirtColor(uint32_t color) { m_ShirtColor = color; } + + /** + * Sets the default shirt style for this character + * @param style the shirt style ID to set + */ + void SetShirtStyle(uint32_t style) { m_ShirtStyle = style; } + + /** + * Sets the default pants color for this character + * @param color the pants color ID to set + */ + void SetPantsColor(uint32_t color) { m_PantsColor = color; } + + /** + * Sets the default hair color for this character + * @param color the hair color ID to set + */ + void SetHairColor(uint32_t color) { m_HairColor = color; } + + /** + * Sets the default hair style for this character + * @param style the hair style ID to set + */ + void SetHairStyle(uint32_t style) { m_HairStyle = style; } + + /** + * Sets the eyes config for this character + * @param eyes the eyes config ID to set + */ + void SetEyes(uint32_t eyes) { m_Eyes = eyes; } + + /** + * Sets the eyebrows config for this character + * @param eyebrows the eyebrows config ID to set + */ + void SetEyebrows(uint32_t eyebrows) { m_Eyebrows = eyebrows; } + + /** + * Sets the mouth config for this character + * @param mouth the mouth config ID to set + */ + void SetMouth(uint32_t mouth) { m_Mouth = mouth; } + + /** + * Sets the left hand color for this character + * @param color the left hand color ID to set + */ + void SetLeftHand(uint32_t leftHand) { m_LeftHand = leftHand; } + + /** + * Sets the right hand color for this character + * @param color the right hand color ID to set + */ + void SetRightHand(uint32_t rightHand) { m_RightHand = rightHand; } - /** - * Gets the right hand color of this character - * @return the right hand color ID - */ - uint32_t GetRightHand() const { return m_RightHand; } /** * Whether this character has visited a certain zone diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index d2335c78..9337c324 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -352,6 +352,26 @@ void CharacterComponent::LoadFromXML() { } void CharacterComponent::UpdateXml(tinyxml2::XMLDocument* doc) { + tinyxml2::XMLElement* minifig = doc->FirstChildElement("obj")->FirstChildElement("mf"); + if (!minifig) { + Game::logger->Log("CharacterComponent", "Failed to find mf tag while updating XML!\n"); + return; + } + + // write minifig information that might have been changed by commands + + minifig->SetAttribute("es", m_Character->GetEyebrows()); + minifig->SetAttribute("ess", m_Character->GetEyes()); + minifig->SetAttribute("hc", m_Character->GetHairColor()); + minifig->SetAttribute("hs", m_Character->GetHairStyle()); + minifig->SetAttribute("l", m_Character->GetPantsColor()); + minifig->SetAttribute("lh", m_Character->GetLeftHand()); + minifig->SetAttribute("ms", m_Character->GetMouth()); + minifig->SetAttribute("rh", m_Character->GetRightHand()); + minifig->SetAttribute("t", m_Character->GetShirtColor()); + + // done with minifig + tinyxml2::XMLElement* character = doc->FirstChildElement("obj")->FirstChildElement("char"); if (!character) { Game::logger->Log("CharacterComponent", "Failed to find char tag while updating XML!\n"); diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 26b88a57..62076fad 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -259,11 +259,12 @@ public: */ void UpdatePlayerStatistic(StatisticID updateID, uint64_t updateValue = 1); -private: /** * Character info regarding this character, including clothing styles, etc. */ - Character* m_Character; + Character* m_Character; +private: + /** * Whether this character is racing diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 4a278230..adcd5c30 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -407,6 +407,50 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit stmt->execute(); delete stmt; + if (chatCommand == "setMinifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 + int32_t minifigItemId; + if (!GeneralUtils::TryParse(args[1], minifigItemId)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); + return; + } + EntityManager::Instance()->DestructEntity(entity, sysAddr); + auto* charComp = entity->GetComponent(); + std::string lowerName = args[0]; + if (lowerName.empty()) return; + std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); + if (lowerName == "eyebrows") { + charComp->m_Character->SetEyebrows(minifigItemId); + } else if (lowerName == "eyes") { + charComp->m_Character->SetEyes(minifigItemId); + } else if (lowerName == "haircolor") { + charComp->m_Character->SetHairColor(minifigItemId); + } else if (lowerName == "hairstyle") { + charComp->m_Character->SetHairStyle(minifigItemId); + } else if (lowerName == "pants") { + charComp->m_Character->SetPantsColor(minifigItemId); + } else if (lowerName == "lefthand") { + charComp->m_Character->SetLeftHand(minifigItemId); + } else if (lowerName == "mouth") { + charComp->m_Character->SetMouth(minifigItemId); + } else if (lowerName == "righthand") { + charComp->m_Character->SetRightHand(minifigItemId); + } else if (lowerName == "shirt") { + charComp->m_Character->SetShirtColor(minifigItemId); + } else if (lowerName == "hands") { + charComp->m_Character->SetLeftHand(minifigItemId); + charComp->m_Character->SetRightHand(minifigItemId); + } else { + EntityManager::Instance()->ConstructEntity(entity); + ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig item to change, try one of the following: Eyebrows, Eyes, HairColor, HairStyle, Pants, LeftHand, Mouth, RightHand, Shirt, Hands"); + return; + } + + EntityManager::Instance()->ConstructEntity(entity); + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId))); + + GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character + } + if (chatCommand == "list-spawns" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); @@ -429,6 +473,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->UnlockEmote(emoteID); } + if (chatCommand == "force-save" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + entity->GetCharacter()->SaveXMLToDatabase(); + } + if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server."); From c8991666d2f01ecee5bdaa4ce53c80e6f9fd6f91 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 10:46:45 +0000 Subject: [PATCH 06/16] Potential solution --- dGame/Entity.cpp | 5 +++++ dGame/dComponents/ControllablePhysicsComponent.cpp | 12 ------------ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c98323a9..a0c19aa0 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1768,6 +1768,7 @@ void Entity::HandleTriggerCommand(std::string id, std::string target, std::strin else if (argArray[0] == "repulse") effectType = 2; else if (argArray[0] == "gravity") effectType = 3; else if (argArray[0] == "friction") effectType = 4; + phanPhys->SetEffectType(effectType); phanPhys->SetDirectionalMultiplier(std::stof(argArray[1])); if (argArray.size() > 4) { @@ -1781,6 +1782,10 @@ void Entity::HandleTriggerCommand(std::string id, std::string target, std::strin phanPhys->SetMin(std::stoi(argArray[6])); phanPhys->SetMax(std::stoi(argArray[7])); } + + if (target == "self") { + EntityManager::Instance()->ConstructEntity(this); + } } else if (id == "updateMission") { CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable("MissionTasks"); diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 7fe19acc..922ae55d 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -40,18 +40,6 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com m_dpEntity = new dpEntity(m_Parent->GetObjectID(), radius, false); m_dpEntity->SetCollisionGroup(COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_FRIENDLY); dpWorld::Instance().AddEntity(m_dpEntity); - - auto triggers = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PHANTOM_PHYSICS); - - for (auto* trigger : triggers) { - for (const auto* event : trigger->GetTrigger()->events) { - if (event->eventID == "OnEnter") { - if (dpCollisionChecks::AreColliding(trigger->GetComponent()->GetdpEntity(), this->m_dpEntity)) { - trigger->TriggerEvent("OnEnter", this->m_Parent); - } - } - } - } } } From 833ed8a40d35e0c30b2228f3fe6b9bb1f71a3adb Mon Sep 17 00:00:00 2001 From: Mick Vermeulen Date: Sat, 11 Dec 2021 11:59:29 +0100 Subject: [PATCH 07/16] Implement Buccaneer Valiant special ability Adds the ability for the buccaneer valiant to spawn a ship that rams enemies and smashes them. Next to a script that triggers the ship skill a few other changes had to be made: - Force movement behavior server side calculation and sync - The ship has no physics volume so the FindValidTargets for behaviors had to be altered to allow ControllablePhysics entities to find entities within their area. The "target_self" AOE flag has been used to replicate the old behavior. --- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 4 +- dGame/dBehaviors/AreaOfEffectBehavior.h | 2 + dGame/dBehaviors/BehaviorContext.cpp | 11 ++- dGame/dBehaviors/BehaviorContext.h | 2 +- dGame/dBehaviors/ForceMovementBehavior.cpp | 85 ++++++++++++++++------ dGame/dBehaviors/ForceMovementBehavior.h | 9 +++ dScripts/BuccaneerValiantShip.cpp | 24 ++++++ dScripts/BuccaneerValiantShip.h | 6 ++ dScripts/CppScripts.cpp | 3 + 9 files changed, 114 insertions(+), 32 deletions(-) create mode 100644 dScripts/BuccaneerValiantShip.cpp create mode 100644 dScripts/BuccaneerValiantShip.h diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index a5341348..b87c7c17 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -74,7 +74,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream includeFaction = 1; } - for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction)) + for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1)) { auto* entity = EntityManager::Instance()->GetEntity(validTarget); @@ -155,4 +155,6 @@ void AreaOfEffectBehavior::Load() this->m_ignoreFaction = GetInt("ignore_faction"); this->m_includeFaction = GetInt("include_faction"); + + this->m_TargetSelf = GetInt("target_self"); } diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.h b/dGame/dBehaviors/AreaOfEffectBehavior.h index c2b6679d..37313499 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.h +++ b/dGame/dBehaviors/AreaOfEffectBehavior.h @@ -13,6 +13,8 @@ public: int32_t m_ignoreFaction; int32_t m_includeFaction; + + int32_t m_TargetSelf; /* * Inherited diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index fd3117a4..2637aa61 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -149,7 +149,7 @@ void BehaviorContext::SyncBehavior(const uint32_t syncId, RakNet::BitStream* bit return; } - + behavior->Sync(this, bitStream, branch); } @@ -325,7 +325,7 @@ void BehaviorContext::Reset() this->scheduledUpdates.clear(); } -std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction) const +std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf) const { auto* entity = EntityManager::Instance()->GetEntity(this->caster); @@ -353,21 +353,20 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in } } - if (ignoreFaction || includeFaction || (!entity->HasComponent(COMPONENT_TYPE_PHANTOM_PHYSICS) && !entity->HasComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS) && targets.empty())) + if (ignoreFaction || includeFaction || (!entity->HasComponent(COMPONENT_TYPE_PHANTOM_PHYSICS) && targets.empty())) { - DestroyableComponent* destroyableComponent; + DestroyableComponent* destroyableComponent; if (!entity->TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)) { return targets; } auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS); - for (auto* candidate : entities) { const auto id = candidate->GetObjectID(); - if (destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction)) + if ((id != entity->GetObjectID() || targetSelf) && destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction)) { targets.push_back(id); } diff --git a/dGame/dBehaviors/BehaviorContext.h b/dGame/dBehaviors/BehaviorContext.h index 58154512..21b2e6e9 100644 --- a/dGame/dBehaviors/BehaviorContext.h +++ b/dGame/dBehaviors/BehaviorContext.h @@ -102,7 +102,7 @@ struct BehaviorContext void Reset(); - std::vector GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0) const; + std::vector GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0, const bool targetSelf = false) const; explicit BehaviorContext(LWOOBJID originator, bool calculation = false); diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index 332cfed6..ea8c04a7 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -1,44 +1,81 @@ #include "ForceMovementBehavior.h" - #include "BehaviorBranchContext.h" #include "BehaviorContext.h" +#include "ControllablePhysicsComponent.h" +#include "EntityManager.h" -void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) -{ - if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) - { - return; - } +void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { + if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { + return; + } - uint32_t handle; - - bitStream->Read(handle); - - context->RegisterSyncBehavior(handle, this, branch); + uint32_t handle; + bitStream->Read(handle); + context->RegisterSyncBehavior(handle, this, branch); } void ForceMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t next; + uint32_t next; + bitStream->Read(next); - bitStream->Read(next); + LWOOBJID target; + bitStream->Read(target); - LWOOBJID target; + branch.target = target; + auto* behavior = CreateBehavior(next); + behavior->Handle(context, bitStream, branch); +} - bitStream->Read(target); +void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { + return; + } - auto* behavior = CreateBehavior(next); + auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + if (casterEntity != nullptr) { + auto* controllablePhysicsComponent = casterEntity->GetComponent(); + if (controllablePhysicsComponent != nullptr) { - branch.target = target; + if (m_Forward == 1) { + controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25); + } - behavior->Handle(context, bitStream, branch); + EntityManager::Instance()->SerializeEntity(casterEntity); + } + } + + const auto skillHandle = context->GetUniqueSkillId(); + bitStream->Write(skillHandle); + + context->SyncCalculation(skillHandle, this->m_Duration, this, branch); } void ForceMovementBehavior::Load() { - this->m_hitAction = GetAction("hit_action"); - - this->m_hitEnemyAction = GetAction("hit_action_enemy"); - - this->m_hitFactionAction = GetAction("hit_action_faction"); + this->m_hitAction = GetAction("hit_action"); + this->m_hitEnemyAction = GetAction("hit_action_enemy"); + this->m_hitFactionAction = GetAction("hit_action_faction"); + this->m_Duration = GetFloat("duration"); + this->m_Forward = GetFloat("forward"); + this->m_Left = GetFloat("left"); + this->m_Yaw = GetFloat("yaw"); +} + +void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + if (casterEntity != nullptr) { + auto* controllablePhysicsComponent = casterEntity->GetComponent(); + if (controllablePhysicsComponent != nullptr) { + + controllablePhysicsComponent->SetPosition(controllablePhysicsComponent->GetPosition() + controllablePhysicsComponent->GetVelocity() * m_Duration); + controllablePhysicsComponent->SetVelocity({}); + + EntityManager::Instance()->SerializeEntity(casterEntity); + } + } + + this->m_hitAction->Calculate(context, bitStream, branch); + this->m_hitEnemyAction->Calculate(context, bitStream, branch); + this->m_hitEnemyAction->Calculate(context, bitStream, branch); } diff --git a/dGame/dBehaviors/ForceMovementBehavior.h b/dGame/dBehaviors/ForceMovementBehavior.h index 5b77e4b7..50b0aa26 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.h +++ b/dGame/dBehaviors/ForceMovementBehavior.h @@ -9,6 +9,11 @@ public: Behavior* m_hitEnemyAction; Behavior* m_hitFactionAction; + + float_t m_Duration; + float_t m_Forward; + float_t m_Left; + float_t m_Yaw; /* * Inherited @@ -18,8 +23,12 @@ public: { } + void Calculate(BehaviorContext *context, RakNet::BitStream *bitStream, BehaviorBranchContext branch) override; + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void SyncCalculation(BehaviorContext *context, RakNet::BitStream *bitStream, BehaviorBranchContext branch) override; + void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; diff --git a/dScripts/BuccaneerValiantShip.cpp b/dScripts/BuccaneerValiantShip.cpp new file mode 100644 index 00000000..2c24b7d4 --- /dev/null +++ b/dScripts/BuccaneerValiantShip.cpp @@ -0,0 +1,24 @@ +#include "BuccaneerValiantShip.h" +#include "SkillComponent.h" +#include "dLogger.h" + +void BuccaneerValiantShip::OnStartup(Entity* self) { + const auto skill = 982; + const auto behavior = 20577; + const auto skillCastTimer = 1.0F; + + self->AddCallbackTimer(skillCastTimer, [self]() { + auto* skillComponent = self->GetComponent(); + auto* owner = self->GetOwner(); + + if (skillComponent != nullptr && owner != nullptr) { + skillComponent->CalculateBehavior(skill, behavior, LWOOBJID_EMPTY, true, false, owner->GetObjectID()); + + // Kill self if missed + const auto selfSmashTimer = 1.1F; + self->AddCallbackTimer(selfSmashTimer, [self]() { + self->Kill(); + }); + } + }); +} diff --git a/dScripts/BuccaneerValiantShip.h b/dScripts/BuccaneerValiantShip.h new file mode 100644 index 00000000..f501d1b9 --- /dev/null +++ b/dScripts/BuccaneerValiantShip.h @@ -0,0 +1,6 @@ +#pragma once +#include "CppScripts.h" + +class BuccaneerValiantShip : public CppScripts::Script { + void OnStartup(Entity *self) override; +}; diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index ed59c5ba..87a2c668 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -261,6 +261,7 @@ #include "PersonalFortress.h" #include "PropertyDevice.h" #include "ImaginationBackpackHealServer.h" +#include "BuccaneerValiantShip.h" // Survival scripts #include "AgSurvivalStromling.h" @@ -774,6 +775,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = new PropertyDevice(); else if (scriptName == "scripts\\02_server\\Map\\General\\L_IMAG_BACKPACK_HEALS_SERVER.lua") script = new ImaginationBackpackHealServer(); + else if (scriptName == "scripts\\EquipmentScripts\\BuccaneerValiantShip.lua") + script = new BuccaneerValiantShip(); //Ignore these scripts: else if (scriptName == "scripts\\02_server\\Enemy\\General\\L_SUSPEND_LUA_AI.lua") From 74742771c4b50ee99c87ace977e683a58a055019 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 12:29:34 +0000 Subject: [PATCH 08/16] Added a LogDebug - Added debug logging - Created vLog, a root function for all log functions - Placed failed to load script log under this new LogDebug function - Updated included config functions --- dAuthServer/AuthServer.cpp | 5 +- dChatServer/ChatServer.cpp | 7 ++- dCommon/dLogger.cpp | 102 +++++++++++---------------------- dCommon/dLogger.h | 7 ++- dMasterServer/MasterServer.cpp | 5 +- dScripts/CppScripts.cpp | 5 +- dWorldServer/WorldServer.cpp | 5 +- resources/authconfig.ini | 3 + resources/chatconfig.ini | 3 + resources/masterconfig.ini | 3 + resources/worldconfig.ini | 3 + 11 files changed, 72 insertions(+), 76 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 22f1dfa0..f7ab7bbe 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -45,6 +45,7 @@ int main(int argc, char** argv) { dConfig config("authconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); //Connect to the MySQL Database std::string mysql_host = config.GetValue("mysql_host"); @@ -152,11 +153,13 @@ int main(int argc, char** argv) { dLogger * SetupLogger() { std::string logPath = "./logs/AuthServer_" + std::to_string(time(nullptr)) + ".log"; bool logToConsole = false; + bool logDebugStatements = false; #ifdef _DEBUG logToConsole = true; + logDebugStatements = true; #endif - return new dLogger(logPath, logToConsole); + return new dLogger(logPath, logToConsole, logDebugStatements); } void HandlePacket(Packet* packet) { diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index be5ec904..57b82721 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -48,6 +48,7 @@ int main(int argc, char** argv) { dConfig config("chatconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); //Connect to the MySQL Database std::string mysql_host = config.GetValue("mysql_host"); @@ -156,14 +157,16 @@ int main(int argc, char** argv) { return 0; } -dLogger* SetupLogger() { +dLogger * SetupLogger() { std::string logPath = "./logs/ChatServer_" + std::to_string(time(nullptr)) + ".log"; bool logToConsole = false; + bool logDebugStatements = false; #ifdef _DEBUG logToConsole = true; + logDebugStatements = true; #endif - return new dLogger(logPath, logToConsole); + return new dLogger(logPath, logToConsole, logDebugStatements); } void HandlePacket(Packet* packet) { diff --git a/dCommon/dLogger.cpp b/dCommon/dLogger.cpp index 6ee0e7d2..572fc1e3 100644 --- a/dCommon/dLogger.cpp +++ b/dCommon/dLogger.cpp @@ -1,7 +1,8 @@ #include "dLogger.h" -dLogger::dLogger(const std::string& outpath, bool logToConsole) { +dLogger::dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements) { m_logToConsole = logToConsole; + m_logDebugStatements = logDebugStatements; m_outpath = outpath; #ifdef _WIN32 @@ -24,39 +25,26 @@ dLogger::~dLogger() { #endif } -void dLogger::LogBasic(const std::string & message) { - LogBasic(message.c_str()); -} - -void dLogger::LogBasic(const char * format, ...) { +void dLogger::vLog(const char* format, va_list args) { #ifdef _WIN32 time_t t = time(NULL); struct tm time; localtime_s(&time, &t); - char timeStr[70]; - strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time); - char message[2048]; - va_list args; - va_start(args, format); vsprintf_s(message, format, args); - va_end(args); - if (m_logToConsole) std::cout << "[" << "time machine broke" << "] " << message; - mFile << "[" << "time" << "] " << message; + if (m_logToConsole) std::cout << "[" << timeStr << "] " << message; + mFile << "[" << timeStr << "] " << message; #else time_t t = time(NULL); - struct tm * time = localtime(&t); - char timeStr[70]; - strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time); - + struct tm time; + localtime_s(&time, &t); + char timeStr[70]; + strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time); char message[2048]; - va_list args; - va_start(args, format); vsprintf(message, format, args); - va_end(args); if (m_logToConsole) { fputs("[", stdout); @@ -76,62 +64,42 @@ void dLogger::LogBasic(const char * format, ...) { #endif } -void dLogger::Log(const char * className, const char * format, ...) { -#ifdef _WIN32 - time_t t = time(NULL); - struct tm time; - localtime_s(&time, &t); - - char timeStr[70]; - strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time); - - char message[2048]; +void dLogger::LogBasic(const char * format, ...) { va_list args; va_start(args, format); - vsprintf_s(message, format, args); - + vLog(format, args); va_end(args); +} - if (m_logToConsole) std::cout << "[" << timeStr << "] [" << className << "]: " << message; - mFile << "[" << timeStr << "] [" << className << "]: " << message; -#else - time_t t = time(NULL); - struct tm * time = localtime(&t); - char timeStr[70]; - strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time); - - char message[2048]; - va_list args; - va_start(args, format); - vsprintf(message, format, args); - va_end(args); - - if (m_logToConsole) { - fputs("[", stdout); - fputs(timeStr, stdout); - fputs("] ", stdout); - fputs("[", stdout); - fputs(className, stdout); - fputs("]: ", stdout); - fputs(message, stdout); - } - - if (fp != NULL) { - fputs("[", fp); - fputs(timeStr, fp); - fputs("] ", fp); - fputs("[", fp); - fputs(className, fp); - fputs("]: ", fp); - fputs(message, fp); - } -#endif +void dLogger::LogBasic(const std::string & message) { + LogBasic(message.c_str()); +} + +void dLogger::Log(const char * className, const char * format, ...) { + va_list args; + std::string log = "[" + std::string(className) + "] " + std::string(format); + va_start(args, format); + vLog(log.c_str(), args); + va_end(args); } void dLogger::Log(const std::string & className, const std::string & message) { Log(className.c_str(), message.c_str()); } +void dLogger::LogDebug(const char * className, const char * format, ...) { + if (!m_logDebugStatements) return; + va_list args; + std::string log = "[" + std::string(className) + "] " + std::string(format); + va_start(args, format); + vLog(log.c_str(), args); + va_end(args); +} + +void dLogger::LogDebug(const std::string & className, const std::string & message) { + LogDebug(className.c_str(), message.c_str()); +} + void dLogger::Flush() { #ifdef _WIN32 mFile.flush(); diff --git a/dCommon/dLogger.h b/dCommon/dLogger.h index 622a90d3..7448237e 100644 --- a/dCommon/dLogger.h +++ b/dCommon/dLogger.h @@ -7,21 +7,26 @@ class dLogger { public: - dLogger(const std::string& outpath, bool logToConsole); + dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements); ~dLogger(); void SetLogToConsole(bool logToConsole) { m_logToConsole = logToConsole; } + void SetLogDebugStatements(bool logDebugStatements) { m_logDebugStatements = logDebugStatements; } + void vLog(const char* format, va_list args); void LogBasic(const std::string& message); void LogBasic(const char* format, ...); void Log(const char* className, const char* format, ...); void Log(const std::string& className, const std::string& message); + void LogDebug(const std::string& className, const std::string& message); + void LogDebug(const char* className, const char* format, ...); void Flush(); const bool GetIsLoggingToConsole() const { return m_logToConsole; } private: + bool m_logDebugStatements; bool m_logToConsole; std::string m_outpath; std::ofstream mFile; diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 926168a3..88a95a6d 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -72,6 +72,7 @@ int main(int argc, char** argv) { dConfig config("masterconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); //Connect to CDClient try { @@ -320,11 +321,13 @@ dLogger* SetupLogger() { std::string logPath = "./logs/MasterServer_" + std::to_string(time(nullptr)) + ".log"; bool logToConsole = false; + bool logDebugStatements = false; #ifdef _DEBUG logToConsole = true; + logDebugStatements = true; #endif - return new dLogger(logPath, logToConsole); + return new dLogger(logPath, logToConsole, logDebugStatements); } void HandlePacket(Packet* packet) { diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index cca8a728..1cd1c24f 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -781,11 +781,10 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = invalidToReturn; else if (scriptName == "scripts\\02_server\\Enemy\\General\\L_BASE_ENEMY_SPIDERLING.lua") script = invalidToReturn; - else if (scriptName == "scripts\\ai\\AG\\L_AG_SHIP_SHAKE.lua") - script = invalidToReturn; //Set ship shake to not log it is missing, it is implemented in AgSpaceStuff else if (script == invalidToReturn) { if (scriptName.length() > 0) - Game::logger->Log("CppScripts", "Attempted to load CppScript for '" + scriptName + "', but returned InvalidScript.\n"); + Game::logger->LogDebug("CppScripts", "Attempted to load CppScript for '" + scriptName + "', but returned InvalidScript.\n"); + // information not really needed for sys admins but is for developers script = invalidToReturn; } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 5d155f29..6c81e93a 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -136,6 +136,7 @@ int main(int argc, char** argv) { dConfig config("worldconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); if (config.GetValue("disable_chat") == "1") chatDisabled = true; // Connect to CDClient @@ -503,11 +504,13 @@ int main(int argc, char** argv) { dLogger * SetupLogger(int zoneID, int instanceID) { std::string logPath = "./logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log"; bool logToConsole = false; + bool logDebugStatements = false; #ifdef _DEBUG logToConsole = true; + logDebugStatements = true; #endif - return new dLogger(logPath, logToConsole); + return new dLogger(logPath, logToConsole, logDebugStatements); } void HandlePacketChat(Packet* packet) { diff --git a/resources/authconfig.ini b/resources/authconfig.ini index fd1fc5c4..40ca146e 100644 --- a/resources/authconfig.ini +++ b/resources/authconfig.ini @@ -19,6 +19,9 @@ max_clients=999 # 0 or 1, should log to console log_to_console=1 +# 0 or 1, should log debug (developer only) statements to console for debugging, not needed for normal operation +log_debug_statements=0 + # 0 or 1, should ignore playkeys # If 1 everyone with an account will be able to login, regardless of if they have a key or not dont_use_keys=0 diff --git a/resources/chatconfig.ini b/resources/chatconfig.ini index 28db5988..f30fb8f9 100644 --- a/resources/chatconfig.ini +++ b/resources/chatconfig.ini @@ -19,5 +19,8 @@ max_clients=999 # 0 or 1, should log to console log_to_console=1 +# 0 or 1, should log debug (developer only) statements to console for debugging, not needed for normal operation +log_debug_statements=0 + # 0 or 1, should not compile chat hash map to file dont_generate_dcf=0 diff --git a/resources/masterconfig.ini b/resources/masterconfig.ini index 120a3743..cedb7c3a 100644 --- a/resources/masterconfig.ini +++ b/resources/masterconfig.ini @@ -32,5 +32,8 @@ max_clients=999 # 0 or 1, should log to console log_to_console=1 +# 0 or 1, should log debug (developer only) statements to console for debugging, not needed for normal operation +log_debug_statements=0 + # 0 or 1, should autostart auth, chat, and char servers prestart_servers=1 diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index e5932ec7..e30aa865 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -20,6 +20,9 @@ max_clients=999 # 0 or 1, should log to console log_to_console=1 +# 0 or 1, should log debug (developer only) statements to console for debugging, not needed for normal operation +log_debug_statements=0 + # 0 or 1, should not compile chat hash map to file dont_generate_dcf=0 From b6453376e43411bc16a69e784fadea148fe5cefd Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 13:21:00 +0000 Subject: [PATCH 09/16] patched coin exploit --- dGame/Entity.cpp | 18 ++++++++++++++++++ dGame/Entity.h | 3 +++ dGame/Player.cpp | 9 +++++++++ dGame/Player.h | 6 ++++++ dGame/dGameMessages/GameMessages.cpp | 10 +++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c98323a9..9f16d456 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1644,6 +1644,24 @@ void Entity::PickupItem(const LWOOBJID& objectID) { droppedLoot.erase(objectID); } +bool Entity::PickupCoins(uint64_t count) { // bool because we are returning whether they can pick up the coins + if (!IsPlayer()) return false; + auto droppedcoins = static_cast(this)->GetDroppedCoins(); + if (count > droppedcoins) { + return false; + } else { + static_cast(this)->SetDroppedCoins(droppedcoins - count); + return true; + } +} + +void Entity::DropCoins(uint64_t count) { + if (!IsPlayer()) return; + auto droppedcoins = static_cast(this)->GetDroppedCoins(); + droppedcoins += count; + static_cast(this)->SetDroppedCoins(droppedcoins); +} + void Entity::AddChild(Entity* child) { m_ChildEntities.push_back(child); } diff --git a/dGame/Entity.h b/dGame/Entity.h index 01699a84..4b83b894 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -202,6 +202,9 @@ public: void AddLootItem(const Loot::Info& info); void PickupItem(const LWOOBJID& objectID); + bool PickupCoins(uint64_t count); + void DropCoins(uint64_t count); + void ScheduleKillAfterUpdate(Entity* murderer = nullptr); void TriggerEvent(std::string eveneventtID, Entity* optionalTarget = nullptr); void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 9a158c8f..634d4a68 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -24,6 +24,7 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti m_GMLevel = m_Character->GetGMLevel(); m_SystemAddress = m_ParentUser->GetSystemAddress(); m_DroppedLoot = {}; + m_DroppedCoins = 0; m_GhostReferencePoint = NiPoint3::ZERO; m_GhostOverridePoint = NiPoint3::ZERO; @@ -290,6 +291,14 @@ const std::vector& Player::GetAllPlayers() return m_Players; } +uint64_t Player::GetDroppedCoins() { + return m_DroppedCoins; +} + +void Player::SetDroppedCoins(uint64_t value) { + m_DroppedCoins = value; +} + Player::~Player() { Game::logger->Log("Player", "Deleted player\n"); diff --git a/dGame/Player.h b/dGame/Player.h index abd811c5..bba01363 100644 --- a/dGame/Player.h +++ b/dGame/Player.h @@ -36,6 +36,8 @@ public: std::map& GetDroppedLoot(); + uint64_t GetDroppedCoins(); + /** * Setters */ @@ -52,6 +54,8 @@ public: void SetGhostOverride(bool value); + void SetDroppedCoins(uint64_t value); + /** * Wrapper for sending an in-game mail. * @@ -126,5 +130,7 @@ private: std::map m_DroppedLoot; + uint64_t m_DroppedCoins; + static std::vector m_Players; }; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c6b3c9bd..727c704c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1031,6 +1031,10 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, entity->AddLootItem(info); } + if (item == LOT_NULL && currency != 0) { + entity->DropCoins(currency); + } + if (spawnPos != NiPoint3::ZERO) { bUsePosition = true; @@ -5232,8 +5236,12 @@ void GameMessages::HandlePickupCurrency(RakNet::BitStream* inStream, Entity* ent unsigned int currency; inStream->Read(currency); + if (currency == 0) return; + auto* ch = entity->GetCharacter(); - ch->SetCoins(ch->GetCoins() + currency); + if (entity->PickupCoins(currency)) { + ch->SetCoins(ch->GetCoins() + currency); + } } void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity) { From 22de531ab3b43c1db358a6510b51370d35d22113 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 13:57:15 +0000 Subject: [PATCH 10/16] Changes asked for by Wincent --- dGame/Entity.cpp | 4 ++-- dGame/Entity.h | 4 ++-- dGame/dGameMessages/GameMessages.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 9f16d456..089452ae 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1644,7 +1644,7 @@ void Entity::PickupItem(const LWOOBJID& objectID) { droppedLoot.erase(objectID); } -bool Entity::PickupCoins(uint64_t count) { // bool because we are returning whether they can pick up the coins +bool Entity::CanPickupCoins(uint64_t count) { // bool because we are returning whether they can pick up the coins if (!IsPlayer()) return false; auto droppedcoins = static_cast(this)->GetDroppedCoins(); if (count > droppedcoins) { @@ -1655,7 +1655,7 @@ bool Entity::PickupCoins(uint64_t count) { // bool because we are returning whet } } -void Entity::DropCoins(uint64_t count) { +void Entity::RegisterCoinDrop(uint64_t count) { if (!IsPlayer()) return; auto droppedcoins = static_cast(this)->GetDroppedCoins(); droppedcoins += count; diff --git a/dGame/Entity.h b/dGame/Entity.h index 4b83b894..31b2b303 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -202,8 +202,8 @@ public: void AddLootItem(const Loot::Info& info); void PickupItem(const LWOOBJID& objectID); - bool PickupCoins(uint64_t count); - void DropCoins(uint64_t count); + bool CanPickupCoins(uint64_t count); + void RegisterCoinDrop(uint64_t count); void ScheduleKillAfterUpdate(Entity* murderer = nullptr); void TriggerEvent(std::string eveneventtID, Entity* optionalTarget = nullptr); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 727c704c..fad5d7de 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1032,7 +1032,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, } if (item == LOT_NULL && currency != 0) { - entity->DropCoins(currency); + entity->RegisterCoinDrop(currency); } if (spawnPos != NiPoint3::ZERO) { @@ -5239,7 +5239,7 @@ void GameMessages::HandlePickupCurrency(RakNet::BitStream* inStream, Entity* ent if (currency == 0) return; auto* ch = entity->GetCharacter(); - if (entity->PickupCoins(currency)) { + if (entity->CanPickupCoins(currency)) { ch->SetCoins(ch->GetCoins() + currency); } } From 6427b097ab9415e32d69768e519a777bc8f7679a Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 14:22:39 +0000 Subject: [PATCH 11/16] Replace two casts with one --- dGame/Entity.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 089452ae..0579035e 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1646,11 +1646,12 @@ void Entity::PickupItem(const LWOOBJID& objectID) { bool Entity::CanPickupCoins(uint64_t count) { // bool because we are returning whether they can pick up the coins if (!IsPlayer()) return false; - auto droppedcoins = static_cast(this)->GetDroppedCoins(); + auto * player = static_cast(this); + auto droppedcoins = player->GetDroppedCoins(); if (count > droppedcoins) { return false; } else { - static_cast(this)->SetDroppedCoins(droppedcoins - count); + player->SetDroppedCoins(droppedcoins - count); return true; } } From 94e32a577348b119c65f79d9cd101f13a1d400cb Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 11 Dec 2021 14:24:25 +0000 Subject: [PATCH 12/16] replace the other double cast --- dGame/Entity.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 0579035e..dbb44f2f 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1658,9 +1658,10 @@ bool Entity::CanPickupCoins(uint64_t count) { // bool because we are returning w void Entity::RegisterCoinDrop(uint64_t count) { if (!IsPlayer()) return; - auto droppedcoins = static_cast(this)->GetDroppedCoins(); + auto * player = static_cast(this); + auto droppedcoins = player->GetDroppedCoins(); droppedcoins += count; - static_cast(this)->SetDroppedCoins(droppedcoins); + player->SetDroppedCoins(droppedcoins); } void Entity::AddChild(Entity* child) { From bb508e91c1d52de0b97b33edd1bbcf7721a9f08a Mon Sep 17 00:00:00 2001 From: wincent Date: Sat, 11 Dec 2021 17:33:54 +0100 Subject: [PATCH 13/16] Update the code style When applied this commit updates the code style used when validating coin pickups. --- dGame/Entity.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index dbb44f2f..ad9b8cd5 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1644,24 +1644,24 @@ void Entity::PickupItem(const LWOOBJID& objectID) { droppedLoot.erase(objectID); } -bool Entity::CanPickupCoins(uint64_t count) { // bool because we are returning whether they can pick up the coins +bool Entity::CanPickupCoins(uint64_t count) { if (!IsPlayer()) return false; - auto * player = static_cast(this); - auto droppedcoins = player->GetDroppedCoins(); - if (count > droppedcoins) { + auto* player = static_cast(this); + auto droppedCoins = player->GetDroppedCoins(); + if (count > droppedCoins) { return false; } else { - player->SetDroppedCoins(droppedcoins - count); + player->SetDroppedCoins(droppedCoins - count); return true; } } void Entity::RegisterCoinDrop(uint64_t count) { if (!IsPlayer()) return; - auto * player = static_cast(this); - auto droppedcoins = player->GetDroppedCoins(); - droppedcoins += count; - player->SetDroppedCoins(droppedcoins); + auto* player = static_cast(this); + auto droppedCoins = player->GetDroppedCoins(); + droppedCoins += count; + player->SetDroppedCoins(droppedCoins); } void Entity::AddChild(Entity* child) { From 834b87f4b264833a177c0db3167207fbdeb0c9bd Mon Sep 17 00:00:00 2001 From: Niklas Conen Date: Sun, 12 Dec 2021 03:45:25 +0100 Subject: [PATCH 14/16] increased the exchange rate of the nimbus station console to 5 faction tokens for 25 maelstrom infected bricks --- dScripts/NsTokenConsoleServer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/NsTokenConsoleServer.cpp b/dScripts/NsTokenConsoleServer.cpp index 90b5ed1d..f6b022d0 100644 --- a/dScripts/NsTokenConsoleServer.cpp +++ b/dScripts/NsTokenConsoleServer.cpp @@ -50,19 +50,19 @@ void NsTokenConsoleServer::OnUse(Entity* self, Entity* user) if (character->GetPlayerFlag(46)) { - inventoryComponent->AddItem(8321, 1); + inventoryComponent->AddItem(8321, 5); } else if (character->GetPlayerFlag(47)) { - inventoryComponent->AddItem(8318, 1); + inventoryComponent->AddItem(8318, 5); } else if (character->GetPlayerFlag(48)) { - inventoryComponent->AddItem(8320, 1); + inventoryComponent->AddItem(8320, 5); } else if (character->GetPlayerFlag(49)) { - inventoryComponent->AddItem(8319, 1); + inventoryComponent->AddItem(8319, 5); } missionComponent->ForceProgressTaskType(863, 1, 1, false); From 259c236b72d13a8b5a91e78139ed8c547963204e Mon Sep 17 00:00:00 2001 From: wincent Date: Mon, 13 Dec 2021 16:57:43 +0100 Subject: [PATCH 15/16] Fixes dlogger PR When applied this commit fixes the unix build of the previous dLogger PR. This commit also fixes backwards compatability with config files. --- CMakeLists.txt | 3 +++ dAuthServer/AuthServer.cpp | 2 +- dChatServer/ChatServer.cpp | 2 +- dCommon/dLogger.cpp | 7 +++---- dMasterServer/MasterServer.cpp | 2 +- dWorldServer/WorldServer.cpp | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf7988c8..fe1f2751 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,9 @@ make_directory(${CMAKE_BINARY_DIR}/res) # Create a /locale directory make_directory(${CMAKE_BINARY_DIR}/locale) +# Create a /logs directory +make_directory(${CMAKE_BINARY_DIR}/logs) + # Copy ini files on first build if (NOT EXISTS ${PROJECT_BINARY_DIR}/authconfig.ini) configure_file( diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index f7ab7bbe..67590fa0 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -45,7 +45,7 @@ int main(int argc, char** argv) { dConfig config("authconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); //Connect to the MySQL Database std::string mysql_host = config.GetValue("mysql_host"); diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 57b82721..81904d41 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -48,7 +48,7 @@ int main(int argc, char** argv) { dConfig config("chatconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); //Connect to the MySQL Database std::string mysql_host = config.GetValue("mysql_host"); diff --git a/dCommon/dLogger.cpp b/dCommon/dLogger.cpp index 572fc1e3..825c10cb 100644 --- a/dCommon/dLogger.cpp +++ b/dCommon/dLogger.cpp @@ -39,10 +39,9 @@ void dLogger::vLog(const char* format, va_list args) { mFile << "[" << timeStr << "] " << message; #else time_t t = time(NULL); - struct tm time; - localtime_s(&time, &t); - char timeStr[70]; - strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time); + struct tm * time = localtime(&t); + char timeStr[70]; + strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time); char message[2048]; vsprintf(message, format, args); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 88a95a6d..e5a6f553 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -72,7 +72,7 @@ int main(int argc, char** argv) { dConfig config("masterconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); //Connect to CDClient try { diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 6c81e93a..ed751f41 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -136,7 +136,7 @@ int main(int argc, char** argv) { dConfig config("worldconfig.ini"); Game::config = &config; Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(bool(std::stoi(config.GetValue("log_debug_statements")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); if (config.GetValue("disable_chat") == "1") chatDisabled = true; // Connect to CDClient From c060b01037646303c7db944cbbb1fd37566b8fc5 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 14 Dec 2021 16:24:48 +0100 Subject: [PATCH 16/16] fix undeleted dpEntity after enemy smashed could be the cause of long-soak (hours long) sessions having CPU issues --- dGame/dComponents/BaseCombatAIComponent.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 44154f52..ae929d57 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -129,6 +129,9 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) BaseCombatAIComponent::~BaseCombatAIComponent() { if (m_dpEntity) dpWorld::Instance().RemoveEntity(m_dpEntity); + + if (m_dpEntityEnemy) + dpWorld::Instance().RemoveEntity(m_dpEntityEnemy); } void BaseCombatAIComponent::Update(const float deltaTime) {