Compare commits

..

856 Commits

Author SHA1 Message Date
Jett
e4adba09b4 A few minor changes and fixing in game camera 2022-09-06 12:45:15 +01:00
Jett
fc0961ed76 Oops 2022-09-04 11:55:32 +01:00
Jett
b28b93b3f0 Add raylib submodule 2022-09-04 11:53:20 +01:00
Jett
f3ace4e7ed Visual Debugger implementation 2022-09-04 11:47:53 +01:00
14d4bf3cc5 Script for aborting a wbl zone transfer (#766) 2022-09-02 13:49:38 -05:00
26f2eb409f Mounts v2 (#726)
* Mounts -v2

* fix stun state and make comments a bit nicer

* remove extra serilization

* update the char position a bit more correctly

* make vehicles face thr player's direction

* address feedback

* fix compiling for real this time

* removed uneeded check
2022-09-02 13:49:19 -05:00
1af3e59348 Scripts for the AG sentinel camp QB wall (#761)
* Scripts for the AG sentinel camp QB wall

* use lookat

* Address feedback

* Fix stromling spawner

* fix aggro and remove logs

Co-authored-by: Jett <55758076+Jettford@users.noreply.github.com>
2022-09-01 21:44:26 -05:00
David Markowitz
e3077aa410 Fix Windows not working due to libbcrypt not working on Ninja (#765) 2022-09-01 19:24:00 -07:00
3b75ecc0b4 Add script to playfx on canisters before consoles are active (#754)
* Add script to playfx on canisters before consoles are active

* remove debug stuff
2022-08-27 21:48:03 -05:00
b70e7334e8 Parrot crash script to become a sneaky ninja and steal the pirate's booty (#752) 2022-08-26 22:58:41 -05:00
500b7885e2 Add pirate rep script (#751)
* Add pirate rep script

* fix formattimg
2022-08-25 21:09:08 -05:00
Demetri Van Sickle
bc132487e9 Updated README (Formatting and flow) (#744)
* Updated flow of database section

* Changed bolded headers to actual headers

Will now allow you to link to them

* Updated Linux build command to match build script

* Updated database wording
2022-08-25 14:16:20 -07:00
47f0830483 Add GF geyser script (#749)
* Add GF geyser script

* remove uneeeded include

* const
2022-08-25 15:51:22 -05:00
e707207ffa Add FV Geyser script (#748)
* Add FV Geyser script

* remove uneeded include

* const
2022-08-25 15:50:13 -05:00
David Markowitz
ceb374591f Move mailbox closing to its script (#740) 2022-08-18 19:42:52 -07:00
David Markowitz
c05562a227 Modularize CMakeLists for submodules (#736)
* Use RecastNavigation CMakeLists

* Use tinyxml2 CMakeLists

* Use bcrypt CMakeLists

* Move variable init to CMakeLists

This has to be done here to prevent missing dependency errors.

* General improvements

Only link dynamic if on gnu
use more thirdparty cmakes

* Disable tinyxml2 testing
2022-08-18 19:23:42 -07:00
f8c1e2fb52 Script for when archway rebuild is done (#739) 2022-08-18 15:33:32 -05:00
e4a15a0f2e Add imagimeter visibility script (#738) 2022-08-18 00:09:14 -05:00
Daniel Seiler
dd8091f60e Hide dependency compilation warnings (#696)
* Hide raknet compilation warnings

* Move out MariaDB Connector/C++ logic

* remove mariadb warnings?

* hide mariadb cmake warnings?
2022-08-17 01:43:54 -07:00
David Markowitz
50b3946548 Fix death planes (#735)
* Correct death plane size

The death plane file size is not in units but is actually in 4x2 tiles.

* Make it a bit bigger for now

* Enjoy your crust

"These things add flavor they said"

Move the position of the death barrier down 13.521004 units so we effectively only extend its hitbox in the -Y direction as opposed to the +Y direction, resolving an issue in Battle of Nimbus Station where the death plane was too tall
2022-08-16 22:28:50 -05:00
976bd3c41b Selective saving for map and location (#732)
* Don't save the map and char location info if
we are in an instanced 
* LUP worlds will be handled in a future PR
* simplify check
2022-08-16 20:53:28 -05:00
David Markowitz
3b7f1dad54 Fix death planes (#733)
* Correct death plane size

The death plane file size is not in units but is actually in 4x2 tiles.

* Make it a bit bigger for now
2022-08-16 18:53:01 -07:00
Demetri Van Sickle
54021458bd Change build command in build script (#729)
The script now uses the cmake build as to be compatible with all platforms as opposed to just platforms that supported gnu make.
2022-08-16 01:49:44 -07:00
Emmett
1e1b6aaa0b Update Docker.md submodule note (#730)
* Update Docker.md 

Changed note to recursively update git submodules, otherwise would lead users into #728
2022-08-14 11:05:07 -07:00
David Markowitz
008f953003 Add physics volume for property orb (#718) 2022-08-08 09:34:56 -05:00
David Markowitz
dc960cb99c Fix landing animation (#720) 2022-08-08 09:34:33 -05:00
2d0faae759 Merge pull request #719 from DarkflameUniverse/unix-line-endings
Unix line endings
2022-08-08 09:33:43 -05:00
932d8030f0 update git blame ignore 2022-08-08 08:31:44 -05:00
Zac Hayes
7f5ab8b9fa Dockerfile: Copy dNavigation to build dir (#722)
Fixes an issue where new directory was not copied over to the correct folder for Docker
2022-08-06 22:59:27 -07:00
Jett
6c97ea8208 Implement flying command (#713)
* Implement flying command

* Add documentation.
2022-08-06 01:19:34 -07:00
72477e01e2 convert to unix line endings 2022-08-05 22:01:59 -05:00
David Markowitz
ea86988521 Revert dZoneManager Initialization order (#717) 2022-08-05 19:20:11 -07:00
d626ac1ed4 Merge pull request #714 from DarkflameUniverse/macro-formatting
Macro formatting consistency
2022-08-05 12:37:29 -05:00
168f837b94 add blame ignore 2022-08-05 08:40:59 -05:00
9e4ce24fd2 add semi-colons to macros consistently 2022-08-05 08:40:12 -05:00
Jett
4112a85906 Fix checks for if the physics world is loaded (#711) 2022-08-05 07:41:07 -05:00
David Markowitz
408163ed35 Add windows docker setup guide to README (#712)
* Add docker windows

* Update README.md
2022-08-05 07:40:27 -05:00
aequabit
4556f13474 Mention option to use Docker in README.md (#702) 2022-08-05 01:04:45 -07:00
Jett
88f316bf93 Add null checks to all free calls to prevent crash on server close. (#709) 2022-08-04 08:54:14 -05:00
Jett
e6c7f744b5 Implement terrain file reading to generate navmeshes in the future (#703)
* Implement terrain file reading to generate navmeshes in the future

* Make Emo's suggested changes.
2022-08-04 01:59:47 +01:00
Daniel Seiler
d2b05a1ac5 Update Diagnostics.cpp (#697) 2022-08-02 08:56:50 -05:00
Daniel Seiler
a429489846 use UTF8ToUTF16 more (#695) 2022-08-02 08:56:20 -05:00
Jett
9ee219ea42 Move Navmesh code away from dPhysics (#701) 2022-08-02 06:30:19 +01:00
a0aa8b2854 standardize line endings (#700) 2022-08-01 22:37:28 -05:00
Jett
c11a4a67d1 Replace the vsprintf used in the logger with vsnprintf. (#694) 2022-08-01 15:23:01 -05:00
Jett
c69d01d77b Merge pull request #688 from DarkflameUniverse/reporter_id_fix
Remove parentheses from ADD reporter_id
2022-07-31 21:06:01 +01:00
Daniel Seiler
50cb9346b8 Merge pull request #689 from DarkflameUniverse/security-policy
Add Security Policy
2022-07-31 20:03:30 +02:00
Gie "Max" Vanommeslaeghe
17d77db1c6 Update SECURITY.md 2022-07-31 15:14:16 +02:00
Daniel Seiler
e97dc6fbff [no ci] update link to darkflame-security-announce 2022-07-31 14:06:05 +02:00
Daniel Seiler
7ec458421f Create SECURITY.md 2022-07-31 13:58:50 +02:00
0b9e97625e Remove parentheses from ADD reporter_id 2022-07-30 22:09:45 -07:00
David Markowitz
d64fa1680d Fix missions re-ordering on reload (#686)
* Fix missions re-ordering on reload

Check for success rather than failure

* Add a comment

* Get base value from database

* Update Mission.h
2022-07-30 20:56:21 -07:00
eddytronpie
f80a26a944 Fix integer issue with BricksCollected (#679)
This fixes an issue where BricksCollected goes to an insane number after selling more bricks than you collected in the area
2022-07-29 20:41:14 -07:00
David Markowitz
26ddeaa429 Fix NPC Proxy items (#684)
* Fix racing lap times

* Address NPC proxies

NPCs are supposed to equip the sub items of items they equip and were not doing so.  This PR adds this functionality and fixes and issue where Neido on Crux Prime was not wearing their sword.

Tested that Neido has their sword and that other NPCs that wear proxies also get their proxies equipped.  Had no issues with any other world crashing.
2022-07-29 19:00:36 -05:00
8b386ae6c5 Merge pull request #685 from DarkflameUniverse/editorconfig
Editorconfig and codebase format
2022-07-29 12:23:27 -05:00
f284e5a6e1 fix filename 2022-07-28 11:35:57 -05:00
1b01abd7d9 Merge branch 'main' into editorconfig 2022-07-28 09:27:06 -05:00
0e46b875a5 blame ignore and contributing update 2022-07-28 08:47:28 -05:00
19e77a38d8 format codebase 2022-07-28 08:39:57 -05:00
David Markowitz
adb6a2c609 Fix racing lap times (#683) 2022-07-27 20:54:42 -07:00
4f7aa11067 add editorconfig 2022-07-27 22:33:36 -05:00
Jett
ffd4477081 Increment DLU patch version 2022-07-27 10:08:04 +01:00
a632ef8ccd Clean up format logs (#682) 2022-07-26 23:52:53 -07:00
Jett
9e08bb20d2 Implement proper bounds checks across the codebase (#681)
* Implement proper bounds checks across the codebase

* Implement strnlen_s for cross platform
2022-07-26 20:52:04 -05:00
Daniel Seiler
9813c3ed2c Better Unicode support in GeneralUtils (#658)
* ASCIIToUTF16: output replacement character instead of failing assert

* Add GeneralUtils::_NextUTF8Char

* Implement GeneralUtils::UTF8ToUTF16

* use string_view everywhere

* use string_view::front instead of begin

* Add PushUTF16CodePoint
2022-07-25 21:11:30 -07:00
e97ae92624 Make logger automatically put a newline (#675)
at the end of the line
remove all the newlines in log calls
2022-07-24 21:26:51 -05:00
a7fb6eb3f3 make LoadFromXml usage consistent across comps (#673) 2022-07-24 21:03:22 -05:00
9ed4a4f47f Remove uneeded include (#674) 2022-07-24 16:17:01 -05:00
b57cacc676 Player forced movement component (#672)
* Split out Level progression component
from Character Component
This is to get to the Player forced movement Comp in a sane way

* move XML to component insted of abusing charComp

* use overrides
should probably make everything that calls that call it correctly

* fix linking issue

* Add proper Player Force movement component
Not used, yet
2022-07-24 13:25:10 -05:00
f2d1c5d26d Split out Level progression component (#671)
* Split out Level progression component
from Character Component
This is to get to the Player forced movement Comp in a sane way

* move XML to component insted of abusing charComp

* use overrides
should probably make everything that calls that call it correctly

* fix linking issue
2022-07-24 13:04:02 -05:00
David Markowitz
ef0a3c6d0b Add Hot Properties struct and address some whitespace (no functionality change) (#667)
* Add GameMessages

* General AMF cleanup

Proper memory management as well as style cleanup

* General AMF cleanup

Proper memory management as well as style cleanup

* General optimizations

Fix AMFArray so values are properly deleted when you leave the scope it was created in.
Add bounds check for deletion so you don't double delete.
Remove all AMFdeletions that are contained in an array since the array now manages its own memory and deletes it when it is no longer needed.

* Better tests and fix de-serialize

Fix de-serialize to be correct and implement a test to check this

* Update AMFDeserializeTests.cpp

* Update GameMessages.h

* Add GM

* Comment out function

* Spacing

* eof
2022-07-22 19:58:20 -07:00
David Markowitz
6a38b67ed5 General AMF cleanup (#663)
* General AMF cleanup

Proper memory management as well as style cleanup

* General optimizations

Fix AMFArray so values are properly deleted when you leave the scope it was created in.
Add bounds check for deletion so you don't double delete.
Remove all AMFdeletions that are contained in an array since the array now manages its own memory and deletes it when it is no longer needed.

* Better tests and fix de-serialize

Fix de-serialize to be correct and implement a test to check this

* Update AMFDeserializeTests.cpp

* Update AMFFormat.cpp
2022-07-21 22:26:09 -07:00
5523b6aafc Refactor UpdateEntities to not lose items if we add them while processing (#664)
* if we are deleting entities, and we add an entity
to delete, dont throw it out

* made it all uniform

* change update back to how it was
since it's an unordere map and
wouldn't be guaranteed to update even in this secnario
2022-07-21 21:09:25 -05:00
David Markowitz
40a9aefb5b Aggro radius (#665) 2022-07-20 20:26:52 -07:00
Jett
91f2cebcc7 Merge pull request #661 from EmosewaMC/bons-fixes
Use Aggro and Tether radii settings from Entity Settings
2022-07-20 10:10:57 +01:00
David Markowitz
45a7dbdadd Add Unimplemented GameMessages (#662) 2022-07-20 01:28:57 -07:00
Daniel Seiler
74bca38253 MSVC: set source / target encoding (#659) 2022-07-20 01:23:53 -07:00
EmosewaMC
082a2a418f Use radii from settings
Override the DB aggro and tether radii from the settings if they are present.
2022-07-19 23:25:50 -07:00
David Markowitz
835cf2b794 Add an AMF Deserializer as well as corresponding Unit Tests (#599)
* Add AMFDeserializer

Add an AMFDeserializer

Reverted unrelated changes

Add unit tests for AMFDeserializer

Added unit tests for the AMFDeserializer

Finish tests

Finish the AMF deserializer tests.  This commit finishes the positive test case and implements a load test case that is expected to take less than 1.5 seconds to process.

Modularized tests

Made tests a bit modular and split into more methods

Specified binary read from file

Specified that on the IO stream we are reading a binary file otherwise windows will terminate reading the binary file on seeing a 1A byte.

Added more tests

Added tests for unimplemented values and edited a test file to be more modular

Updated test text

Fix spacing

Update AMFDeserializeTests.cpp

* Update CMakeLists.txt

* Update AMFDeserializeTests.cpp

f

Actually follow the AMF spec

Update AMFDeserializeTests.cpp

tabs

Add in commented tests

* Follow spec

formatting

Add Integer Tests

Follow Spec more

Follow spec

* Use unique_ptr

* Update AMFDeserialize.cpp

Semantics

Update AMFDeserialize.cpp

Add new lines to EOF

CMake fix

* Add better std string read

Co-authored-by: Daniel Seiler <xiphoseer@mailbox.org>

* make not static

Co-authored-by: Daniel Seiler <xiphoseer@mailbox.org>
2022-07-19 21:51:05 -07:00
David Markowitz
74343be871 Enable _dynamic by default (#656) 2022-07-19 16:52:39 -05:00
David Markowitz
ed5ced0bed Fix Model Component Serialization (#655)
* Fix model component serialization

* Update ModelComponent.h
2022-07-19 16:51:35 -05:00
3dfe363a6b Added Aronwk and Simon to the readme (#657)
* Added myself and Simon to the readme

Me, since I've started to work on implementing mounts again.
Simon for his work in Reverse engineering the client which has been helping over the years.
Venture Vision and moving platforms/simple movers being two recent things that his RE has helped fix.

moved the special thanks out a header at the suggestion of Xipho and Max, since these people have not directly contributed to the DLU codebase.
made a section under the DLU team recognizing Blaster for the Logo that DLU uses
bumped up the credits header to make formatting make more sense

* Update based on feedback

Credit Blaster builder as they requested.
Remove duplicate entries for under DLU Team as requested
2022-07-19 09:29:26 -05:00
Jett
8e5da2cf1f Merge pull request #652 from DarkflameUniverse/blacklist-and-chat-changes
Blacklist and chat changes
2022-07-19 10:40:44 +01:00
Demetri Van Sickle
ec4ed8fa7e Adding migration command to build script (updated) (#653)
* Added checks for migration runner

* Added migration command to build script
2022-07-18 18:44:21 -05:00
David Markowitz
b55606d41e Fix the issue where we would create new worlds on ports that were still being used (#625)
* Wait for world to shutdown

We need to wait for the message that the world has shutdown before shutting it down.

* Dont sent people to dead instances

* Added shutting down check

Added check for isShuttingDown

* Update when we remove from master
2022-07-18 18:08:33 -05:00
Jett
69a0d5a50b Efficiency and naming changes. 2022-07-18 10:01:43 +01:00
Jett
945e572493 Add best friend check and complete blacklist 2022-07-17 09:40:34 +01:00
ef8c2a40f3 Framework for GM's and helpers for mounts (#651)
* Framework for GM's and helpers for mounts

* docs and spacing

* whitespace
2022-07-17 02:35:11 -05:00
Jett
fab8a1e982 Implement new chat features 2022-07-17 07:54:36 +01:00
Jett
0d4f86b20b Resolve missing RakNet replacement (#650)
Repair issue from PR earlier, crucial fix.
2022-07-17 06:57:00 +01:00
David Markowitz
c689b3d3d1 Parent and Child Deletion Improvements (#649)
* Fix timers

* Update Entity.cpp

* Fix timers

Fix timers

Remove debug logs

remove _dynamic

* I like to move it move it

* Child Deletion Improvements

* Check bounds
2022-07-16 21:39:13 -07:00
Jett
77d35019cc Replace the usage of RakString (#648) 2022-07-17 04:40:46 +01:00
9287e5bc4b Split itemType enum into it's own header (#647)
* Split itemType enum into it's own header
add mount item type

* fix whitespace
2022-07-16 20:36:09 -05:00
David Markowitz
f5ae5aa13e Address timers being iterated through poorly (#646)
* Fix timers

* Update Entity.cpp

* Fix timers

Fix timers

Remove debug logs

remove _dynamic

* I like to move it move it
2022-07-16 20:21:35 -05:00
Jett
df0f11c95b Update CMake configuration for easier maintenance (#642)
* Update CMake configuration for easier maintenance

* Incorrect casing fix

* Move package requirement

* Update CTest linking

* Add logs to the CMake

* Add linking for common libraries

Added linking for common libraries in tests subdirectory.

* Move test subdirectory higher up for some reason

* Whitespace a log removal

Missed new line

* Add dCommon to dChatFilter

* Update library output dir

* Correct libBcrypt

* Further refactor CMake behaviour

* Repair bad comments and update library defines

* Revert to old include directory method

* Implement platform defines

* Add missing include

Mac needs a specific include for defining platform.  Does not compile without this.

Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com>
2022-07-17 00:24:16 +01:00
Jett
9c0819de4f Add MacOS building to the Github Actions (#643)
* Add MacOS to CMakePresets.json

* Update workflow to run MacOS builds

* Update test and build presets

* Add libssl install to integration

* Update workflow to install libssl and openssl

* Prevent brew running as super user
2022-07-16 22:55:54 +01:00
David Markowitz
3d46d703b2 Remove memory leak in player container and warning in Behavior (#640)
* Add friends list migration

* Change friends to use charID

Update friends table to use charID and not LWOOBJID variant.

* Fix remove friend

Fix remove friend and make the query more readable at a glance.

* Add and remove friends in the container

Properly add and remove friends in the player container

* add enums

* Add best friends and basic GM support V1

* Add more features

* not online / doesnt exist implementation

Implements the not online and invalid character response codes

* Address players not being removed

Fix an issue where players would not be marked as offline in the friends list due to the message not being sent in all circumstances.

Tested changes on 3 clients, switching characters, logging out from character select, switching characters, world transfer and my friends list looked as it was supposed to.

* Implement proper friends system

Remove debug logs

Track count of best friends

Add best friends list cap of 5

Add config option and best friend update

Add a config option and implement the last missing best friend serialization

Added comments and fixed remove best friend bug

Added some comments and addressed an issue where removing best friends would not remove them from your internal count of friends.

properties and logs fixes

whoops, had an issue

send reply if already BFFs

Send the correct objectID

I really need to rename these

Fix white space

goon

* Replace queries with unique ptrs

* remove user from player container on deletion

Remove the user from the player container when they delete their character.

* Bump patch version

* Improvements to PlayerContainer

Resolved a memory leak in the player container, removed commented out code and resolved a warning in Behavior.cpp

* Make it a unique ptr

* Improvements to PlayerContainer

Resolved a memory leak in the player container, removed commented out code and resolved a warning in Behavior.cpp

Make it a unique ptr

* Update PlayerContainer.cpp
2022-07-13 09:11:24 -07:00
David Markowitz
9ba297dd2e Add code to complete hidden property mission (#641) 2022-07-13 09:10:02 -07:00
David Markowitz
ccb9f7c499 Move instruction for database
Move the instruction for running the MasterServer migration down to where the command will actually work as well as use a more syntactically correct statement
2022-07-12 20:45:25 -07:00
David Markowitz
24dbd3944d Friends List Overhaul (#630) v103
* Add friends list migration

* Change friends to use charID

Update friends table to use charID and not LWOOBJID variant.

* Fix remove friend

Fix remove friend and make the query more readable at a glance.

* Add and remove friends in the container

Properly add and remove friends in the player container

* add enums

* Add best friends and basic GM support V1

* Add more features

* not online / doesnt exist implementation

Implements the not online and invalid character response codes

* Address players not being removed

Fix an issue where players would not be marked as offline in the friends list due to the message not being sent in all circumstances.

Tested changes on 3 clients, switching characters, logging out from character select, switching characters, world transfer and my friends list looked as it was supposed to.

* Implement proper friends system

Remove debug logs

Track count of best friends

Add best friends list cap of 5

Add config option and best friend update

Add a config option and implement the last missing best friend serialization

Added comments and fixed remove best friend bug

Added some comments and addressed an issue where removing best friends would not remove them from your internal count of friends.

properties and logs fixes

whoops, had an issue

send reply if already BFFs

Send the correct objectID

I really need to rename these

Fix white space

goon

* Replace queries with unique ptrs

* remove user from player container on deletion

Remove the user from the player container when they delete their character.
2022-07-12 20:36:06 -07:00
Jett
5888c9f468 Merge pull request #635 from DarkflameUniverse/improve-cpplinq-min-max-checks
Improve cpplinq checks
2022-07-12 11:17:59 +01:00
Jett
c9cd7a200a Merge pull request #634 from DarkflameUniverse/migration-runner
Add a argument to the MasterServer for running migrations
2022-07-12 11:17:42 +01:00
David Markowitz
b7497a47e4 Lower memory usage of Behavior Parameter Table by 10MB (#627)
* Added caching for table

Added caching for table

Add more caching

Update MasterServer.cpp

grds

Update CDBehaviorParameterTable.cpp

Update CDBehaviorParameterTable.h

Update CDBehaviorTemplateTable.cpp

Update Behavior.cpp

Update Behavior.cpp

change to map

Remove redundant query

* Remove include

* change to enum

* Update Behavior.cpp

* Use already cached table

* Update Behavior.cpp

* Reduce memory usage

Reduces the memory usage for the BehaviorParameter table by 10MB in memory.

* Update CDBehaviorTemplateTable.cpp
2022-07-11 20:43:09 -07:00
Jett
bfa1f57158 Improve cpplinq checks
On certain Windows header versions defining NOMINMAX doesn't work for some odd reason.
2022-07-12 03:06:54 +01:00
Jett
d642de9462 Implement a migration runner 2022-07-12 02:16:08 +01:00
David Markowitz
06217ad5e3 Address friends list IDs and removal of friends (#628)
* Add friends list migration

* Change friends to use charID

Update friends table to use charID and not LWOOBJID variant.

* Fix remove friend

Fix remove friend and make the query more readable at a glance.

* Add and remove friends in the container

Properly add and remove friends in the player container
2022-07-10 17:59:07 -07:00
David Markowitz
325dc5a571 Revert "Wait for world to shutdown (#624)" (#626)
This reverts commit 66edf57b02.
2022-07-09 15:57:45 -07:00
David Markowitz
66edf57b02 Wait for world to shutdown (#624)
We need to wait for the message that the world has shutdown before shutting it down.
2022-07-09 15:27:20 -07:00
David Markowitz
485de6173a Added caching for behavior parameter table (#621)
* Added caching for table

Added caching for table

Add more caching

Update MasterServer.cpp

grds

Update CDBehaviorParameterTable.cpp

Update CDBehaviorParameterTable.h

Update CDBehaviorTemplateTable.cpp

Update Behavior.cpp

Update Behavior.cpp

change to map

Remove redundant query

* Remove include

* change to enum

* Update Behavior.cpp

* Use already cached table

* Update Behavior.cpp
2022-07-08 23:07:52 -07:00
dddc33607b remove unused code and callbacktimers in testmap (#620) 2022-07-08 22:25:44 -05:00
3865a186a7 Possessor and possessable additions (#619)
* possessor-fixup and possessable additions

* comment and docstring fixes

* fix possessable initialization

* split animation flags into it's own header
remove unnecessary checks
2022-07-08 22:25:15 -05:00
David Markowitz
22b2516107 Fix nested preconditions not evaluating costs (#618)
Fixed an issue with some builds that had preconditions not taking items from the players due to the evaluate costs parameter not being passed to nested conditions.

Tested the build in Avant Gardens and it now correctly takes items from the player upon completion.
2022-07-06 19:29:15 -07:00
David Markowitz
0734760d42 Add openssl to list of package requirements
I forgot to add this to the list of needed packages.
2022-07-06 12:05:42 -07:00
David Markowitz
138fffda2c Fix item collection missions (#617)
* Implement Precompiled Headers

* fix cmake

* Fix modular builds not returning parts

Modular builds would not search inventory A for their corresponding item and by default would only look in the models bag.  This PR forces the item to be looked for in the inventory its coming from (inventoryA) as a second resort before doing the final search in the default inventory of the item.

Tested modular building a car and a rocket and when replacing parts the part that was already placed was returned to the inventory correctly.

* Push equipped items upon entering build mode

Fixes an issue where leaving build mode anywhere would not re-equip your items.  This also implements the feature to set your stats back to full, as was done in the live game.

Tested exiting build mode on a property with full venture gear and all gear was re-equipped and stats were set to the expected values.

* Fix item collection missions

Item collection missions are only supposed to take items should they be in the items inventory or the hidden inventory and no others.  This change removes the global inventory find of items and only removes it from the two inventories that items get taken from in live, ITEMS and HIDDEN

Tested completing mission 470 and 477 as well as 622 and the correct items were taken or not taken, based on the inventory the target item was in.
2022-07-06 08:54:41 -07:00
David Markowitz
de5d9182eb Address items not re-equipping upon exiting build mode (#615)
* Implement Precompiled Headers

* fix cmake

* Fix modular builds not returning parts

Modular builds would not search inventory A for their corresponding item and by default would only look in the models bag.  This PR forces the item to be looked for in the inventory its coming from (inventoryA) as a second resort before doing the final search in the default inventory of the item.

Tested modular building a car and a rocket and when replacing parts the part that was already placed was returned to the inventory correctly.

* Push equipped items upon entering build mode

Fixes an issue where leaving build mode anywhere would not re-equip your items.  This also implements the feature to set your stats back to full, as was done in the live game.

Tested exiting build mode on a property with full venture gear and all gear was re-equipped and stats were set to the expected values.
2022-07-06 01:30:13 -07:00
David Markowitz
3cf243b1d7 Address modular build not returning parts upon switching some out (#614) 2022-07-05 23:18:04 -07:00
David Markowitz
8cdb388915 Optimize scripts for faster compilation (#597)
* Implement Precompiled Headers

* First volume of optimizations

* Scripts A-B

Gonna be doing this in alphabetical order now.

* C Scripts and remove unneeded includes from base cppscripts header

Remove the MissionComponent and Loot includes from all base scripts and place their needed includes in the respective scripts.

* D scripts

* F scripts

* F scripts 2

Finish up removing extraneous includes from scripts that start with the letter F

* G scripts

Removing extraneous includes from scripts that start with the letter G

* I scripts

Removing extraneous includes from scripts that start with the letter I

* M-Z scripts

Removing extraneous includes from scripts that start with the letter M-Z

* Revert "Implement Precompiled Headers"

This reverts commit d79d8d4991.

* Revert "Revert "Implement Precompiled Headers""

This reverts commit 0597faf308.

* Add back in PCH

Add back in PCH

* Fix CMake

Whitespace

Remove duplicate file glob

Remove newline
2022-07-04 23:00:10 -07:00
David Markowitz
cc25ec0151 Add Venture Vision Behavior (#609)
Add the Venture Vision behavior and associated functionality.  Pet digs still do not show up however.

The Kit bonus for factions have been tested and properly grant and take away the buff when it is casted and uncasted.  Tested as well using multiple Venture Vision behaviors at once and the vision only went away when there were zero equipped at once.

Remove extra includes

Convert to Tabs

Remove extra forward declaration
2022-07-04 21:48:56 -07:00
David Markowitz
8a54e7ccd2 Implement Precompiled Headers (#591)
When applied, this will speed up compile times dramatically.
2022-07-04 15:24:45 -07:00
Daniel Seiler
6e2936504c Improve CI (#345)
* Don't upload artifacts unless on main

* Fix if/endif mismatch warning

* Add thirdparty CMakeLists

* Keep more warnings around

* Remove more RakNet warnings

* Fix indentation and divided the cmake into libraries and bins

- Each library and binary got their own CMakeLists.txt
- Indentation was fixed everywhere
- Weird if statement flows replaced

* Revert "Fix indentation and divided the cmake into libraries and bins"

This reverts commit 005a12424e.

* Add async value assignments

Resolves a warning where on some compilers this thread would _not_ be run async and would instead be run synchronous with the main thread, halting execution.

* Revert "Add async value assignments"

This commit was meant to be done on a seaparate branch but was accidentally pushed upstream to this branch.

* Fix Merge Conflict

* Resolve errors

Resolve errors with using continue() outside a foreach loop.

* breakout mariadb to thirdparty cmake

Move the mariadb cmake to its own directory to make each cmake file more focussed.

Co-authored-by: Jett <55758076+Jettford@users.noreply.github.com>
Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com>
2022-07-04 01:30:11 -07:00
jumpy-badger
eaa962f265 Add Aarch64 support (#231)
* added mariadb-connector-cpp submodule

* raknet aarch64 support

* fix compile errors

* mariadb connector swap (in progress)

* update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors

* update types with missing aarch64 check

* corrected adding extra flag to properly compile mariadbconn in CMakeLists

* updated readme with arm builds section

* fix build failure if test folder does not exist

* Remove mysql connector from all builds, add mariadbconnector to windows build

* readd Linux check for backtrace lib to CMakeLists.txt

* Separate system specific mariadbconncpp extra compile flags

* Copy dlls to exes directory once built

* fetch prebuilt binaries on windows so that ClangCL can be used

* Delay load dll so that plugin directory is set correctly

* Fixed typo in glibcxx compile flag

* whitespacing, spaces -> tabs

* Updated README.md, included instructions to update

* Updated README.md

added libssl-dev requirement and removed mysql connector references from macOS builds section

* apple compile fixes for zlib and shared library name

* add windows arm64 checks to raknet

* remove extra . in shared library location

* Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple

* Fix copy paths for single config generators and non windows

* change plugin folder location, another single config generator fix

* GENERATOR_IS_MULTI_CONFIG is a property not a variable

* Fixed a few errors after merge

* Fix plugin directory path, force windows to look at the right folder

* fixed directory name for make_directory command

* Update README.md

Updated MacOS, Windows build instructions.

* set INSTALL_PLUGINDIR so that the right directory is used

* Support for relative rpath for docker build

* added mariadb-connector-cpp submodule

* raknet aarch64 support

* fix compile errors

* mariadb connector swap (in progress)

* update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors

* update types with missing aarch64 check

* corrected adding extra flag to properly compile mariadbconn in CMakeLists

* updated readme with arm builds section

* fix build failure if test folder does not exist

* Remove mysql connector from all builds, add mariadbconnector to windows build

* readd Linux check for backtrace lib to CMakeLists.txt

* Separate system specific mariadbconncpp extra compile flags

* Copy dlls to exes directory once built

* fetch prebuilt binaries on windows so that ClangCL can be used

* Delay load dll so that plugin directory is set correctly

* Fixed typo in glibcxx compile flag

* whitespacing, spaces -> tabs

* Updated README.md, included instructions to update

* Updated README.md

added libssl-dev requirement and removed mysql connector references from macOS builds section

* apple compile fixes for zlib and shared library name

* add windows arm64 checks to raknet

* Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple

* Fix copy paths for single config generators and non windows

* change plugin folder location, another single config generator fix

* GENERATOR_IS_MULTI_CONFIG is a property not a variable

* Fixed a few errors after merge

* Fix plugin directory path, force windows to look at the right folder

* fixed directory name for make_directory command

* Update README.md

Updated MacOS, Windows build instructions.

* set INSTALL_PLUGINDIR so that the right directory is used

* Support for relative rpath for docker build

* Rebase on main

* Remove extra git submodule

* Update CMakeLists.txt

* Remove CMakeLists.txt file from mariadb

Remove the CMakeLists.txt file from the mariaDBConnector so we dont build the tests.  Also add a config option to the CMakeVariables.txt so you can build the connector with multiple jobs

* Compile on windows

Specify the mariadbcpp.dll file location with a defined absolute path so windows knows it actually exists.

* default to 1 job

Default mariadb jobs running in parallel to 1 instead of 4

* Move mariadbcpp.dll file to the expected directory on windows

* Changed plugin

Updated the plugin location from the project binary directory to the expected location, the mariadb binary directory.

* Addressed windows dll issues by moving files to the expected directory instead of a directory that wouldnt get created

* Update README

Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com>
2022-07-03 21:33:05 -07:00
1497d9b35a breakout possessor from char comp (#606)
* breakout possessor from char comp
Use the correct component for possessor
cleanup scirps that were using possessor improperly
beginnings of mounts

* fix comments
added bounds check
2022-06-29 18:50:24 -05:00
David Markowitz
a55162775e Address incorrect stun played by growl speakers (#605)
Add the FireFirstSkillonStartup script to allow for scripts that use this to function.

Add comments

Fix QB Stunner scripts

Use SetVar for variable

Remember that variables for scripts need to be stored in the entity since a script can be used across multiple entities.

Remove unused variable

Specify Unsigned Int

Start skill asap, not next tick
2022-06-28 23:17:45 -07:00
David Markowitz
670a2de95b Address issue with Inventor Beehive and Buccaneer Monkey ability on valiant weapon (#604)
* Add Script

Add the FireFirstSkillonStartup script to allow for scripts that use this to function.

* Add comments
2022-06-27 21:36:18 -07:00
94e161df55 Address players leaving Battle of Nimbus Station causing a crash that wont save (#600) 2022-06-24 15:26:09 -05:00
David Markowitz
06dc18fb49 Merge pull request #594 Add new contributors to contributions list
Add new contributors to contributions list
2022-06-22 16:58:38 -07:00
Jett
00f7a5c4d6 Update README.md 2022-06-22 08:57:36 +01:00
5dd4086bd5 yoink
I just want mounts to work, this isn't fun
2022-06-21 20:10:44 -05:00
1b222a64c3 removing myself from the situation 2022-06-21 20:07:44 -05:00
Jett
6a7c6da01a Update to simpler list. 2022-06-22 00:35:24 +01:00
Jett
9bfff533c3 Update Darwins link on the README 2022-06-22 00:04:45 +01:00
Jett
8e9c48cce0 Update README.md 2022-06-21 23:57:47 +01:00
Jett
fb81c0c9a2 Update CREDITS.md with more accurate information 2022-06-21 09:04:31 +01:00
Jett
c0d05b00df Replace list with new formatting 2022-06-21 09:03:31 +01:00
Jett
ef0873075f Reflect the same order as that in the CREDITS.md file 2022-06-21 07:04:41 +01:00
David Markowitz
c89f420204 Merge pull request #593 Fix issue with dropship computer
Fix issue with dropship computer
2022-06-20 22:48:52 -07:00
Jett
ea94de16cd Update Xiphoseers position on the project 2022-06-21 06:48:35 +01:00
Jett
c5f2f4b708 Update CREDITS.md 2022-06-21 06:45:19 +01:00
Jett
cb6d91cfb2 Revert "Update Credits markdown data"
This reverts commit e24ad43dc5.
2022-06-21 06:44:40 +01:00
Jett
e24ad43dc5 Update Credits markdown data 2022-06-21 06:44:21 +01:00
Jett
09d50faf79 Add new contributors to contributions list 2022-06-21 06:40:19 +01:00
EmosewaMC
6b30292efd Fix issue with dropship computer
The dropship computer now no longer gives a player a second mission item should they interact with it again after mission completion
2022-06-20 22:22:32 -07:00
David Markowitz
5f34b7150a Merge pull request #592 Added item precondition checks
Added item precondition checks
2022-06-20 21:41:08 -07:00
EmosewaMC
43377caa3b Added item precondition checks
Added item precondition checks for items so players who do not meet the conditions cannot use the items.  tested with the faction bag tokens and they only gave the tokens when a player met all the preconditions or was a Game Master of level 6+
2022-06-20 21:03:08 -07:00
29199f4755 Update README.md 2022-06-19 18:34:18 -07:00
David Markowitz
f4b89a8925 Merge pull request #590 Fix instances not stopping on all players leaving
Address order of deletion of entities on server to allow scripted activities to properly remove players
2022-06-19 14:26:23 -07:00
EmosewaMC
968114199b The shooting Gallery now properly ends when a player leaves the instance
The shooting Gallery now properly ends when a player leaves the instance

Frakjaw player update

Update the Frakjaw battle instance script to remove players when they leave the instance

Simplify comparison

Simplify comparison for entity pointer to be implicit
2022-06-19 01:40:16 -07:00
EmosewaMC
c871aeef56 Merge branch 'ScritpedActivityFixes' of https://github.com/EmosewaMC/DarkflameServer into ScritpedActivityFixes 2022-06-19 00:14:42 -07:00
EmosewaMC
9cf534dc0a Move to new branch
Added comments

Added some comments and changed a variable name to be less ambiguous.
2022-06-19 00:14:33 -07:00
EmosewaMC
de47210f15 Move to new branch
Added comments

Added some comments and changed a variable name to be less ambiguous.
2022-06-19 00:12:02 -07:00
David Markowitz
ba5037300f Merge pull request #587 Address pets not consuming imagination on summon or while being active
Address pets not consuming imagination on summon or while being active
2022-06-18 20:26:55 -07:00
EmosewaMC
2e224cb151 update name
Pets will take imagination by default now
2022-06-18 13:25:34 -07:00
EmosewaMC
2a0616d0e9 Dont take imagination on initial tame 2022-06-18 00:16:00 -07:00
EmosewaMC
0774ab930d inverted config check
Since most people are not regularly updating their config files, this needs to assume the value is disabled rather than enabled.
2022-06-18 00:09:05 -07:00
EmosewaMC
e415d96a9d Added config setting
Added a config setting to allow players to disable pets consuming imagination.  This value defaults to zero as a feature of DLU.
2022-06-18 00:03:27 -07:00
EmosewaMC
35ea3d35ae Add pet imagination draining
Address an issue where pets did not consume imagination when they were spawned.
2022-06-17 23:53:09 -07:00
EmosewaMC
e28b084395 Add GM
Added GM for UseItemRequirementsResponse that was missing in current implementation
2022-06-17 22:19:28 -07:00
EmosewaMC
136937184e Add to common vars and dnet
Added values to enums on dnet and common vars that were missing
2022-06-17 22:18:46 -07:00
David Markowitz
2403a7fe45 Merge pull request #585 Fix child entities not being removed from their parents correctly on deletion
Fix child entities not being removed from their parents correctly on deletion
2022-06-16 19:34:03 -07:00
EmosewaMC
531c4a594c remove children
We need to make sure we are actually deleting children from the vector of children when they are deleted as entities.
2022-06-16 17:50:33 -07:00
David Markowitz
1fe6c32933 Merge pull request #584 Fix an issue where quickbuilds were sometimes unbuildable
Fix an issue where quickbuilds were sometimes unbuildable
2022-06-16 09:06:45 -07:00
EmosewaMC
4a39221dd0 Address reviews
Changed the activator position parsing to have TryParse so that we dont throw an exception trying to load the position.  Should the loading of the activator position fail the game will default to the position of the entity.

change delimiter value to hex

Updated the character delimiter used for rebuild_activator settings to use hex

Remove extra parsing of activator position

in Entity.cpp we were parsing the activator position but when doing so where we were, this was after we had ended up spawning the activator since that is now in the constructor of the rebuild component.  The extra parsing has been removed.

Simplify dirty parent/child info

Simplify the if condition for parent child info.  This info only needs to be written should it be changed (dirty) or if the packet being sent is a construction, meaning that a requesting player needs all base data and needs to know what parents/children an entity has at that time.

get rid of extra parenthesis

Left over extra parenthesis were around these conditions on accident
2022-06-16 08:50:01 -07:00
EmosewaMC
09c459a083 Added comment 2022-06-15 23:17:44 -07:00
EmosewaMC
7dfcd22a2e Properly place build activator
The build activator as a result of the previous changes was spawning at the wrong position.  This commit pulls the activators position from the settings (should they exist) and sets them accordingly.
2022-06-15 22:59:30 -07:00
EmosewaMC
8bdd5b6e2c Address quickbuilds being unbuildable
Address an issue where quickbuilds would become unbuildable.  The main issue lied within serializing parent/child info too often for some reason / serializing it when the info wasnt dirty.  Only serializing this info when it is actually dirty and has changed has addressed the issue and allows quickbuilds to never break.
2022-06-15 22:58:38 -07:00
David Markowitz
4556faf833 Merge pull request #583 from EmosewaMC/SetLevelCommand
Add setlevel command
2022-06-13 01:06:41 -07:00
EmosewaMC
1179f5a2fe Add setlevel to commands doc 2022-06-13 00:45:29 -07:00
EmosewaMC
a61c6e5e41 Add /setlevel slash command
Add the setlevel slash command.  Command accepts parameters of the requested level and a player to set the level of.  This also adjects the uscore of the player accordingly.  The player must re-log upon using the command to see any updates to themselves or others.
2022-06-13 00:45:17 -07:00
Jett
1f62f169c8 Merge pull request #582 from DarkflameUniverse/revert-581-bons-hotfix
Revert "Don't give activity loot for Battle of Nimbus Station"
2022-06-13 04:20:54 +01:00
Jett
842cb80137 Revert "Don't give activity loot for Battle of Nimbus Station" 2022-06-13 04:19:27 +01:00
David Markowitz
2868465e89 Merge pull request #581 Don't give activity loot for Battle of Nimbus Station
Don't give activity loot for Battle of Nimbus Station
2022-06-12 19:25:56 -07:00
EmosewaMC
ef8ea13d99 Don't give activity loot for Battle of Nimbus Station
Address an issue on Brick Mesa where Battle of Nimbus Station was dropping activity loot.  Tested completing Battle of Nimbus Station and ending early and was not given loot as is expected.
2022-06-12 19:25:28 -07:00
David Markowitz
df9f9f08b6 Merge pull request #580 Address issue with bricks selling 1 at a time
Address issue with bricks selling 1 at a time
2022-06-12 14:15:42 -07:00
David Markowitz
50fd27b973 Merge branch 'DarkflameUniverse:main' into selling-fix-bricks 2022-06-12 11:49:17 -07:00
EmosewaMC
81431cfcbd Address bricks selling 1 at a time
Bricks have a stack size of zero in the cdclient so we need to make sure to give them a full stack size of 999 as we do for the bricks inventory with the selling inventory.
2022-06-12 11:48:52 -07:00
David Markowitz
7af248feeb Merge pull request #578 Fix Selling "random" item
Address issue with selling/moving items grabbing a "random" item
2022-06-12 11:43:36 -07:00
EmosewaMC
fbf0b59ff1 Fix item getter for moving items
This fixes an issue where the item would get overwritten and would effectively fetch a "random" item in the inventory to move instead of the requested one.
2022-06-12 10:56:01 -07:00
David Markowitz
c5dff54e01 Merge pull request #577 Address issue with some kills not contributing towards progress
Address issue with player spawned abilities not getting team
2022-06-11 22:01:41 -07:00
EmosewaMC
30c8326c3e Move owner override
Mover owner override to be earlier so that we dont try to get the team of an entity that doesnt have a team and may be a child entity of a player.  Tested changes with a team of two players and players were correctly given credit for kills
2022-06-11 20:50:01 -07:00
Shane Clark
d8cde40b49 Fix unhealthy docker containers (#574)
* Add curl to brickfix dockerfile.

* Add curl to AccountManager docker.

* Fix issue preventing container from building.
2022-06-11 19:31:58 -05:00
David Markowitz
db773e9778 Merge pull request #573 Fix crash for Footraces on Windows
Corrected ambiguous string to number conversion  which would cause a crash on operating systems where a long is 32 bits and not 64 bits.
2022-06-06 23:09:10 -07:00
EmosewaMC
33cc3a3dd9 Corrected string to long conversion
For Windows, the definition for a long is 32 bits, not 64 bits like on other operating systems.  This caused an issue on Windows only where a number larger than 32 bits was attempted to be converted to a long, the WorldServer would crash.  This commit replaces all instances of `stol` with `stoull` to further define a long and reduce ambiguity of number length.
2022-06-05 21:02:41 -07:00
66215da37a Fix overrides in ActMine (#568) 2022-05-31 00:24:55 -05:00
David Markowitz
73bbe641c6 Merge pull request #567 Address solo activity team sizes
Activities that would now force players into teams no longer make teams of size 1.
2022-05-27 19:04:46 -07:00
c6f871d42b only make teams for minigames
if we have more than one participant
2022-05-27 15:25:57 -05:00
Jett
445c01d485 Add instructions on solving missing DLL issue (#379)
* Add instructions on solving missing DLL issue

* Repair formatting to be consistent
2022-05-25 18:41:42 -05:00
luke-sparks
915b779f03 Update Docker.md with buildkit and submodule notes. (#458)
* Update Docker.md

Add link to enabling docker buildkit. Add note to remember to clone submodules.

* Remove unpacked client option

Unpacked client does not have required directories/files (e.g. /versions/trunk.txt) and thus the packed client is required.

* Add note about renaming CDClient.fdb

DarkflameSetup will fail because it cannot find cdclient.fdb. However, CDClient.fdb exists. Renaming it fixes the issue.

* Remove extra "client"
2022-05-25 12:32:18 -05:00
David Markowitz
731c25741c Merge pull request #563 Fix leaderboard not updating when it is supposed to
Fixed leaderboards not updating when they are supposed to.
2022-05-24 20:36:35 -07:00
HailStorm32
f8d73ccbc5 Fixed display logic for NS Survival leaderboard 2022-05-25 02:03:40 +00:00
HailStorm32
f5caa1f00d Merge branch 'leaderboard-updates' of https://github.com/Verathian/DarkflameServer into leaderboard-fix-resubmit 2022-05-25 02:00:10 +00:00
David Markowitz
769f789a43 Merge pull request #354 Sanitize SQLite Queries
adds support to prevent sql injection via using prepared statements and also fixes an issue with the runmacro command.
2022-05-24 17:31:58 -07:00
e3422ac0c5 Merge branch 'main' into main 2022-05-24 19:00:52 -05:00
Jasper Reddin
cdb2cf0344 Added Comprehensive Slash Command Documentation (#402)
* Added documentation for all available commands

* Adjust formatting, removing backtick characters

* Replace HTML tables with Markdown tables

* Formatting changes

* Suggestions from @sersorrel in #402 and other minor edits

* Add detailed usage for /inspect

(thanks to @sersorrel for this information, in discussion of #402)
2022-05-23 21:59:31 -05:00
David Markowitz
44e17eabca Merge pull request #559 Properly implement climbable setting for climbables
This shouldn't change anything that was available in live but anything that can be spawned in as climbable is able to be done so now.
2022-05-19 12:38:40 -07:00
06df15717c maybe fix it 2022-05-19 08:40:50 -05:00
813aca9d20 resolve comments 2022-05-18 06:36:21 -05:00
David Markowitz
a363d0734c Merge pull request #557 optimized LUP Component
Optimized LUP Component to not use a query to build its list of worlds
2022-05-17 21:30:12 -07:00
David Markowitz
667677dcdd Merge pull request #558 Implement boom trap
Implement Mine Script for boom trap
2022-05-17 21:29:33 -07:00
9169d844e2 explicit set to 0 2022-05-17 21:38:36 -05:00
03a5aa4da0 climbable server side settings 2022-05-17 21:27:08 -05:00
729e79eadb resolves #556 2022-05-17 19:12:43 -05:00
ca55fccb27 remove cdclient include 2022-05-17 10:20:36 -05:00
81af1f382e get zones from settings 2022-05-17 10:18:50 -05:00
David Markowitz
cc23538244 Merge pull request #549 Players hold rockets when interacting with some launch pads 2022-05-12 19:25:58 -07:00
20b45bc27f Merge branch 'main' into proper-rocket-holding 2022-05-12 08:21:17 -05:00
David Markowitz
85cd8c8833 Merge pull request #553 Fix Crux Prime Teapot
Add crux prime tea pot server script
2022-05-10 14:18:28 -07:00
David Markowitz
d6aece44aa Merge pull request #552 Replace survey link with repo link
Replace the survey link with the repo link
2022-05-10 04:16:22 -07:00
aba349301f Add AM Teapot server
Resolves #224
2022-05-09 23:21:20 -05:00
875827d688 Set url from world config instead of hardcoding 2022-05-09 17:33:43 -05:00
d7eb8783a8 replace the survey link with the repo link
(not that anything can load in the in-game browser anyway)
2022-05-09 08:43:31 -05:00
David Markowitz
d39df2e5a1 Merge pull request #551 exclude Frostburgh race track from ghosting
Exclude space blizzard from Zone ghosting
2022-05-09 04:51:37 -07:00
4c7034648b Exclude space blizzard from Zone ghosting 2022-05-08 22:07:07 -05:00
ec207838d4 Proper Rocket Holding
Sanity checks on Prop and LUP launchpads to not open if no valid rocket
Add serialization for sending item configs
so that rockets show for other players
2022-05-08 19:57:36 -05:00
David Markowitz
24745c2e7a Merge pull request #541 Implement the LUP Rocket Launch Component
Implemented the LUP Rocket Launch Component and makes its UI live accurate
2022-05-06 11:54:32 -07:00
David Markowitz
8601976498 Merge pull request #544 address Elephant precondition
Pet Components now read in their preconditions from their settings (if they have any).  Mainly fixes just elephants not taking peanuts.
2022-05-06 04:15:13 -07:00
David Markowitz
ca042bd415 bump patch version
- Quickbuilds jump on completion
- Fong now plays darkitect cutscene on a mission completion
- Nexus Tower panels now play the repair animation
- Vendors can now refresh
- Loot magnet abilities now work
- Spinjitzu Initiate now works
- Achievement items now get moved to the players inventory as they did in live, by popping up from the achievement box
- pop up when you get a new life container now shows up as it did in live
- Parrot in Nexus Tower is no longer an oar
- Fixed an item underflow bug
- Vaults for Items and Models now are the same size and start out at the correct size
- The buy back inventory for vendors now allows you to scroll (only after backing out of the menu first for some reason)
- Untamed pets no longer cause client hitches in Nimbus Station and Forbidden Valley
- When shutting down, the server now shuts down in 1 second instead of 75
- Plunger gun is no longer a main hand item
- Skills for proxy items no longer require a reload to be used
- Resolved some MacOS compilation warnings
- Quickbuilds now play a celebration on completion
- Bug reports are more specific
- Property viewer and plaques now work as they did in live and display all the correct information
- Properties now also save more often instead of every 10 minutes
- Avant Gardens Survival buff station now works
- Exploding dummy for Nexus Tower combat training now works and allows progression
- Racing missions for smashables now work
- Apes now act as they did in live
- Dragons on Crux Prime now spawn the quick build for insta smashes
- Civilian players can no longer use /playanim
- Proxy items no longer grant extra stats
- Shooting gallery daily missions now work
- Operators can now spawn race cars in non-racing worlds
- Level rewards now show their achievement as they did in live

We really need to do this monthly so the notes arent this long lol
2022-05-06 04:01:34 -07:00
06a1949eaa remove sysaddr from call in Game Messages 2022-05-04 19:31:56 -05:00
b11b516641 fix Java doc comments
removed unused param
2022-05-04 19:26:56 -05:00
ad5c679d2d Styling edits 2022-05-04 18:24:28 -05:00
e81acb4c67 Client handles rocket being unequiped
when closing the dialog
and when launching
2022-05-04 07:50:05 -05:00
aa212ae6d8 Add precondition check 2022-05-03 22:38:49 -05:00
bd3e8aee51 Implement Rocket Launch Lup Component 2022-05-03 15:05:29 -05:00
David Markowitz
a1a345326a Merge pull request #534 Quickbuilds jumping again
Addresses quickbuilds not jumping anymore.
2022-05-03 12:18:26 -07:00
EmosewaMC
6b409303af Update RebuildComponent.h
Quickbuilds jump fix

Corrected an error where the builder was erronously changed to an empty lwoobjid when a quickbuild was completed, causing the builds to no longer jump on completion (if configured to do so.)  Packet captures from live show that we do not want to get rid of the builder during resetting or during completion of the build so the file has been changed to not clear the builder in those cases.
2022-05-02 22:50:28 -07:00
David Markowitz
427c4a8c33 Merge pull request #531 Add Fong Architect Script
Added the Fong Architect script and split out the Darkitect method into its own file so it can be used across multiple scripts.
2022-05-01 16:22:12 -07:00
763a1f4a61 Split out Darkitect reveal into it's own file
add reveal to Fong
2022-05-01 08:54:45 -05:00
David Markowitz
12ae6a5525 Merge pull request #528 from EmosewaMC/NTParadoxPanelFix
Added animation for Nexus Tower Panels
2022-04-28 20:20:43 -07:00
EmosewaMC
2435870ec5 Added animation
Added the GM animation and stun for the Nexus Tower Paradox Panels for mission 1281.  Tested on local instance and animation played correctly when having the mission and did not play at all before or after completing the mission
2022-04-28 19:52:03 -07:00
EmosewaMC
59be7d8635 Added back brick inventory resizing 2022-04-28 14:36:55 -07:00
David Markowitz
bbedf5d174 Merge pull request #525 from EmosewaMC/money-fix
Serialize ape when changing armor value
2022-04-28 00:38:33 -07:00
EmosewaMC
2f598dad09 Serialize ape when changing armor value 2022-04-28 00:14:06 -07:00
David Markowitz
16b108f69c Merge pull request #522 from EmosewaMC/vendor-refresh
Added vendor refreshing
2022-04-27 13:21:59 -07:00
David Markowitz
94c00417ff Merge pull request #524 from EmosewaMC/lootBuffFix
Added LootBuff behavior and serialization
2022-04-27 13:21:16 -07:00
EmosewaMC
b713b94841 Added Loot Buff Behavior
Added functions and methods to support the pickup radius.  Functionality includes:
Corrected serialization for ControllablePhysicsComponent which correctly serializes the pickup radius to the client.
A method to add the pickup radius to the list of active pickup radii the component has.
A method to remove and re-calculate the largest active radii the component currently has.

Tested equipping all variations of the LootBuff behavior (passive skills, items, item skills) and all functioned as intended.  Tested equipping multiple items with a loot buff and then unequipping them in different orders.  Tested adding pickup radii of different values and the server correctly adjusted the pickup radius to the largest one currently equipped.
2022-04-27 12:40:43 -07:00
EmosewaMC
843a5b39c0 Vendor refresh change
Changed vendor refresh to happen as soon as it is able to.
2022-04-27 01:35:46 -07:00
EmosewaMC
fa7c4d9c27 added comments 2022-04-26 15:26:30 -07:00
EmosewaMC
cacf4fcd97 corrected serialization 2022-04-26 15:23:29 -07:00
EmosewaMC
5afeb265cd Updated vendor component
Fixed a few issues in VendorComponent.
- Corrected serialization to only happen on construction.
- Added functionality to refresh the vendor based on info from the vendor component table
- some whitespaceing inconsistencies.
- Sorted includes.
Tested the vendor in Nimbus Station and when the player re-enters the world, the vendor inventory refreshes, as opposed to previously where the world would need to reset in order to refresh the inventory.
2022-04-26 03:41:16 -07:00
David Markowitz
aca2bb1090 Merge pull request #520 from EmosewaMC/skill-tasks
Corrected action for OverTimeBehavior
2022-04-25 20:22:19 -07:00
David Markowitz
2bd90ce353 Merge pull request #521 from EmosewaMC/hotfix-for-instruments
Typo in NsConcertInstruments
2022-04-25 18:22:58 -07:00
EmosewaMC
27edf5da1d Typo in NsConcertInstruments 2022-04-25 18:16:47 -07:00
EmosewaMC
7d233a04c0 Corrected action for OverTimeBehavior 2022-04-25 16:56:40 -07:00
David Markowitz
c2c8cf9767 Merge pull request #519 from EmosewaMC/skill-tasks
Skill Task changes (also fixes Spinjitzu Initiate)
2022-04-25 13:42:19 -07:00
EmosewaMC
4117ceb6c1 Skill Tasks changes
Addressed an issue where the Spinjitzu Initiate achievement would not progress.  This also allows mission tasks that specify that the player must get a kill on an enemy with a skill to progress.  Tested mission 1935 and 1139 and both missions progressed and completed as intended.
2022-04-25 03:25:07 -07:00
David Markowitz
58d2cee984 Merge pull request #516 from EmosewaMC/isPlayer-changes
Live accurate item loot sources
2022-04-24 18:56:49 -07:00
EmosewaMC
4fd1467cbf changed loot sources to none
Changed loot sources for some scripts to none so they properly give loot to the player.
2022-04-24 18:40:20 -07:00
David Markowitz
7b32d2f609 Merge pull request #518 from EmosewaMC/popup-fix
Pop up now appears for life containers
2022-04-24 18:39:35 -07:00
EmosewaMC
2e29dce77c removed logs 2022-04-24 17:27:25 -07:00
EmosewaMC
e56732184f commit 2022-04-24 17:26:05 -07:00
EmosewaMC
dc770299d1 removed debug logs 2022-04-23 22:22:21 -07:00
EmosewaMC
18fc01cd49 missed change for forge 2022-04-23 20:44:08 -07:00
EmosewaMC
c6480192f8 Revert "isPlayer changes"
This reverts commit 2e61839d93.
2022-04-23 20:35:39 -07:00
EmosewaMC
7a051afd97 loot source for item drops
Added support for Items to have a loot source attached to them when dropped or rolled.  This fixes the issue where achievements would give the item before it appeared in the achievement window.
2022-04-23 20:35:34 -07:00
EmosewaMC
ceab229a63 Specified enum
the LOOT_SOURCE enum is now attached to all loot sources.
2022-04-23 20:32:31 -07:00
EmosewaMC
8e10f090fd corrected number 2022-04-23 18:52:21 -07:00
EmosewaMC
a4d934913c added lootsource send in GM
WIP commit
2022-04-23 05:13:06 -07:00
EmosewaMC
0eece14b68 Vendor buyback inventory
Fixed vendor buyback inventory so it properly scrolls when the player adds enough items to it.
2022-04-23 04:16:10 -07:00
EmosewaMC
d0233a2cd0 Updated AddItemToInventorySync
AddItemToInventorySync now sends the correct loot source type
2022-04-23 04:14:55 -07:00
EmosewaMC
834b53b4ec Grammar error
Level reward needed an underscore
2022-04-23 04:13:23 -07:00
EmosewaMC
2e61839d93 isPlayer changes
Changed isPlayer to check for whether the entity has a character instead of checking system address of entity.
2022-04-22 00:10:15 -07:00
David Markowitz
e85cf466d4 Merge pull request #513 from aronwk-aaron/fix-parrot-being-oar
A new migration for the CDServer has been added this merge.  Please update your CDServer.sqlite files with the new migration
2022-04-19 20:32:59 -07:00
d42cbb2473 make newline at end of file 2022-04-19 21:36:09 -05:00
d4adb0e6e5 Fix migration 0 for cd server
setting every component to 1901 instead of just component 39
Add migration to fix it for existing users
and set the values back to what they were
2022-04-19 21:30:38 -05:00
4cf9865431 Merge branch 'DarkflameUniverse:main' into main 2022-04-19 19:19:41 -05:00
David Markowitz
6f9caaa8c1 Merge pull request #510 from IAmMajo/frostburgh-solo-racing
Fix solo_racing for Frostburgh's Space Blizzard Racetrack
2022-04-19 16:30:54 -07:00
David Markowitz
c489132f59 Merge pull request #504 from NinjaOfLU/fix-item-removal-underflow
Prevent integer underflow in item removal
2022-04-19 15:21:28 -07:00
c845055e6b Merge pull request #1 from NinjaOfLU/fix-item-removal-underflow
Fix item removal underflow
2022-04-19 11:56:57 -05:00
Majo
a3331d009d Fix solo_racing for Frostburgh's Space Blizzard Racetrack 2022-04-19 12:33:57 +02:00
David Markowitz
80a09881c0 Merge pull request #508 from aronwk-aaron/Frostburgh
Frostburgh Server fixes
2022-04-18 22:58:02 -07:00
263b019262 Merge branch 'main' into Frostburgh 2022-04-18 23:35:40 -05:00
6933b2c301 case for putting you back into FB when leavign space blizzard 2022-04-18 23:33:09 -05:00
8db7dfef75 also apply overrides to AG fans 2022-04-18 21:09:27 -05:00
f3dd71ccb1 cleanup logs, fix overrides, define LOTs in header 2022-04-18 21:02:04 -05:00
8fe5c00984 remove dereference
(I think that's what it is called)
2022-04-18 08:36:11 -05:00
d05601ce64 Fixes 2022-04-18 08:27:37 -05:00
David Markowitz
1defc22caf Merge pull request #509 from EmosewaMC/racing-achievement-fixes
Fixed Racing Missions Try, Try again and Race Series 1
2022-04-18 04:03:32 -07:00
EmosewaMC
5691df9009 Fixed Racing Mission
* Try, Try Again achievement now progresses when the player gets last place in a race of 3 or more players, or when solo racing is enabled.
* Race Series 1 mission from Velocity Lane now progresses correctly.
2022-04-18 01:04:29 -07:00
2122448284 cleaning up some stuff 2022-04-17 21:30:25 -05:00
263eaf03b0 ugh, another semicolon 2022-04-17 20:24:49 -05:00
6cef7a437a scope 2022-04-17 20:24:19 -05:00
0778b4f81c missed semicolon 2022-04-17 20:17:36 -05:00
235934714f honor the logic in the lua script 2022-04-17 20:16:27 -05:00
a343ed9493 rock hydrants work 2022-04-17 19:43:17 -05:00
cc68b0768b remove log 2022-04-17 17:43:25 -05:00
e696d26941 update the Effect ID 2022-04-17 17:41:10 -05:00
a8fcb4c153 make the hydrant match the lua script 2022-04-17 16:44:46 -05:00
1e85ae2035 tabs and log 2022-04-17 15:58:26 -05:00
67615d5688 fix volumen physics name 2022-04-17 12:46:41 -05:00
23677b4bd3 Simplify some stuff
Remove render component in startup
2022-04-17 12:38:12 -05:00
5b0f917485 update script path for fans 2022-04-17 00:05:04 -05:00
b3695c42b2 fix copy past error 2022-04-16 23:35:22 -05:00
0e5a1c9721 fix comparator 2022-04-16 23:33:44 -05:00
b4acf329b4 implement some missing scripts 2022-04-16 23:32:15 -05:00
David Markowitz
8f50e4ff56 Merge pull request #503 from aronwk-aaron/testmap-enhancements
Dynamically check if zone is viable from existence of file
2022-04-14 16:46:37 -07:00
David Markowitz
a3e2aa2a97 Merge pull request #505 from EmosewaMC/Vault-fixes
Addressed vault size issues
2022-04-14 16:30:55 -07:00
3d6d5e58a7 Update GameMessages.cpp
I promise I'm not farming changes. I woke up at like 4AM and realised that I'd screwed up in an obvious way. Note to self: You are ALLOWED to change variables.

Wasn't caught in testing because, well, it turns out it's actually impossible to test the edge case this covers, due to the script for the brick console.
2022-04-14 10:09:40 +01:00
cdbb42badf Added a bracket... -_-
Maybe I should write and test code on my computer rather than using Git as an IDE and commits as the save button...
2022-04-14 00:15:45 +01:00
1d1f479387 Ensure items correctly removed from missions
Doubt it would have affected anyone, but technically if you had a mission to collect something interactable, and you deleted the items at the same time as interacting with something, this would have counted incorrectly. I'm being defensive because I was an idiot who couldn't read, but in my defence, it was late when I made the first edit, and I'm also a blundering idiot!
2022-04-14 00:11:35 +01:00
EmosewaMC
a32c5a2f3c Vault corrections 2022-04-13 01:50:06 -07:00
59ec28a5a4 Prevent integer underflow in item removal
Previously, the only check that the user wasn't trashing more items than they had was clientsided, and this could be bypassed by contacting the server to remove items via a console or the like, and then trashing them before the server could respond, resulting in the count for the items being less than iStackCount. This check prevents that underflow.
2022-04-13 01:58:00 +01:00
959c90985c missed a semicolon 2022-04-12 18:32:52 -05:00
4a98c46fb9 fix tabs/spaces 2022-04-12 18:30:46 -05:00
40d396c7e2 simplify 2022-04-12 18:05:22 -05:00
6b44936c68 check if map exists for testmap 2022-04-12 14:06:03 -05:00
David Markowitz
e92cdc4f14 Merge pull request #493 from EmosewaMC/ugh
Pets no longer cause client hitches in Nimbus Station and Forbidden Valley
2022-04-11 14:35:57 -07:00
David Markowitz
0f738c8d9c Merge pull request #419 from Marcono1234/issue-template-improvements
Improve GitHub issue templates
2022-04-11 02:25:54 -07:00
David Markowitz
7a354b3545 Merge pull request #456 from Marcono1234/marcono1234/zlib-https
Fetch zlib library over HTTPS
2022-04-10 20:04:23 -07:00
David Markowitz
f45cb380e0 Merge pull request #499 from EmosewaMC/master-server-shutdown
Dramatically speed up server shutdown and specify database destruction source in logging message
2022-04-10 17:25:04 -07:00
EmosewaMC
f01c2e1bd3 Updated logging 2022-04-10 17:08:29 -07:00
EmosewaMC
30c7b65150 incorrecly named variable 2022-04-10 17:00:03 -07:00
EmosewaMC
1e514a8b61 more specific logging 2022-04-09 18:48:13 -07:00
EmosewaMC
c08557f37d separated world server to more functions 2022-04-09 18:35:41 -07:00
EmosewaMC
6927bc614e Spacing 2022-04-09 18:33:38 -07:00
EmosewaMC
ae61b23896 Chat log no longer needed 2022-04-09 16:02:27 -07:00
EmosewaMC
aee3290248 Update MasterServer.cpp 2022-04-09 16:02:12 -07:00
EmosewaMC
1efbe2d2c0 added returns 2022-04-09 15:57:18 -07:00
EmosewaMC
d085c0cf10 correct exit 2022-04-09 15:35:40 -07:00
EmosewaMC
3e60b9db4a Destroying database specifier 2022-04-09 15:35:01 -07:00
EmosewaMC
fd13770e87 Sped up server shutdown 2022-04-09 14:17:31 -07:00
David Markowitz
5ef1848474 Merge pull request #498 from EmosewaMC/plunger_gun_migration
Changed 0_initial.sql so it wont accidentally wipe a database if run again
2022-04-09 00:52:07 -07:00
EmosewaMC
77c6350f03 updated initial migration
Made it so people wont accidentally wipe their database if 0_initial.sql is ever run again
2022-04-09 00:48:14 -07:00
David Markowitz
f17e6d6a4a Merge pull request #496 from EmosewaMC/fix-skill-proxies
Addressed proxy items removing skills
2022-04-09 00:37:40 -07:00
David Markowitz
53823a0be5 Added plunger gun CDServer migration
A new migration has been added with this merge to address the plunger gun in the CDServer.  Please run the 3_plunger_gun_fix.sql migration to update your database.
2022-04-09 00:32:34 -07:00
EmosewaMC
3900267fed added comment 2022-04-09 00:31:18 -07:00
EmosewaMC
0a494422b7 Added migration for plunger gun 2022-04-09 00:22:02 -07:00
EmosewaMC
96f1c0a709 Fixed skills proxies 2022-04-08 20:20:42 -07:00
David Markowitz
39089284ff Merge pull request #495 from EmosewaMC/hello-there-obiwan
fixed out of context log for launching to properties
2022-04-08 19:37:36 -07:00
EmosewaMC
5a76cb3b44 fixed erronous log 2022-04-08 19:36:43 -07:00
David Markowitz
92d36496df Merge pull request #490 from EmosewaMC/macos_compilation_warnings
Resolved MacOS (and possibly ARM?) compilation warnings
2022-04-07 12:09:37 -07:00
David Markowitz
9b6caef6b5 Merge pull request #487 from EmosewaMC/quickbuild-fixes
Added a GM send after QB complete
2022-04-07 09:48:40 -07:00
EmosewaMC
7030d937b1 dirty bit 2022-04-06 22:24:50 -07:00
EmosewaMC
e73793c1a3 removed unnccessary work 2022-04-06 22:21:54 -07:00
EmosewaMC
5eb801eb12 uses number of bricks now 2022-04-06 22:21:29 -07:00
EmosewaMC
4b0ab2380c Client does calcs 2022-04-06 22:21:17 -07:00
EmosewaMC
bd0926e0a5 special case for pets 2022-04-06 22:21:08 -07:00
EmosewaMC
9d79fc3d2e resolved MacOS compilation warnings 2022-04-05 05:11:06 -07:00
Gie "Max" Vanommeslaeghe
a0a9936e47 Merge pull request #415 from Marcono1234/UserManager-name-logging
Fix UserManager not logging chosen name properly
2022-04-03 11:33:59 +02:00
Gie "Max" Vanommeslaeghe
5e5fefb501 Merge pull request #416 from Marcono1234/MasterServer-closing-db
Fix MasterServer not always closing database connection on exit
2022-04-03 11:31:53 +02:00
David Markowitz
395d607632 Merge pull request #484 from EmosewaMC/property-fixes
Reputation now saved in charxml.  This is not a retroactive fix for reputation earned before this merge.
2022-04-01 15:25:30 -07:00
David Markowitz
db0f363967 Merge pull request #476 from EmosewaMC/bugReportFixing
Added more specific bug reporting.  There is a new migration called migrations/dlu/2_reporter_id.sql to run on the database.
2022-04-01 15:12:58 -07:00
EmosewaMC
ec463dd4c8 Added a GM send after QB complete 2022-04-01 04:14:28 -07:00
David Markowitz
acbd46afcb Removed debug log 2022-03-31 20:55:47 -07:00
EmosewaMC
8379fba079 added initializer 2022-03-31 18:46:56 -07:00
EmosewaMC
4bc5c8194f Added reputation tracker in charxml 2022-03-31 18:18:13 -07:00
EmosewaMC
ba33c15b2d reputation rewards are now applied to character and not properties 2022-03-31 18:17:58 -07:00
EmosewaMC
0bf2d398ea moved initialization of entity 2022-03-31 18:17:43 -07:00
EmosewaMC
ece83db6ed World packets change
World packets now takes an entity so we can process reputation
2022-03-31 18:17:23 -07:00
EmosewaMC
8ae7bc0f92 Where to send reputation to client 2022-03-31 16:12:36 -07:00
David Markowitz
ccff6746ce Merge pull request #483 from DarkflameUniverse/hot-fix-hard-coded-database
Fixed a hard coded database issue
2022-03-31 14:14:35 -07:00
EmosewaMC
450bebc8a2 i am a big dum 2022-03-31 14:11:43 -07:00
EmosewaMC
cf70881370 simplified conversion 2022-03-31 03:20:13 -07:00
David Markowitz
4724e0ebc1 Merge pull request #481 from EmosewaMC/buff-station-faction
Corrected faction for Buff Station
2022-03-31 02:50:32 -07:00
Gie "Max" Vanommeslaeghe
95010e791f Merge pull request #479 from EmosewaMC/property-fixes
Property fixes
2022-03-31 11:21:37 +02:00
EmosewaMC
33b16a56e3 Added a save and fixed a crash
If am item were to be added to properties_contents and an item with that Primary Key already existed, the world would crash.  This addresses this.
2022-03-30 22:51:09 -07:00
EmosewaMC
cc9b6c05f6 removed include 2022-03-30 22:35:41 -07:00
EmosewaMC
9169acad47 changed to update 2022-03-30 22:14:51 -07:00
EmosewaMC
aed0ecc9fc removed newline 2022-03-30 22:05:09 -07:00
EmosewaMC
0561f60031 Added negative checks 2022-03-30 21:58:59 -07:00
EmosewaMC
e66421d34f clarified variable name 2022-03-30 21:58:43 -07:00
EmosewaMC
8462068a05 clarified variable names, used encapsulation 2022-03-30 21:33:25 -07:00
EmosewaMC
8a8b5b4f44 removed new line 2022-03-30 21:18:29 -07:00
EmosewaMC
bc7c543530 removed debug log 2022-03-30 21:15:50 -07:00
EmosewaMC
f22dab0f72 unapproved properties render correctly 2022-03-30 21:12:22 -07:00
EmosewaMC
002025231e Semantics 2022-03-30 20:33:50 -07:00
EmosewaMC
061d2b394c on the fly property moderating notifications 2022-03-30 20:33:37 -07:00
EmosewaMC
d3f954bdac changed serialized value to old
I am unsure if this is what gets serialized here so I am reverting this back to a zero.
2022-03-30 20:32:59 -07:00
EmosewaMC
c80a90e81e rejection statuses were backwards 2022-03-30 20:31:51 -07:00
EmosewaMC
b903c81a0a Shortened reputation update 2022-03-30 20:31:23 -07:00
EmosewaMC
f72c2dcaa5 Merge branch 'property-fixes' of https://github.com/EmosewaMC/DarkflameServer into property-fixes 2022-03-30 18:38:43 -07:00
David Markowitz
6b759ff54e Merge branch 'DarkflameUniverse:main' into property-fixes 2022-03-30 18:38:07 -07:00
EmosewaMC
041dc8256f comment 2022-03-30 18:34:26 -07:00
EmosewaMC
b79ebf1d40 Corrected faction for Buff Station 2022-03-30 18:25:32 -07:00
EmosewaMC
0bf2f0e92a Added enum for rejection statuses 2022-03-30 16:14:24 -07:00
EmosewaMC
04852ac1d9 Removed const 2022-03-30 16:13:21 -07:00
EmosewaMC
5fa0a16302 more options in BuildQuery method 2022-03-30 16:13:01 -07:00
EmosewaMC
4edb428954 next page query now works 2022-03-30 16:12:42 -07:00
Jett
ff9d736073 Merge pull request #442 from EmosewaMC/AvantGardensSurvivalBuffStation
Fully implemented Avant Gardens Survival Buff Station
2022-03-30 22:22:50 +01:00
Jett
b2890262fb Merge pull request #445 from EmosewaMC/explodingDummyFix
Implemented script for exploding dummy in Nexus Tower Combat Training
2022-03-30 22:21:30 +01:00
Jett
0a6b8f139e Merge pull request #437 from EmosewaMC/racingSpecificSmashFix
Addressed specific race smash missions not progressing
2022-03-30 22:20:38 +01:00
Jett
529b40b66c Merge pull request #474 from EmosewaMC/char-create-fixes
Addressed hard coded character create values for shirts and pants
2022-03-30 22:19:55 +01:00
Jett
2a2fa94b03 Merge pull request #475 from EmosewaMC/ape-fixes
Addressed incorrect ape attacks
2022-03-30 22:18:57 +01:00
Jett
58c6429209 Merge pull request #393 from EmosewaMC/DragonQBFix
Implemented a script that spawns a Golem Quick Build on Crux Prime dragons when they reach zero armor
2022-03-30 22:18:44 +01:00
EmosewaMC
5c16dd11f4 altered table now has a default for performance cost 2022-03-30 00:37:36 -07:00
EmosewaMC
bd6bdddcde clone ID now based on character data 2022-03-30 00:33:31 -07:00
EmosewaMC
fe334d8739 clarified magic nums 2022-03-30 00:20:26 -07:00
EmosewaMC
69cc265fea added performance cost initializer 2022-03-30 00:20:15 -07:00
EmosewaMC
17e9fb0d3c Default time is now the current time rather than 0 2022-03-30 00:20:04 -07:00
EmosewaMC
b676343b02 removed print and rejection send 2022-03-30 00:02:18 -07:00
EmosewaMC
c838f4f422 Added query for friends list next page 2022-03-29 23:59:50 -07:00
EmosewaMC
e244fbccc2 General updates to the property manager
clone id is correctly assigned, reputation now shows up, rejection verdict is sent correctly (not sure about where the reason goes if  it even goes here).
2022-03-29 23:49:04 -07:00
EmosewaMC
36edbf393b Added support to update reputation 2022-03-29 23:46:56 -07:00
EmosewaMC
258174d4e1 Added GameMessage for UpdateReputation 2022-03-29 23:46:23 -07:00
EmosewaMC
fdd3e15b2f Added GM for reputation update 2022-03-29 19:52:07 -07:00
EmosewaMC
94e0ef77a9 performance cost is still a float 2022-03-29 19:49:54 -07:00
EmosewaMC
06671b8d66 performance cost is a float 2022-03-29 19:48:34 -07:00
EmosewaMC
1783904cb6 fixed __int64 in missions table 2022-03-29 19:47:27 -07:00
EmosewaMC
9f16284595 tab spacing 2022-03-29 19:47:15 -07:00
EmosewaMC
af15cc60eb Add GM for performance cost 2022-03-29 19:46:47 -07:00
EmosewaMC
e79d4e66f3 add performance cost column 2022-03-29 19:46:38 -07:00
EmosewaMC
82ebdccdb2 Reputation is sent as a float not an int 2022-03-29 14:54:31 -07:00
75fd425ef6 Remove ability for gmlevel 0 to use /playanim (#391) 2022-03-29 13:06:28 -07:00
EmosewaMC
ec9749ab85 flag for are more being worked on 2022-03-29 03:50:41 -07:00
EmosewaMC
9385c33729 grammar and new line 2022-03-29 02:33:15 -07:00
EmosewaMC
7b536ee079 Best friends is 2 not 1 2022-03-29 01:57:23 -07:00
EmosewaMC
0c41026df0 Fixed friendless crash 2022-03-29 01:00:30 -07:00
EmosewaMC
b0d4993344 owner name change 2022-03-28 21:02:46 -07:00
EmosewaMC
35e576a839 fixed moderator issue 2022-03-28 20:53:09 -07:00
EmosewaMC
69ec1216dc added comments 2022-03-28 20:51:19 -07:00
EmosewaMC
19e82a5150 more cleanup 2022-03-28 20:51:15 -07:00
EmosewaMC
965d4c7af0 cleaned up file and added helper functions 2022-03-28 19:58:50 -07:00
EmosewaMC
17b0de8062 clarified variable name 2022-03-28 19:58:23 -07:00
EmosewaMC
895bbec277 clarified variable name 2022-03-28 19:58:15 -07:00
EmosewaMC
17f773c6cb comment 2022-03-28 04:25:44 -07:00
EmosewaMC
dc74b46e11 off by one moment 2022-03-28 03:58:40 -07:00
EmosewaMC
148c177d27 shortened method 2022-03-28 03:37:12 -07:00
EmosewaMC
c94f0918c9 testing number reverted 2022-03-28 03:26:01 -07:00
EmosewaMC
54de6c6878 FINALLY WORKING JESUS 2022-03-28 03:24:49 -07:00
Daniel Seiler
acb7ad78e8 Merge pull request #478 from EmosewaMC/hp-item-mission-triggers-fix
Fixed mission progression for item proxies
2022-03-28 08:49:31 +02:00
EmosewaMC
0a453e9dca working state 2022-03-27 23:46:43 -07:00
EmosewaMC
0a7fd6f79a updates 2022-03-27 20:05:00 -07:00
EmosewaMC
a7cd2f4d9b comments 2022-03-27 15:37:05 -07:00
EmosewaMC
e43517efe6 comments 2022-03-27 15:28:21 -07:00
EmosewaMC
b459790b2f Fixed mission progression 2022-03-27 15:24:24 -07:00
Daniel Seiler
66b7c6522e Merge pull request #441 from EmosewaMC/ProxyItemFix
Addressed some proxy items granting duplicate skills
2022-03-26 08:17:04 +01:00
Jett
3a959778fe Merge pull request #451 from EmosewaMC/ShootingGalleryScoreFix
Shooting Gallery daily mission fix
2022-03-25 15:59:39 +00:00
EmosewaMC
db3cd33bca fixed incorrect variable name 2022-03-24 17:51:21 -07:00
EmosewaMC
6499139a49 moved addition to new migration. 2022-03-24 01:11:21 -07:00
EmosewaMC
f83ad8bbe4 fixed wrong stun removal
Apes no longer stack their attacks

Apes no longer stack their attacks and excess comments removed
2022-03-24 01:05:36 -07:00
EmosewaMC
819c58df7c semantics 2022-03-24 00:33:05 -07:00
EmosewaMC
4e2c352ab9 Changed pants query and removed extra comments 2022-03-24 00:30:52 -07:00
EmosewaMC
b2c88bb6a7 working query 2022-03-24 00:09:18 -07:00
EmosewaMC
e2bfdcd174 moved char id storage 2022-03-20 20:46:34 -07:00
EmosewaMC
22a00de8cd added char id column 2022-03-20 20:46:15 -07:00
EmosewaMC
68c600facc Added better bug reports 2022-03-20 20:28:26 -07:00
Daniel Seiler
a49f9dc586 Merge pull request #461 from EmosewaMC/mailboxSpecialCase
Addressed special case in GameMessage for interacting with a mailbox
2022-02-24 16:10:10 +01:00
EmosewaMC
6be274b259 fixed issue 2022-02-23 17:38:25 -08:00
EmosewaMC
24d443537a Addressed spacing 2022-02-20 20:01:55 -08:00
EmosewaMC
3d1283675f Updated comment 2022-02-20 20:00:56 -08:00
Jett
ad52facef7 Merge pull request #452 from EmosewaMC/GMRacingCarFix
Addressed GM Operators not being able to spawn in cars in non-racing worlds
2022-02-21 03:55:28 +00:00
EmosewaMC
55def02c8f Added script to CppScripts 2022-02-20 19:51:54 -08:00
EmosewaMC
6905120ac6 Added MailBoxServer files 2022-02-20 19:51:35 -08:00
EmosewaMC
5ffb57d92c Removed special case from GM 2022-02-20 19:51:21 -08:00
Jett
87d3ac15bd Merge pull request #460 from EmosewaMC/HandleLEvelUpFix
Added UI pop up for level rewards
2022-02-21 03:50:31 +00:00
EmosewaMC
1c116fb0c4 Sending rewards works fully 2022-02-20 19:23:17 -08:00
EmosewaMC
1c43d7f38c GameMessage is correct 2022-02-20 19:23:03 -08:00
EmosewaMC
78fbe3c7fe Added support for Windows Native 2022-02-17 03:17:41 -08:00
Marcono1234
4ef5508347 Fetch zlib library over HTTPS 2022-02-16 23:38:40 +01:00
EmosewaMC
afa38ae890 Added call to GM in CharacterComponent 2022-02-12 21:03:04 -08:00
EmosewaMC
352f654ede Added GM in GameMessages 2022-02-12 21:02:52 -08:00
EmosewaMC
2bc9f8f66d Correctly set task value for shooting gallery 2022-02-10 03:08:47 -08:00
EmosewaMC
5fbb1e9cc2 removed comments 2022-02-10 02:16:33 -08:00
EmosewaMC
7c80c12b90 Removed comments 2022-02-10 01:40:57 -08:00
EmosewaMC
9021c5209f backup commit with comments 2022-02-10 01:03:51 -08:00
EmosewaMC
6c5c6b7b8e commit when car work 2022-02-09 21:21:10 -08:00
EmosewaMC
a60738f78f cleaned up SGCannon 2022-02-09 16:42:31 -08:00
EmosewaMC
b077bd937d Fixed bugs with minigame progression 2022-02-09 16:42:17 -08:00
EmosewaMC
1607b506c8 bodgy bodge to fix minigame missions 2022-02-09 16:42:03 -08:00
Gie "Max" Vanommeslaeghe
42f6f2f10b Bump patch version
Should have been done quite a while ago, but ah well
2022-02-09 10:59:43 +01:00
Gie "Max" Vanommeslaeghe
788cd3f807 Merge pull request #449 from DarkflameUniverse/physics-fix
Rehook dPhysics to main framerate
2022-02-09 10:55:21 +01:00
Unknown
d5a18af0e8 Rehook dPhysics to main framerate
Should fix bug causing double enter and exit events
2022-02-09 10:38:09 +01:00
Xiphoseer
cabd220a66 Fix spam-log on master disconnect (#447) 2022-02-08 17:25:14 +01:00
EmosewaMC
e397ed310e Updated script for teams
Updated script to drop buffing items for all members in a team.
2022-02-08 02:02:05 -08:00
EmosewaMC
1122f50c7c Changed time when buff station spawns 2022-02-08 01:55:25 -08:00
Marcono1234
d9874b452e Fix Plunger Gun not being removed from inventory after mission (#444) 2022-02-07 21:45:56 +01:00
EmosewaMC
0253a1fcb4 Added script for exploding asset 2022-02-07 03:43:57 -08:00
EmosewaMC
a22e1bd53d Added new case in CppScripts 2022-02-07 03:43:57 -08:00
Xiphoseer
56765d355b Merge pull request #443 from DarkflameUniverse/log-missing-master-conn-shutdown
Log WorldServer shutdown when MasterServer connection is missing
2022-02-07 10:58:52 +01:00
Xiphoseer
417a1a7485 Improve logging
Log when a WorldServer initiates shutdown because the master server connection went missing or wasn't established in the first place.
2022-02-07 10:19:16 +01:00
EmosewaMC
204f03fd2a removed extra function 2022-02-06 22:19:23 -08:00
EmosewaMC
b297d21a8d Fully implemented buff station script 2022-02-06 22:15:32 -08:00
EmosewaMC
f41e8292e8 Clarified numbers and added comments 2022-02-06 21:34:26 -08:00
EmosewaMC
3de2c3bfc6 set faction of buff station to 6 2022-02-06 21:32:36 -08:00
EmosewaMC
a6ed435038 Added bounds check for proxies 2022-02-06 20:54:04 -08:00
EmosewaMC
679f077772 updated comment 2022-02-06 20:54:03 -08:00
EmosewaMC
9cfb9a0de6 Added specific smashable mission progression 2022-02-06 14:28:37 -08:00
EmosewaMC
56521d35d0 Added associate for 17 2022-02-06 14:28:27 -08:00
EmosewaMC
72b3812716 fixed tab indent 2022-02-06 14:28:15 -08:00
Jett
b7d7146821 Merge pull request #435 from EmosewaMC/ghosting-fix
fixed ghosting issue
2022-02-06 02:25:46 +00:00
EmosewaMC
6ac90f98d1 fixed ghosting issue 2022-02-05 17:56:19 -08:00
Marcono1234
42e20d6db5 Explain in issue templates how to get Git commit SHA 2022-02-05 22:51:44 +01:00
Xiphoseer
b8c1f7629e Merge pull request #359 from AxtonF/HandleSIGTERM
Add handling of SIGTERM
2022-02-05 15:38:49 +01:00
Xiphoseer
448e888d69 Merge pull request #356 from EmosewaMC/UniqueCharacterNamesAddition
Added UNIQUE to charInfo table for names
2022-02-05 15:37:26 +01:00
Xiphoseer
ae6980966d Merge pull request #414 from Marcono1234/docker-read-only-volumes
Make some Docker Compose volumes read-only
2022-02-05 15:18:01 +01:00
cooltrain7
579cf590b4 Implement CDZoneTable PlayerLoseCoinsOnDeath (#251)
* Implement ZoneTable PlayerLoseCoinsOnDeath

- Adds a check on death if the character should drop coins in the current zone

* Refactored PlayerLoseCoinOnDeath into dZoneManager

* Coin death drops use LootGenerator

* Refactored again with use of CDZoneTableTable

* Remove duplicate CDZone call during initialization
2022-02-05 13:27:24 +01:00
Nordegraf
f7009b499b added tracking of Pet Excavator achievement (#213)
* added tracking of the Pet Excavator achievement

* make Pet Extractor Progress Zone specific

* added tracking of Pet Excavator Achievement using player flags
2022-02-05 13:19:25 +01:00
David Markowitz
84cf79906b Frakjaw Battle instance fixes (#409)
* Update NjMonastryBossInstance.cpp

* Changed spawn position to be 1.

* Changed stored variable from vector to int

Added clarifying comments
2022-02-05 13:11:58 +01:00
David Markowitz
933cdee414 Implemented Model Pickup and Reputation achievements (#413)
* Implemented Model Pickup and Reputation achievements

* Moved mission progression to placement

* Changed name to place
2022-02-05 13:08:40 +01:00
David Markowitz
77459af1d3 Removed AI Stopping after they use a skill (#407)
* Removed SkillTime from stopping AI

* Reverted Downtime removal
2022-02-05 13:07:30 +01:00
David Markowitz
828c457614 Added script for Friend of the Ninja mission (#406)
* Added script for Friend of the Ninja mission

* Added comments
2022-02-05 13:00:10 +01:00
David Markowitz
6ba9eea993 Added check to prevent accidental sentinel passive proc (#396)
* Added check to prevent accidental sentinel passive proc

Added a boolean to check if the player is at zero armor already and if so, do not trigger the passive ability.

* Renamed variable and condensed armor check
2022-02-05 12:59:07 +01:00
David Markowitz
fe178bf745 Fully Implemented Shooting Gallery Mission and Achievement Fixes (#381)
* Fixed tab indent

* Fully implemented Achievement tracking for Shooting Gallery

- Removed logging in MissionTask.cpp and moved the checks for mission progression to after checking the instance.

- Implemented the achievement tracking in SGCannon as well as tracking of the maximum hit streak and progression of enemy smashes in the shooting gallery.
2022-02-05 12:54:12 +01:00
David Markowitz
c6f220ee31 Implementing and Fixing All Racing Achievements (#366)
* Grammatical changes in comments

* Grammatical fixes in comments

Small grammatical fixes found in comments throughout the code.

* Added descriptions to functions

Added descriptions to functions that didn't have them to keep the code well documented

* Created RacingTaskParam.h

Created RacingTaskParam so eliminate magic numbers in the original implementation of completing racing missions.

* Updated magic numbers in Mission.cpp

Updated magic numbers in Mission.cpp to a meaningful name.

* Implemented racing smashable task progression

Previously, races did not progress tasks for smashing Entities.  Now all achievements tracking smashables track them correctly.  This has been implemented in the three Entities that can be smashed in a race (imagination boxes, track specific smashables, Forbidden Valley dragon eggs).

* Updated race imagination task progression

Race imagination now no longer uses a magic number when passed to missionComponent.  Instead we use a number defined in an enum located in RacingTaskParam.h

* Updated Race task checks

Racing tasks for completing races without smashing now no longer auto complete the whole chain of missions.  Tasks that track placing on tracks and races overall now properly complete.  Tasks that count how many missions in a zone are completed now function.  Tasks that track race completions in multiple areas now function.

* Updated RacingControlComponent.cpp

Fixed any tasks that required 3 players to now require 3 or more players in a race to progress.  This restriction is ignored if the world config opted in for solo racing to allow progression in solo worlds.  Updated magic numbers sent into missionComponent->Progress to an enum created in this PR.  Fixed some indentation.

* Fixed a grammatical error in variable name

Fixed a grammatical error in the enum for task params
2022-02-05 12:28:17 +01:00
wincent
dc2bd76aba Fixed scripted powerup spawners
When applied this commit fixes scripted powerups
2022-02-05 12:27:24 +01:00
David Markowitz
f0a4324bd4 Fixed an issue where leave-zone was working outside of instanced zones (#431) 2022-02-04 07:32:45 +01:00
Marcono1234
0d0949f5f0 Adjust chosen character name logging 2022-02-03 23:43:47 +01:00
David Markowitz
13980c4133 Added logic to Convert UScore to Coins for Level 45 Characters (#348) 2022-02-03 07:50:02 +01:00
David Markowitz
dac8ec621c Added stun immunity for bosses in Battle of Nimbus Station (#428) 2022-02-01 17:48:23 +01:00
026654b0d0 Update README.md 2022-01-31 04:34:22 -08:00
TheMatt2
59afc63a2f Merge DarkflameServer 2022-01-30 13:40:08 -05:00
Gie "Max" Vanommeslaeghe
344af924fe Merge pull request #405 from EmosewaMC/FvGateCrasherFix
Added missing script for Gate Crasher mission
2022-01-25 15:49:19 +01:00
Marcono1234
676611ed6f Improve GitHub issue templates 2022-01-25 03:18:10 +01:00
Marcono1234
4cd38f1174 Use exit code macros 2022-01-25 01:30:06 +01:00
Marcono1234
910448b0e7 Fix MasterServer not always closing database connection on exit 2022-01-25 01:30:06 +01:00
Marcono1234
477b629faf Fix UserManager not logging chosen name properly 2022-01-25 00:14:21 +01:00
f6558aa31e implement jetpack behavior and remove hardcoded jetpacks (#411) 2022-01-24 14:02:56 -08:00
Marcono1234
4f1df372a2 Make some Docker Compose volumes read-only 2022-01-24 21:52:11 +01:00
David Markowitz
1e01423a93 Added support for flags in macros (#410) 2022-01-24 14:57:50 +01:00
Xiphoseer
20037d12f7 Merge pull request #339 from CodeAX2/fix-aoe-targets
Fix Area of Effect Behavior Targets
2022-01-23 14:12:59 +01:00
EmosewaMC
f605451693 Added pragma once to header file 2022-01-22 17:48:09 -08:00
EmosewaMC
fa747a27db Added missing script for Gate Crasher mission 2022-01-22 17:40:08 -08:00
Gie "Max" Vanommeslaeghe
02bf5937dc Merge pull request #397 from EmosewaMC/AvantGardensSurvivalBuffStation
Fixed an issue where the Avant Gardens Survival buff station was not spawning and implemented its' script
2022-01-22 15:53:58 +01:00
TheMatt2
ef194f8796 Remove <filesystem> dependency (#400) 2022-01-21 17:46:19 +01:00
EmosewaMC
20789bab7f Changed out Timer for CallBackTimer 2022-01-20 16:00:45 -08:00
Gie "Max" Vanommeslaeghe
e248b74ee6 Merge pull request #386 from EmosewaMC/passportflagnotbeingset
Added joined a faction flag
2022-01-20 15:15:50 +01:00
EmosewaMC
e11260a2fe Added comment 2022-01-20 03:54:58 -08:00
EmosewaMC
24f8ea21db Added redundancy for smashing buff station 2022-01-20 03:48:43 -08:00
EmosewaMC
6fc0683ce9 Added comments 2022-01-20 03:26:41 -08:00
EmosewaMC
15831e8d6c Added Script files for Avant Gardens Buff Station 2022-01-20 03:20:39 -08:00
EmosewaMC
2a5f3b8072 Added script for Avant Gardens Survival buff station 2022-01-20 03:20:24 -08:00
EmosewaMC
850ae40f05 Moved retroactive flag check to Character.cpp 2022-01-19 17:34:53 -08:00
Gie "Max" Vanommeslaeghe
3bb1491f09 Merge pull request #387 from EmosewaMC/BonsRepeatMissionTriggers
Fixed Battle of Nimbus Station achievements being repeatable
2022-01-19 21:08:25 +01:00
EmosewaMC
a9389fcabf Merge branch 'passportflagnotbeingset' of https://github.com/EmosewaMC/DarkflameServer into passportflagnotbeingset 2022-01-19 03:37:52 -08:00
EmosewaMC
7cf458cff2 Removed redundant comparison 2022-01-19 03:36:18 -08:00
Jett
2bfff2933a Remove equal checks 2022-01-19 11:35:46 +00:00
EmosewaMC
46f375a58e Added comments to header file 2022-01-19 02:31:22 -08:00
EmosewaMC
097af41392 Deleted unused variables 2022-01-19 02:28:50 -08:00
EmosewaMC
67d5061416 Implemented Dragon Smash Quick Build for Crux Prime Dragons
Implemented a script for the crux prime dragons to spawn the Golem Quick Build that insta kills the Entity if the player hits the dragon after the golem is built.  Tested on Local Ubuntu instance against 1 Crux Prime Maelstrom Dragon and 1 Butterscorch and had no issues building the quick build or with the enemy not smashing.  Enemies also correctly reset to their default behavior after the stun period has expired.
2022-01-19 02:10:04 -08:00
EmosewaMC
d69a4ffaf0 Added retroactive check for player faction flags
Added a retroactive check for player flag when loading into a world.
2022-01-18 17:51:12 -08:00
enteryournamehere
84a376b425 Add zone 1700 to list of accessible zones (#87)
* Add zone 1700 to list of accessible zones

also fix indentation

* Indent using tabs instead of spaces

* Add zone 1500

* Remove zone 1500

and add back 1700 which was accidentally deleted again
2022-01-18 11:48:56 -08:00
Gie "Max" Vanommeslaeghe
179d44fdd3 Merge pull request #385 from TheMatt2/error-handling
Clearer Error Message on Misconfiguration
2022-01-18 12:51:48 +01:00
Jett
2f2e670ef3 Merge pull request #388 from EmosewaMC/ApeQBFix
Changed Script Created for Apes on Crux Prime to allow for Anchor QuickBuilds
2022-01-18 11:19:13 +00:00
EmosewaMC
01ed5106b9 Changed Script Created for Apes on Crux Prime 2022-01-18 02:28:17 -08:00
EmosewaMC
60ba78d639 Fixed BoNS achievements being repeatable 2022-01-17 21:55:01 -08:00
EmosewaMC
3ede7006f9 Added Joined a faction flag
Added logic to set the player flag for joining a faction.  Tested on Ubuntu and had zero issues.
2022-01-17 19:43:37 -08:00
TheMatt2
df77997b0b Clearer Error Message on Misconfiguration
Checks if CDServer.sqlite exists before attempting to open it. Otherwise 
Sqlite will create an empty file only cause a crash when CDClientManager 
tries to Initialize.

Also catches error if CDClientManager tries to initialize, in case an 
empty CDServer.sqlite file already exists.
2022-01-17 15:13:30 -05:00
Nico Mexis
7dd7fdaf71 Update CMake minimum requirement (#380) 2022-01-17 12:46:33 +01:00
Gie "Max" Vanommeslaeghe
789c0890ca Merge pull request #383 from EmosewaMC/bananaFixes
Changed banana drop spawn Y height to prevent them from getting stuck on the trees
2022-01-17 00:51:42 +01:00
EmosewaMC
d883536ebd Reverted change and simply lowered the spawn height to 8 2022-01-15 19:12:07 -08:00
EmosewaMC
fa714aa843 Changed Banana spawn Y height
Changed the Bananas Y spawn height to be 10 Y units lower to prevent bananas from getting stuck on the tree.
2022-01-15 17:55:44 -08:00
TheMatt2
9dfa401b27 Fix whitespace
Convert to tabs and remove trailing whitespace
2022-01-15 14:02:14 -05:00
TheMatt2
4ff84e0730 Fix whitespace 2022-01-15 13:37:43 -05:00
David Markowitz
70af1f9314 Fixed an issue where repeatable missions were not rewarding the items they should be rewarding (#357)
When applied this fixes issues with repeatable mission were not rewarding the correct items.
2022-01-14 14:00:09 +01:00
David Markowitz
24aaa04954 Fixed an issue with shark missions (#372)
Fixed an issue where getting eaten by a shark would accidentally progress the task for entering the Ravencloud gate's left hand side.
2022-01-14 13:48:33 +01:00
David Markowitz
ae06188871 Added Bat Lord Full Set Bonus (#375)
* Added Bat Lord Full Set Bonus
2022-01-14 13:46:41 +01:00
Jett
3eb319af5b Merge pull request #370 from EmosewaMC/AdditionOfExtraMissionItem
Fixed a bug where Chaos Cleaner would accidentally add a Maelstrom Dagger to your inventory
2022-01-14 11:54:08 +00:00
TheMatt2
3de3932503 Comply with Xiphoseer required changes.
Remove the CDClientDatabase::ExecuteQueryWithArgs() function and replace 
it with CDClientDatabase::CreatePreppedStmt().

This prevents a developer from accidently using %s, or incorrectly 
passing std::string, and causing a silent error.
2022-01-12 22:48:27 -05:00
Mick
470bc65239 Merge pull request #290 from Verathian/battle-of-nimbus-adjustments 2022-01-12 08:30:25 +01:00
EmosewaMC
304b03b1d1 Removed add item 2022-01-11 18:18:51 -08:00
Gie "Max" Vanommeslaeghe
d9d27a88fc Merge pull request #293 from Racater/main
Fix issue #268 : wrong shirt colors in the character selection
2022-01-11 23:48:58 +01:00
Gie "Max" Vanommeslaeghe
3fb61f068b Merge pull request #353 from OogwayUniverse/remove-ips-from-logging
Remove IP Logging
2022-01-11 23:45:44 +01:00
Felix Racz
2221945dc8 Add handling of SIGTERM 2022-01-11 22:47:29 +01:00
Gie "Max" Vanommeslaeghe
03fd073e76 Merge pull request #365 from OogwayUniverse/bons-fixes
Change the win delay to increase time to get BONS loot
2022-01-10 22:15:12 +01:00
Mick
0415ada289 Merge pull request #90 from TheNoim/main
Completely automated docker setup
2022-01-10 15:44:05 +01:00
Jett
b7b182c57c Change the win delay to increase time to get BONS loot 2022-01-10 11:59:56 +00:00
EmosewaMC
150dec1cc2 Added file to run on table charinfo to allow for unique names only
Created a new file to run on the MySQL database to alter the MySQL table charinfo.names to only allow unique entries
2022-01-09 00:12:49 -08:00
EmosewaMC
01230e2575 Revert change in 0_initial.sql 2022-01-09 00:09:27 -08:00
Felix Racz
03e2a855b1 Add handling of SIGTERM 2022-01-09 01:25:45 +01:00
Xiphoseer
77826c8691 Merge pull request #352 from DarkflameUniverse/feature/windows-ci
Add windows CI
2022-01-09 00:54:24 +01:00
EmosewaMC
b529b7d3a0 Added UNIQUE for charInfo table
Added UNIQUE for charInfo table.
2022-01-08 00:00:27 -08:00
TheMatt2
e5f7d164cb Additional SQLite lookup sanitizing.
Using CDClientDatabase::ExecuteQueryWithArgs() across all known lookups.
2022-01-06 21:12:47 -05:00
Jett
c1903ca12d Remove IP Logging 2022-01-06 21:54:48 +00:00
TheMatt2
4796b551ad Additional SQLite lookup sanitizing with CDClientDatabase::ExecuteQueryWithArgs() 2022-01-06 16:05:03 -05:00
TheMatt2
590ccc78aa Add proper sanitizing for input to SQLite database.
Adds function `ExecuteQueryWithArgs(query, ...)` to allow for queries 
with user input.

There is a known issue, that the funciton does not work with 
std::string. All strings must be converted to c strings.
2022-01-05 21:52:33 -05:00
Nils Bergmann
eef2ed0b4c Add special character warning 2022-01-05 17:46:59 +01:00
Nils Bergmann
9a7654806f Rename build dir to cmake_build 2022-01-05 17:38:53 +01:00
Nils Bergmann
72e2d24c67 Move AccountManager to submodules 2022-01-05 17:32:30 +01:00
Nils Bergmann
dc39acaa75 Fix build for newest changes 2022-01-05 17:21:25 +01:00
Nils Bergmann
f914799b62 Use LUnpack instead of lcdr utils for unpacking the client 2022-01-05 17:21:11 +01:00
Nils Bergmann
0f3fafde4b Merge branch 'DarkflameUniverse:main' into main 2022-01-05 16:33:13 +01:00
Xiphoseer
852ec4d990 Update requested VS version 2022-01-05 14:29:24 +01:00
Xiphoseer
30fa4c2aa9 Rename CI workflow 2022-01-05 14:28:14 +01:00
Xiphoseer
b21a88d1b0 Pin ubuntu version 2022-01-05 14:23:28 +01:00
Xiphoseer
5e7566c89a Pin to windows-2022 2022-01-05 14:21:59 +01:00
Xiphoseer
adab6cf96f Add windows CI 2022-01-05 14:12:28 +01:00
TheMatt2
f7b3a1ef10 Merge branch 'DarkflameUniverse:main' into main 2022-01-04 12:53:41 -08:00
CodeAX2
a19454f7ae Change destroyable component validator to properly check friends 2022-01-04 11:11:23 -07:00
Xiphoseer
8ed7690b96 Merge pull request #203 from cooltrain7/Log-Line-Cleaning
Added Log content additions
2022-01-04 13:15:24 +01:00
Xiphoseer
4d19459015 Merge pull request #291 from EmosewaMC/EmosewaMC
Implemented sourceType for SendSetCurrency
2022-01-04 12:01:32 +01:00
Xiphoseer
a9c0cfd9c8 Merge pull request #340 from DarkflameUniverse/feature/tests
Add basic CTest infrastructure
2022-01-04 09:27:24 +01:00
Xiphoseer
227b82c446 Add newline at EOF [skip ci] 2022-01-04 09:26:43 +01:00
EmosewaMC
cca5b79e91 Update Mission.cpp 2022-01-03 23:05:56 -08:00
David Markowitz
329d3d66b3 Update dGame/dGameMessages/GameMessages.h
Co-authored-by: Xiphoseer <Xiphoseer@users.noreply.github.com>
2022-01-03 22:37:58 -08:00
David Markowitz
cb9ce85bda Update dGame/Character.cpp
Co-authored-by: Xiphoseer <Xiphoseer@users.noreply.github.com>
2022-01-03 22:37:53 -08:00
David Markowitz
7aed5f0500 Update dGame/Character.h
Co-authored-by: Xiphoseer <Xiphoseer@users.noreply.github.com>
2022-01-03 22:37:49 -08:00
David Markowitz
a92e05c640 Update dGame/dGameMessages/GameMessages.cpp
Co-authored-by: Xiphoseer <Xiphoseer@users.noreply.github.com>
2022-01-03 22:37:40 -08:00
Xiphoseer
f1525028da Merge pull request #289 from Verathian/portal-fixes
Portal Stun Time Reductions
2022-01-04 07:31:35 +01:00
TheMatt2
f2b3b0bf66 Check user input for the "/runmacro" command
Presents users from specifying a file path, and looking up macros in the 
expected folder.
2022-01-03 21:40:07 -08:00
Xiphoseer
64a78532ed Merge pull request #325 from Marcono1234/marcono1234/malformed-character-xml
Fix initial character XML being malformed
2022-01-04 06:12:55 +01:00
EmosewaMC
a9da275673 removed extra tab
removed extra tab
2022-01-03 16:01:54 -08:00
EmosewaMC
f74cc9cb10 Updated variable assignment
Changed the variable assignment to be a ternary operator.
2022-01-03 16:01:28 -08:00
cooltrain7
975654f8e2 Merge branch 'main' into Log-Line-Cleaning 2022-01-03 17:51:13 +00:00
Mick
73718fe9af Merge pull request #14 from maxdelayer/main
Set `build.sh` as executable & update `README.md` to acknowledge  `build.sh`'s existence
2022-01-03 18:48:33 +01:00
Xiphoseer
a06fa39a5d Add newline at EOF; re-merge cmake steps 2022-01-03 16:36:15 +01:00
Xiphoseer
03d4d84eeb Update CI pipeline 2022-01-03 16:28:16 +01:00
Xiphoseer
eb18115c99 Update CMakePresets 2022-01-03 16:25:47 +01:00
Xiphoseer
1100c57e2d Run tests with CI 2022-01-03 16:00:32 +01:00
Xiphoseer
a591dbfe9c Basic tests infrastructure 2022-01-03 16:00:21 +01:00
EmosewaMC
74013e07a8 Encapsulated variable properly
lootSource was not encapsulated properly so this is now fixed.
2022-01-03 03:11:04 -08:00
CodeAX2
d78b2404e2 Refactor CheckValidity
- Change variables names to make it clear they are referring to the target
- Change how the target is decided to be an enemy of friend to use the built-in method
2022-01-02 14:01:29 -07:00
CodeAX2
9f895205d4 Fix formatting and add comments 2022-01-02 14:00:01 -07:00
Jacob Hofer
1ddf7d1f94 Fix for Area of Affect Behaviors targeting incorrect entities 2022-01-02 20:37:03 +00:00
Nils Bergmann
4d6991ea4b Merge branch 'DarkflameUniverse:main' into main 2022-01-02 16:08:18 +01:00
Nils Bergmann
15e8343e75 Merge pull request #8 from VBMCBoy/readme-improvements
Readme improvements as suggested by Marcono1234
2022-01-02 16:08:05 +01:00
Kay Kaprolat
4198379aa8 Removed unnecessary note about slashes 2022-01-02 10:24:01 +01:00
Marcono1234
df369612be Add XML attribute spaces consistently 2022-01-01 18:23:14 +01:00
Raphaël Dunant
f02165b912 Update UserManager.cpp
fix function call
2022-01-01 14:31:13 +01:00
Jett
203e75ef3d Fix resurrecting in BONS (#334) 2022-01-01 02:10:12 -08:00
m888r
14fc049ea0 Damage Buff source fix - inventor beehive bug (#306)
* add HandleUnmanaged overload to account for skill source

* add source to buff damage skill call to credit players for kills

* use LWOOBJID_EMPTY default arg & behaviorcontext constructor
2022-01-01 01:46:05 -08:00
Jett
83107d413d More windows fixes (#329)
- Added World, Chat and Auth servers as deps to Master
- Added "windows-default" CMake preset so that CMake didn't error out on Windows
- Added NOMINMAX define above cpplinq include
2022-01-01 01:38:45 -08:00
Jett
a15f9f38d8 Update script value to that in the lua file (#331) 2022-01-01 00:02:28 -08:00
Wincent Holm
00e841587d Merge pull request #332 from OogwayUniverse/spooky-fixes 2021-12-31 16:59:28 +01:00
Jett
2d5d5b273a remove unneeded log 2021-12-31 15:07:20 +00:00
Nils Bergmann
84b3386eab Merge branch 'DarkflameUniverse:main' into main 2021-12-31 14:14:04 +01:00
Nils Bergmann
824ab7c0c2 Update Docker_Windows.md
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-12-31 14:13:41 +01:00
Nils Bergmann
d501a85c51 Improve order of execution for start_server.sh
Suggested by @Marcono1234
2021-12-31 14:12:09 +01:00
Nils Bergmann
f53a43631c Use LF for *.sh files
Suggested by @Marcono1234
2021-12-31 14:07:40 +01:00
Nils Bergmann
9c10a7adef More meaningful error messages
Suggested by @Marcono1234
2021-12-31 14:04:51 +01:00
Nils Bergmann
bb1c7095d7 Update Docker_Windows.md
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-12-31 13:58:09 +01:00
Nils Bergmann
0bf03cb66e Update Docker_Windows.md
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-12-31 13:57:53 +01:00
Jett
f15b716ea7 Implement master server fix 2021-12-31 02:52:35 +00:00
Marcono1234
7c1f392fdf Fix initial character XML being malformed
XML was missing a space between attributes `lzrw` and `stt`.
2021-12-30 19:42:59 +01:00
Kay Kaprolat
0a737eaa0d Add note about client files and linux performance 2021-12-30 19:35:06 +01:00
Kay Kaprolat
64edb88d36 Changed docker-compose to docker compose 2021-12-30 19:21:53 +01:00
Kay Kaprolat
1e7a2febea Fix Docker Desktop download link 2021-12-30 19:19:27 +01:00
Kay Kaprolat
da0be9f226 Clarify alt-text of step 7 2021-12-30 17:13:37 +01:00
Kay Kaprolat
8af1c92eff Fix typo in step 7 2021-12-30 17:13:07 +01:00
Kay Kaprolat
be008ca439 Indent all images 2021-12-30 17:11:25 +01:00
cooltrain7
6e6eee71b3 Added more missing newline characters 2021-12-28 19:27:46 +00:00
Raphaël Dunant
2ac2dbd650 Update UserManager.cpp
Style fix (CamelCase and space)
2021-12-28 19:56:49 +01:00
cooltrain7
ff8d68f45c Merge branch 'main' into Log-Line-Cleaning 2021-12-28 18:46:44 +00:00
Gie "Max" Vanommeslaeghe
0a7d9c46eb Merge pull request #304 from OogwayUniverse/team_loot_repairs
Team loot fixes
2021-12-26 16:18:23 +01:00
Racater
b6fc49f057 simplify shirt code in character creation 2021-12-26 14:45:21 +01:00
Raphaël Dunant
57e28d4619 Merge branch 'DarkflameUniverse:main' into main 2021-12-26 14:42:16 +01:00
Nils Bergmann
8ba3fe33f3 Merge branch 'DarkflameUniverse:main' into main 2021-12-25 17:05:37 +01:00
Jett
76c9d057cf Update ChatPacketHandler.cpp 2021-12-24 11:57:31 +00:00
EmosewaMC
5e605b30de Grammatical change in a comment
Small grammatical change in a comment
2021-12-23 19:50:17 -08:00
EmosewaMC
e95af79c8a Consolidated if statement
Changed default variable to achievement and removed the else.
2021-12-23 19:43:19 -08:00
EmosewaMC
e84811bdce Refactored if statement for coins
Refactored the if statement for coins so there is only one SetCoins call for the function.
2021-12-23 18:49:01 -08:00
EmosewaMC
6aad799f95 Updated variable names
Updated the variable names to match the enum name update.
2021-12-23 18:48:08 -08:00
EmosewaMC
6ff5ae78aa Corrected enum name
Corrected the enum name and prefixes of the elements in the enum.
2021-12-23 18:46:21 -08:00
Jett
7d40585211 Test frakjaw fix 2021-12-24 01:14:15 +00:00
Jett
9440af0d67 Repaired some bugs
- Fixed Team loot
- LMI dropping for team sizes
- No more > 4 player teams
2021-12-24 00:25:52 +00:00
Wincent Holm
0afba0d1d3 Merge pull request #294 from DarkflameUniverse/fix-loot-crash 2021-12-22 17:55:53 +01:00
Wincent Holm
271e14e2f1 Fix loot crash
When applied this commit fixes a crash with the loot system due to a missing nullptr check.
2021-12-22 17:16:31 +01:00
Raphaël Dunant
ac01edd440 Fix wrong shirt colors in the character selection 2021-12-22 16:02:19 +01:00
EmosewaMC
f772fedf19 Updated description of SetCoins
Updated the description of the Character::SetCoins function to more accurately describe how the function works.
2021-12-22 00:43:42 -08:00
EmosewaMC
29cf7f8998 Changed ambiguous variables
Changed ambiguous variables from int to int32_t to clarify what they are.
2021-12-22 00:15:08 -08:00
EmosewaMC
97f8e9e9fc Added enum for coin sources
Added an enum for coin sources as to avoid leaving a random number in the code.
2021-12-22 00:01:55 -08:00
EmosewaMC
c575294587 Changed variable names
Changed variable names to more accurately match what they are
2021-12-21 23:32:39 -08:00
EmosewaMC
23e269940b Implemented sourceType for SendSetCurrency
Implemented sourceType for the function SendSetCurrency.
2021-12-21 23:26:54 -08:00
Verathian
7b18c81608 BoNS Time Smash Fix 2021-12-22 00:20:53 -05:00
Verathian
eae1a38705 Portal Stun Time Reductions 2021-12-21 22:51:38 -05:00
Verathian
3cb16ddb5f Leaderboard Scoring Updates 2021-12-21 22:30:37 -05:00
Verathian
dcbca46e75 Leaderboard Scoring Updates 2021-12-21 22:15:29 -05:00
Wincent Holm
65b7f49c9b Merge pull request #248 from Xiphoseer/main 2021-12-21 21:23:56 +01:00
Gie "Max" Vanommeslaeghe
1006bd17e3 Merge pull request #276 from cuzitsjonny/main
ChatServer respawn after crash
2021-12-21 20:09:16 +01:00
Wincent Holm
0700b9647b Merge pull request #284 from saltshaker/main 2021-12-21 11:23:26 +01:00
saltshaker
aad4ed6a83 Added include <vector> to Loot.h to allow the server to build on GCP. Resolves #281. 2021-12-21 03:17:35 -07:00
Nils Bergmann
185bed2048 Merge pull request #7 from VBMCBoy/readme-improvements 2021-12-20 14:07:04 +01:00
Jonny
9d52ee7120 WorldServer now attempts to reconnect to ChatServer 2021-12-20 13:50:53 +01:00
Jett
0531365cb5 Make loot accurate to the loot drop rates during live. (#216)
* loot fix (broken)

* Fixed loot

* Update SlashCommandHandler.cpp

* Remove debug command

* Roll loot command

* Remove debug log

* Added const references
When this commit is applied it adds const references to the loot system avoid some unnecessary copies.

Co-authored-by: wincent <wincent.holm@gmail.com>
Co-authored-by: Avery <averysumner@gmail.com>
2021-12-20 02:25:45 -08:00
f7858ab183 Merge pull request #222 from anarcal/main
Add port recycling to instance creation
2021-12-20 01:47:23 -08:00
Jonny
dfb41c7c40 MasterServer now respawns ChatServer on crash 2021-12-20 10:08:57 +01:00
Wincent Holm
c8177563e9 Fix non-standard lambda.
When this commit is applied it fixes use of non-standard lambda.
2021-12-19 14:47:03 +01:00
Wincent Holm
6f6be5ec47 Remove utils module adde in PR by mistake 2021-12-19 13:48:31 +01:00
Wincent Holm
54501bce2a Merge pull request #258 from Nordegraf/fix-wreckin-it 2021-12-19 12:49:14 +01:00
Wincent Holm
46149b19f1 Merge pull request #254 from EmosewaMC/Crux-Prime-Enemy-Fix 2021-12-19 08:43:24 +01:00
EmosewaMC
35e8a374df Required script functions added
Re-added the required script functions.
2021-12-18 00:22:49 -08:00
EmosewaMC
88af3c7681 Change of reset use
Instead of doing a hard reset on the spawner, we simply do a SoftReset.  I also removed some dead code that was doing nothing.
2021-12-17 18:07:52 -08:00
Wincent Holm
93ddd50f76 Merge pull request #236 from ckawell/die-roll-anims-ckawell
Implemented die roll animations for the Lego Dice item
2021-12-17 18:29:15 +01:00
Niklas Conen
3793b1f00b fixed bug where smashedTimes counter cont incremented at the beginning of a race 2021-12-17 17:37:03 +01:00
EmosewaMC
8dd376ae1e Crux Prime named enemy fix
Fixed an issue where named enemies on crux prime would no longer spawn by un-commenting a line that was commented out.
2021-12-17 00:31:19 -08:00
Wincent Holm
f816ce4beb Merge pull request #189 from OogwayUniverse/fdb_checksum
Implement FDB Checksum
Checks the client database with a checksum. This is an optional check to prevent the use of modded or outdated clients.
2021-12-16 23:54:08 +01:00
Jett
6f932fe2cb Spelling and set filestream mode 2021-12-16 22:51:37 +00:00
wincent
49aba62dbb Updated database check
When applied this commit updates the style of the database check, changes some logging statements, and makes developers able to skip the check.
2021-12-16 23:11:51 +01:00
Xiphoseer
630d34f51c Set CMakePresets.json min cmake to 3.12 2021-12-16 20:56:11 +01:00
Xiphoseer
8846524541 Add GitHub Actions Workflow
* Create build.yml
* Create CMakePresets.json
2021-12-16 20:29:48 +01:00
Nils Bergmann
279fa076d6 Merge branch 'DarkflameUniverse:main' into main 2021-12-16 14:51:16 +01:00
Wincent Holm
3cad0214d1 Merge pull request #233 from sersorrel/instanceinfo-is-one-word
Correct documentation for /instanceinfo
2021-12-16 11:30:33 +01:00
Christopher Kawell
9c570b8121 Merge pull request #1 from Nordegraf/add-its-truly-random-achievement
Add its truly random achievement
2021-12-15 20:37:58 -06:00
Niklas Conen
2a00d50672 fixed formatting 2021-12-16 00:36:10 +01:00
Niklas Conen
b05c41fe8f added tracking of the It's Truly Random achievement 2021-12-16 00:30:46 +01:00
Mick
52fa7aaeae Merge pull request #239 from MickVermeulen/main
Fix issue templates
2021-12-15 22:36:16 +01:00
Mick Vermeulen
9f761a9ea5 Fix issue templates
GitHub updated their issue template format, checklists now also need a label attribute.
2021-12-15 22:34:26 +01:00
BuildTools
337383b6fd Changed Log statement to debug log 2021-12-15 14:44:10 -06:00
BuildTools
c4dd85be53 Added error log for die roll 2021-12-15 14:33:16 -06:00
BuildTools
de202ac6cc minor formatting fix 2021-12-15 13:27:57 -06:00
Christopher Kawell
34050f641d Merge branch 'main' into die-roll-anims-ckawell 2021-12-15 13:27:11 -06:00
BuildTools
fb18225f46 Implemented die roll animations for the Lego Dice item 2021-12-15 13:23:49 -06:00
Jett
a5d527d0cf client fdb checksum bug 2021-12-15 18:45:42 +00:00
58229a922e setminifig shirt -> setminifig shirtcolor 2021-12-14 18:55:05 -08:00
a2ed772417 setMinifig -> setminifig 2021-12-14 18:51:41 -08:00
ash
e58af90c8b Correct documentation for /instanceinfo 2021-12-14 21:45:35 +00:00
Kay Kaprolat
0d88357c85 Add Git installation instructions 2021-12-14 21:14:48 +01:00
Jett
ff2f5cb2ce (untested) 2021-12-14 19:25:30 +00:00
Nils Bergmann
0f7986ff36 Building now creates log directory by itself 2021-12-14 20:19:00 +01:00
Nils Bergmann
f96a5e2b1a Update utils url 2021-12-14 20:09:10 +01:00
Nils Bergmann
2b92bbc45f Merge branch 'DarkflameUniverse:main' into main 2021-12-14 20:05:31 +01:00
Nils Bergmann
5ab326142f Merge pull request #6 from jgkawell/pr-comments
Addressing more PR comments
2021-12-14 20:04:21 +01:00
Nils Bergmann
023b7f85fb Merge branch 'main' into pr-comments 2021-12-14 20:03:58 +01:00
Nils Bergmann
79bcf811d6 Merge pull request #5 from VBMCBoy/readme-improvements
Readme: link to Docker Desktop and on stopping the server
2021-12-14 20:01:30 +01:00
Jett
543b231a80 Update WorldServer.cpp 2021-12-14 18:12:44 +00:00
Unknown
c060b01037 fix undeleted dpEntity after enemy smashed
could be the cause of long-soak (hours long) sessions having CPU issues
2021-12-14 16:24:48 +01:00
Jack Kawell
f6a401ac6b Addressing PR comments 2021-12-14 00:08:08 -07:00
Nexus
ca8f0059a3 Add port recycling to instance creation
Made instance creation use previously used ports when available, to prevent
crashes caused by ports being used that are outside of the assigned range.
2021-12-14 11:05:33 +08:00
cooltrain7
995042f130 Added missing log newline character 2021-12-13 19:45:08 +00:00
wincent
259c236b72 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.
2021-12-13 16:57:43 +01:00
Mick
81d25dd574 Merge pull request #150 from OogwayUniverse/script_ignore 2021-12-13 15:44:35 +01:00
Mick
ff3e10d076 Merge pull request #177 from DarkflameUniverse/implement-buccanneer-valiant
Fix #164: Implement Buccaneer Valiant special ability
2021-12-13 14:31:36 +01:00
cooltrain7
9b1fbe6c2c Added extra log information and replaced incorrect print statements
- Added extra Zone and Instance information to ambiguous log calls during loading. chat connection, chat connection loss, and shutdown
- Fixed correct class names in some log lines
- Replaced printf during world shutdown with correct log call with instance and zone info
2021-12-13 01:37:09 +00:00
cooltrain7
ed151e6d45 Added extra information to connection log
- Added correct class name to log calls
 - Added extra zone and instance information in ambiguous log call
2021-12-13 01:33:51 +00:00
cooltrain7
932128a084 Replaced printf with correct logger->log call
-  Use of printf breaks the flow of the console
2021-12-13 01:31:39 +00:00
cooltrain7
8c6ef98b22 Replaced cout with correct logger->log call
-  Use of cout breaks the flow of the console
2021-12-13 01:29:38 +00:00
Jett
9e032223eb Remove unused MD5 functions and fixed memory leak 2021-12-12 15:53:19 +00:00
Jett
830cf22beb Calculate FDB checksum in chunks 2021-12-12 15:14:04 +00:00
Wincent Holm
d7294bda55 Merge pull request #187 from Nordegraf/fix-nstokenconsole-exchangerate
increased the exchange rate of the nimbus station console to 5 faction tokens for 25 maelstrom infected bricks
2021-12-12 08:44:15 +01:00
Jett
49c1cb3aff Implement FDB Checksum
- Added config option `check_fdb`
- Added check in WorldServer.cpp
- Added raw MD5 function in MD5.cpp and MD5.h
2021-12-12 03:41:11 +00:00
Niklas Conen
834b87f4b2 increased the exchange rate of the nimbus station console to 5 faction tokens for 25 maelstrom infected bricks 2021-12-12 03:45:25 +01:00
Gie "Max" Vanommeslaeghe
180db5dea5 Merge pull request #151 from OogwayUniverse/trigger_fixes
Moonbase fix
2021-12-11 19:39:24 +01:00
Wincent Holm
95d1c65011 Merge pull request #180 from OogwayUniverse/coin_exploit
Patched coin exploit
2021-12-11 17:40:59 +01:00
wincent
bb508e91c1 Update the code style
When applied this commit updates the code style used when validating coin pickups.
2021-12-11 17:33:54 +01:00
Jett
94e32a5773 replace the other double cast 2021-12-11 14:24:25 +00:00
Jett
6427b097ab Replace two casts with one 2021-12-11 14:22:39 +00:00
Jett
22de531ab3 Changes asked for by Wincent 2021-12-11 13:57:15 +00:00
Jett
b6453376e4 patched coin exploit 2021-12-11 13:21:00 +00:00
Jett
74742771c4 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
2021-12-11 12:29:34 +00:00
Mick Vermeulen
833ed8a40d 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.
2021-12-11 11:59:29 +01:00
Jett
c8991666d2 Potential solution 2021-12-11 10:46:45 +00:00
Mick
e31dc35733 Merge pull request #170 from OogwayUniverse/minifig_editing 2021-12-11 10:50:44 +01:00
Mick
5767ebea38 Merge pull request #132 from StefanH-AT/readme-note-delete-script-pak 2021-12-11 10:48:26 +01:00
Jett
6500b62c52 Minifig editing 2021-12-11 02:02:02 +00:00
Kay Kaprolat
4a1928ba92 removed forgotten TODO from Docker_Windows.md 2021-12-10 22:00:00 +01:00
Kay Kaprolat
6350d8e135 placed images on their own line in Docker_Windows.md 2021-12-10 21:59:20 +01:00
Kay Kaprolat
1dd5ac0ecb resolved merge - removed leading slashes from image paths 2021-12-10 21:54:11 +01:00
Kay Kaprolat
b42c4db400 removed spaces from image names 2021-12-10 21:51:49 +01:00
Kay Kaprolat
dca1361bac Added slashes to image paths 2021-12-10 21:29:42 +01:00
Kay Kaprolat
f7cf0010db clarified CLIENT_PATH 2021-12-10 21:21:22 +01:00
Kay Kaprolat
1073a2e2d1 added all images to Docker_Windows.md 2021-12-10 21:21:06 +01:00
Kay Kaprolat
b6648ff596 cropped images and added highlights 2021-12-10 21:19:47 +01:00
Kay Kaprolat
3a7db82004 added currently used images 2021-12-10 21:03:52 +01:00
Kay Kaprolat
cd3540b085 first draft for Docker usage under Windows 2021-12-10 20:38:51 +01:00
Kay Kaprolat
c7c1500c5e resolved merge conflict 2021-12-10 20:36:05 +01:00
Kay Kaprolat
0316b2189d removed . after command and added link for MacOS 2021-12-10 20:34:21 +01:00
Kay Kaprolat
67ca452993 Make docker-compose consistently docker compose 2021-12-09 22:43:18 +01:00
Nils Bergmann
0bad9d7186 Move utils to submodule 2021-12-09 22:39:54 +01:00
Nils Bergmann
960b090702 Move utils to submodule 2021-12-09 22:39:43 +01:00
Kay Kaprolat
ecbf886e52 Merge TheNoim's current changes. 2021-12-09 22:32:47 +01:00
Nils Bergmann
da5b290809 Merge branch 'DarkflameUniverse:main' into main 2021-12-09 22:29:10 +01:00
Nils Bergmann
d1e0a73f36 Simplify run steps 2021-12-09 22:28:16 +01:00
Jett
a9dc0e0dac to improve (broken) 2021-12-09 21:06:01 +00:00
Kay Kaprolat
22e6caa0e6 added link to Docker Desktop and details on stopping the server 2021-12-09 20:38:15 +01:00
Nils Bergmann
11ade05510 style: fix whitespace 2021-12-09 18:49:46 +01:00
Nils Bergmann
ef7dd0f069 Merge pull request #3 from jgkawell/pr-improvements
Dockerized improvements
2021-12-09 18:46:44 +01:00
Jack Kawell
417ff818d3 Merge pull request #3 from TheNoim/pr-improvements
WIP: make this work independent of the repo directory
2021-12-09 10:44:02 -07:00
Mick
82a1c8a765 Merge pull request #147 from Daystar1998/main
Fix spelling
2021-12-09 18:20:41 +01:00
Mick
1f083cb168 Merge pull request #136 from MickVermeulen/main
Add issue templates
2021-12-09 18:18:24 +01:00
Mick
51600a5329 Merge pull request #134 from DarkflameUniverse/fix-sentry-faction
Update BaseEnemyMech script to change the default faction
2021-12-09 18:17:55 +01:00
Mick
140c736bef Merge pull request #130 from DarkflameUniverse/contributing-commit-guidelines
Update CONTRIBUTING.md to include commit guidelines
2021-12-09 18:17:41 +01:00
Mick Vermeulen
9b085faf07 Add issue templates
Added issue templates to aid with the structural submission of issues.
2021-12-09 18:17:19 +01:00
Nils Bergmann
619eec8335 Merge branch 'pr-improvements' into pr-improvements 2021-12-09 17:43:52 +01:00
Jett
e4de42659e Update Entity.cpp 2021-12-09 13:56:07 +00:00
Jett
bd609dfc90 Add ship shake to not log about being missing
This log was causing confusion and issues when in reality there was no problem present.
2021-12-09 13:09:12 +00:00
Matthew Day
50512cdef8 Fix spelling 2021-12-09 03:17:08 -06:00
Jack Kawell
56f860676d Added admin setup command to docs 2021-12-09 00:37:14 -07:00
Jack Kawell
3b90669d03 Added a link to keygen for flask secret 2021-12-09 00:34:14 -07:00
Jack Kawell
ecd717702d Added client setup check to start_server.sh 2021-12-09 00:20:10 -07:00
Jack Kawell
18d797150e PR comments 2021-12-09 00:10:29 -07:00
Matthew Day
8c16127115 Fix spelling 2021-12-08 23:31:58 -06:00
Mick Vermeulen
f22bf24663 Update BaseEnemyMech script to change the default faction
As part of the base enemy mech script its faction should be updated to 4
to make sure it's seen as an enemy by the client. The AgDarklingMech script
has been deleted as its functionality was essentially that of BaseEnemyMech
and thus no longer necessary.
2021-12-08 20:00:08 +01:00
Stefan Heinz
fdd4e3cc80 Add note to readme for troubleshooting tips with script editing 2021-12-08 18:22:05 +01:00
Mick Vermeulen
e91222b504 Update CONTRIBUTING.md to include commit guidelines
Added commit guidelines to CONTRIBUTING.md to aid people in writing proper
commits.
2021-12-08 18:11:12 +01:00
Nils Bergmann
72ffe50ca6 Merge branch 'DarkflameUniverse:main' into pr-improvements 2021-12-08 15:10:17 +01:00
Nils Bergmann
7f1e392be2 WIP: add master_ip option 2021-12-08 14:57:16 +01:00
Nils Bergmann
51a9f61e88 WIP: make this work independent of the repo directory 2021-12-08 14:39:19 +01:00
Jack Kawell
293aaff2a5 A few more improvements 2021-12-08 01:54:44 -07:00
Jack Kawell
f185c8b5db Moved all the setup of client files into a single use Docker image 2021-12-08 00:50:15 -07:00
Jack Kawell
a38765d02d fixing my mistakes (aka TheNoim is smarter than me) 2021-12-07 23:44:37 -07:00
Jack Kawell
59f053433c External IP configuration as well as other small improvements 2021-12-07 23:33:34 -07:00
a923a2baa7 Merge pull request #116 from DarkflameUniverse/revert-83-main
Revert "separate AgSpaceStuff and AgShipShake"
2021-12-07 18:14:26 -08:00
f68f683e22 Revert "separate AgSpaceStuff and AgShipShake" 2021-12-07 18:14:15 -08:00
Nils Bergmann
0dfc962df5 WIP: connection issue 2021-12-08 02:40:27 +01:00
Nils Bergmann
cf6f69ba93 WIP: try to fix navmesh load 2021-12-08 00:40:15 +01:00
Nils Bergmann
4a3d341c9a WIP: default to BUILD_VERSION=171022 2021-12-07 23:18:20 +01:00
Nils Bergmann
78a04c90e6 WIP: fix migration volume and add ports 2021-12-07 23:17:26 +01:00
Nils Bergmann
9b0ba22ef9 Merge pull request #2 from jgkawell/db-with-volume
DB migrations from volume
2021-12-07 23:09:13 +01:00
Nils Bergmann
0d910e3307 Merge branch 'DarkflameUniverse:main' into main 2021-12-07 23:03:30 +01:00
Jack Kawell
b1e700e2a2 Removed db migrations from script 2021-12-07 14:56:56 -07:00
Jack Kawell
a6190fe29d Add init volume to database 2021-12-07 14:55:19 -07:00
Nils Bergmann
cf79175500 WIP: add basic docker setup instructions 2021-12-07 22:46:02 +01:00
Nils Bergmann
a1f003edd9 WIP: ignore docker-compose.override.yml 2021-12-07 22:44:21 +01:00
Nils Bergmann
0780824e31 WIP: change the example thread size to 1 2021-12-07 22:44:08 +01:00
Nils Bergmann
4cf2f4e7c7 WIP: error if the client path is missing 2021-12-07 22:43:53 +01:00
Nils Bergmann
53c9467bec WIP: use fixed mariadb version 2021-12-07 22:30:08 +01:00
Nils Bergmann
157977e267 Merge pull request #1 from VBMCBoy/main
Add Brick-Building-Fix and AccountManager
2021-12-07 22:28:37 +01:00
Nils Bergmann
e714cacc58 WIP: produce valid MasterServer binary 2021-12-07 22:25:58 +01:00
Kay Kaprolat
ac20be8744 moved healthchecks from Dockerfiles to docker-compose.yml 2021-12-07 22:17:18 +01:00
Kay Kaprolat
2681ab3828 removed AccountManager secret generation from Dockerfile 2021-12-07 22:09:54 +01:00
Kay Kaprolat
7a55db3f21 moved AccountManager secret to environment 2021-12-07 22:08:53 +01:00
Mick
5281253f66 Merge pull request #83 from red031000/main
separate AgSpaceStuff and AgShipShake
2021-12-07 21:53:42 +01:00
red031000
7bead89e39 fix a bug with timer erasing 2021-12-07 20:50:09 +00:00
red031000
002f3b6c0e separate AgSpaceStuff and AgShipShake 2021-12-07 20:50:09 +00:00
Mick
a873de5e9e Merge pull request #68 from Ramen2X/main
Make 0_initial.sql compatible with MySQL
2021-12-07 21:48:44 +01:00
Wincent Holm
73ef2e6c59 Merge pull request #91 from JoachimFlottorp/FixChat
Pull Request to fix chat messages
2021-12-07 21:35:55 +01:00
Kay Kaprolat
b46f833e23 added darkflame network to brickbuildfix 2021-12-07 21:34:06 +01:00
Kay Kaprolat
e01a7be08e added AccountManager 2021-12-07 21:30:08 +01:00
Kay Kaprolat
b35a367ed1 added brick-building fix 2021-12-07 21:25:15 +01:00
wincent
e967bf2398 Updated solution 2021-12-07 21:03:55 +01:00
Nils Bergmann
9387e88dc0 WIP: still no working MasterServer binary 2021-12-07 20:58:18 +01:00
TomNordesen
eede772b53 Nice Commit! :) 2021-12-07 20:43:42 +01:00
TomNordesen
bcb0454916 fixed 2021-12-07 20:38:05 +01:00
TomNordesen
d2fe15679c Nice Commit! :) 2021-12-07 20:35:12 +01:00
TomNordesen
c48f4b08a2 Nice Commit! :) 2021-12-07 20:19:47 +01:00
TomNordesen
bfcce19649 Nice Commit! :) 2021-12-07 19:58:24 +01:00
0db954fa72 Update README.md 2021-12-07 12:15:57 -05:00
Gie "Max" Vanommeslaeghe
6e33f5e545 Merge pull request #88 from OogwayUniverse/windows
Windows fixes (needs proper ZCompresion fix in the future)
2021-12-07 17:30:37 +01:00
Gie "Max" Vanommeslaeghe
eab32c68f3 Update CONTRIBUTING.md 2021-12-07 16:36:38 +01:00
TomNordesen
fe5814d5ba Nice Commit! :) 2021-12-07 16:31:53 +01:00
Nils Bergmann
50221fbd65 WIP: do more post build steps 2021-12-07 16:29:26 +01:00
Nils Bergmann
6f2e306c7e Merge branch 'main' of github.com:TheNoim/DarkflameServer 2021-12-07 14:51:54 +01:00
Nils Bergmann
a59ea5e245 Merge branch 'main' of github.com:TheNoim/DarkflameServer 2021-12-07 14:51:40 +01:00
Nils Bergmann
0add6853bf WIP: completely automated docker setup 2021-12-07 14:50:05 +01:00
Jett
393cce885b Windows fixes
- "Fixed" segfault
- Fixed logger not actually logging time
2021-12-07 11:12:29 +00:00
Mick
b580f19825 Merge pull request #2 from StefanH-AT/readme-cmake-version
Add note to readme about cmake version to build
2021-12-07 10:22:26 +01:00
17e4f2536b Merge pull request #85 from DarkflameUniverse/revert-44-patch/zone_path_casing
Revert "Try to load from original zone path before a lowercased one"
2021-12-07 00:25:33 -08:00
595afc4a93 Revert "Try to load from original zone path before a lowercased one" 2021-12-07 00:25:19 -08:00
Ramen2X
ca287db536 make 0_initial.sql compatible with MySQL 2021-12-06 20:06:12 -05:00
Gie "Max" Vanommeslaeghe
994382b801 Merge pull request #43 from TheLongestRose/patch-1
Important note for WSL2 users
2021-12-06 23:08:41 +01:00
Wincent Holm
d9348054f1 Merge pull request #15 from Arkannex/patch-1
Update NPC.xml
2021-12-06 15:06:34 +01:00
Arkannex
713cb6c6e5 Update NPC.xml 2021-12-06 08:04:19 -06:00
Wincent Holm
d7b443d51b Merge pull request #13 from JoachimFlottorp/main
Modified README specifying CMakeVariables outside the Python box
2021-12-06 15:01:22 +01:00
Wincent Holm
af05371c09 Merge pull request #44 from yuwui/patch/zone_path_casing
Try to load from original zone path before a lowercased one
2021-12-06 14:58:34 +01:00
Wincent Holm
9dc38e87cd Merge pull request #11 from yuwui/patch/default_net_version
change default network version to unmodded client
2021-12-06 14:53:23 +01:00
yuwui
932bf7ca60 update readme 2021-12-06 12:29:42 +01:00
yuwui
2dd96198af try original zone path before lowercasing 2021-12-06 10:31:09 +01:00
TheLongestRose
7dadc4ce77 Important note for WSL2 users
The server and client cannot connect when the server is running on a WSL2 distro and the server is set to localhost, due to differences between WSL1 and 2. This won't affect most people, but would have saved me a few hours.
2021-12-06 00:04:52 -08:00
Wincent Holm
34f1d4002b Merge pull request #38 from yuwui/patch/strip_cr 2021-12-06 07:46:14 +01:00
yuwui
3845dc77f9 strip carriage return from txt files 2021-12-06 07:07:17 +01:00
Wincent Holm
3163c91a4a Merge pull request #34 from aronwk-aaron/patch-1 2021-12-06 06:39:28 +01:00
7e4be6fdb6 Update README.md 2021-12-06 00:39:13 -05:00
4b8712b0f5 Update README.md 2021-12-06 00:37:30 -05:00
2f064f0145 change repo url in worldconfig.ini to be correct 2021-12-05 22:37:32 -06:00
0a9d4d0d66 Update 0_nt_footrace.sql 2021-12-05 19:28:06 -08:00
bcfa1fb906 Update 1_fix_overbuild_mission.sql 2021-12-05 19:27:45 -08:00
3c3a3dba8f Merge pull request #17 from m888r/clangfix
Small fixes for windows clang compile
2021-12-05 19:09:47 -05:00
Manas Shah
f760ef456c Small fixes for windows clang compile 2021-12-05 15:59:50 -08:00
Arkannex
1ba48ecd64 Update NPC.xml
Addition of an NPC to Gnarled Forest near Bucky Urchin.
2021-12-05 17:43:38 -06:00
Max
57ba0cde37 Tweaked markdown of README to reflected what was intended in previous commit. 2021-12-05 17:30:24 -06:00
Max
a409132f69 Marked build.sh as executable and updated README.md to note that build.sh exists and is useful 2021-12-05 17:28:27 -06:00
JoachimF
0c006b4007 Update README.md 2021-12-05 23:50:30 +01:00
Gie "Max" Vanommeslaeghe
498a9c0be4 Merge pull request #3 from luxaritas/patch-1
Note that the zlib -dev package is needed
2021-12-05 23:25:14 +01:00
yuwui
26dd78fff7 change default network version to 171022 2021-12-05 23:16:12 +01:00
Wincent Holm
54810fd5ef Added names to folder to copy over to build/res 2021-12-05 22:11:09 +01:00
Gie "Max" Vanommeslaeghe
27dace206b Merge pull request #6 from XenoTrixx/main
Corrected apt install command for ubuntu
2021-12-05 22:01:39 +01:00
XenoTrixx
a54687671a Correctet apt install command for ubuntu 2021-12-05 21:48:43 +01:00
Jonathan Romano
e0ef02bfdb Note that the zlib -dev package is needed 2021-12-05 15:31:42 -05:00
Stefan Heinz
18d33933d4 Add note to readme about cmake version to build 2021-12-05 21:26:58 +01:00
1053 changed files with 46460 additions and 42959 deletions

10
.dockerignore Normal file
View File

@@ -0,0 +1,10 @@
.git
Dockerfile
*.md
logo.png
versions.txt
build.sh
docker-compose.yml
.env
docker/__pycache__
.env.example

76
.editorconfig Normal file
View File

@@ -0,0 +1,76 @@
# top-most EditorConfig file
root=true
# Unix-style newlines with a newline ending every file
[*]
indent_style=tab
tab_width=4
charset=utf-8
trim_trailing_whitespace=true
end_of_line=lf
insert_final_newline=true
[*.{c++,cc,cpp,cxx,h,h++,hh,hpp,hxx,inl,ipp,tlh,tli}]
vc_generate_documentation_comments=doxygen_slash_star
cpp_indent_braces=false
cpp_alignment_tab_fill_style=use_spaces
cpp_indent_multi_line_relative_to=innermost_parenthesis
cpp_indent_within_parentheses=indent
cpp_indent_preserve_within_parentheses=false
cpp_indent_case_labels=false
cpp_indent_case_contents=true
cpp_indent_case_contents_when_block=false
cpp_indent_lambda_braces_when_parameter=true
cpp_indent_goto_labels=one_left
cpp_indent_preprocessor=leftmost_column
cpp_indent_access_specifiers=false
cpp_indent_namespace_contents=true
cpp_indent_preserve_comments=false
cpp_new_line_before_open_brace_namespace=same_line
cpp_new_line_before_open_brace_type=same_line
cpp_new_line_before_open_brace_function=same_line
cpp_new_line_before_open_brace_block=same_line
cpp_new_line_before_open_brace_lambda=same_line
cpp_new_line_scope_braces_on_separate_lines=false
cpp_new_line_close_brace_same_line_empty_type=false
cpp_new_line_close_brace_same_line_empty_function=false
cpp_new_line_before_catch=false
cpp_new_line_before_else=false
cpp_new_line_before_while_in_do_while=false
cpp_space_before_function_open_parenthesis=remove
cpp_space_within_parameter_list_parentheses=false
cpp_space_between_empty_parameter_list_parentheses=false
cpp_space_after_keywords_in_control_flow_statements=true
cpp_space_within_control_flow_statement_parentheses=false
cpp_space_before_lambda_open_parenthesis=false
cpp_space_within_cast_parentheses=false
cpp_space_after_cast_close_parenthesis=false
cpp_space_within_expression_parentheses=false
cpp_space_before_block_open_brace=true
cpp_space_between_empty_braces=false
cpp_space_before_initializer_list_open_brace=false
cpp_space_within_initializer_list_braces=true
cpp_space_preserve_in_initializer_list=true
cpp_space_before_open_square_bracket=false
cpp_space_within_square_brackets=false
cpp_space_before_empty_square_brackets=false
cpp_space_between_empty_square_brackets=false
cpp_space_group_square_brackets=true
cpp_space_within_lambda_brackets=false
cpp_space_between_empty_lambda_brackets=false
cpp_space_before_comma=false
cpp_space_after_comma=true
cpp_space_remove_around_member_operators=true
cpp_space_before_inheritance_colon=true
cpp_space_before_constructor_colon=true
cpp_space_remove_before_semicolon=true
cpp_space_after_semicolon=false
cpp_space_remove_around_unary_operator=true
cpp_space_around_binary_operator=insert
cpp_space_around_assignment_operator=insert
cpp_space_pointer_reference_alignment=left
cpp_space_around_ternary_operator=insert
cpp_wrap_preserve_blocks=one_liners
cpp_indent_comment=fasle

17
.env.example Normal file
View File

@@ -0,0 +1,17 @@
# Full path to the LEGO Universe client
CLIENT_PATH=/Users/someuser/LEGO Universe
# Can improve build time
BUILD_THREADS=1
# Updates NET_VERSION in CMakeVariables.txt
BUILD_VERSION=171022
# make sure this is a long random string
# grab a "SHA 256-bit Key" from here: https://keygen.io/
ACCOUNT_MANAGER_SECRET=
# Should be the externally facing IP of your server host
EXTERNAL_IP=localhost
# Database values
# Be careful with special characters here. It is more safe to use normal characters and/or numbers.
MARIADB_USER=darkflame
MARIADB_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_DATABASE=darkflame

8
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,8 @@
# format codebase
19e77a38d837ce781ba0ca6ea8e78b67a6e3b5a5
# add semi-colons to macros consistently
9e4ce24fd2851e65df776dd9c57bcb0d45f4453a
# convert to unix line endings
72477e01e2711e0f61cdb192ee266e5e21b8846f

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto eol=lf

60
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: Bug Report
description: Report incorrect behavior in DarkflameServer
title: "BUG: "
labels: ["bug", "triage"]
body:
- type: checkboxes
id: checks
attributes:
label: "Make sure you've done the following:"
options:
- label: >
I have checked that this issue has not already been reported.
required: true
- label: >
I have validated that this issue is not a syntax error of either MySQL or SQLite.
required: true
- label: >
I have pulled the latest version of the main branch of DarkflameServer and have confirmed that the issue exists there.
required: true
- type: input
id: server-version
attributes:
label: DarkflameServer Version
description: >
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
validations:
required: true
- type: textarea
id: problem
attributes:
label: Issue Description
description: >
Please provide a description of the issue. If this is an in-game bug, please also include pictures that showcase the issue.
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction Steps
description: >
Please provide a concise list of steps needed to reproduce this issue.
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
description: >
Please describe what you expected to happen instead of the issue.
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: >
Please include the environment you're running DarkflameServer on (for example: Windows, macOS, Ubuntu, WSL, etc).
validations:
required: true

View File

@@ -0,0 +1,44 @@
name: Documentation Improvement
description: Report wrong or missing documentation
title: "DOC: "
labels: ["docs", "triage"]
body:
- type: checkboxes
id: checks
attributes:
label: "Make sure you've done the following:"
options:
- label: >
I have checked that this issue has not already been reported.
required: true
- label: >
I have validated that the documentation is wrong or missing on the latest version of the main branch of DarkflameServer
required: true
- type: textarea
id: location
attributes:
label: Location of the documentation
description: >
Please provide the location of the documentation, e.g. "Entity.cpp" or the
URL of the documentation, e.g.
"https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md"
placeholder: https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md
validations:
required: true
- type: textarea
id: problem
attributes:
label: Documentation problem
description: >
Please provide a description of what documentation you believe needs to be fixed/improved
validations:
required: true
- type: textarea
id: suggested-fix
attributes:
label: Suggested fix for documentation
description: >
Please explain the suggested fix and **why** it's better than the existing documentation
validations:
required: true

View File

@@ -0,0 +1,40 @@
name: Feature Request
description: Suggest an idea for DarkflameServer
title: "ENH: "
labels: ["enhancement", "triage"]
body:
- type: textarea
id: problem
attributes:
label: Is your feature request related to a problem?
description: >
Please provide a description of what the problem is, e.g. "I wish I could use DarkflameServer to do [...]"
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: >
Please provide a description of the feature request, e.g. "`SlashCommandHandler.cpp` should get a new command `/unlimited-coins` that [...]", try to write a docstring for the desired feature
validations:
required: true
- type: textarea
id: implications
attributes:
label: Repository breaking implications
description: >
Please provide a description of how this feature will affect the DarkflameServer repository
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: >
Please provide a description of any alternative solutions or features you've considered
- type: textarea
id: example
attributes:
label: Additional context
description: >
Please add any other context, code examples, or references to existing implementations about the feature request here

View File

@@ -0,0 +1,62 @@
name: Installation Issue
description: Report issues installing the DarkflameServer on your system
title: "BUILD: "
labels: ["build", "triage"]
body:
- type: checkboxes
id: checks
attributes:
label: "Make sure you've done the following:"
options:
- label: >
I have read the [installation guide](https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md).
required: true
- type: input
id: server-version
attributes:
label: DarkflameServer Version
description: >
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
validations:
required: true
- type: dropdown
id: platform
attributes:
label: Platform
description: >
Please provide on which platform you've tried to install DarkflameServer
options:
- Windows
- WSL1
- WSL2
- macOS
- Ubuntu
- Other
validations:
required: true
- type: dropdown
id: architecture
attributes:
label: Architecture
description: >
Please provide on which architecture you've tried to install DarkflameServer
options:
- x86
- ARM
validations:
required: true
- type: textarea
id: logs
attributes:
label: Error Logs
description: >
If possible, please copy and paste the error logs when attempting to install DarkflameServer.
value: >
<details>
Replace this line with the error logs.
</details>

View File

@@ -0,0 +1,50 @@
name: Performance Issue
description: Report slow performance or memory issues when running DarkflameServer
title: "PERF: "
labels: ["performance", "triage"]
body:
- type: checkboxes
id: checks
attributes:
label: "Make sure you've done the following:"
options:
- label: >
I have checked that this issue has not already been reported.
required: true
- label: >
I have pulled the latest version of the main branch of DarkflameServer and have confirmed that the issue exists there.
required: true
- type: input
id: server-version
attributes:
label: DarkflameServer Version
description: >
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: >
Please include the environment you're running DarkflameServer on (for example: Windows, macOS, Ubuntu, WSL, etc), available memory, number of CPU cores.
validations:
required: true
- type: textarea
id: example
attributes:
label: Reproducible Example
description: >
Please provide a minimal, example that quantifies slow runtime or memory issues.
Ideally include screenshots of CPU usage or memory usage. And if possible point
to the code that you may suspect to cause the issue.
validations:
required: true
- type: textarea
id: prior-performance
attributes:
label: Prior Performance
description: >
If applicable, please provide the prior version of DarkflameServer and output
of the same reproducible example where the performance issue did not exist.

56
.github/workflows/build-and-test.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
name: Build & Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ windows-2022, ubuntu-20.04, macos-11 ]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Add msbuild to PATH (Windows only)
if: ${{ matrix.os == 'windows-2022' }}
uses: microsoft/setup-msbuild@v1.1
with:
vs-version: '[17,18)'
msbuild-architecture: x64
- name: Install libssl (Mac Only)
if: ${{ matrix.os == 'macos-11' }}
run: brew install openssl@3
- name: cmake
uses: lukka/run-cmake@v10
with:
configurePreset: "ci-${{matrix.os}}"
buildPreset: "ci-${{matrix.os}}"
testPreset: "ci-${{matrix.os}}"
- name: artifacts
uses: actions/upload-artifact@v2
if: ${{ github.ref == 'ref/head/main' }}
with:
name: build-${{matrix.os}}
path: |
build
!build/tests
!build/Testing
!build/CMakeFiles
!build/DartConfiguration.tcl
!build/CTestTestfile.cmake
!build/CMakeCache.txt
!build/build.ninja
!build/_deps
!build/cmake_install.cmake
!build/*.a
!build/*.lib
!build/*.dir
!build/*.vcxproj
!build/*.vcxproj.filters

8
.gitignore vendored
View File

@@ -1,6 +1,7 @@
temp/
cmake-build-debug/
RelWithDebInfo/
docker/configs
# Third party libraries
thirdparty/mysql/
@@ -114,3 +115,10 @@ CMakeFiles/TargetDirectories.txt
# clangd
.cache
thirdparty/zlib-1.2.11/
.env
docker/__pycache__
docker-compose.override.yml
!/tests/TestBitStreams/*.bin

16
.gitmodules vendored
View File

@@ -10,3 +10,19 @@
[submodule "thirdparty/libbcrypt"]
path = thirdparty/libbcrypt
url = https://github.com/trusch/libbcrypt.git
[submodule "thirdparty/mariadb-connector-cpp"]
path = thirdparty/mariadb-connector-cpp
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
ignore = dirty
[submodule "thirdparty/docker-utils"]
path = thirdparty/docker-utils
url = https://github.com/lcdr/utils.git
[submodule "thirdparty/LUnpack"]
path = thirdparty/LUnpack
url = https://github.com/Xiphoseer/LUnpack.git
[submodule "thirdparty/AccountManager"]
path = thirdparty/AccountManager
url = https://github.com/DarkflameUniverse/AccountManager
[submodule "thirdparty/raylib"]
path = thirdparty/raylib
url = https://github.com/raysan5/raylib

View File

@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.14)
project(Darkflame)
include(CTest)
set (CMAKE_CXX_STANDARD 17)
# Read variables from file
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
@@ -9,113 +12,76 @@ string(REPLACE "\n" ";" variables ${variables})
# Set the cmake variables, formatted as "VARIABLE #" in variables
foreach(variable ${variables})
# If the string contains a #, skip it
if("${variable}" MATCHES "#")
continue()
endif()
# If the string contains a #, skip it
if(NOT "${variable}" MATCHES "#")
# Split the variable into name and value
string(REPLACE "=" ";" variable ${variable})
# Split the variable into name and value
string(REPLACE "=" ";" variable ${variable})
# Check that the length of the variable is 2 (name and value)
list(LENGTH variable length)
if(NOT ${length} EQUAL 2)
continue()
endif()
# Check that the length of the variable is 2 (name and value)
list(LENGTH variable length)
if(${length} EQUAL 2)
list(GET variable 0 variable_name)
list(GET variable 1 variable_value)
list(GET variable 0 variable_name)
list(GET variable 1 variable_value)
# Set the variable
set(${variable_name} ${variable_value})
# Set the variable
set(${variable_name} ${variable_value})
# Add compiler definition
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}")
# Add compiler definition
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}")
message(STATUS "Variable: ${variable_name} = ${variable_value}")
message(STATUS "Variable: ${variable_name} = ${variable_value}")
endif()
endif()
endforeach()
# On windows it's better to build this from source, as there's no way FindZLIB is gonna find it
if(NOT WIN32)
find_package(ZLIB REQUIRED)
endif()
# Fetch External (Non-Submodule) Libraries
if(WIN32)
include(FetchContent)
FetchContent_Declare(
mysql
URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-winx64.zip
URL_HASH MD5=e3c53f6e4d0a72fde2713f7597bf9468
)
FetchContent_Declare(
zlib
URL http://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
)
FetchContent_MakeAvailable(zlib)
FetchContent_MakeAvailable(mysql)
set(ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR})
set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") # Why?
add_library(ZLIB::ZLIB ALIAS zlib) # You're welcome
endif(WIN32)
if(UNIX)
if(APPLE)
else()
include(FetchContent)
FetchContent_Declare(
mysql
URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-linux-glibc2.12-x86-64bit.tar.gz
URL_HASH MD5=12f086b76c11022cc7139b41a36cdf9e
)
FetchContent_MakeAvailable(mysql)
if (__include_backtrace__ AND __compile_backtrace__)
FetchContent_Declare(
backtrace
GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git
)
FetchContent_MakeAvailable(backtrace)
if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs)
set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind")
execute_process(
COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}"
)
endif()
link_directories(${backtrace_SOURCE_DIR}/.libs/)
include_directories(${backtrace_SOURCE_DIR})
endif(__include_backtrace__)
endif()
endif(UNIX)
# Set the version
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}")
# Set our compile options
option(BUILD_VISUAL_DEBUGGER "Toggle for building visual debugger (default off)" OFF)
# Echo the version
message(STATUS "Version: ${PROJECT_VERSION}")
set(CMAKE_CXX_STANDARD 17)
# Disable demo, tests and examples for recastNavigation. Turn these to ON if you want to use them
# This has to be done here to prevent a rare build error due to missing dependencies on the initial generations.
set(RECASTNAVIGATION_DEMO OFF CACHE BOOL "" FORCE)
set(RECASTNAVIGATION_TESTS OFF CACHE BOOL "" FORCE)
set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
if(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif(WIN32)
# Compiler flags:
# Disabled deprecated warnings as the MySQL includes have deprecated code in them.
# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent.
# Disabled no-register
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}")
if(UNIX)
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC")
endif()
if (__dynamic AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
endif()
if (__ggdb)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
elseif(MSVC)
# Skip warning for invalid conversion from size_t to uint32_t for all targets below for now
add_compile_options("/wd4267" "/utf-8")
elseif(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
# Our output dir
set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
# Create a /res directory
make_directory(${CMAKE_BINARY_DIR}/res)
@@ -123,364 +89,184 @@ make_directory(${CMAKE_BINARY_DIR}/res)
# Create a /locale directory
make_directory(${CMAKE_BINARY_DIR}/locale)
# Copy ini files on first build
if (NOT EXISTS ${PROJECT_BINARY_DIR}/authconfig.ini)
configure_file(
${CMAKE_SOURCE_DIR}/resources/authconfig.ini ${PROJECT_BINARY_DIR}/authconfig.ini
COPYONLY
)
endif()
if (NOT EXISTS ${PROJECT_BINARY_DIR}/chatconfig.ini)
configure_file(
${CMAKE_SOURCE_DIR}/resources/chatconfig.ini ${PROJECT_BINARY_DIR}/chatconfig.ini
COPYONLY
)
endif()
if (NOT EXISTS ${PROJECT_BINARY_DIR}/worldconfig.ini)
configure_file(
${CMAKE_SOURCE_DIR}/resources/worldconfig.ini ${PROJECT_BINARY_DIR}/worldconfig.ini
COPYONLY
)
endif()
if (NOT EXISTS ${PROJECT_BINARY_DIR}/masterconfig.ini)
configure_file(
${CMAKE_SOURCE_DIR}/resources/masterconfig.ini ${PROJECT_BINARY_DIR}/masterconfig.ini
COPYONLY
)
# Create a /logs directory
make_directory(${CMAKE_BINARY_DIR}/logs)
# Copy resource files on first build
set(RESOURCE_FILES "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf")
foreach(resource_file ${RESOURCE_FILES})
if (NOT EXISTS ${PROJECT_BINARY_DIR}/${resource_file})
configure_file(
${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file}
COPYONLY
)
message("Moved ${resource_file} to project binary directory")
endif()
endforeach()
# Copy vanity files on first build
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml")
foreach(file ${VANITY_FILES})
configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY)
endforeach()
# Move our migrations for MasterServer to run
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/)
file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/dlu/*.sql)
foreach(file ${SQL_FILES})
get_filename_component(file ${file} NAME)
if (NOT EXISTS ${PROJECT_BINARY_DIR}/migrations/${file})
configure_file(
${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/${file}
COPYONLY
)
endif()
endforeach()
# Create our list of include directories
set(INCLUDED_DIRECTORIES
"dCommon"
"dChatFilter"
"dGame"
"dGame/dBehaviors"
"dGame/dComponents"
"dGame/dGameMessages"
"dGame/dInventory"
"dGame/dMission"
"dGame/dEntity"
"dGame/dUtilities"
"dPhysics"
"dNavigation"
"dNavigation/dTerrain"
"dZoneManager"
"dDatabase"
"dDatabase/Tables"
"dNet"
"dScripts"
"dWorldServer"
"thirdparty/raknet/Source"
"thirdparty/tinyxml2"
"thirdparty/recastnavigation"
"thirdparty/SQLite"
"thirdparty/cpplinq"
)
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
if (APPLE)
include_directories("/usr/local/include/")
endif()
# Copy files to output
configure_file("${CMAKE_SOURCE_DIR}/vanity/CREDITS.md" "${CMAKE_BINARY_DIR}/vanity/CREDITS.md" COPYONLY)
configure_file("${CMAKE_SOURCE_DIR}/vanity/INFO.md" "${CMAKE_BINARY_DIR}/vanity/INFO.md" COPYONLY)
configure_file("${CMAKE_SOURCE_DIR}/vanity/TESTAMENT.md" "${CMAKE_BINARY_DIR}/vanity/TESTAMENT.md" COPYONLY)
configure_file("${CMAKE_SOURCE_DIR}/vanity/NPC.xml" "${CMAKE_BINARY_DIR}/vanity/NPC.xml" COPYONLY)
if (WIN32)
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include")
elseif (UNIX)
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt")
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include/bcrypt")
endif()
# 3rdparty includes
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/)
if(UNIX)
if(APPLE)
include_directories(/usr/local/include/)
include_directories(/usr/local/mysql-connector-c++/include/jdbc/)
include_directories(/usr/local/mysql-connector-c++/include/jdbc/cppconn/)
else()
include_directories(${mysql_SOURCE_DIR}/include/jdbc/)
include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn/)
endif(APPLE)
endif(UNIX)
if(WIN32)
include_directories(${mysql_SOURCE_DIR}/include/jdbc)
include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn)
endif(WIN32)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include)
include_directories(${ZLIB_INCLUDE_DIRS})
# Bcrypt
if (NOT WIN32)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt)
else ()
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include)
endif ()
# Our includes
# Add binary directory as an include directory
include_directories(${PROJECT_BINARY_DIR})
include_directories(${PROJECT_SOURCE_DIR}/dChatFilter/)
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
include_directories(${PROJECT_SOURCE_DIR}/dGame/)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dBehaviors)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dComponents)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dGameMessages)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dInventory)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dMission)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dEntity)
include_directories(${PROJECT_SOURCE_DIR}/dGame/dUtilities)
include_directories(${PROJECT_SOURCE_DIR}/dPhysics/)
include_directories(${PROJECT_SOURCE_DIR}/dZoneManager/)
include_directories(${PROJECT_SOURCE_DIR}/dDatabase/)
include_directories(${PROJECT_SOURCE_DIR}/dDatabase/Tables/)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/SQLite/)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/cpplinq/)
include_directories(${PROJECT_SOURCE_DIR}/dNet/)
include_directories(${PROJECT_SOURCE_DIR}/dScripts/)
# Default to linking to libmysql
set(MYSQL_LIB mysql)
if(WIN32)
set(MYSQL_LIB mysqlcppconn)
endif(WIN32)
# Actually include the directories from our list
foreach (dir ${INCLUDED_DIRECTORIES})
include_directories(${PROJECT_SOURCE_DIR}/${dir})
endforeach()
# Lib folders:
# Add linking directories:
link_directories(${PROJECT_BINARY_DIR})
if(UNIX)
if(APPLE)
link_directories(/usr/local/mysql-connector-c++/lib64/)
else()
link_directories(${mysql_SOURCE_DIR}/lib64/)
# Link to libmysqlcppconn on Linux
set(MYSQL_LIB mysqlcppconn)
endif(APPLE)
endif(UNIX)
if(WIN32)
link_directories(${mysql_SOURCE_DIR}/lib64/vs14)
endif(WIN32)
# Load all of our third party directories
add_subdirectory(thirdparty)
# Source Code
# Glob together all headers that need to be precompiled
file(
GLOB SOURCES
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dWorldServer/*.cpp
GLOB HEADERS_DDATABASE
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dDatabase/*.h
${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.h
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h
)
# Source Code for AuthServer
file(
GLOB SOURCES_AUTH
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dAuthServer/*.cpp
GLOB HEADERS_DZONEMANAGER
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dZoneManager/*.h
)
# Source Code for MasterServer
file(
GLOB SOURCES_MASTER
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dMasterServer/*.cpp
GLOB HEADERS_DCOMMON
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dCommon/*.h
)
# Source Code for ChatServer
file(
GLOB SOURCES_CHAT
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dChatServer/*.cpp
GLOB HEADERS_DGAME
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dGame/Entity.h
${PROJECT_SOURCE_DIR}/dGame/dGameMessages/GameMessages.h
${PROJECT_SOURCE_DIR}/dGame/EntityManager.h
${PROJECT_SOURCE_DIR}/dScripts/CppScripts.h
)
# Source Code for raknet
file(
GLOB SOURCES_RAKNET
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/*.cpp
)
# Add our library subdirectories for creation of the library object
add_subdirectory(dCommon)
add_subdirectory(dDatabase)
add_subdirectory(dChatFilter)
add_subdirectory(dNet)
add_subdirectory(dScripts) # Add for dGame to use
add_subdirectory(dGame)
add_subdirectory(dZoneManager)
add_subdirectory(dNavigation)
add_subdirectory(dPhysics)
# Source Code for recast
file(
GLOB SOURCES_RECAST
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Source/*.cpp
)
# Source Code for detour
file(
GLOB SOURCES_DETOUR
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Source/*.cpp
)
# Source Code for tinyxml2
file(
GLOB SOURCES_TINYXML2
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.cpp
)
# Source Code for libbcrypt
file(
GLOB SOURCES_LIBBCRYPT
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/*.c
${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/src/*.c
)
# Source Code for dCommon
file(
GLOB SOURCES_DCOMMON
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dCommon/*.cpp
)
# Source Code for dChatFilter
file(
GLOB SOURCES_DCHATFILTER
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dChatFilter/*.cpp
)
# Source Code for dDatabase
file(
GLOB SOURCES_DDATABASE
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dDatabase/*.cpp
${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.cpp
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.cpp
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.c
)
# Source Code for dNet
file(
GLOB SOURCES_DNET
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dNet/*.cpp
)
# Source Code for dGame
file(
GLOB SOURCES_DGAME
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dGame/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dBehaviors/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dComponents/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dGameMessages/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dInventory/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dMission/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dEntity/*.cpp
${PROJECT_SOURCE_DIR}/dGame/dUtilities/*.cpp
${PROJECT_SOURCE_DIR}/dScripts/*.cpp
)
# Source Code for dZoneManager
file(
GLOB SOURCES_DZM
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dZoneManager/*.cpp
)
# Source Code for dPhysics
file(
GLOB SOURCES_DPHYSICS
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
${PROJECT_SOURCE_DIR}/dPhysics/*.cpp
)
# 3rdparty static libraries:
#add_library(zlib ${SOURCES_ZLIB})
add_library(raknet ${SOURCES_RAKNET})
add_library(tinyxml2 ${SOURCES_TINYXML2})
add_library(detour ${SOURCES_DETOUR})
add_library(recast ${SOURCES_RECAST})
add_library(libbcrypt ${SOURCES_LIBBCRYPT})
# Our static libraries:
add_library(dCommon ${SOURCES_DCOMMON})
add_library(dChatFilter ${SOURCES_DCHATFILTER})
add_library(dDatabase ${SOURCES_DDATABASE})
add_library(dNet ${SOURCES_DNET})
add_library(dGame ${SOURCES_DGAME})
add_library(dZoneManager ${SOURCES_DZM})
add_library(dPhysics ${SOURCES_DPHYSICS})
target_link_libraries(dNet dCommon) #Needed because otherwise linker errors occur.
target_link_libraries(dCommon ZLIB::ZLIB)
target_link_libraries(dCommon libbcrypt)
# Our executables:
add_executable(WorldServer ${SOURCES})
add_executable(AuthServer ${SOURCES_AUTH})
add_executable(MasterServer ${SOURCES_MASTER})
add_executable(ChatServer ${SOURCES_CHAT})
# Target libraries to link to:
target_link_libraries(WorldServer dCommon)
target_link_libraries(WorldServer dChatFilter)
target_link_libraries(WorldServer dDatabase)
target_link_libraries(WorldServer dNet)
target_link_libraries(WorldServer dGame)
target_link_libraries(WorldServer dZoneManager)
target_link_libraries(WorldServer dPhysics)
target_link_libraries(WorldServer detour)
target_link_libraries(WorldServer recast)
target_link_libraries(WorldServer raknet)
target_link_libraries(WorldServer ${MYSQL_LIB})
if(UNIX)
target_link_libraries(WorldServer pthread)
target_link_libraries(WorldServer dl)
if(NOT APPLE AND __include_backtrace__)
target_link_libraries(WorldServer backtrace)
target_link_libraries(MasterServer backtrace)
target_link_libraries(AuthServer backtrace)
target_link_libraries(ChatServer backtrace)
if (BUILD_VISUAL_DEBUGGER)
add_subdirectory(dVisualDebugger)
endif()
endif(UNIX)
if(WIN32)
target_link_libraries(WorldServer ws2_32)
endif(WIN32)
target_link_libraries(WorldServer tinyxml2)
# Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp")
# Target libraries for Auth:
target_link_libraries(AuthServer dCommon)
target_link_libraries(AuthServer dDatabase)
target_link_libraries(AuthServer dNet)
target_link_libraries(AuthServer raknet)
target_link_libraries(AuthServer ${MYSQL_LIB})
if(UNIX)
target_link_libraries(AuthServer pthread)
target_link_libraries(AuthServer dl)
endif(UNIX)
if(WIN32)
target_link_libraries(AuthServer ws2_32)
endif(WIN32)
# Add platform specific common libraries
if (UNIX)
set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "dl" "pthread")
# Target libraries for Master:
target_link_libraries(MasterServer dCommon)
target_link_libraries(MasterServer dDatabase)
target_link_libraries(MasterServer dNet)
target_link_libraries(MasterServer raknet)
target_link_libraries(MasterServer ${MYSQL_LIB})
if(UNIX)
target_link_libraries(MasterServer pthread)
target_link_libraries(MasterServer dl)
endif(UNIX)
if(WIN32)
target_link_libraries(MasterServer ws2_32)
endif(WIN32)
if (NOT APPLE AND __include_backtrace__)
set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "backtrace")
endif()
endif()
# Target libraries for Chat:
target_link_libraries(ChatServer dCommon)
target_link_libraries(ChatServer dChatFilter)
target_link_libraries(ChatServer dDatabase)
target_link_libraries(ChatServer dNet)
target_link_libraries(ChatServer raknet)
target_link_libraries(ChatServer ${MYSQL_LIB})
if(UNIX)
target_link_libraries(ChatServer pthread)
target_link_libraries(ChatServer dl)
endif(UNIX)
if(WIN32)
target_link_libraries(ChatServer ws2_32)
endif(WIN32)
add_subdirectory(tests)
# Compiler flags:
# Disabled deprecated warnings as the MySQL includes have deprecated code in them.
# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent.
# Disabled no-register
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
if(UNIX)
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC")
endif()
if (__dynamic)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
endif()
if (__ggdb)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
endif(UNIX)
# Include all of our binary directories
add_subdirectory(dWorldServer)
add_subdirectory(dAuthServer)
add_subdirectory(dChatServer)
add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries
# Add our precompiled headers
target_precompile_headers(
dGame PRIVATE
${HEADERS_DGAME}
)
target_precompile_headers(
dZoneManager PRIVATE
${HEADERS_DZONEMANAGER}
)
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
target_precompile_headers(
dDatabase PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>"
)
target_precompile_headers(
dCommon PRIVATE
${HEADERS_DCOMMON}
)
target_precompile_headers(
tinyxml2 PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>"
)

126
CMakePresets.json Normal file
View File

@@ -0,0 +1,126 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 14,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default configure step",
"description": "Use 'build' dir and Unix makefiles",
"binaryDir": "${sourceDir}/build",
"generator": "Unix Makefiles"
},
{
"name": "ci-ubuntu-20.04",
"displayName": "CI configure step for Ubuntu",
"description": "Same as default, Used in GitHub actions workflow",
"inherits": "default"
},
{
"name": "ci-macos-11",
"displayName": "CI configure step for MacOS",
"description": "Same as default, Used in GitHub actions workflow",
"inherits": "default",
"cacheVariables": {
"OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/"
}
},
{
"name": "ci-windows-2022",
"displayName": "CI configure step for Windows",
"description": "Set architecture to 64-bit (b/c RakNet)",
"inherits": "default",
"generator": "Visual Studio 17 2022",
"architecture": {
"value": "x64"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
},
{
"name": "windows-default",
"inherits": "ci-windows-2022",
"displayName": "Windows only Configure Settings",
"description": "Sets build and install directories",
"generator": "Ninja",
"architecture": {
"value": "x64",
"strategy": "external"
}
}
],
"buildPresets": [
{
"name": "default",
"configurePreset": "default",
"displayName": "Default Build",
"description": "Default Build",
"jobs": 2
},
{
"name": "ci-windows-2022",
"configurePreset": "ci-windows-2022",
"displayName": "Windows CI Build",
"description": "This preset is used by the CI build on windows",
"configuration": "RelWithDebInfo",
"jobs": 2
},
{
"name": "ci-ubuntu-20.04",
"configurePreset": "ci-ubuntu-20.04",
"displayName": "Linux CI Build",
"description": "This preset is used by the CI build on linux",
"jobs": 2
},
{
"name": "ci-macos-11",
"configurePreset": "ci-macos-11",
"displayName": "MacOS CI Build",
"description": "This preset is used by the CI build on MacOS",
"jobs": 2
}
],
"testPresets": [
{
"name": "ci-ubuntu-20.04",
"configurePreset": "ci-ubuntu-20.04",
"displayName": "CI Tests on Linux",
"description": "Runs all tests on a linux configuration",
"execution": {
"jobs": 2
},
"output": {
"outputOnFailure": true
}
},
{
"name": "ci-macos-11",
"configurePreset": "ci-macos-11",
"displayName": "CI Tests on MacOS",
"description": "Runs all tests on a Mac configuration",
"execution": {
"jobs": 2
},
"output": {
"outputOnFailure": true
}
},
{
"name": "ci-windows-2022",
"configurePreset": "ci-windows-2022",
"displayName": "CI Tests on windows",
"description": "Runs all tests on a windows configuration",
"configuration": "RelWithDebInfo",
"execution": {
"jobs": 2
},
"output": {
"outputOnFailure": true
}
}
]
}

View File

@@ -1,14 +1,14 @@
PROJECT_VERSION_MAJOR=1
PROJECT_VERSION_MINOR=0
PROJECT_VERSION_PATCH=0
PROJECT_VERSION_PATCH=4
# LICENSE
LICENSE=AGPL-3.0
# The network version.
# 171023 - Darkflame Universe client
# 171022 - Unmodded client
NET_VERSION=171023
NET_VERSION=171022
# Debugging
# __dynamic=1
__dynamic=1
# Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
# __ggdb=1
# Set __ggdb to 1 to enable the -ggdb flag for the linker, including more debug info.
@@ -16,3 +16,5 @@ NET_VERSION=171023
# Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs.
# __compile_backtrace__=1
# Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries.
__maria_db_connector_compile_jobs__=1
# Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with.

View File

@@ -36,23 +36,109 @@ In general, we follow the "fork-and-pull" Git workflow
- Open a PR in our repository.
PRs should include (when applicable):
- A descriptive title that covers the **entire** content of the pull request
- Description
- Motivation and Context
- Type of Changes
- How Has This Been Tested?
- Screenshots
## Commits
Commits to this project should be concise, descriptive and to the point. Writing proper commits helps define a clear project history and makes it easier to browse the source and pinpoint issues. Although this might seem trivial, a pull request with improperly formatted commits will not be accepted. An overview of good commit practices can be found in [this](https://cbea.ms/git-commit/) article. In a nutshell, a good commit has:
#### one conceptual change with a subject line that reflects it
The subject line of the commit is what you specify when doing `git commit -m "<subject-line>"`. When making commit, make sure that you create it for one conceptual change. E.g. do not use a commit to dump all the changes you have locally, but split your changes into commits that conceptually make sense and use the subject line to refelct that. Some examples:
**Bad:**
Commit message: `Document MovementAIComponent and add Avant Gardens Mech Scripts and fix Entity.cpp bug causing infinite loops`
Changed files:
- MovementAIComponent.cpp
- AgMechScript.cpp
- Entity.cpp
**Good:**
Commit message: `Document MovementAIComponent`
Changed files:
- MovementAIComponent.cpp
Commit message: `Add Avant Gardens Mech Scripts`
Changed files:
- AgMechScript.cpp
Commit message: `Fix Entity.cpp bug causing infinite loops`
Changed files:
- Entity.cpp
Not only does this logically make more sense, it'll make it easier to revert a conceptual change once something wrong with it. If you commit using the bad example but your bugfix turned out to introduce an even worse bug, all your changes have to be reverted, even though your other changes might not be broken. Splitting your commits into conceptually unique commits makes it easier to find and revert issues.
#### an imperative subject line
In the subject line it's also important to have an imperative writing style that covers the contents of your commit so that it easily reflects what it'll do when applied. We pick an imperative writing style so that all commits have equal tonality. An easy check for this is placing `When applied, this commit will ...` in front of your commit message and checking if that makes sense. Some examples:
**Bad:**
```
Nice commit :) -> "When applied, this commit will nice commit :)"
```
**Bad:**
```
fixed bug -> "When applied, this commit will fixed bug"
```
**Good:**
```
Fix Entity.cpp bug causing infinite loop -> "When applied, this commit will fix Entity.cpp bug causing infinite loop"
```
**Good:**
```
Add Avant Gardens mech scripts -> "When applied, this commit will add Avant Gardens mech scripts"
```
#### a subject line and a body
A good commit has a subject line that summarizes the change and a body that further describes the context required to understand the change. In this body you don't have to explain *what* the change was, as the code should reflect that, but *why* a change was made. Some examples:
**Bad:**
```
Add Avant Gardens mech scripts
Added the Avant Gardens mech scripts by creaing a new file called
AgMechScripts.cpp and then adding the proper event handlers to that
to send events to the client regarding changes of the mech.
```
**Good:**
```
Add Avant Gardens mech scripts
Added the Avant Gardens mech scripts as they were previously not
added, which produced InvalidScript errors.
```
## Development Resources
Check out a compiled list of development resources and tools [here](https://lu-dev.net/).
Please use [.editorconfig](https://editorconfig.org/#pre-installed) with your preferred IDE.
And run:
```bash
git config blame.ignoreRevsFile .git-blame-ignore-revs
```
to ignore the gitblame of mass formatting commits
## Coding Style
This project has gone through multiple iterations of coding style. In the code you'll find a number of different coding styles in use. What follows is the preferred style for this project.
### General
Use 4 spaces instead of the tab character.
**Never** use spaces instead of tabs. 1 Tab = 4 space character's width by default.
Use typically trailing braces everywhere (if, else, functions, structures, typedefs, class definitions, etc.)
@@ -77,7 +163,7 @@ if (x) {
}
```
Instead of
Instead of
```cpp
if ( x ) {

46
Docker.md Normal file
View File

@@ -0,0 +1,46 @@
# Run the Darkflame Server inside Docker
## What you need
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this.
## Run server inside Docker
1. Copy `.env.example` and save it as `.env` inside the root directory of this repository
2. Edit the `.env` file and add your path to the root directory of your LEGO® Universe Client after `CLIENT_PATH=`
3. Update other values in the `.env` file as needed (be sure to update passwords!)
4. Run `docker compose up -d --build`
5. Run `docker compose exec darkflame /app/MasterServer -a` and setup your admin account
6. Follow the directions [here](https://github.com/DarkflameUniverse/AccountManager) to setup regular user accounts. The server will be accessible at: `http://<EXTERNAL_IP>:5000`
7. Now you can see the output of the server with `docker compose logs -f --tail 100` or `docker compose logs -f --tail 100`. This can help you understand issues and there you can also see when the server finishes it's startup.
8. You're ready to connect your client!
**NOTE #1**: If you're running an older version of Docker, you may need to use the command `docker-compose` instead of `docker compose`.
**NOTE #2**: To stop the server simply run `docker compose down` and to restart it just run `docker compose up -d` again. No need to run all the steps above every time.
**NOTE #3**: Docker buildkit needs to be enabled. https://docs.docker.com/develop/develop-images/build_enhancements/#to-enable-buildkit-builds
**NOTE #4**: Make sure to run the following in the repo root directory after cloning so submodules are also downloaded.
```
git submodule update --init --recursive
```
**NOTE #5**: If DarkflameSetup fails due to not having cdclient.fdb, rename CDClient.fdb (in the same folder) to cdclient.fdb
## Disable brickbuildfix
If you don't need the http server running on port 80 do this:
1. Create a file with the name `docker-compose.override.yml` in the root of the repository
2. Paste this content:
```yml
services:
brickbuildfix:
profiles:
- donotstart
```
3. Now run `docker compose up -d`

58
Docker_Windows.md Normal file
View File

@@ -0,0 +1,58 @@
# Installation under Windows
## First Run
1. Navigate to the [Docker download page](https://www.docker.com/products/docker-desktop) and download docker.
![Docker Download Page](docker/images/Docker_Download_Page.png)
2. Once the file has finished downloading, run it and proceed through the installation. Make sure, "Install required Windows components for WSL 2" is checked.
![Docker Desktop Installer Configuration](docker/images/Docker_Desktop_Installer_Configuration.png)
3. If necessary, restart your computer.
4. After the restart, Docker Desktop will automatically open. If it does not, simply start it like any other program.
5. If a window "WSL 2 Installation is incomplete." pops up, follow the link and click "WSL2 Linux kernel update package for x64 machines". Run the downloaded file and once that finishes, click "Restart" in the Docker Desktop window.
![WSL 2 download](docker/images/WSL_2_download.png)
6. Wait until Docker Desktop has started. You may skip the tutorial.
7. You may want to disable "Open Docker Dashboard at startup" in _Settings_ -> _General_
![Disable Dashboard Autostart](docker/images/DD_General_Settings.png)
8. Install [Git for Windows](https://git-scm.com/download/win). During the installation, simply confirming the defaults is sufficient.
9. In the folder you wish to save the Server, right click and select "Git Bash Here".
10. Type `git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer`
11. Once the command has completed (you can see you path again and can enter commands), close the window.
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
14. Change the text after `CLIENT_PATH=` to the location of your client. The folder you are pointing to must contain a folder called `client` which should contain the client files.
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
16. After `ACCOUNT_MANAGER_SECRET=` paste a "SHA 256-bit Key" from https://keygen.io/
17. If you are not only hosting a local server, change the value after `EXTERNAL_IP=` to the external IP address of your computer.
18. Change the two values `SECRET_VALUE_CHANGE_ME` to passwords only you know. Save and close the file.
19. In the extracted folder hit Shift+Right Click and select "Open PowerShell window here".
![Open PowerShell](docker/images/Open_Powershell.png)
17. In the new window, paste (with right click) or type `docker compose up -d --build` and confirm with enter.
18. Once you see the blinking cursor and the path again, setup has finished and the server is already running.
![setup done](docker/images/setup_finished.png)
19. Create an admin account by pasting `docker compose exec darkflame /app/MasterServer -a` and following the prompts.
![admin account creation](docker/images/Account_Creation.png)
20. You can now login with these credentials at `http://your_ip:5000` (replace your_ip with your external IP). There you can create your account for playing as well as generate keys for other people to join; use these at `http://your_ip:5000/activate`
## Normal Use
1. In Docker Desktop you should now see an entry `darkflameserver-main` and when you click on it all containers but `DarkflameSetup` should eventually be green. That means the server is running.
![server running](docker/images/Docker_Compose_Finished.png)
2. For troubleshooting, you can check the logs of the various parts by clicking their entry.
3. You can start and stop the server with the corresponding buttons. Once all containers are grey, the server has shut down, and when all containers but `DarkflameSetup` are green, the server is running. Note that starting and stopping takes some time, please be patient.
![start stop buttons](docker/images/DD_Server_Startstop.png)

169
README.md
View File

@@ -27,25 +27,41 @@ Darkflame Universe is a server emulator and does not distribute any LEGO® Unive
Development of the latest iteration of Darkflame Universe has been done primarily in a Unix-like environment and is where it has been tested and designed for deployment. It is therefore highly recommended that Darkflame Universe be built and deployed using a Unix-like environment for the most streamlined experience.
### Prerequisites
**Clone the repository**
#### Clone the repository
```bash
git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer
```
**Python**
#### Python
Some tools utilized to streamline the setup process require Python 3, make sure you have it installed.
**Choosing the right version for your client**
### Choosing the right version for your client
DLU clients identify themselves using a higher version number than the regular live clients out there.
This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client.
If you're using a DLU client, then you don't need to change anything. But if you're using any other client, you'll have to go into the "CMakeVariables.txt" file and change it to match your client's version. (likely 171022)
If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number.
### Using Docker
Refer to [Docker.md](/Docker.md).
For Windows, refer to [Docker_Windows.md](/Docker_Windows.md).
### Linux builds
Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed.
Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`.
CMake must be version 3.14 or higher!
#### Build the repository
You can either run `build.sh` when in the root folder of the repository:
```bash
./build.sh
```
Or manually run the commands used in `build.sh`:
**Build the repository**
```bash
# Create the build directory, preserving it if it already exists
mkdir -p build
@@ -54,33 +70,30 @@ cd build
# Run CMake to generate make files
cmake ..
# Run make to build the project. To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `make -j8`
make
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
cmake --build . --config Release
```
### MacOS builds
Ensure `cmake`, `zlib` and `open ssl` are installed as well as a compiler (e.g `clang` or `gcc`).
**Download precompiled MySQL connector**
In the repository root folder run the following. Ensure -DOPENSSL_ROOT_DIR=/path/to/openssl points to your openssl install location
```bash
# Install required tools
brew install boost mysql-connector-c++
# Create the build directory, preserving it if it already exists
mkdir -p build
cd build
# Symlinks for finding the required modules
sudo ln -s /usr/local/mysql-connector-c++/lib64/libmysqlcppconn.dylib /usr/local/mysql-connector-c++/lib64/libmysql.dylib
sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /usr/local/mysql/lib/libcrypto.1.1.dylib
```
# Run CMake to generate build files
cmake .. -DOPENSSL_ROOT_DIR=/path/to/openssl
Then follow the Linux build steps (gcc is not required), but before running `make`, run the following to make sure all the libs are available in the build folder:
```bash
sudo ln -s /usr/local/mysql-connector-c++/lib64/libssl.1.1.dylib /path/to/build/folder/libssl.1.1.dylib
sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /path/to/build/folder/libcrypto.1.1.dylib
# Get cmake to build the project. If make files are being used then using make and appending `-j` and the amount of cores to utilize may be preferable, for example `make -j8`
cmake --build . --config Release
```
### Windows builds (native)
Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/).
Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/). Currently on native Windows the server will only work in Release mode.
**Build the repository**
#### Build the repository
```batch
:: Create the build directory
mkdir build
@@ -90,20 +103,31 @@ cd build
cmake ..
:: Run CMake with build flag to build
cmake --build .
cmake --build . --config Release
```
#### Windows for ARM has not been tested but should build by doing the following
```batch
:: Create the build directory
mkdir build
cd build
:: Run CMake to generate make files
cmake .. -DMARIADB_BUILD_SOURCE=ON
:: Run CMake with build flag to build
cmake --build . --config Release
```
### Windows builds (WSL)
This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11.
**Open the Command Prompt application with Administrator permissions and run the following:**
#### Open the Command Prompt application with Administrator permissions and run the following:
```bash
# Installing Windows Subsystem for Linux
wsl --install
```
**Open the Ubuntu application and run the following:**
#### Open the Ubuntu application and run the following:
```bash
# Make sure the install is up to date
apt update && apt upgrade
@@ -111,23 +135,31 @@ apt update && apt upgrade
# Make sure the gcc, cmake, and build-essentials are installed
sudo apt install gcc
sudo apt install cmake
sudo apt install build-essentials
sudo apt install build-essential
```
[**Follow the Linux instructions**](#linux-builds)
### ARM builds
AArch64 builds should work on linux and MacOS using their respective build steps. Windows ARM should build but it has not been tested
### Updating your build
To update your server to the latest version navigate to your cloned directory
```bash
cd /path/to/DarkflameServer
```
run the following commands to update to the latest changes
```bash
git pull
git submodule update --init --recursive
```
now follow the build section for your system
## Setting up the environment
### Database
Darkflame Universe utilizes a MySQL/MariaDB database for account and character information.
Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running.
* Create a database for Darkflame Universe to use
* Run each SQL file in the order at which they appear [here](migrations/dlu/) on the database
### Resources
**LEGO® Universe 1.10.64**
#### LEGO® Universe 1.10.64
This repository does not distribute any LEGO® Universe files. A full install of LEGO® Universe version 1.10.64 (latest) is required to finish setting up Darkflame Universe.
@@ -150,29 +182,39 @@ shasum -a 256 <file>
certutil -hashfile <file> SHA256
```
**Unpacking the client**
#### Unpacking the client
* Clone lcdr's utilities repository [here](https://github.com/lcdr/utils)
* Use `pkextractor.pyw` to unpack the client files if they are not already unpacked
**Setup resource directory**
#### Setup resource directory
* In the `build` directory create a `res` directory if it does not already exist.
* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, and `maps` in your client `res` directory to the server `build/res` directory
* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, `names`, and `maps` in your client `res` directory to the server `build/res` directory
* Unzip the navmeshes [here](./resources/navmeshes.zip) and place them in `build/res/maps/navmeshes`
**Setup locale**
#### Setup locale
* In the `build` directory create a `locale` directory if it does not already exist
* Copy over or create symlinks from `locale.xml` in your client `locale` directory to the `build/locale` directory
**Client database**
#### Client database
* Use `fdb_to_sqlite.py` in lcdr's utilities on `res/cdclient.fdb` in the unpacked client to convert the client database to `cdclient.sqlite`
* Move and rename `cdclient.sqlite` into `build/res/CDServer.sqlite`
* Run each SQL file in the order at which they appear [here](migrations/cdserver/) on the SQLite database
**Configuration**
### Database
Darkflame Universe utilizes a MySQL/MariaDB database for account and character information.
Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running.
* Create a database for Darkflame Universe to use
#### Configuration
After the server has been built there should be four `ini` files in the build director: `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. Go through them and fill in the database credentials and configure other settings if necessary.
**Verify**
#### Setup and Migrations
Use the command `./MasterServer -m` to setup the tables in the database. The first time this command is run on a database, the tables will be up to date with the most recent version. To update your database tables, run this command again. Multiple invocations will not affect any functionality.
#### Verify
Your build directory should now look like this:
* AuthServer
@@ -223,6 +265,7 @@ To connect to a server follow these steps:
* Open it in a text editor and locate where it says `AUTHSERVERIP=0:`
* Replace the contents after to `:` and the following `,` with what you configured as the server's public facing IP. For example `AUTHSERVERIP=0:localhost` for locally hosted servers
* Launch `legouniverse.exe`, through `wine` if on a Unix-like operating system
* Note that if you are on WSL2, you will need to configure the public IP in the server and client to be the IP of the WSL2 instance and not localhost, which can be found by running `ifconfig` in the terminal. Windows defaults to WSL1, so this will not apply to most users.
### Survival
@@ -232,6 +275,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.pk`.
### 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.
@@ -283,10 +328,10 @@ Here is a summary of the commands available in-game. All commands are prefixed b
</tr>
<tr>
<td>
instance-info
instanceinfo
</td>
<td>
/instance-info
/instanceinfo
</td>
<td>
Displays in the chat the current zone, clone, and instance id.
@@ -380,30 +425,38 @@ Here is a summary of the commands available in-game. All commands are prefixed b
</tbody>
</table>
## Credits
### Contributors to DLUv3
* DarwinAnim8or
* Wincent01
* Mick
* averysumner
* Jon002
* Jonny
* Xiphoseer
# Credits
## Active Contributors
* [EmosewaMC](https://github.com/EmosewaMC)
* [Jettford](https://github.com/Jettford)
* [Aaron K.](https://github.com/aronwk-aaron)
## DLU Team
* [DarwinAnim8or](https://github.com/DarwinAnim8or)
* [Wincent01](https://github.com/Wincent01)
* [Mick](https://github.com/MickVermeulen)
* [averysumner](https://github.com/codeshaunted)
* [Jon002](https://github.com/jaller200)
* [Jonny](https://github.com/cuzitsjonny)
### Research and tools
* lcdr
* [lcdr](https://github.com/lcdr)
* [Xiphoseer](https://github.com/Xiphoseer)
### Community management
* Neal
* [Neal](https://github.com/NealSpellman)
### Former contributors
* TheMachine
* Matthew
* Raine
* [Raine](https://github.com/Rainebannister)
* Bricknave
### Special thanks
### Logo
* Cole Peterson (BlasterBuilder)
## Special thanks
* humanoid24
* pwjones1969
* BlasterBuilder for the logo
* [Simon](https://github.com/SimonNitzsche)
* ALL OF THE NETDEVIL AND LEGO TEAMS!

51
SECURITY.md Normal file
View File

@@ -0,0 +1,51 @@
# Security Policy
## Supported Versions
At the moment, only the latest commit on the `main` branch will be supported for security vulnerabilities. Private server operators
should keep their instances up to date and forks should regularily rebase on `main`.
| Branch | Supported |
| ------- | ------------------ |
| `main` | :white_check_mark: |
## Reporting a Vulnerability
If you found a security vulnerability in DLU, please send a message to [darkflame-security@googlegroups.com][darkflame-security]. You should get a
reply within *72 hours* that we have received your report and a tentative [CVSS score](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator).
We will do a preliminary analysis to confirm that the vulnerability is a plausible claim and decline the report otherwise.
If possible, please include
1. reproducible steps on how to trigger the vulnerability
2. a description on why you are convinced that it exists.
3. any information you may have on active exploitation of the vulnerability (zero-day).
## Security Advisories
The project will release advisories on resolved vulnerabilities at <https://github.com/DarkflameUniverse/DarkflameServer/security/advisories>
## Receiving Security Updates
We set up [darkflame-security-announce@googlegroups.com][darkflame-security-announce] for private server operators to receive updates on vulnerabilities
such as the release of [Security Advisories](#security-advisories) or early workarounds and recommendations to mitigate ongoing
vulnerabilities.
Unfortunately, we cannot guarantee that announcements will be sent for every vulnerability.
## Embargo
We propose a 90 day (approx. 3 months) embargo on security vulnerabilities. That is, we ask everyone not to disclose the vulnerabilty
publicly until either:
1. 90 days have passed from the time the first related email is sent to `darkflame-security@`
2. a security advisory related to the vulnerability has been published by the project.
If you fail to comply with this embargo, you might be exluded from [receiving security updates](#receiving-security-updates).
## Bug Bounty
Unfortunately we cannot provide bug bounties at this time.
[darkflame-security]: mailto:darkflame-security@googlegroups.com
[darkflame-security-announce]: https://groups.google.com/g/darkflame-security-announce

7
build.sh Normal file → Executable file
View File

@@ -5,5 +5,8 @@ cd build
# Run cmake to generate make files
cmake ..
# Run make to build the project. To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `make -j8`
make
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
cmake --build . --config Release
# Run migrations
./MasterServer -m

View File

@@ -37,14 +37,15 @@ int main(int argc, char** argv) {
//Create all the objects we need to run our service:
Game::logger = SetupLogger();
if (!Game::logger) return 0;
Game::logger->Log("AuthServer", "Starting Auth server...\n");
Game::logger->Log("AuthServer", "Version: %i.%i\n", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
Game::logger->Log("AuthServer", "Compiled on: %s\n", __TIMESTAMP__);
Game::logger->Log("AuthServer", "Starting Auth server...");
Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__);
//Read our config:
dConfig config("authconfig.ini");
Game::config = &config;
Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console"))));
Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1");
//Connect to the MySQL Database
std::string mysql_host = config.GetValue("mysql_host");
@@ -52,15 +53,15 @@ int main(int argc, char** argv) {
std::string mysql_username = config.GetValue("mysql_username");
std::string mysql_password = config.GetValue("mysql_password");
try {
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
} catch (sql::SQLException& ex) {
Game::logger->Log("AuthServer", "Got an error while connecting to the database: %s\n", ex.what());
Database::Destroy();
try {
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
} catch (sql::SQLException& ex) {
Game::logger->Log("AuthServer", "Got an error while connecting to the database: %s", ex.what());
Database::Destroy("AuthServer");
delete Game::server;
delete Game::logger;
return 0;
}
}
//Find out the master's IP:
std::string masterIP;
@@ -77,10 +78,10 @@ int main(int argc, char** argv) {
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
int maxClients = 50;
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth);
//Run it until server gets a kill message from Master:
@@ -97,8 +98,7 @@ int main(int argc, char** argv) {
if (framesSinceMasterDisconnect >= 30)
break; //Exit our loop, shut down.
}
else framesSinceMasterDisconnect = 0;
} else framesSinceMasterDisconnect = 0;
//In world we'd update our other systems here.
@@ -133,8 +133,7 @@ int main(int argc, char** argv) {
delete stmt;
framesSinceLastSQLPing = 0;
}
else framesSinceLastSQLPing++;
} else framesSinceLastSQLPing++;
//Sleep our thread since auth can afford to.
t += std::chrono::milliseconds(mediumFramerate); //Auth can run at a lower "fps"
@@ -142,21 +141,24 @@ int main(int argc, char** argv) {
}
//Delete our objects here:
Database::Destroy();
Database::Destroy("AuthServer");
delete Game::server;
delete Game::logger;
return 0;
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
dLogger * SetupLogger() {
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) {

View File

@@ -0,0 +1,4 @@
set(DAUTHSERVER_SOURCES "AuthServer.cpp")
add_executable(AuthServer ${DAUTHSERVER_SOURCES})
target_link_libraries(AuthServer ${COMMON_LIBRARIES})

View File

@@ -0,0 +1,4 @@
set(DCHATFILTER_SOURCES "dChatFilter.cpp")
add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES})
target_link_libraries(dChatFilter dDatabase)

View File

@@ -8,8 +8,9 @@
#include <regex>
#include "dCommonVars.h"
#include "Database.h"
#include "dLogger.h"
#include "dConfig.h"
#include "Database.h"
#include "Game.h"
using namespace dChatFilterDCF;
@@ -18,11 +19,15 @@ dChatFilter::dChatFilter(const std::string& filepath, bool dontGenerateDCF) {
m_DontGenerateDCF = dontGenerateDCF;
if (!BinaryIO::DoesFileExist(filepath + ".dcf") || m_DontGenerateDCF) {
ReadWordlistPlaintext(filepath + ".txt");
if (!m_DontGenerateDCF) ExportWordlistToDCF(filepath + ".dcf");
ReadWordlistPlaintext(filepath + ".txt", true);
if (!m_DontGenerateDCF) ExportWordlistToDCF(filepath + ".dcf", true);
} else if (!ReadWordlistDCF(filepath + ".dcf", true)) {
ReadWordlistPlaintext(filepath + ".txt", true);
ExportWordlistToDCF(filepath + ".dcf", true);
}
else {
ReadWordlistDCF(filepath + ".dcf");
if (BinaryIO::DoesFileExist("blacklist.dcf")) {
ReadWordlistDCF("blacklist.dcf", false);
}
//Read player names that are ok as well:
@@ -31,65 +36,71 @@ dChatFilter::dChatFilter(const std::string& filepath, bool dontGenerateDCF) {
while (res->next()) {
std::string line = res->getString(1).c_str();
std::transform(line.begin(), line.end(), line.begin(), ::tolower); //Transform to lowercase
m_Words.push_back(CalculateHash(line));
m_ApprovedWords.push_back(CalculateHash(line));
}
delete res;
delete stmt;
}
dChatFilter::~dChatFilter() {
m_Words.clear();
m_ApprovedWords.clear();
m_DeniedWords.clear();
}
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath) {
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath, bool whiteList) {
std::ifstream file(filepath);
if (file) {
std::string line;
while (std::getline(file, line)) {
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
std::transform(line.begin(), line.end(), line.begin(), ::tolower); //Transform to lowercase
m_Words.push_back(CalculateHash(line));
if (whiteList) m_ApprovedWords.push_back(CalculateHash(line));
else m_DeniedWords.push_back(CalculateHash(line));
}
}
}
void dChatFilter::ReadWordlistDCF(const std::string& filepath) {
bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool whiteList) {
std::ifstream file(filepath, std::ios::binary);
if (file) {
fileHeader hdr;
BinaryIO::BinaryRead(file, hdr);
if (hdr.header != header) {
std::cout << "Wrong file header!" << std::endl;
file.close();
return;
return false;
}
if (hdr.formatVersion <= formatVersion) {
if (hdr.formatVersion == formatVersion) {
size_t wordsToRead = 0;
BinaryIO::BinaryRead(file, wordsToRead);
m_Words.reserve(wordsToRead);
if (whiteList) m_ApprovedWords.reserve(wordsToRead);
else m_DeniedWords.reserve(wordsToRead);
size_t word = 0;
for (size_t i = 0; i < wordsToRead; ++i) {
BinaryIO::BinaryRead(file, word);
m_Words.push_back(word);
if (whiteList) m_ApprovedWords.push_back(word);
else m_DeniedWords.push_back(word);
}
}
else {
std::cout << "Newer file or corrupt" << std::endl;
return true;
} else {
file.close();
return;
return false;
}
}
return false;
}
void dChatFilter::ExportWordlistToDCF(const std::string& filepath) {
std::ofstream file(filepath, std::ios::binary);
void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteList) {
std::ofstream file(filepath, std::ios::binary | std::ios_base::out);
if (file) {
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::header));
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::formatVersion));
BinaryIO::BinaryWrite(file, size_t(m_Words.size()));
BinaryIO::BinaryWrite(file, size_t(whiteList ? m_ApprovedWords.size() : m_DeniedWords.size()));
for (size_t word : m_Words) {
for (size_t word : whiteList ? m_ApprovedWords : m_DeniedWords) {
BinaryIO::BinaryWrite(file, word);
}
@@ -97,31 +108,45 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath) {
}
}
bool dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel) {
if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return true; //If anything but a forum mod, return true.
if (message.empty()) return true;
std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList) {
if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return { }; //If anything but a forum mod, return true.
if (message.empty()) return { };
if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } };
std::stringstream sMessage(message);
std::string segment;
std::regex reg("(!*|\\?*|\\;*|\\.*|\\,*)");
std::vector<std::pair<uint8_t, uint8_t>> listOfBadSegments = std::vector<std::pair<uint8_t, uint8_t>>();
uint32_t position = 0;
while (std::getline(sMessage, segment, ' ')) {
std::string originalSegment = segment;
std::transform(segment.begin(), segment.end(), segment.begin(), ::tolower); //Transform to lowercase
segment = std::regex_replace(segment, reg, "");
size_t hash = CalculateHash(segment);
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end()) {
return false;
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end() && whiteList) {
listOfBadSegments.emplace_back(position, originalSegment.length());
}
if (!IsInWordlist(hash)) {
if (std::find(m_ApprovedWords.begin(), m_ApprovedWords.end(), hash) == m_ApprovedWords.end() && whiteList) {
m_UserUnapprovedWordCache.push_back(hash);
return false;
listOfBadSegments.emplace_back(position, originalSegment.length());
}
if (std::find(m_DeniedWords.begin(), m_DeniedWords.end(), hash) != m_DeniedWords.end() && !whiteList) {
m_UserUnapprovedWordCache.push_back(hash);
listOfBadSegments.emplace_back(position, originalSegment.length());
}
position += segment.length() + 1;
}
return true;
return listOfBadSegments;
}
size_t dChatFilter::CalculateHash(const std::string& word) {
@@ -131,7 +156,3 @@ size_t dChatFilter::CalculateHash(const std::string& word) {
return value;
}
bool dChatFilter::IsInWordlist(size_t word) {
return std::find(m_Words.begin(), m_Words.end(), word) != m_Words.end();
}

View File

@@ -6,7 +6,7 @@
namespace dChatFilterDCF {
static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24));
static const uint32_t formatVersion = 1;
static const uint32_t formatVersion = 2;
struct fileHeader {
uint32_t header;
@@ -20,17 +20,17 @@ public:
dChatFilter(const std::string& filepath, bool dontGenerateDCF);
~dChatFilter();
void ReadWordlistPlaintext(const std::string & filepath);
void ReadWordlistDCF(const std::string & filepath);
void ExportWordlistToDCF(const std::string & filepath);
bool IsSentenceOkay(const std::string& message, int gmLevel);
void ReadWordlistPlaintext(const std::string& filepath, bool whiteList);
bool ReadWordlistDCF(const std::string& filepath, bool whiteList);
void ExportWordlistToDCF(const std::string& filepath, bool whiteList);
std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList = true);
private:
bool m_DontGenerateDCF;
std::vector<size_t> m_Words;
std::vector<size_t> m_DeniedWords;
std::vector<size_t> m_ApprovedWords;
std::vector<size_t> m_UserUnapprovedWordCache;
//Private functions:
size_t CalculateHash(const std::string& word);
bool IsInWordlist(size_t word);
};

View File

@@ -0,0 +1,6 @@
set(DCHATSERVER_SOURCES "ChatPacketHandler.cpp"
"ChatServer.cpp"
"PlayerContainer.cpp")
add_executable(ChatServer ${DCHATSERVER_SOURCES})
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter)

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
#include "BitStream.h"
struct PlayerData;
enum class AddFriendResponseType : uint8_t;
namespace ChatPacketHandler {
void HandleFriendlistRequest(Packet* packet);
@@ -31,10 +32,9 @@ namespace ChatPacketHandler {
void SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID);
//FriendData is the player we're SENDING this stuff to. Player is the friend that changed state.
void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType);
void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend);
void SendFriendRequest(PlayerData* receiver, PlayerData* sender, bool isBFFReq = false);
void SendFriendResponse(PlayerData* receiver, PlayerData* sender, uint8_t responseCode = 3);
void SendFriendRequest(PlayerData* receiver, PlayerData* sender);
void SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U);
void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful);
};

View File

@@ -40,14 +40,15 @@ int main(int argc, char** argv) {
//Create all the objects we need to run our service:
Game::logger = SetupLogger();
if (!Game::logger) return 0;
Game::logger->Log("ChatServer", "Starting Chat server...\n");
Game::logger->Log("ChatServer", "Version: %i.%i\n", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
Game::logger->Log("ChatServer", "Compiled on: %s\n", __TIMESTAMP__);
Game::logger->Log("ChatServer", "Starting Chat server...");
Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__);
//Read our config:
dConfig config("chatconfig.ini");
Game::config = &config;
Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console"))));
Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1");
//Connect to the MySQL Database
std::string mysql_host = config.GetValue("mysql_host");
@@ -57,10 +58,9 @@ int main(int argc, char** argv) {
try {
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
}
catch (sql::SQLException& ex) {
Game::logger->Log("ChatServer", "Got an error while connecting to the database: %s\n", ex.what());
Database::Destroy();
} catch (sql::SQLException& ex) {
Game::logger->Log("ChatServer", "Got an error while connecting to the database: %s", ex.what());
Database::Destroy("ChatServer");
delete Game::server;
delete Game::logger;
return 0;
@@ -103,8 +103,7 @@ int main(int argc, char** argv) {
if (framesSinceMasterDisconnect >= 30)
break; //Exit our loop, shut down.
}
else framesSinceMasterDisconnect = 0;
} else framesSinceMasterDisconnect = 0;
//In world we'd update our other systems here.
@@ -121,8 +120,7 @@ int main(int argc, char** argv) {
if (framesSinceLastFlush >= 900) {
Game::logger->Flush();
framesSinceLastFlush = 0;
}
else framesSinceLastFlush++;
} else framesSinceLastFlush++;
//Every 10 min we ping our sql server to keep it alive hopefully:
if (framesSinceLastSQLPing >= 40000) {
@@ -140,8 +138,7 @@ int main(int argc, char** argv) {
delete stmt;
framesSinceLastSQLPing = 0;
}
else framesSinceLastSQLPing++;
} else framesSinceLastSQLPing++;
//Sleep our thread since auth can afford to.
t += std::chrono::milliseconds(mediumFramerate); //Chat can run at a lower "fps"
@@ -149,30 +146,33 @@ int main(int argc, char** argv) {
}
//Delete our objects here:
Database::Destroy();
Database::Destroy("ChatServer");
delete Game::server;
delete Game::logger;
return 0;
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
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) {
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
Game::logger->Log("ChatServer", "A server has disconnected, erasing their connected players from the list.\n");
Game::logger->Log("ChatServer", "A server has disconnected, erasing their connected players from the list.");
}
if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) {
Game::logger->Log("ChatServer", "A server is connecting, awaiting user list.\n");
Game::logger->Log("ChatServer", "A server is connecting, awaiting user list.");
}
if (packet->data[1] == CHAT_INTERNAL) {
@@ -201,7 +201,7 @@ void HandlePacket(Packet* packet) {
}
default:
Game::logger->Log("ChatServer", "Unknown CHAT_INTERNAL id: %i\n", int(packet->data[3]));
Game::logger->Log("ChatServer", "Unknown CHAT_INTERNAL id: %i", int(packet->data[3]));
}
}
@@ -212,7 +212,7 @@ void HandlePacket(Packet* packet) {
break;
case MSG_CHAT_GET_IGNORE_LIST:
Game::logger->Log("ChatServer", "Asked for ignore list, but is unimplemented right now.\n");
Game::logger->Log("ChatServer", "Asked for ignore list, but is unimplemented right now.");
break;
case MSG_CHAT_TEAM_GET_STATUS:
@@ -268,21 +268,21 @@ void HandlePacket(Packet* packet) {
case MSG_CHAT_TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet);
break;
default:
Game::logger->Log("ChatServer", "Unknown CHAT id: %i\n", int(packet->data[3]));
Game::logger->Log("ChatServer", "Unknown CHAT id: %i", int(packet->data[3]));
}
}
if (packet->data[1] == WORLD) {
switch (packet->data[3]) {
case MSG_WORLD_CLIENT_ROUTE_PACKET: {
printf("routing packet from world\n");
Game::logger->Log("ChatServer", "Routing packet from world");
break;
}
default:
Game::logger->Log("ChatServer", "Unknown World id: %i\n", int(packet->data[3]));
Game::logger->Log("ChatServer", "Unknown World id: %i", int(packet->data[3]));
}
}
}

View File

@@ -20,17 +20,25 @@ PlayerContainer::~PlayerContainer() {
void PlayerContainer::InsertPlayer(Packet* packet) {
CINSTREAM;
PlayerData* data = new PlayerData();
inStream.SetReadOffset(inStream.GetReadOffset() + 64);
inStream.Read(data->playerID);
inStream.Read(data->playerID);
inStream.Read(data->playerName);
uint32_t len;
inStream.Read<uint32_t>(len);
for (int i = 0; i < len; i++) {
char character; inStream.Read<char>(character);
data->playerName += character;
}
inStream.Read(data->zoneID);
inStream.Read(data->muteExpire);
data->sysAddr = packet->systemAddress;
mNames[data->playerID] = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.C_String()));
mNames[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
mPlayers.insert(std::make_pair(data->playerID, data));
Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i\n", data->playerName.C_String(), data->playerID, data->zoneID.GetMapID());
Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID());
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@@ -49,39 +57,32 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
inStream.Read(playerID);
//Before they get kicked, we need to also send a message to their friends saying that they disconnected.
auto player = this->GetPlayerData(playerID);
std::unique_ptr<PlayerData> player(this->GetPlayerData(playerID));
if (player == nullptr) {
return;
}
for (auto& fr : player->friends) {
//if (!fr.isOnline) continue;
auto fd = this->GetPlayerData(fr.friendID);
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0);
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player.get(), 0, fr.isBestFriend);
}
auto* team = GetTeam(playerID);
if (team != nullptr)
{
//TeamStatusUpdate(team);
if (team != nullptr) {
const auto memberName = GeneralUtils::UTF8ToUTF16(std::string(player->playerName.c_str()));
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(player->playerName.C_String()));
for (const auto memberId : team->memberIDs)
{
for (const auto memberId : team->memberIDs) {
auto* otherMember = GetPlayerData(memberId);
if (otherMember == nullptr) continue;
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, {0, 0, 0});
//ChatPacketHandler::SendTeamRemovePlayer(otherMember, false, false, true, false, team->leaderID, player->playerID, memberName);
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 });
}
}
Game::logger->Log("PlayerContainer", "Removed user: %llu\n", playerID);
Game::logger->Log("PlayerContainer", "Removed user: %llu", playerID);
mPlayers.erase(playerID);
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@@ -94,8 +95,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
insertLog->executeUpdate();
}
void PlayerContainer::MuteUpdate(Packet* packet)
{
void PlayerContainer::MuteUpdate(Packet* packet) {
CINSTREAM;
LWOOBJID playerID;
inStream.Read(playerID); //skip header
@@ -105,9 +105,8 @@ void PlayerContainer::MuteUpdate(Packet* packet)
auto* player = this->GetPlayerData(playerID);
if (player == nullptr)
{
Game::logger->Log("PlayerContainer", "Failed to find user: %llu\n", playerID);
if (player == nullptr) {
Game::logger->Log("PlayerContainer", "Failed to find user: %llu", playerID);
return;
}
@@ -117,8 +116,7 @@ void PlayerContainer::MuteUpdate(Packet* packet)
BroadcastMuteUpdate(playerID, expire);
}
void PlayerContainer::CreateTeamServer(Packet* packet)
{
void PlayerContainer::CreateTeamServer(Packet* packet) {
CINSTREAM;
LWOOBJID playerID;
inStream.Read(playerID); //skip header
@@ -130,8 +128,7 @@ void PlayerContainer::CreateTeamServer(Packet* packet)
members.reserve(membersSize);
for (size_t i = 0; i < membersSize; i++)
{
for (size_t i = 0; i < membersSize; i++) {
LWOOBJID member;
inStream.Read(member);
members.push_back(member);
@@ -140,19 +137,17 @@ void PlayerContainer::CreateTeamServer(Packet* packet)
LWOZONEID zoneId;
inStream.Read(zoneId);
auto* team = CreateLocalTeam(members);
if (team != nullptr)
{
if (team != nullptr) {
team->zoneId = zoneId;
}
UpdateTeamsOnWorld(team, false);
}
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time)
{
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_MUTE_UPDATE);
@@ -162,30 +157,23 @@ void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time)
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
}
TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members)
{
if (members.empty())
{
TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members) {
if (members.empty()) {
return nullptr;
}
TeamData* newTeam = nullptr;
for (const auto member : members)
{
for (const auto member : members) {
auto* team = GetTeam(member);
if (team != nullptr)
{
if (team != nullptr) {
RemoveMember(team, member, false, false, true);
}
if (newTeam == nullptr)
{
if (newTeam == nullptr) {
newTeam = CreateTeam(member, true);
}
else
{
} else {
AddMember(newTeam, member);
}
}
@@ -197,14 +185,13 @@ TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members)
return newTeam;
}
TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local)
{
TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local) {
auto* team = new TeamData();
team->teamID = ++mTeamIDCounter;
team->leaderID = leader;
team->local = local;
mTeams.push_back(team);
AddMember(team, leader);
@@ -212,20 +199,17 @@ TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local)
return team;
}
TeamData* PlayerContainer::GetTeam(LWOOBJID playerID)
{
for (auto* team : mTeams)
{
TeamData* PlayerContainer::GetTeam(LWOOBJID playerID) {
for (auto* team : mTeams) {
if (std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID) == team->memberIDs.end()) continue;
return team;
}
return nullptr;
}
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID)
{
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID);
if (index != team->memberIDs.end()) return;
@@ -237,64 +221,49 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID)
if (leader == nullptr || member == nullptr) return;
const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String()));
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(member->playerName.C_String()));
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
const auto memberName = GeneralUtils::UTF8ToUTF16(member->playerName);
ChatPacketHandler::SendTeamInviteConfirm(member, false, leader->playerID, leader->zoneID, team->lootFlag, 0, 0, leaderName);
/*
ChatPacketHandler::SendTeamAddPlayer(member, false, false, false, leader->playerID, leaderName, leader->zoneID);
Game::logger->Log("PlayerContainer", "Team invite successfully accepted, leader: %s, member: %s\n", leader->playerName.C_String(), member->playerName.C_String());
*/
if (!team->local)
{
if (!team->local) {
ChatPacketHandler::SendTeamSetLeader(member, leader->playerID);
}
else
{
} else {
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
}
UpdateTeamsOnWorld(team, false);
for (const auto memberId : team->memberIDs)
{
for (const auto memberId : team->memberIDs) {
auto* otherMember = GetPlayerData(memberId);
if (otherMember == member) continue;
const auto otherMemberName = GetName(memberId);
ChatPacketHandler::SendTeamAddPlayer(member, false, team->local, false, memberId, otherMemberName, otherMember != nullptr ? otherMember->zoneID : LWOZONEID(0, 0, 0));
if (otherMember != nullptr)
{
if (otherMember != nullptr) {
ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member->playerID, memberName, member->zoneID);
}
}
}
void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disband, bool kicked, bool leaving, bool silent)
{
void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disband, bool kicked, bool leaving, bool silent) {
const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID);
if (index == team->memberIDs.end()) return;
auto* member = GetPlayerData(playerID);
if (member != nullptr && !silent)
{
if (member != nullptr && !silent) {
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
}
const auto memberName = GetName(playerID);
for (const auto memberId : team->memberIDs)
{
if (silent && memberId == playerID)
{
for (const auto memberId : team->memberIDs) {
if (silent && memberId == playerID) {
continue;
}
@@ -309,25 +278,19 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
UpdateTeamsOnWorld(team, false);
if (team->memberIDs.size() <= 1)
{
if (team->memberIDs.size() <= 1) {
DisbandTeam(team);
}
else
{
if (playerID == team->leaderID)
{
} else {
if (playerID == team->leaderID) {
PromoteMember(team, team->memberIDs[0]);
}
}
}
void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader)
{
void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader) {
team->leaderID = newLeader;
for (const auto memberId : team->memberIDs)
{
for (const auto memberId : team->memberIDs) {
auto* otherMember = GetPlayerData(memberId);
if (otherMember == nullptr) continue;
@@ -336,24 +299,22 @@ void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader)
}
}
void PlayerContainer::DisbandTeam(TeamData* team)
{
void PlayerContainer::DisbandTeam(TeamData* team) {
const auto index = std::find(mTeams.begin(), mTeams.end(), team);
if (index == mTeams.end()) return;
for (const auto memberId : team->memberIDs)
{
for (const auto memberId : team->memberIDs) {
auto* otherMember = GetPlayerData(memberId);
if (otherMember == nullptr) continue;
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(otherMember->playerName.C_String()));
const auto memberName = GeneralUtils::UTF8ToUTF16(otherMember->playerName);
ChatPacketHandler::SendTeamSetLeader(otherMember, LWOOBJID_EMPTY);
ChatPacketHandler::SendTeamRemovePlayer(otherMember, true, false, false, team->local, team->leaderID, otherMember->playerID, memberName);
}
UpdateTeamsOnWorld(team, true);
mTeams.erase(index);
@@ -361,8 +322,7 @@ void PlayerContainer::DisbandTeam(TeamData* team)
delete team;
}
void PlayerContainer::TeamStatusUpdate(TeamData* team)
{
void PlayerContainer::TeamStatusUpdate(TeamData* team) {
const auto index = std::find(mTeams.begin(), mTeams.end(), team);
if (index == mTeams.end()) return;
@@ -371,41 +331,32 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team)
if (leader == nullptr) return;
const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String()));
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
for (const auto memberId : team->memberIDs)
{
for (const auto memberId : team->memberIDs) {
auto* otherMember = GetPlayerData(memberId);
if (otherMember == nullptr) continue;
if (!team->local)
{
if (!team->local) {
ChatPacketHandler::SendTeamStatus(otherMember, team->leaderID, leader->zoneID, team->lootFlag, 0, leaderName);
}
else
{
//ChatPacketHandler::SendTeamStatus(otherMember, LWOOBJID_EMPTY, LWOZONEID(0, 0, 0), 1, 0, u"");
}
}
UpdateTeamsOnWorld(team, false);
}
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam)
{
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_TEAM_UPDATE);
bitStream.Write(team->teamID);
bitStream.Write(deleteTeam);
if (!deleteTeam)
{
if (!deleteTeam) {
bitStream.Write(team->lootFlag);
bitStream.Write(static_cast<char>(team->memberIDs.size()));
for (const auto memberID : team->memberIDs)
{
for (const auto memberID : team->memberIDs) {
bitStream.Write(memberID);
}
}
@@ -413,8 +364,7 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam)
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
}
std::u16string PlayerContainer::GetName(LWOOBJID playerID)
{
std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
const auto& pair = mNames.find(playerID);
if (pair == mNames.end()) return u"";
@@ -422,20 +372,16 @@ std::u16string PlayerContainer::GetName(LWOOBJID playerID)
return pair->second;
}
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName)
{
for (const auto& pair : mNames)
{
if (pair.second == playerName)
{
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
for (const auto& pair : mNames) {
if (pair.second == playerName) {
return pair.first;
}
}
return LWOOBJID_EMPTY;
}
bool PlayerContainer::GetIsMuted(PlayerData* data)
{
bool PlayerContainer::GetIsMuted(PlayerData* data) {
return data->muteExpire == 1 || data->muteExpire > time(NULL);
}

View File

@@ -9,17 +9,18 @@
struct PlayerData {
LWOOBJID playerID;
RakNet::RakString playerName;
std::string playerName;
SystemAddress sysAddr;
LWOZONEID zoneID;
std::vector<FriendData> friends;
time_t muteExpire;
uint8_t countOfBestFriends = 0;
};
struct TeamData {
LWOOBJID teamID = LWOOBJID_EMPTY; // Internal use
LWOOBJID leaderID = LWOOBJID_EMPTY;
std::vector<LWOOBJID> memberIDs {};
std::vector<LWOOBJID> memberIDs{};
uint8_t lootFlag = 0;
bool local = false;
LWOZONEID zoneId = {};
@@ -45,7 +46,7 @@ public:
PlayerData* GetPlayerData(const std::string& playerName) {
for (auto player : mPlayers) {
if (player.second) {
std::string pn = player.second->playerName.C_String();
std::string pn = player.second->playerName.c_str();
if (pn == playerName) return player.second;
}
}

160
dCommon/AMFDeserialize.cpp Normal file
View File

@@ -0,0 +1,160 @@
#include "AMFDeserialize.h"
#include "AMFFormat.h"
/**
* AMF3 Reference document https://rtmp.veriskope.com/pdf/amf3-file-format-spec.pdf
* AMF3 Deserializer written by EmosewaMC
*/
AMFValue* AMFDeserialize::Read(RakNet::BitStream* inStream) {
if (!inStream) return nullptr;
AMFValue* returnValue = nullptr;
// Read in the value type from the bitStream
int8_t marker;
inStream->Read(marker);
// Based on the typing, create the value associated with that and return the base value class
switch (marker) {
case AMFValueType::AMFUndefined: {
returnValue = new AMFUndefinedValue();
break;
}
case AMFValueType::AMFNull: {
returnValue = new AMFNullValue();
break;
}
case AMFValueType::AMFFalse: {
returnValue = new AMFFalseValue();
break;
}
case AMFValueType::AMFTrue: {
returnValue = new AMFTrueValue();
break;
}
case AMFValueType::AMFInteger: {
returnValue = ReadAmfInteger(inStream);
break;
}
case AMFValueType::AMFDouble: {
returnValue = ReadAmfDouble(inStream);
break;
}
case AMFValueType::AMFString: {
returnValue = ReadAmfString(inStream);
break;
}
case AMFValueType::AMFArray: {
returnValue = ReadAmfArray(inStream);
break;
}
// TODO We do not need these values, but if someone wants to implement them
// then please do so and add the corresponding unit tests.
case AMFValueType::AMFXMLDoc:
case AMFValueType::AMFDate:
case AMFValueType::AMFObject:
case AMFValueType::AMFXML:
case AMFValueType::AMFByteArray:
case AMFValueType::AMFVectorInt:
case AMFValueType::AMFVectorUInt:
case AMFValueType::AMFVectorDouble:
case AMFValueType::AMFVectorObject:
case AMFValueType::AMFDictionary: {
throw static_cast<AMFValueType>(marker);
break;
}
default:
throw static_cast<AMFValueType>(marker);
break;
}
return returnValue;
}
uint32_t AMFDeserialize::ReadU29(RakNet::BitStream* inStream) {
bool byteFlag = true;
uint32_t actualNumber{};
uint8_t numberOfBytesRead{};
while (byteFlag && numberOfBytesRead < 4) {
uint8_t byte{};
inStream->Read(byte);
// Parse the byte
if (numberOfBytesRead < 3) {
byteFlag = byte & static_cast<uint8_t>(1 << 7);
byte = byte << 1UL;
}
// Combine the read byte with our current read in number
actualNumber <<= 8UL;
actualNumber |= static_cast<uint32_t>(byte);
// If we are not done reading in bytes, shift right 1 bit
if (numberOfBytesRead < 3) actualNumber = actualNumber >> 1UL;
numberOfBytesRead++;
}
return actualNumber;
}
std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) {
auto length = ReadU29(inStream);
// Check if this is a reference
bool isReference = length % 2 == 1;
// Right shift by 1 bit to get index if reference or size of next string if value
length = length >> 1;
if (isReference) {
std::string value(length, 0);
inStream->Read(&value[0], length);
// Empty strings are never sent by reference
if (!value.empty()) accessedElements.push_back(value);
return value;
} else {
// Length is a reference to a previous index - use that as the read in value
return accessedElements[length];
}
}
AMFValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) {
auto doubleValue = new AMFDoubleValue();
double value;
inStream->Read<double>(value);
doubleValue->SetDoubleValue(value);
return doubleValue;
}
AMFValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) {
auto arrayValue = new AMFArrayValue();
// Read size of dense array
auto sizeOfDenseArray = (ReadU29(inStream) >> 1);
// Then read Key'd portion
while (true) {
auto key = ReadString(inStream);
// No more values when we encounter an empty string
if (key.size() == 0) break;
arrayValue->InsertValue(key, Read(inStream));
}
// Finally read dense portion
for (uint32_t i = 0; i < sizeOfDenseArray; i++) {
arrayValue->PushBackValue(Read(inStream));
}
return arrayValue;
}
AMFValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) {
auto stringValue = new AMFStringValue();
stringValue->SetStringValue(ReadString(inStream));
return stringValue;
}
AMFValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) {
auto integerValue = new AMFIntegerValue();
integerValue->SetIntegerValue(ReadU29(inStream));
return integerValue;
}

71
dCommon/AMFDeserialize.h Normal file
View File

@@ -0,0 +1,71 @@
#pragma once
#include "BitStream.h"
#include <vector>
#include <string>
class AMFValue;
class AMFDeserialize {
public:
/**
* Read an AMF3 value from a bitstream.
*
* @param inStream inStream to read value from.
* @return Returns an AMFValue with all the information from the bitStream in it.
*/
AMFValue* Read(RakNet::BitStream* inStream);
private:
/**
* @brief Private method to read a U29 integer from a bitstream
*
* @param inStream bitstream to read data from
* @return The number as an unsigned 29 bit integer
*/
uint32_t ReadU29(RakNet::BitStream* inStream);
/**
* @brief Reads a string from a bitstream
*
* @param inStream bitStream to read data from
* @return The read string
*/
std::string ReadString(RakNet::BitStream* inStream);
/**
* @brief Read an AMFDouble value from a bitStream
*
* @param inStream bitStream to read data from
* @return Double value represented as an AMFValue
*/
AMFValue* ReadAmfDouble(RakNet::BitStream* inStream);
/**
* @brief Read an AMFArray from a bitStream
*
* @param inStream bitStream to read data from
* @return Array value represented as an AMFValue
*/
AMFValue* ReadAmfArray(RakNet::BitStream* inStream);
/**
* @brief Read an AMFString from a bitStream
*
* @param inStream bitStream to read data from
* @return String value represented as an AMFValue
*/
AMFValue* ReadAmfString(RakNet::BitStream* inStream);
/**
* @brief Read an AMFInteger from a bitStream
*
* @param inStream bitStream to read data from
* @return Integer value represented as an AMFValue
*/
AMFValue* ReadAmfInteger(RakNet::BitStream* inStream);
/**
* List of strings read so far saved to be read by reference.
*/
std::vector<std::string> accessedElements;
};

View File

@@ -2,156 +2,170 @@
// AMFInteger
void AMFIntegerValue::SetIntegerValue(uint32_t value) {
this->value = value;
this->value = value;
}
uint32_t AMFIntegerValue::GetIntegerValue() {
return this->value;
return this->value;
}
// AMFDouble
void AMFDoubleValue::SetDoubleValue(double value) {
this->value = value;
this->value = value;
}
double AMFDoubleValue::GetDoubleValue() {
return this->value;
return this->value;
}
// AMFString
void AMFStringValue::SetStringValue(const std::string& value) {
this->value = value;
this->value = value;
}
std::string AMFStringValue::GetStringValue() {
return this->value;
return this->value;
}
// AMFXMLDoc
void AMFXMLDocValue::SetXMLDocValue(const std::string& value) {
this->xmlData = value;
this->xmlData = value;
}
std::string AMFXMLDocValue::GetXMLDocValue() {
return this->xmlData;
return this->xmlData;
}
// AMFDate
void AMFDateValue::SetDateValue(uint64_t value) {
this->millisecondTimestamp = value;
this->millisecondTimestamp = value;
}
uint64_t AMFDateValue::GetDateValue() {
return this->millisecondTimestamp;
return this->millisecondTimestamp;
}
// AMFArray Insert Value
void AMFArrayValue::InsertValue(const std::string& key, AMFValue* value) {
this->associative.insert(std::make_pair(key, value));
this->associative.insert(std::make_pair(key, value));
}
// AMFArray Remove Value
void AMFArrayValue::RemoveValue(const std::string& key) {
_AMFArrayMap_::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
this->associative.erase(it);
}
_AMFArrayMap_::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
this->associative.erase(it);
}
}
// AMFArray Find Value
AMFValue* AMFArrayValue::FindValue(const std::string& key) {
_AMFArrayMap_::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
return it->second;
}
return nullptr;
_AMFArrayMap_::iterator it = this->associative.find(key);
if (it != this->associative.end()) {
return it->second;
}
return nullptr;
}
// AMFArray Get Associative Iterator Begin
_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueBegin() {
return this->associative.begin();
return this->associative.begin();
}
// AMFArray Get Associative Iterator End
_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueEnd() {
return this->associative.end();
return this->associative.end();
}
// AMFArray Push Back Value
void AMFArrayValue::PushBackValue(AMFValue* value) {
this->dense.push_back(value);
this->dense.push_back(value);
}
// AMFArray Pop Back Value
void AMFArrayValue::PopBackValue() {
this->dense.pop_back();
this->dense.pop_back();
}
// AMFArray Get Dense List Size
uint32_t AMFArrayValue::GetDenseValueSize() {
return (uint32_t)this->dense.size();
return (uint32_t)this->dense.size();
}
// AMFArray Get value at index in Dense List
AMFValue* AMFArrayValue::GetValueAt(uint32_t index) {
return this->dense.at(index);
return this->dense.at(index);
}
// AMFArray Get Dense Iterator Begin
_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorBegin() {
return this->dense.begin();
return this->dense.begin();
}
// AMFArray Get Dense Iterator End
_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorEnd() {
return this->dense.end();
return this->dense.end();
}
AMFArrayValue::~AMFArrayValue() {
for (auto valueToDelete : GetDenseArray()) {
if (valueToDelete) delete valueToDelete;
}
for (auto valueToDelete : GetAssociativeMap()) {
if (valueToDelete.second) delete valueToDelete.second;
}
}
// AMFObject Constructor
AMFObjectValue::AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits) {
this->traits.reserve(traits.size());
std::vector<std::pair<std::string, AMFValueType>>::iterator it = traits.begin();
while (it != traits.end()) {
this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue())));
it++;
}
this->traits.reserve(traits.size());
std::vector<std::pair<std::string, AMFValueType>>::iterator it = traits.begin();
while (it != traits.end()) {
this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue())));
it++;
}
}
// AMFObject Set Value
void AMFObjectValue::SetTraitValue(const std::string& trait, AMFValue* value) {
if (value) {
_AMFObjectTraits_::iterator it = this->traits.find(trait);
if (it != this->traits.end()) {
if (it->second.first == value->GetValueType()) {
it->second.second = value;
}
}
}
if (value) {
_AMFObjectTraits_::iterator it = this->traits.find(trait);
if (it != this->traits.end()) {
if (it->second.first == value->GetValueType()) {
it->second.second = value;
}
}
}
}
// AMFObject Get Value
AMFValue* AMFObjectValue::GetTraitValue(const std::string& trait) {
_AMFObjectTraits_::iterator it = this->traits.find(trait);
if (it != this->traits.end()) {
return it->second.second;
}
return nullptr;
_AMFObjectTraits_::iterator it = this->traits.find(trait);
if (it != this->traits.end()) {
return it->second.second;
}
return nullptr;
}
// AMFObject Get Trait Iterator Begin
_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorBegin() {
return this->traits.begin();
return this->traits.begin();
}
// AMFObject Get Trait Iterator End
_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorEnd() {
return this->traits.end();
return this->traits.end();
}
// AMFObject Get Trait Size
uint32_t AMFObjectValue::GetTraitArrayCount() {
return (uint32_t)this->traits.size();
return (uint32_t)this->traits.size();
}
AMFObjectValue::~AMFObjectValue() {
for (auto valueToDelete = GetTraitsIteratorBegin(); valueToDelete != GetTraitsIteratorEnd(); valueToDelete++) {
if (valueToDelete->second.second) delete valueToDelete->second.second;
}
}

View File

@@ -23,42 +23,43 @@ class AMFValue; // Forward declaration
//! An enum for each AMF value type
enum AMFValueType : unsigned char {
AMFUndefined = 0x00, //!< An undefined AMF Value
AMFNull = 0x01, //!< A null AMF value
AMFFalse = 0x02, //!< A false AMF value
AMFTrue = 0x03, //!< A true AMF value
AMFInteger = 0x04, //!< An integer AMF value
AMFDouble = 0x05, //!< A double AMF value
AMFString = 0x06, //!< A string AMF value
AMFXMLDoc = 0x07, //!< An XML Doc AMF value
AMFDate = 0x08, //!< A date AMF value
AMFArray = 0x09, //!< An array AMF value
AMFObject = 0x0A, //!< An object AMF value
AMFXML = 0x0B, //!< An XML AMF value
AMFByteArray = 0x0C, //!< A byte array AMF value
AMFVectorInt = 0x0D, //!< An integer vector AMF value
AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value
AMFVectorDouble = 0x0F, //!< A double vector AMF value
AMFVectorObject = 0x10, //!< An object vector AMF value
AMFDictionary = 0x11 //!< A dictionary AMF value
AMFUndefined = 0x00, //!< An undefined AMF Value
AMFNull = 0x01, //!< A null AMF value
AMFFalse = 0x02, //!< A false AMF value
AMFTrue = 0x03, //!< A true AMF value
AMFInteger = 0x04, //!< An integer AMF value
AMFDouble = 0x05, //!< A double AMF value
AMFString = 0x06, //!< A string AMF value
AMFXMLDoc = 0x07, //!< An XML Doc AMF value
AMFDate = 0x08, //!< A date AMF value
AMFArray = 0x09, //!< An array AMF value
AMFObject = 0x0A, //!< An object AMF value
AMFXML = 0x0B, //!< An XML AMF value
AMFByteArray = 0x0C, //!< A byte array AMF value
AMFVectorInt = 0x0D, //!< An integer vector AMF value
AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value
AMFVectorDouble = 0x0F, //!< A double vector AMF value
AMFVectorObject = 0x10, //!< An object vector AMF value
AMFDictionary = 0x11 //!< A dictionary AMF value
};
//! An enum for the object value types
enum AMFObjectValueType : unsigned char {
AMFObjectAnonymous = 0x01,
AMFObjectTyped = 0x02,
AMFObjectDynamic = 0x03,
AMFObjectExternalizable = 0x04
AMFObjectAnonymous = 0x01,
AMFObjectTyped = 0x02,
AMFObjectDynamic = 0x03,
AMFObjectExternalizable = 0x04
};
//! The base AMF value class
class AMFValue {
public:
//! Returns the AMF value type
/*!
\return The AMF value type
*/
virtual AMFValueType GetValueType() = 0;
//! Returns the AMF value type
/*!
\return The AMF value type
*/
virtual AMFValueType GetValueType() = 0;
virtual ~AMFValue() {};
};
//! A typedef for a pointer to an AMF value
@@ -70,299 +71,314 @@ typedef AMFValue* NDGFxValue;
//! The undefined value AMF type
class AMFUndefinedValue : public AMFValue {
private:
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFUndefined; }
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFUndefined; }
};
//! The null value AMF type
class AMFNullValue : public AMFValue {
private:
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFNull; }
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFNull; }
};
//! The false value AMF type
class AMFFalseValue : public AMFValue {
private:
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFFalse; }
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFFalse; }
};
//! The true value AMF type
class AMFTrueValue : public AMFValue {
private:
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFTrue; }
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFTrue; }
};
//! The integer value AMF type
class AMFIntegerValue : public AMFValue {
private:
uint32_t value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFInteger; }
uint32_t value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFInteger; }
public:
//! Sets the integer value
/*!
\param value The value to set
*/
void SetIntegerValue(uint32_t value);
//! Gets the integer value
/*!
\return The integer value
*/
uint32_t GetIntegerValue();
//! Sets the integer value
/*!
\param value The value to set
*/
void SetIntegerValue(uint32_t value);
//! Gets the integer value
/*!
\return The integer value
*/
uint32_t GetIntegerValue();
};
//! The double value AMF type
class AMFDoubleValue : public AMFValue {
private:
double value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFDouble; }
double value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFDouble; }
public:
//! Sets the double value
/*!
\param value The value to set to
*/
void SetDoubleValue(double value);
//! Gets the double value
/*!
\return The double value
*/
double GetDoubleValue();
//! Sets the double value
/*!
\param value The value to set to
*/
void SetDoubleValue(double value);
//! Gets the double value
/*!
\return The double value
*/
double GetDoubleValue();
};
//! The string value AMF type
class AMFStringValue : public AMFValue {
private:
std::string value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFString; }
std::string value; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFString; }
public:
//! Sets the string value
/*!
\param value The string value to set to
*/
void SetStringValue(const std::string& value);
//! Gets the string value
/*!
\return The string value
*/
std::string GetStringValue();
//! Sets the string value
/*!
\param value The string value to set to
*/
void SetStringValue(const std::string& value);
//! Gets the string value
/*!
\return The string value
*/
std::string GetStringValue();
};
//! The XML doc value AMF type
class AMFXMLDocValue : public AMFValue {
private:
std::string xmlData; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFXMLDoc; }
std::string xmlData; //!< The value of the AMF type
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFXMLDoc; }
public:
//! Sets the XML Doc value
/*!
\param value The value to set to
*/
void SetXMLDocValue(const std::string& value);
//! Gets the XML Doc value
/*!
\return The XML Doc value
*/
std::string GetXMLDocValue();
//! Sets the XML Doc value
/*!
\param value The value to set to
*/
void SetXMLDocValue(const std::string& value);
//! Gets the XML Doc value
/*!
\return The XML Doc value
*/
std::string GetXMLDocValue();
};
//! The date value AMF type
class AMFDateValue : public AMFValue {
private:
uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFDate; }
uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFDate; }
public:
//! Sets the date time
/*!
\param value The value to set to
*/
void SetDateValue(uint64_t value);
//! Gets the date value
/*!
\return The date value in milliseconds since the epoch
*/
uint64_t GetDateValue();
//! Sets the date time
/*!
\param value The value to set to
*/
void SetDateValue(uint64_t value);
//! Gets the date value
/*!
\return The date value in milliseconds since the epoch
*/
uint64_t GetDateValue();
};
//! The array value AMF type
// This object will manage it's own memory map and list. Do not delete its values.
class AMFArrayValue : public AMFValue {
private:
_AMFArrayMap_ associative; //!< The array map (associative part)
_AMFArrayList_ dense; //!< The array list (dense part)
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFArray; }
_AMFArrayMap_ associative; //!< The array map (associative part)
_AMFArrayList_ dense; //!< The array list (dense part)
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFArray; }
public:
//! Inserts an item into the array map for a specific key
/*!
\param key The key to set
\param value The value to add
*/
void InsertValue(const std::string& key, AMFValue* value);
//! Removes an item for a specific key
/*!
\param key The key to remove
*/
void RemoveValue(const std::string& key);
//! Finds an AMF value
/*!
\return The AMF value if found, nullptr otherwise
*/
AMFValue* FindValue(const std::string& key);
//! Returns where the associative iterator begins
/*!
\return Where the array map iterator begins
*/
_AMFArrayMap_::iterator GetAssociativeIteratorValueBegin();
//! Returns where the associative iterator ends
/*!
\return Where the array map iterator ends
*/
_AMFArrayMap_::iterator GetAssociativeIteratorValueEnd();
//! Pushes back a value into the array list
/*!
\param value The value to push back
*/
void PushBackValue(AMFValue* value);
//! Pops back the last value in the array list
void PopBackValue();
//! Gets the count of the dense list
/*!
\return The dense list size
*/
uint32_t GetDenseValueSize();
//! Gets a specific value from the list for the specified index
/*!
\param index The index to get
*/
AMFValue* GetValueAt(uint32_t index);
//! Returns where the dense iterator begins
/*!
\return Where the iterator begins
*/
_AMFArrayList_::iterator GetDenseIteratorBegin();
//! Returns where the dense iterator ends
/*!
\return Where the iterator ends
*/
_AMFArrayList_::iterator GetDenseIteratorEnd();
~AMFArrayValue() override;
//! Inserts an item into the array map for a specific key
/*!
\param key The key to set
\param value The value to add
*/
void InsertValue(const std::string& key, AMFValue* value);
//! Removes an item for a specific key
/*!
\param key The key to remove
*/
void RemoveValue(const std::string& key);
//! Finds an AMF value
/*!
\return The AMF value if found, nullptr otherwise
*/
AMFValue* FindValue(const std::string& key);
//! Returns where the associative iterator begins
/*!
\return Where the array map iterator begins
*/
_AMFArrayMap_::iterator GetAssociativeIteratorValueBegin();
//! Returns where the associative iterator ends
/*!
\return Where the array map iterator ends
*/
_AMFArrayMap_::iterator GetAssociativeIteratorValueEnd();
//! Pushes back a value into the array list
/*!
\param value The value to push back
*/
void PushBackValue(AMFValue* value);
//! Pops back the last value in the array list
void PopBackValue();
//! Gets the count of the dense list
/*!
\return The dense list size
*/
uint32_t GetDenseValueSize();
//! Gets a specific value from the list for the specified index
/*!
\param index The index to get
*/
AMFValue* GetValueAt(uint32_t index);
//! Returns where the dense iterator begins
/*!
\return Where the iterator begins
*/
_AMFArrayList_::iterator GetDenseIteratorBegin();
//! Returns where the dense iterator ends
/*!
\return Where the iterator ends
*/
_AMFArrayList_::iterator GetDenseIteratorEnd();
//! Returns the associative map
/*!
\return The associative map
*/
_AMFArrayMap_ GetAssociativeMap() { return this->associative; };
//! Returns the dense array
/*!
\return The dense array
*/
_AMFArrayList_ GetDenseArray() { return this->dense; };
};
//! The anonymous object value AMF type
class AMFObjectValue : public AMFValue {
private:
_AMFObjectTraits_ traits; //!< The object traits
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFObject; }
_AMFObjectTraits_ traits; //!< The object traits
//! Returns the AMF value type
/*!
\return The AMF value type
*/
AMFValueType GetValueType() { return AMFObject; }
~AMFObjectValue() override;
public:
//! Constructor
/*!
\param traits The traits to set
*/
AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits);
//! Gets the object value type
/*!
\return The object value type
*/
virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; }
//! Sets the value of a trait
/*!
\param trait The trait to set the value for
\param value The AMF value to set
*/
void SetTraitValue(const std::string& trait, AMFValue* value);
//! Gets a trait value
/*!
\param trait The trait to get the value for
\return The trait value
*/
AMFValue* GetTraitValue(const std::string& trait);
//! Gets the beginning of the object traits iterator
/*!
\return The AMF trait array iterator begin
*/
_AMFObjectTraits_::iterator GetTraitsIteratorBegin();
//! Gets the end of the object traits iterator
/*!
\return The AMF trait array iterator begin
*/
_AMFObjectTraits_::iterator GetTraitsIteratorEnd();
//! Gets the amount of traits
/*!
\return The amount of traits
*/
uint32_t GetTraitArrayCount();
//! Constructor
/*!
\param traits The traits to set
*/
AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits);
//! Gets the object value type
/*!
\return The object value type
*/
virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; }
//! Sets the value of a trait
/*!
\param trait The trait to set the value for
\param value The AMF value to set
*/
void SetTraitValue(const std::string& trait, AMFValue* value);
//! Gets a trait value
/*!
\param trait The trait to get the value for
\return The trait value
*/
AMFValue* GetTraitValue(const std::string& trait);
//! Gets the beginning of the object traits iterator
/*!
\return The AMF trait array iterator begin
*/
_AMFObjectTraits_::iterator GetTraitsIteratorBegin();
//! Gets the end of the object traits iterator
/*!
\return The AMF trait array iterator begin
*/
_AMFObjectTraits_::iterator GetTraitsIteratorEnd();
//! Gets the amount of traits
/*!
\return The amount of traits
*/
uint32_t GetTraitArrayCount();
};

View File

@@ -3,269 +3,248 @@
// Writes an AMFValue pointer to a RakNet::BitStream
template<>
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value) {
if (value != nullptr) {
AMFValueType type = value->GetValueType();
switch (type) {
case AMFUndefined: {
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
this->Write(*v);
break;
}
case AMFNull: {
AMFNullValue* v = (AMFNullValue*)value;
this->Write(*v);
break;
}
case AMFFalse: {
AMFFalseValue* v = (AMFFalseValue*)value;
this->Write(*v);
break;
}
case AMFTrue: {
AMFTrueValue* v = (AMFTrueValue*)value;
this->Write(*v);
break;
}
case AMFInteger: {
AMFIntegerValue* v = (AMFIntegerValue*)value;
this->Write(*v);
break;
}
case AMFString: {
AMFStringValue* v = (AMFStringValue*)value;
this->Write(*v);
break;
}
case AMFXMLDoc: {
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
this->Write(*v);
break;
}
case AMFDate: {
AMFDateValue* v = (AMFDateValue*)value;
this->Write(*v);
break;
}
case AMFArray: {
AMFArrayValue* v = (AMFArrayValue*)value;
this->Write(*v);
break;
}
}
}
if (value != nullptr) {
AMFValueType type = value->GetValueType();
switch (type) {
case AMFUndefined: {
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
this->Write(*v);
break;
}
case AMFNull: {
AMFNullValue* v = (AMFNullValue*)value;
this->Write(*v);
break;
}
case AMFFalse: {
AMFFalseValue* v = (AMFFalseValue*)value;
this->Write(*v);
break;
}
case AMFTrue: {
AMFTrueValue* v = (AMFTrueValue*)value;
this->Write(*v);
break;
}
case AMFInteger: {
AMFIntegerValue* v = (AMFIntegerValue*)value;
this->Write(*v);
break;
}
case AMFDouble: {
AMFDoubleValue* v = (AMFDoubleValue*)value;
this->Write(*v);
break;
}
case AMFString: {
AMFStringValue* v = (AMFStringValue*)value;
this->Write(*v);
break;
}
case AMFXMLDoc: {
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
this->Write(*v);
break;
}
case AMFDate: {
AMFDateValue* v = (AMFDateValue*)value;
this->Write(*v);
break;
}
case AMFArray: {
this->Write((AMFArrayValue*)value);
break;
}
}
}
}
// A private function to write an value to a RakNet::BitStream
/**
* A private function to write an value to a RakNet::BitStream
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteUInt29(RakNet::BitStream* bs, uint32_t v) {
unsigned char b4 = (unsigned char)v;
if (v < 0x00200000) {
b4 = b4 & 0x7F;
if (v > 0x7F) {
unsigned char b3;
v = v >> 7;
b3 = ((unsigned char)(v)) | 0x80;
if (v > 0x7F) {
unsigned char b2;
v = v >> 7;
b2 = ((unsigned char)(v)) | 0x80;
bs->Write(b2);
}
bs->Write(b3);
}
} else {
unsigned char b1;
unsigned char b2;
unsigned char b3;
v = v >> 8;
b3 = ((unsigned char)(v)) | 0x80;
v = v >> 7;
b2 = ((unsigned char)(v)) | 0x80;
v = v >> 7;
b1 = ((unsigned char)(v)) | 0x80;
bs->Write(b1);
bs->Write(b2);
bs->Write(b3);
}
bs->Write(b4);
unsigned char b4 = (unsigned char)v;
if (v < 0x00200000) {
b4 = b4 & 0x7F;
if (v > 0x7F) {
unsigned char b3;
v = v >> 7;
b3 = ((unsigned char)(v)) | 0x80;
if (v > 0x7F) {
unsigned char b2;
v = v >> 7;
b2 = ((unsigned char)(v)) | 0x80;
bs->Write(b2);
}
bs->Write(b3);
}
} else {
unsigned char b1;
unsigned char b2;
unsigned char b3;
v = v >> 8;
b3 = ((unsigned char)(v)) | 0x80;
v = v >> 7;
b2 = ((unsigned char)(v)) | 0x80;
v = v >> 7;
b1 = ((unsigned char)(v)) | 0x80;
bs->Write(b1);
bs->Write(b2);
bs->Write(b3);
}
bs->Write(b4);
}
// Writes a flag number to a RakNet::BitStream
/**
* Writes a flag number to a RakNet::BitStream
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) {
v = (v << 1) | 0x01;
WriteUInt29(bs, v);
v = (v << 1) | 0x01;
WriteUInt29(bs, v);
}
// Writes an AMFString to a RakNet::BitStream
/**
* Writes an AMFString to a RakNet::BitStream
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFString(RakNet::BitStream* bs, const std::string& str) {
WriteFlagNumber(bs, (uint32_t)str.size());
bs->Write(str.c_str(), (uint32_t)str.size());
WriteFlagNumber(bs, (uint32_t)str.size());
bs->Write(str.c_str(), (uint32_t)str.size());
}
// Writes an AMF U16 to a RakNet::BitStream
/**
* Writes an U16 to a bitstream
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) {
unsigned char b2;
b2 = (unsigned char)value;
value = value >> 8;
bs->Write((unsigned char)value);
bs->Write(b2);
bs->Write(value);
}
// Writes an AMF U32 to RakNet::BitStream
/**
* Writes an U32 to a bitstream
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) {
unsigned char b2;
unsigned char b3;
unsigned char b4;
b4 = (unsigned char)value;
value = value >> 8;
b3 = (unsigned char)value;
value = value >> 8;
b2 = (unsigned char)value;
value = value >> 8;
bs->Write((unsigned char)value);
bs->Write(b2);
bs->Write(b3);
bs->Write(b4);
bs->Write(value);
}
// Writes an AMF U64 to RakNet::BitStream
/**
* Writes an U64 to a bitstream
*
* RakNet writes in the correct byte order - do not reverse this.
*/
void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) {
unsigned char b2;
unsigned char b3;
unsigned char b4;
unsigned char b5;
unsigned char b6;
unsigned char b7;
unsigned char b8;
b8 = (unsigned char)value;
value = value >> 8;
b7 = (unsigned char)value;
value = value >> 8;
b6 = (unsigned char)value;
value = value >> 8;
b5 = (unsigned char)value;
value = value >> 8;
b4 = (unsigned char)value;
value = value >> 8;
b3 = (unsigned char)value;
value = value >> 8;
b2 = (unsigned char)value;
value = value >> 8;
bs->Write((unsigned char)value);
bs->Write(b2);
bs->Write(b3);
bs->Write(b4);
bs->Write(b5);
bs->Write(b6);
bs->Write(b7);
bs->Write(b8);
bs->Write(value);
}
// Writes an AMFUndefinedValue to BitStream
template<>
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value) {
this->Write(AMFUndefined);
this->Write(AMFUndefined);
}
// Writes an AMFNullValue to BitStream
template<>
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value) {
this->Write(AMFNull);
this->Write(AMFNull);
}
// Writes an AMFFalseValue to BitStream
template<>
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value) {
this->Write(AMFFalse);
this->Write(AMFFalse);
}
// Writes an AMFTrueValue to BitStream
template<>
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value) {
this->Write(AMFTrue);
this->Write(AMFTrue);
}
// Writes an AMFIntegerValue to BitStream
template<>
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value) {
this->Write(AMFInteger);
WriteUInt29(this, value.GetIntegerValue());
this->Write(AMFInteger);
WriteUInt29(this, value.GetIntegerValue());
}
// Writes an AMFDoubleValue to BitStream
template<>
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value) {
this->Write(AMFDouble);
double d = value.GetDoubleValue();
WriteAMFU64(this, *((unsigned long long*)&d));
this->Write(AMFDouble);
double d = value.GetDoubleValue();
WriteAMFU64(this, *((unsigned long long*) & d));
}
// Writes an AMFStringValue to BitStream
template<>
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value) {
this->Write(AMFString);
std::string v = value.GetStringValue();
WriteAMFString(this, v);
this->Write(AMFString);
std::string v = value.GetStringValue();
WriteAMFString(this, v);
}
// Writes an AMFXMLDocValue to BitStream
template<>
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value) {
this->Write(AMFXMLDoc);
std::string v = value.GetXMLDocValue();
WriteAMFString(this, v);
this->Write(AMFXMLDoc);
std::string v = value.GetXMLDocValue();
WriteAMFString(this, v);
}
// Writes an AMFDateValue to BitStream
template<>
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value) {
this->Write(AMFDate);
uint64_t date = value.GetDateValue();
WriteAMFU64(this, date);
this->Write(AMFDate);
uint64_t date = value.GetDateValue();
WriteAMFU64(this, date);
}
// Writes an AMFArrayValue to BitStream
template<>
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value) {
this->Write(AMFArray);
uint32_t denseSize = value.GetDenseValueSize();
WriteFlagNumber(this, denseSize);
_AMFArrayMap_::iterator it = value.GetAssociativeIteratorValueBegin();
_AMFArrayMap_::iterator end = value.GetAssociativeIteratorValueEnd();
while (it != end) {
WriteAMFString(this, it->first);
this->Write(it->second);
it++;
}
this->Write(AMFNull);
if (denseSize > 0) {
_AMFArrayList_::iterator it2 = value.GetDenseIteratorBegin();
_AMFArrayList_::iterator end2 = value.GetDenseIteratorEnd();
while (it2 != end2) {
this->Write(*it2);
it2++;
}
}
void RakNet::BitStream::Write<AMFArrayValue*>(AMFArrayValue* value) {
this->Write(AMFArray);
uint32_t denseSize = value->GetDenseValueSize();
WriteFlagNumber(this, denseSize);
_AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin();
_AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd();
while (it != end) {
WriteAMFString(this, it->first);
this->Write(it->second);
it++;
}
this->Write(AMFNull);
if (denseSize > 0) {
_AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin();
_AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd();
while (it2 != end2) {
this->Write(*it2);
it2++;
}
}
}

View File

@@ -7,86 +7,86 @@
#include <BitStream.h>
/*!
\file AMFBitStream.hpp
\brief A class that implements native writing of AMF values to RakNet::BitStream
\file AMFFormat_BitStream.h
\brief A class that implements native writing of AMF values to RakNet::BitStream
*/
// We are using the RakNet namespace
// We are using the RakNet namespace
namespace RakNet {
//! Writes an AMFValue pointer to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value);
//! Writes an AMFUndefinedValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value);
//! Writes an AMFNullValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value);
//! Writes an AMFFalseValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value);
//! Writes an AMFTrueValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value);
//! Writes an AMFIntegerValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value);
//! Writes an AMFDoubleValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value);
//! Writes an AMFStringValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value);
//! Writes an AMFXMLDocValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value);
//! Writes an AMFDateValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value);
//! Writes an AMFArrayValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template<>
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value);
}
//! Writes an AMFValue pointer to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value);
//! Writes an AMFUndefinedValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value);
//! Writes an AMFNullValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value);
//! Writes an AMFFalseValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value);
//! Writes an AMFTrueValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value);
//! Writes an AMFIntegerValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value);
//! Writes an AMFDoubleValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value);
//! Writes an AMFStringValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value);
//! Writes an AMFXMLDocValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value);
//! Writes an AMFDateValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value);
//! Writes an AMFArrayValue to a RakNet::BitStream
/*!
\param value The value to write
*/
template <>
void RakNet::BitStream::Write<AMFArrayValue*>(AMFArrayValue* value);
} // namespace RakNet

View File

@@ -0,0 +1,15 @@
#pragma once
#ifndef __ADDFRIENDRESPONSECODE__H__
#define __ADDFRIENDRESPONSECODE__H__
#include <cstdint>
enum class AddFriendResponseCode : uint8_t {
ACCEPTED = 0,
REJECTED,
BUSY,
CANCELLED
};
#endif //!__ADDFRIENDRESPONSECODE__H__

View File

@@ -0,0 +1,24 @@
#pragma once
#ifndef __ADDFRIENDRESPONSETYPE__H__
#define __ADDFRIENDRESPONSETYPE__H__
#include <cstdint>
enum class AddFriendResponseType : uint8_t {
ACCEPTED = 0,
ALREADYFRIEND,
INVALIDCHARACTER,
GENERALERROR,
YOURFRIENDSLISTFULL,
THEIRFRIENDLISTFULL,
DECLINED,
BUSY,
NOTONLINE,
WAITINGAPPROVAL,
MYTHRAN,
CANCELLED,
FRIENDISFREETRIAL
};
#endif //!__ADDFRIENDRESPONSETYPE__H__

View File

@@ -10,7 +10,7 @@ void BinaryIO::WriteString(const std::string& stringToWrite, std::ofstream& outs
}
//For reading null-terminated strings
std::string BinaryIO::ReadString(std::ifstream & instream) {
std::string BinaryIO::ReadString(std::ifstream& instream) {
std::string toReturn;
char buffer;
@@ -37,7 +37,7 @@ std::string BinaryIO::ReadString(std::ifstream& instream, size_t size) {
return toReturn;
}
std::string BinaryIO::ReadWString(std::ifstream & instream) {
std::string BinaryIO::ReadWString(std::ifstream& instream) {
size_t size;
BinaryRead(instream, size);
//toReturn.resize(size);

View File

@@ -9,15 +9,15 @@ namespace BinaryIO {
}
template<typename T>
std::istream & BinaryRead(std::istream& stream, T& value) {
if (!stream.good())
std::istream& BinaryRead(std::istream& stream, T& value) {
if (!stream.good())
printf("bla");
return stream.read(reinterpret_cast<char*>(&value), sizeof(T));
}
void WriteString(const std::string& stringToWrite, std::ofstream& outstream);
std::string ReadString(std::ifstream & instream);
std::string ReadString(std::ifstream& instream);
std::string ReadString(std::ifstream& instream, size_t size);
std::string ReadWString(std::ifstream& instream);

27
dCommon/CMakeLists.txt Normal file
View File

@@ -0,0 +1,27 @@
set(DCOMMON_SOURCES "AMFFormat.cpp"
"AMFDeserialize.cpp"
"AMFFormat_BitStream.cpp"
"BinaryIO.cpp"
"dConfig.cpp"
"Diagnostics.cpp"
"dLogger.cpp"
"GeneralUtils.cpp"
"LDFFormat.cpp"
"MD5.cpp"
"Metrics.cpp"
"NiPoint3.cpp"
"NiQuaternion.cpp"
"SHA512.cpp"
"Type.cpp"
"ZCompression.cpp")
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
add_library(dCommon STATIC ${DCOMMON_SOURCES})
target_link_libraries(dCommon bcrypt)
if (UNIX)
find_package(ZLIB REQUIRED)
target_link_libraries(dCommon ZLIB::ZLIB)
endif()

View File

@@ -2,58 +2,59 @@
// If we're on Win32, we'll include our minidump writer
#ifdef _WIN32
#include <Dbghelp.h>
#include <Windows.h>
#include <Dbghelp.h>
#include "Game.h"
#include "dLogger.h"
void make_minidump(EXCEPTION_POINTERS* e) {
auto hDbgHelp = LoadLibraryA("dbghelp");
if (hDbgHelp == nullptr)
return;
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (pMiniDumpWriteDump == nullptr)
return;
auto hDbgHelp = LoadLibraryA("dbghelp");
if (hDbgHelp == nullptr)
return;
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (pMiniDumpWriteDump == nullptr)
return;
char name[MAX_PATH];
{
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
SYSTEMTIME t;
GetSystemTime(&t);
wsprintfA(nameEnd - strlen(".exe"),
"_%4d%02d%02d_%02d%02d%02d.dmp",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
}
char name[MAX_PATH];
{
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
SYSTEMTIME t;
GetSystemTime(&t);
wsprintfA(nameEnd - strlen(".exe"),
"_%4d%02d%02d_%02d%02d%02d.dmp",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
}
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
return;
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
return;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = e;
exceptionInfo.ClientPointers = FALSE;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = e;
exceptionInfo.ClientPointers = FALSE;
auto dumped = pMiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
e ? &exceptionInfo : nullptr,
nullptr,
nullptr);
auto dumped = pMiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
e ? &exceptionInfo : nullptr,
nullptr,
nullptr);
CloseHandle(hFile);
CloseHandle(hFile);
return;
return;
}
LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) {
make_minidump(e);
if (Game::logger)
Game::logger->Flush(); // Flush our log if we have one, before exiting.
return EXCEPTION_CONTINUE_SEARCH;
make_minidump(e);
if (Game::logger)
Game::logger->Flush(); // Flush our log if we have one, before exiting.
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
@@ -74,146 +75,146 @@ LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) {
#include <backtrace-supported.h>
struct bt_ctx {
struct backtrace_state* state;
int error;
struct backtrace_state* state;
int error;
};
static inline void Bt(struct backtrace_state* state) {
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != nullptr) {
backtrace_print(state, 2, file);
fclose(file);
}
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != nullptr) {
backtrace_print(state, 2, file);
fclose(file);
}
backtrace_print(state, 2, stdout);
backtrace_print(state, 2, stdout);
}
static void ErrorCallback(void* data, const char* msg, int errnum) {
auto* ctx = (struct bt_ctx*)data;
fprintf(stderr, "ERROR: %s (%d)", msg, errnum);
ctx->error = 1;
auto* ctx = (struct bt_ctx*)data;
fprintf(stderr, "ERROR: %s (%d)", msg, errnum);
ctx->error = 1;
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != nullptr) {
fprintf(file, "ERROR: %s (%d)", msg, errnum);
fclose(file);
}
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != nullptr) {
fprintf(file, "ERROR: %s (%d)", msg, errnum);
fclose(file);
}
}
#endif
#include "Type.h"
void GenerateDump() {
std::string cmd = "sudo gcore " + std::to_string(getpid());
system(cmd.c_str());
std::string cmd = "sudo gcore " + std::to_string(getpid());
system(cmd.c_str());
}
void CatchUnhandled(int sig) {
#ifndef __include_backtrace__
if (Diagnostics::GetProduceMemoryDump()) {
GenerateDump();
}
if (Diagnostics::GetProduceMemoryDump()) {
GenerateDump();
}
void* array[10];
size_t size;
void* array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// get void*'s for all entries on the stack
size = backtrace(array, 10);
printf("Fatal error %i\nStacktrace:\n", sig);
printf("Fatal error %i\nStacktrace:\n", sig);
#if defined(__GNUG__) and defined(__dynamic)
// Loop through the returned addresses, and get the symbols to be demangled
char** strings = backtrace_symbols(array, size);
// Loop through the returned addresses, and get the symbols to be demangled
char** strings = backtrace_symbols(array, size);
// Print the stack trace
for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
std::string functionName = strings[i];
std::string::size_type start = functionName.find('(');
std::string::size_type end = functionName.find('+');
if (start != std::string::npos && end != std::string::npos) {
std::string demangled = functionName.substr(start + 1, end - start - 1);
// Print the stack trace
for (size_t i = 0; i < size; i++) {
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
std::string functionName = strings[i];
std::string::size_type start = functionName.find('(');
std::string::size_type end = functionName.find('+');
if (start != std::string::npos && end != std::string::npos) {
std::string demangled = functionName.substr(start + 1, end - start - 1);
demangled = demangle(functionName.c_str());
demangled = demangle(functionName.c_str());
if (demangled.empty()) {
printf("[%02d] %s\n", i, demangled.c_str());
} else {
printf("[%02d] %s\n", i, functionName.c_str());
}
} else {
printf("[%02d] %s\n", i, functionName.c_str());
}
}
if (demangled.empty()) {
printf("[%02zu] %s\n", i, demangled.c_str());
} else {
printf("[%02zu] %s\n", i, functionName.c_str());
}
} else {
printf("[%02zu] %s\n", i, functionName.c_str());
}
}
#else
backtrace_symbols_fd(array, size, STDOUT_FILENO);
backtrace_symbols_fd(array, size, STDOUT_FILENO);
#endif
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
// print out all the frames to stderr
fprintf(file, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, fileno(file));
fclose(file);
}
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
FILE* file = fopen(fileName.c_str(), "w+");
if (file != NULL) {
// print out all the frames to stderr
fprintf(file, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, fileno(file));
fclose(file);
}
#else
struct backtrace_state* state = backtrace_create_state(
Diagnostics::GetProcessFileName().c_str(),
BACKTRACE_SUPPORTS_THREADS,
ErrorCallback,
nullptr);
struct backtrace_state* state = backtrace_create_state(
Diagnostics::GetProcessFileName().c_str(),
BACKTRACE_SUPPORTS_THREADS,
ErrorCallback,
nullptr);
struct bt_ctx ctx = {state, 0};
Bt(state);
struct bt_ctx ctx = { state, 0 };
Bt(state);
#endif
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
void CritErrHdlr(int sig_num, siginfo_t* info, void* ucontext) {
CatchUnhandled(sig_num);
CatchUnhandled(sig_num);
}
void OnTerminate() {
CatchUnhandled(-1);
CatchUnhandled(-1);
}
void MakeBacktrace() {
struct sigaction sigact;
struct sigaction sigact;
sigact.sa_sigaction = CritErrHdlr;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
sigact.sa_sigaction = CritErrHdlr;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
if (sigaction(SIGSEGV, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGFPE, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGABRT, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGILL, &sigact, (struct sigaction*)nullptr) != 0) {
fprintf(stderr, "error setting signal handler for %d (%s)\n",
SIGSEGV,
strsignal(SIGSEGV));
if (sigaction(SIGSEGV, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGFPE, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGABRT, &sigact, (struct sigaction*)nullptr) != 0 ||
sigaction(SIGILL, &sigact, (struct sigaction*)nullptr) != 0) {
fprintf(stderr, "error setting signal handler for %d (%s)\n",
SIGSEGV,
strsignal(SIGSEGV));
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
std::set_terminate(OnTerminate);
std::set_terminate(OnTerminate);
}
#endif
void Diagnostics::Initialize() {
#ifdef _WIN32
SetUnhandledExceptionFilter(unhandled_handler);
SetUnhandledExceptionFilter(unhandled_handler);
#elif defined(__linux__) //&& !defined(__clang__)
MakeBacktrace();
MakeBacktrace();
#else
fprintf(stderr, "Diagnostics not supported on this platform.\n");
fprintf(stderr, "Diagnostics not supported on this platform.\n");
#endif
}
@@ -223,33 +224,33 @@ std::string Diagnostics::m_OutDirectory{};
bool Diagnostics::m_ProduceMemoryDump{};
void Diagnostics::SetProcessName(const std::string& name) {
m_ProcessName = name;
m_ProcessName = name;
}
void Diagnostics::SetProcessFileName(const std::string& name) {
m_ProcessFileName = name;
m_ProcessFileName = name;
}
void Diagnostics::SetOutDirectory(const std::string& path) {
m_OutDirectory = path;
m_OutDirectory = path;
}
void Diagnostics::SetProduceMemoryDump(bool value) {
m_ProduceMemoryDump = value;
m_ProduceMemoryDump = value;
}
const std::string& Diagnostics::GetProcessName() {
return m_ProcessName;
return m_ProcessName;
}
const std::string& Diagnostics::GetProcessFileName() {
return m_ProcessFileName;
return m_ProcessFileName;
}
const std::string& Diagnostics::GetOutDirectory() {
return m_OutDirectory;
return m_OutDirectory;
}
bool Diagnostics::GetProduceMemoryDump() {
return m_ProduceMemoryDump;
return m_ProduceMemoryDump;
}

View File

@@ -5,27 +5,27 @@
class Diagnostics
{
public:
static void Initialize();
static void Initialize();
static void SetProcessName(const std::string& name);
static void SetProcessName(const std::string& name);
static void SetProcessFileName(const std::string& name);
static void SetProcessFileName(const std::string& name);
static void SetOutDirectory(const std::string& path);
static void SetOutDirectory(const std::string& path);
static void SetProduceMemoryDump(bool value);
static void SetProduceMemoryDump(bool value);
static const std::string& GetProcessName();
static const std::string& GetProcessName();
static const std::string& GetProcessFileName();
static const std::string& GetProcessFileName();
static const std::string& GetOutDirectory();
static const std::string& GetOutDirectory();
static bool GetProduceMemoryDump();
static bool GetProduceMemoryDump();
private:
static std::string m_ProcessName;
static std::string m_ProcessFileName;
static std::string m_OutDirectory;
static bool m_ProduceMemoryDump;
static std::string m_ProcessName;
static std::string m_ProcessFileName;
static std::string m_OutDirectory;
static bool m_ProduceMemoryDump;
};

View File

@@ -23,4 +23,4 @@ namespace Game {
extern std::mt19937 randomEngine;
extern RakPeerInterface* chatServer;
extern SystemAddress chatSysAddr;
}
}

View File

@@ -6,166 +6,266 @@
#include <algorithm>
template <typename T>
inline size_t MinSize(size_t size, const std::basic_string<T>& string) {
if (size == size_t(-1) || size > string.size()) {
return string.size();
} else {
return size;
}
inline size_t MinSize(size_t size, const std::basic_string_view<T>& string) {
if (size == size_t(-1) || size > string.size()) {
return string.size();
} else {
return size;
}
}
inline bool IsLeadSurrogate(char16_t c) {
return (0xD800 <= c) && (c <= 0xDBFF);
return (0xD800 <= c) && (c <= 0xDBFF);
}
inline bool IsTrailSurrogate(char16_t c) {
return (0xDC00 <= c) && (c <= 0xDFFF);
return (0xDC00 <= c) && (c <= 0xDFFF);
}
inline void PushUTF8CodePoint(std::string& ret, char32_t cp) {
if (cp <= 0x007F) {
ret.push_back(cp);
} else if (cp <= 0x07FF) {
ret.push_back(0xC0 | (cp >> 6));
ret.push_back(0x80 | (cp & 0x3F));
} else if (cp <= 0xFFFF) {
ret.push_back(0xE0 | (cp >> 12));
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
ret.push_back(0x80 | (cp & 0x3F));
} else if (cp <= 0x10FFFF) {
ret.push_back(0xF0 | (cp >> 18));
ret.push_back(0x80 | ((cp >> 12) & 0x3F));
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
ret.push_back(0x80 | (cp & 0x3F));
} else {
assert(false);
}
if (cp <= 0x007F) {
ret.push_back(static_cast<uint8_t>(cp));
} else if (cp <= 0x07FF) {
ret.push_back(0xC0 | (cp >> 6));
ret.push_back(0x80 | (cp & 0x3F));
} else if (cp <= 0xFFFF) {
ret.push_back(0xE0 | (cp >> 12));
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
ret.push_back(0x80 | (cp & 0x3F));
} else if (cp <= 0x10FFFF) {
ret.push_back(0xF0 | (cp >> 18));
ret.push_back(0x80 | ((cp >> 12) & 0x3F));
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
ret.push_back(0x80 | (cp & 0x3F));
} else {
assert(false);
}
}
constexpr const char16_t REPLACEMENT_CHARACTER = 0xFFFD;
bool _IsSuffixChar(uint8_t c) {
return (c & 0xC0) == 0x80;
}
bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
size_t rem = slice.length();
const uint8_t* bytes = (const uint8_t*)&slice.front();
if (rem > 0) {
uint8_t first = bytes[0];
if (first < 0x80) { // 1 byte character
out = static_cast<uint32_t>(first & 0x7F);
slice.remove_prefix(1);
return true;
} else if (first < 0xC0) {
// middle byte, not valid at start, fall through
} else if (first < 0xE0) { // two byte character
if (rem > 1) {
uint8_t second = bytes[1];
if (_IsSuffixChar(second)) {
out = (static_cast<uint32_t>(first & 0x1F) << 6)
+ static_cast<uint32_t>(second & 0x3F);
slice.remove_prefix(2);
return true;
}
}
} else if (first < 0xF0) { // three byte character
if (rem > 2) {
uint8_t second = bytes[1];
uint8_t third = bytes[2];
if (_IsSuffixChar(second) && _IsSuffixChar(third)) {
out = (static_cast<uint32_t>(first & 0x0F) << 12)
+ (static_cast<uint32_t>(second & 0x3F) << 6)
+ static_cast<uint32_t>(third & 0x3F);
slice.remove_prefix(3);
return true;
}
}
} else if (first < 0xF8) { // four byte character
if (rem > 3) {
uint8_t second = bytes[1];
uint8_t third = bytes[2];
uint8_t fourth = bytes[3];
if (_IsSuffixChar(second) && _IsSuffixChar(third) && _IsSuffixChar(fourth)) {
out = (static_cast<uint32_t>(first & 0x07) << 18)
+ (static_cast<uint32_t>(second & 0x3F) << 12)
+ (static_cast<uint32_t>(third & 0x3F) << 6)
+ static_cast<uint32_t>(fourth & 0x3F);
slice.remove_prefix(4);
return true;
}
}
}
out = static_cast<uint32_t>(REPLACEMENT_CHARACTER);
slice.remove_prefix(1);
return true;
}
return false;
}
/// See <https://www.ietf.org/rfc/rfc2781.html#section-2.1>
bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
if (output.length() >= size) return false;
if (U < 0x10000) {
// If U < 0x10000, encode U as a 16-bit unsigned integer and terminate.
output.push_back(static_cast<uint16_t>(U));
return true;
} else if (U > 0x10FFFF) {
output.push_back(REPLACEMENT_CHARACTER);
return true;
} else if (output.length() + 1 < size) {
// Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
// U' must be less than or equal to 0xFFFFF. That is, U' can be
// represented in 20 bits.
uint32_t Ut = U - 0x10000;
// Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
// 0xDC00, respectively. These integers each have 10 bits free to
// encode the character value, for a total of 20 bits.
uint16_t W1 = 0xD800;
uint16_t W2 = 0xDC00;
// Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
// bits of W1 and the 10 low-order bits of U' to the 10 low-order
// bits of W2.
W1 += static_cast<uint16_t>((Ut & 0x3FC00) >> 10);
W2 += static_cast<uint16_t>((Ut & 0x3FF) >> 0);
// Terminate.
output.push_back(W1); // high surrogate
output.push_back(W2); // low surrogate
return true;
} else return false;
}
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string output;
output.reserve(newSize);
std::string_view iterator = string;
uint32_t c;
while (_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
return output;
}
//! Converts an std::string (ASCII) to UCS-2 / UTF-16
std::u16string GeneralUtils::ASCIIToUTF16(const std::string& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string ret;
ret.reserve(newSize);
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; i++) {
char c = string[i];
assert(c > 0 && c <= 127);
ret.push_back(static_cast<char16_t>(c));
}
for (size_t i = 0; i < newSize; i++) {
char c = string[i];
// Note: both 7-bit ascii characters and REPLACEMENT_CHARACTER fit in one char16_t
ret.push_back((c > 0 && c <= 127) ? static_cast<char16_t>(c) : REPLACEMENT_CHARACTER);
}
return ret;
return ret;
}
//! Converts a (potentially-ill-formed) UTF-16 string to UTF-8
//! See: <http://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16>
std::string GeneralUtils::UTF16ToWTF8(const std::u16string& string, size_t size) {
size_t newSize = MinSize(size, string);
std::string ret;
ret.reserve(newSize);
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; i++) {
char16_t u = string[i];
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
char16_t next = string[i + 1];
if (IsTrailSurrogate(next)) {
i += 1;
char32_t cp = 0x10000
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
+ (static_cast<char32_t>(next) - 0xDC00);
PushUTF8CodePoint(ret, cp);
} else {
PushUTF8CodePoint(ret, u);
}
} else {
PushUTF8CodePoint(ret, u);
}
}
for (size_t i = 0; i < newSize; i++) {
char16_t u = string[i];
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
char16_t next = string[i + 1];
if (IsTrailSurrogate(next)) {
i += 1;
char32_t cp = 0x10000
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
+ (static_cast<char32_t>(next) - 0xDC00);
PushUTF8CodePoint(ret, cp);
} else {
PushUTF8CodePoint(ret, u);
}
} else {
PushUTF8CodePoint(ret, u);
}
}
return ret;
return ret;
}
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string& a, const std::string& b) {
return std::equal(a.begin(), a.end (), b.begin(), b.end(),[](char a, char b) { return tolower(a) == tolower(b); });
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) { return tolower(a) == tolower(b); });
}
// MARK: Bits
//! Sets a specific bit in a signed 64-bit integer
int64_t GeneralUtils::SetBit(int64_t value, uint32_t index) {
return value |= 1ULL << index;
return value |= 1ULL << index;
}
//! Clears a specific bit in a signed 64-bit integer
int64_t GeneralUtils::ClearBit(int64_t value, uint32_t index) {
return value &= ~(1ULL << index);
return value &= ~(1ULL << index);
}
//! Checks a specific bit in a signed 64-bit integer
bool GeneralUtils::CheckBit(int64_t value, uint32_t index) {
return value & (1ULL << index);
return value & (1ULL << index);
}
bool GeneralUtils::ReplaceInString(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
size_t start_pos = str.find(from);
if (start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter)
{
std::vector<std::wstring> vector = std::vector<std::wstring>();
std::wstring current;
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter) {
std::vector<std::wstring> vector = std::vector<std::wstring>();
std::wstring current;
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = L"";
} else {
current += c;
}
}
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = L"";
} else {
current += c;
}
}
vector.push_back(current);
return vector;
vector.push_back(current);
return vector;
}
std::vector<std::u16string> GeneralUtils::SplitString(std::u16string& str, char16_t delimiter)
{
std::vector<std::u16string> vector = std::vector<std::u16string>();
std::u16string current;
std::vector<std::u16string> GeneralUtils::SplitString(std::u16string& str, char16_t delimiter) {
std::vector<std::u16string> vector = std::vector<std::u16string>();
std::u16string current;
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = u"";
} else {
current += c;
}
}
for (const auto& c : str) {
if (c == delimiter) {
vector.push_back(current);
current = u"";
} else {
current += c;
}
}
vector.push_back(current);
return vector;
vector.push_back(current);
return vector;
}
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter)
{
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter) {
std::vector<std::string> vector = std::vector<std::string>();
std::string current = "";
for (size_t i = 0; i < str.length(); i++)
{
for (size_t i = 0; i < str.length(); i++) {
char c = str[i];
if (c == delimiter)
{
if (c == delimiter) {
vector.push_back(current);
current = "";
}
else
{
} else {
current += c;
}
}
@@ -175,16 +275,65 @@ std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char
return vector;
}
std::u16string GeneralUtils::ReadWString(RakNet::BitStream *inStream) {
uint32_t length;
inStream->Read<uint32_t>(length);
std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) {
uint32_t length;
inStream->Read<uint32_t>(length);
std::u16string string;
for (auto i = 0; i < length; i++) {
uint16_t c;
inStream->Read(c);
string.push_back(c);
}
std::u16string string;
for (auto i = 0; i < length; i++) {
uint16_t c;
inStream->Read(c);
string.push_back(c);
}
return string;
return string;
}
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
std::vector<std::string> names;
std::string search_path = folder + "/*.*";
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
names.push_back(fd.cFileName);
}
} while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
return names;
}
#else
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <iostream>
#include <vector>
#include <cstring>
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
std::vector<std::string> names;
struct dirent* entry;
DIR* dir = opendir(folder.c_str());
if (dir == NULL) {
return names;
}
while ((entry = readdir(dir)) != NULL) {
std::string value(entry->d_name, strlen(entry->d_name));
if (value == "." || value == "..") {
continue;
}
names.push_back(value);
}
closedir(dir);
return names;
}
#endif

View File

@@ -18,109 +18,119 @@
\brief A namespace containing general utility functions
*/
//! The general utils namespace
//! The general utils namespace
namespace GeneralUtils {
//! Converts a plain ASCII string to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string ASCIIToUTF16(const std::string& string, size_t size = -1);
//! Converts a plain ASCII string to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string ASCIIToUTF16(const std::string_view& string, size_t size = -1);
//! Converts a UTF-16 string to a UTF-8 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-8 representation of the string
*/
std::string UTF16ToWTF8(const std::u16string& string, size_t size = -1);
//! Converts a UTF-8 String to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string UTF8ToUTF16(const std::string_view& string, size_t size = -1);
/**
* Compares two basic strings but does so ignoring case sensitivity
* \param a the first string to compare against the second string
* \param b the second string to compare against the first string
* @return if the two strings are equal
*/
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
//! Internal, do not use
bool _NextUTF8Char(std::string_view& slice, uint32_t& out);
// MARK: Bits
//! Converts a UTF-16 string to a UTF-8 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\return An UTF-8 representation of the string
*/
std::string UTF16ToWTF8(const std::u16string_view& string, size_t size = -1);
// MARK: Bits
/**
* Compares two basic strings but does so ignoring case sensitivity
* \param a the first string to compare against the second string
* \param b the second string to compare against the first string
* @return if the two strings are equal
*/
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
//! Sets a bit on a numerical value
template <typename T>
void SetBit(T& value, size_t index) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if (index > (sizeof(T) * 8) - 1) {
return;
}
value |= static_cast<T>(1) << index;
}
//! Clears a bit on a numerical value
template <typename T>
void ClearBit(T& value, size_t index) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if (index > (sizeof(T) * 8 - 1)) {
return;
}
value &= ~(static_cast<T>(1) << index);
}
//! Sets a specific bit in a signed 64-bit integer
/*!
\param value The value to set the bit for
\param index The index of the bit
*/
int64_t SetBit(int64_t value, uint32_t index);
//! Clears a specific bit in a signed 64-bit integer
/*!
\param value The value to clear the bit from
\param index The index of the bit
*/
int64_t ClearBit(int64_t value, uint32_t index);
//! Checks a specific bit in a signed 64-bit integer
/*!
\parma value The value to check the bit in
\param index The index of the bit
\return Whether or not the bit is set
*/
bool CheckBit(int64_t value, uint32_t index);
// MARK: Bits
// MARK: Random Number Generation
// MARK: Bits
//! Generates a random number
/*!
\param min The minimum the generate from
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
//! Sets a bit on a numerical value
template <typename T>
void SetBit(T& value, size_t index) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
std::uniform_int_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
}
else if (std::is_floating_point_v<T>) {
std::uniform_real_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
}
if (index > (sizeof(T) * 8) - 1) {
return;
}
value |= static_cast<T>(1) << index;
}
//! Clears a bit on a numerical value
template <typename T>
void ClearBit(T& value, size_t index) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if (index > (sizeof(T) * 8 - 1)) {
return;
}
value &= ~(static_cast<T>(1) << index);
}
//! Sets a specific bit in a signed 64-bit integer
/*!
\param value The value to set the bit for
\param index The index of the bit
*/
int64_t SetBit(int64_t value, uint32_t index);
//! Clears a specific bit in a signed 64-bit integer
/*!
\param value The value to clear the bit from
\param index The index of the bit
*/
int64_t ClearBit(int64_t value, uint32_t index);
//! Checks a specific bit in a signed 64-bit integer
/*!
\parma value The value to check the bit in
\param index The index of the bit
\return Whether or not the bit is set
*/
bool CheckBit(int64_t value, uint32_t index);
// MARK: Random Number Generation
//! Generates a random number
/*!
\param min The minimum the generate from
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
std::uniform_int_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
} else if (std::is_floating_point_v<T>) {
std::uniform_real_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
}
return T();
}
return T();
}
bool ReplaceInString(std::string& str, const std::string& from, const std::string& to);
std::u16string ReadWString(RakNet::BitStream *inStream);
std::u16string ReadWString(RakNet::BitStream* inStream);
std::vector<std::wstring> SplitString(std::wstring& str, wchar_t delimiter);
@@ -128,83 +138,71 @@ namespace GeneralUtils {
std::vector<std::string> SplitString(const std::string& str, char delimiter);
template <typename T>
T Parse(const char* value);
std::vector<std::string> GetFileNamesFromFolder(const std::string& folder);
template <typename T>
T Parse(const char* value);
template <>
inline int32_t Parse(const char* value)
{
return std::stoi(value);
inline int32_t Parse(const char* value) {
return std::stoi(value);
}
template <>
inline int64_t Parse(const char* value)
{
return std::stoll(value);
}
template <>
inline int64_t Parse(const char* value) {
return std::stoll(value);
}
template <>
inline float Parse(const char* value)
{
return std::stof(value);
}
template <>
inline float Parse(const char* value) {
return std::stof(value);
}
template <>
inline double Parse(const char* value)
{
return std::stod(value);
}
template <>
inline uint32_t Parse(const char* value)
{
return std::stoul(value);
}
template <>
inline double Parse(const char* value) {
return std::stod(value);
}
template <>
inline uint64_t Parse(const char* value)
{
return std::stoull(value);
}
template <typename T>
bool TryParse(const char* value, T& dst)
{
try
{
dst = Parse<T>(value);
template <>
inline uint32_t Parse(const char* value) {
return std::stoul(value);
}
return true;
}
catch (...)
{
return false;
}
}
template <>
inline uint64_t Parse(const char* value) {
return std::stoull(value);
}
template <typename T>
T Parse(const std::string& value)
{
return Parse<T>(value.c_str());
}
template <typename T>
bool TryParse(const char* value, T& dst) {
try {
dst = Parse<T>(value);
template <typename T>
bool TryParse(const std::string& value, T& dst)
{
return TryParse<T>(value.c_str(), dst);
}
return true;
} catch (...) {
return false;
}
}
template<typename T>
std::u16string to_u16string(T value)
{
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
}
template <typename T>
T Parse(const std::string& value) {
return Parse<T>(value.c_str());
}
// From boost::hash_combine
template <class T>
void hash_combine(std::size_t& s, const T& v)
{
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
template <typename T>
bool TryParse(const std::string& value, T& dst) {
return TryParse<T>(value.c_str(), dst);
}
template<typename T>
std::u16string to_u16string(T value) {
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
}
// From boost::hash_combine
template <class T>
void hash_combine(std::size_t& s, const T& v) {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
}

View File

@@ -8,25 +8,25 @@
#include <vector>
//! Returns a pointer to a LDFData value based on string format
LDFBaseData * LDFBaseData::DataFromString(const std::string& format) {
// First, check the format
std::istringstream ssFormat(format);
std::string token;
std::vector<std::string> keyValueArray;
while (std::getline(ssFormat, token, '=')) {
keyValueArray.push_back(token);
}
if (keyValueArray.size() == 2) {
std::u16string key = GeneralUtils::ASCIIToUTF16(keyValueArray[0]);
std::vector<std::string> dataArray;
std::istringstream ssData(keyValueArray[1]);
while (std::getline(ssData, token, ':')) {
dataArray.push_back(token);
}
LDFBaseData* LDFBaseData::DataFromString(const std::string& format) {
// First, check the format
std::istringstream ssFormat(format);
std::string token;
std::vector<std::string> keyValueArray;
while (std::getline(ssFormat, token, '=')) {
keyValueArray.push_back(token);
}
if (keyValueArray.size() == 2) {
std::u16string key = GeneralUtils::ASCIIToUTF16(keyValueArray[0]);
std::vector<std::string> dataArray;
std::istringstream ssData(keyValueArray[1]);
while (std::getline(ssData, token, ':')) {
dataArray.push_back(token);
}
if (dataArray.size() > 2) { // hacky fix for strings with colons in them
std::vector<std::string> newDataArray;
@@ -39,96 +39,86 @@ LDFBaseData * LDFBaseData::DataFromString(const std::string& format) {
newDataArray.push_back(value);
dataArray = newDataArray;
}
if ((dataArray[0] == "0" || dataArray[0] == "13") && dataArray.size() == 1) {
dataArray.push_back("");
}
if (dataArray.size() == 2) {
eLDFType type = static_cast<eLDFType>(stoi(dataArray[0]));
switch (type) {
case LDF_TYPE_UTF_16: {
std::u16string data = GeneralUtils::ASCIIToUTF16(dataArray[1]);
return new LDFData<std::u16string>(key, data);
}
case LDF_TYPE_S32: {
int32_t data = static_cast<int32_t>(stol(dataArray[1]));
return new LDFData<int32_t>(key, data);
}
case LDF_TYPE_FLOAT: {
float data = static_cast<float>(stof(dataArray[1]));
return new LDFData<float>(key, data);
}
case LDF_TYPE_DOUBLE: {
double data = static_cast<float>(stod(dataArray[1]));
return new LDFData<double>(key, data);
}
case LDF_TYPE_U32:
{
uint32_t data;
if (dataArray[1] == "true")
{
data = 1;
}
else if (dataArray[1] == "false")
{
data = 0;
}
else
{
data = static_cast<uint32_t>(stoul(dataArray[1]));
}
return new LDFData<uint32_t>(key, data);
}
case LDF_TYPE_BOOLEAN: {
bool data;
if (dataArray[1] == "true")
{
data = true;
}
else if (dataArray[1] == "false")
{
data = false;
}
else
{
data = static_cast<bool>(stoi(dataArray[1]));
}
return new LDFData<bool>(key, data);
}
case LDF_TYPE_U64: {
uint64_t data = static_cast<uint64_t>(stoull(dataArray[1]));
return new LDFData<uint64_t>(key, data);
}
case LDF_TYPE_OBJID: {
LWOOBJID data = static_cast<LWOOBJID>(stoll(dataArray[1]));
return new LDFData<LWOOBJID>(key, data);
}
case LDF_TYPE_UTF_8: {
std::string data = dataArray[1];
return new LDFData<std::string>(key, data);
}
case LDF_TYPE_UNKNOWN: {
return nullptr;
}
}
}
}
return nullptr;
if ((dataArray[0] == "0" || dataArray[0] == "13") && dataArray.size() == 1) {
dataArray.push_back("");
}
if (dataArray.size() == 2) {
eLDFType type = static_cast<eLDFType>(stoi(dataArray[0]));
switch (type) {
case LDF_TYPE_UTF_16: {
std::u16string data = GeneralUtils::UTF8ToUTF16(dataArray[1]);
return new LDFData<std::u16string>(key, data);
}
case LDF_TYPE_S32: {
int32_t data = static_cast<int32_t>(stoull(dataArray[1]));
return new LDFData<int32_t>(key, data);
}
case LDF_TYPE_FLOAT: {
float data = static_cast<float>(stof(dataArray[1]));
return new LDFData<float>(key, data);
}
case LDF_TYPE_DOUBLE: {
double data = static_cast<float>(stod(dataArray[1]));
return new LDFData<double>(key, data);
}
case LDF_TYPE_U32:
{
uint32_t data;
if (dataArray[1] == "true") {
data = 1;
} else if (dataArray[1] == "false") {
data = 0;
} else {
data = static_cast<uint32_t>(stoul(dataArray[1]));
}
return new LDFData<uint32_t>(key, data);
}
case LDF_TYPE_BOOLEAN: {
bool data;
if (dataArray[1] == "true") {
data = true;
} else if (dataArray[1] == "false") {
data = false;
} else {
data = static_cast<bool>(stoi(dataArray[1]));
}
return new LDFData<bool>(key, data);
}
case LDF_TYPE_U64: {
uint64_t data = static_cast<uint64_t>(stoull(dataArray[1]));
return new LDFData<uint64_t>(key, data);
}
case LDF_TYPE_OBJID: {
LWOOBJID data = static_cast<LWOOBJID>(stoll(dataArray[1]));
return new LDFData<LWOOBJID>(key, data);
}
case LDF_TYPE_UTF_8: {
std::string data = dataArray[1];
return new LDFData<std::string>(key, data);
}
case LDF_TYPE_UNKNOWN: {
return nullptr;
}
}
}
}
return nullptr;
}

View File

@@ -17,64 +17,64 @@
\brief A collection of LDF format classes
*/
//! An enum for LDF Data Types
//! An enum for LDF Data Types
enum eLDFType {
LDF_TYPE_UNKNOWN = -1, //!< Unknown data type
LDF_TYPE_UTF_16 = 0, //!< UTF-16 wstring data type
LDF_TYPE_S32 = 1, //!< Signed 32-bit data type
LDF_TYPE_FLOAT = 3, //!< Float data type
LDF_TYPE_DOUBLE = 4, //!< Double data type
LDF_TYPE_U32 = 5, //!< Unsigned 32-bit data type
LDF_TYPE_BOOLEAN = 7, //!< Boolean data type
LDF_TYPE_U64 = 8, //!< Unsigned 64-bit data type (originally signed, templates won't work with both S64 & OBJID
LDF_TYPE_OBJID = 9, //!< Signed 64-bit data type (reserved for object IDs)
LDF_TYPE_UTF_8 = 13, //!< UTF-8 string data type
LDF_TYPE_UNKNOWN = -1, //!< Unknown data type
LDF_TYPE_UTF_16 = 0, //!< UTF-16 wstring data type
LDF_TYPE_S32 = 1, //!< Signed 32-bit data type
LDF_TYPE_FLOAT = 3, //!< Float data type
LDF_TYPE_DOUBLE = 4, //!< Double data type
LDF_TYPE_U32 = 5, //!< Unsigned 32-bit data type
LDF_TYPE_BOOLEAN = 7, //!< Boolean data type
LDF_TYPE_U64 = 8, //!< Unsigned 64-bit data type (originally signed, templates won't work with both S64 & OBJID
LDF_TYPE_OBJID = 9, //!< Signed 64-bit data type (reserved for object IDs)
LDF_TYPE_UTF_8 = 13, //!< UTF-8 string data type
};
//! A base class for the LDF data
class LDFBaseData {
public:
//! Destructor
virtual ~LDFBaseData(void) { }
//! Writes the data to a packet
/*!
\param packet The packet
*/
virtual void WriteToPacket(RakNet::BitStream * packet) = 0;
//! Gets the key
/*!
\return The key
*/
virtual const std::u16string& GetKey(void) = 0;
//! Gets the value type
/*!
\return The value type
*/
virtual eLDFType GetValueType(void) = 0;
//! Gets a string from the key/value pair
/*!
\param includeKey Whether or not to include the key in the data
\param includeTypeId Whether or not to include the type id in the data
\return The string representation of the data
*/
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) = 0;
virtual std::string GetValueAsString() = 0;
virtual LDFBaseData * Copy() = 0;
// MARK: Functions
//! Returns a pointer to a LDFData value based on string format
/*!
\param format The format
*/
static LDFBaseData * DataFromString(const std::string& format);
//! Destructor
virtual ~LDFBaseData(void) {}
//! Writes the data to a packet
/*!
\param packet The packet
*/
virtual void WriteToPacket(RakNet::BitStream* packet) = 0;
//! Gets the key
/*!
\return The key
*/
virtual const std::u16string& GetKey(void) = 0;
//! Gets the value type
/*!
\return The value type
*/
virtual eLDFType GetValueType(void) = 0;
//! Gets a string from the key/value pair
/*!
\param includeKey Whether or not to include the key in the data
\param includeTypeId Whether or not to include the type id in the data
\return The string representation of the data
*/
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) = 0;
virtual std::string GetValueAsString() = 0;
virtual LDFBaseData* Copy() = 0;
// MARK: Functions
//! Returns a pointer to a LDFData value based on string format
/*!
\param format The format
*/
static LDFBaseData* DataFromString(const std::string& format);
};
@@ -82,115 +82,115 @@ public:
template<typename T>
class LDFData : public LDFBaseData {
private:
std::u16string key;
T value;
//! Writes the key to the packet
void WriteKey(RakNet::BitStream * packet) {
packet->Write(static_cast<uint8_t>(this->key.length() * sizeof(uint16_t)));
for (uint32_t i = 0; i < this->key.length(); ++i) {
packet->Write(static_cast<uint16_t>(this->key[i]));
}
}
//! Writes the value to the packet
void WriteValue(RakNet::BitStream * packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(this->value);
}
std::u16string key;
T value;
//! Writes the key to the packet
void WriteKey(RakNet::BitStream* packet) {
packet->Write(static_cast<uint8_t>(this->key.length() * sizeof(uint16_t)));
for (uint32_t i = 0; i < this->key.length(); ++i) {
packet->Write(static_cast<uint16_t>(this->key[i]));
}
}
//! Writes the value to the packet
void WriteValue(RakNet::BitStream* packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(this->value);
}
public:
//! Initializer
LDFData(const std::u16string& key, const T& value) {
this->key = key;
this->value = value;
}
//! Destructor
~LDFData(void) override { }
//! Gets the value
/*!
\return The value
*/
const T& GetValue(void) { return this->value; }
//! Sets the value
/*!
\param value The value to set to
*/
void SetValue(T value) { this->value = value; };
//! Gets the value string
/*!
\return The value string
*/
std::string GetValueString(void) { return ""; }
//! Writes the data to a packet
/*!
\param packet The packet
*/
void WriteToPacket(RakNet::BitStream * packet) override {
this->WriteKey(packet);
this->WriteValue(packet);
}
//! Gets the key
/*!
\return The key
*/
const std::u16string& GetKey(void) override { return this->key; }
//! Gets the LDF Type
/*!
\return The LDF value type
*/
eLDFType GetValueType(void) override { return LDF_TYPE_UNKNOWN; }
//! Gets the string data
/*!
\param includeKey Whether or not to include the key in the data
\param includeTypeId Whether or not to include the type id in the data
\return The string representation of the data
*/
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) override {
if (GetValueType() == -1) {
return GeneralUtils::UTF16ToWTF8(this->key) + "=-1:<server variable>";
}
//! Initializer
LDFData(const std::u16string& key, const T& value) {
this->key = key;
this->value = value;
}
std::stringstream stream;
//! Destructor
~LDFData(void) override {}
if (includeKey) {
const std::string& sKey = GeneralUtils::UTF16ToWTF8(this->key, this->key.size());
stream << sKey << "=";
}
//! Gets the value
/*!
\return The value
*/
const T& GetValue(void) { return this->value; }
if (includeTypeId) {
const std::string& sType = std::to_string(this->GetValueType());
//! Sets the value
/*!
\param value The value to set to
*/
void SetValue(T value) { this->value = value; };
stream << sType << ":";
}
//! Gets the value string
/*!
\return The value string
*/
std::string GetValueString(void) { return ""; }
const std::string& sData = this->GetValueString();
stream << sData;
//! Writes the data to a packet
/*!
\param packet The packet
*/
void WriteToPacket(RakNet::BitStream* packet) override {
this->WriteKey(packet);
this->WriteValue(packet);
}
return stream.str();
}
std::string GetValueAsString() override {
return this->GetValueString();
}
LDFBaseData * Copy() override {
return new LDFData<T>(key, value);
}
inline static T Default = {};
//! Gets the key
/*!
\return The key
*/
const std::u16string& GetKey(void) override { return this->key; }
//! Gets the LDF Type
/*!
\return The LDF value type
*/
eLDFType GetValueType(void) override { return LDF_TYPE_UNKNOWN; }
//! Gets the string data
/*!
\param includeKey Whether or not to include the key in the data
\param includeTypeId Whether or not to include the type id in the data
\return The string representation of the data
*/
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) override {
if (GetValueType() == -1) {
return GeneralUtils::UTF16ToWTF8(this->key) + "=-1:<server variable>";
}
std::stringstream stream;
if (includeKey) {
const std::string& sKey = GeneralUtils::UTF16ToWTF8(this->key, this->key.size());
stream << sKey << "=";
}
if (includeTypeId) {
const std::string& sType = std::to_string(this->GetValueType());
stream << sType << ":";
}
const std::string& sData = this->GetValueString();
stream << sData;
return stream.str();
}
std::string GetValueAsString() override {
return this->GetValueString();
}
LDFBaseData* Copy() override {
return new LDFData<T>(key, value);
}
inline static T Default = {};
};
// LDF Types
@@ -206,38 +206,38 @@ template<> inline eLDFType LDFData<std::string>::GetValueType(void) { return LDF
// The specialized version for std::u16string (UTF-16)
template<>
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream * packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint32_t>(this->value.length()));
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet->Write(static_cast<uint16_t>(this->value[i]));
}
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream* packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint32_t>(this->value.length()));
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet->Write(static_cast<uint16_t>(this->value[i]));
}
}
// The specialized version for bool
template<>
inline void LDFData<bool>::WriteValue(RakNet::BitStream * packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint8_t>(this->value));
inline void LDFData<bool>::WriteValue(RakNet::BitStream* packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint8_t>(this->value));
}
// The specialized version for std::string (UTF-8)
template<>
inline void LDFData<std::string>::WriteValue(RakNet::BitStream * packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint32_t>(this->value.length()));
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet->Write(static_cast<uint8_t>(this->value[i]));
}
inline void LDFData<std::string>::WriteValue(RakNet::BitStream* packet) {
packet->Write(static_cast<uint8_t>(this->GetValueType()));
packet->Write(static_cast<uint32_t>(this->value.length()));
for (uint32_t i = 0; i < this->value.length(); ++i) {
packet->Write(static_cast<uint8_t>(this->value[i]));
}
}
// MARK: String Data
template<> inline std::string LDFData<std::u16string>::GetValueString(void) {
//std::string toReturn(this->value.begin(), this->value.end());
//return toReturn;
//std::string toReturn(this->value.begin(), this->value.end());
//return toReturn;
return GeneralUtils::UTF16ToWTF8(this->value, this->value.size());
}

View File

@@ -1,36 +1,36 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implemantion of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* interface header */
/* interface header */
#include "MD5.h"
/* system implementation headers */
@@ -59,304 +59,290 @@
// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
return x&y | ~x&z;
return x & y | ~x & z;
}
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
return x&z | y&~z;
return x & z | y & ~z;
}
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
return x^y^z;
return x ^ y ^ z;
}
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
return y ^ (x | ~z);
return y ^ (x | ~z);
}
// rotate_left rotates x left n bits.
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
return (x << n) | (x >> (32 - n));
return (x << n) | (x >> (32 - n));
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
}
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
}
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
}
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
}
//////////////////////////////////////////////
// default ctor, just initailize
MD5::MD5()
{
init();
MD5::MD5() {
init();
}
//////////////////////////////////////////////
// nifty shortcut ctor, compute MD5 for string and finalize it right away
MD5::MD5(const std::string &text)
{
init();
update(text.c_str(), text.length());
finalize();
MD5::MD5(const std::string& text) {
init();
update(text.c_str(), text.length());
finalize();
}
//////////////////////////////
void MD5::init()
{
finalized = false;
count[0] = 0;
count[1] = 0;
// load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
void MD5::init() {
finalized = false;
count[0] = 0;
count[1] = 0;
// load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
//////////////////////////////
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
{
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
(((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
void MD5::decode(uint4 output[], const uint1 input[], size_type len) {
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
(((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
}
//////////////////////////////
// encodes input (uint4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
{
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
output[j] = input[i] & 0xff;
output[j + 1] = (input[i] >> 8) & 0xff;
output[j + 2] = (input[i] >> 16) & 0xff;
output[j + 3] = (input[i] >> 24) & 0xff;
}
void MD5::encode(uint1 output[], const uint4 input[], size_type len) {
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
output[j] = input[i] & 0xff;
output[j + 1] = (input[i] >> 8) & 0xff;
output[j + 2] = (input[i] >> 16) & 0xff;
output[j + 3] = (input[i] >> 24) & 0xff;
}
}
//////////////////////////////
// apply MD5 algo on a block
void MD5::transform(const uint1 block[blocksize])
{
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode(x, block, blocksize);
/* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset(x, 0, sizeof x);
void MD5::transform(const uint1 block[blocksize]) {
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode(x, block, blocksize);
/* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset(x, 0, sizeof x);
}
//////////////////////////////
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block
void MD5::update(const unsigned char input[], size_type length)
{
// compute number of bytes mod 64
size_type index = count[0] / 8 % blocksize;
// Update number of bits
if ((count[0] += (length << 3)) < (length << 3))
count[1]++;
count[1] += (length >> 29);
// number of bytes we need to fill in buffer
size_type firstpart = 64 - index;
size_type i;
// transform as many times as possible.
if (length >= firstpart)
{
// fill buffer first, transform
memcpy(&buffer[index], input, firstpart);
transform(buffer);
// transform chunks of blocksize (64 bytes)
for (i = firstpart; i + blocksize <= length; i += blocksize)
transform(&input[i]);
index = 0;
}
else
i = 0;
// buffer remaining input
memcpy(&buffer[index], &input[i], length - i);
void MD5::update(const unsigned char input[], size_type length) {
// compute number of bytes mod 64
size_type index = count[0] / 8 % blocksize;
// Update number of bits
if ((count[0] += (length << 3)) < (length << 3))
count[1]++;
count[1] += (length >> 29);
// number of bytes we need to fill in buffer
size_type firstpart = 64 - index;
size_type i;
// transform as many times as possible.
if (length >= firstpart) {
// fill buffer first, transform
memcpy(&buffer[index], input, firstpart);
transform(buffer);
// transform chunks of blocksize (64 bytes)
for (i = firstpart; i + blocksize <= length; i += blocksize)
transform(&input[i]);
index = 0;
} else
i = 0;
// buffer remaining input
memcpy(&buffer[index], &input[i], length - i);
}
//////////////////////////////
// for convenience provide a verson with signed char
void MD5::update(const char input[], size_type length)
{
update((const unsigned char*)input, length);
void MD5::update(const char input[], size_type length) {
update((const unsigned char*)input, length);
}
//////////////////////////////
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
MD5& MD5::finalize()
{
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!finalized) {
// Save number of bits
unsigned char bits[8];
encode(bits, count, 8);
// pad out to 56 mod 64.
size_type index = count[0] / 8 % 64;
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
update(padding, padLen);
// Append length (before padding)
update(bits, 8);
// Store state in digest
encode(digest, state, 16);
// Zeroize sensitive information.
memset(buffer, 0, sizeof buffer);
memset(count, 0, sizeof count);
finalized = true;
}
return *this;
MD5& MD5::finalize() {
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!finalized) {
// Save number of bits
unsigned char bits[8];
encode(bits, count, 8);
// pad out to 56 mod 64.
size_type index = count[0] / 8 % 64;
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
update(padding, padLen);
// Append length (before padding)
update(bits, 8);
// Store state in digest
encode(digest, state, 16);
// Zeroize sensitive information.
memset(buffer, 0, sizeof buffer);
memset(count, 0, sizeof count);
finalized = true;
}
return *this;
}
//////////////////////////////
// return hex representation of digest as string
std::string MD5::hexdigest() const
{
if (!finalized)
return "";
char buf[33];
for (int i = 0; i<16; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
buf[32] = 0;
return std::string(buf);
std::string MD5::hexdigest() const {
if (!finalized)
return "";
char buf[33];
for (int i = 0; i < 16; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
buf[32] = 0;
return std::string(buf);
}
//////////////////////////////
std::ostream& operator<<(std::ostream& out, MD5 md5)
{
return out << md5.hexdigest();
std::ostream& operator<<(std::ostream& out, MD5 md5) {
return out << md5.hexdigest();
}
//////////////////////////////
std::string md5(const std::string str)
{
MD5 md5 = MD5(str);
return md5.hexdigest();
std::string md5(const std::string str) {
MD5 md5 = MD5(str);
return md5.hexdigest();
}

View File

@@ -1,33 +1,33 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implementation of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef BZF_MD5_H
@@ -37,55 +37,55 @@
#include <iostream>
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{
public:
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char *buf, size_type length);
void update(const char *buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char* buf, size_type length);
void update(const char* buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum { blocksize = 64 }; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum { blocksize = 64 }; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};
std::string md5(const std::string str);

View File

@@ -4,174 +4,156 @@
std::unordered_map<MetricVariable, Metric*> Metrics::m_Metrics = {};
std::vector<MetricVariable> Metrics::m_Variables = {
MetricVariable::GameLoop,
MetricVariable::PacketHandling,
MetricVariable::UpdateEntities,
MetricVariable::UpdateSpawners,
MetricVariable::Physics,
MetricVariable::UpdateReplica,
MetricVariable::Ghosting,
MetricVariable::CPUTime,
MetricVariable::Sleep,
MetricVariable::Frame,
MetricVariable::GameLoop,
MetricVariable::PacketHandling,
MetricVariable::UpdateEntities,
MetricVariable::UpdateSpawners,
MetricVariable::Physics,
MetricVariable::UpdateReplica,
MetricVariable::Ghosting,
MetricVariable::CPUTime,
MetricVariable::Sleep,
MetricVariable::Frame,
#ifdef BUILD_VISUAL_DEBUGGER
MetricVariable::VisualDebugger,
#endif
};
void Metrics::AddMeasurement(MetricVariable variable, int64_t value)
{
const auto& iter = m_Metrics.find(variable);
void Metrics::AddMeasurement(MetricVariable variable, int64_t value) {
const auto& iter = m_Metrics.find(variable);
Metric* metric;
Metric* metric;
if (iter == m_Metrics.end())
{
metric = new Metric();
if (iter == m_Metrics.end()) {
metric = new Metric();
m_Metrics[variable] = metric;
}
else
{
metric = iter->second;
}
m_Metrics[variable] = metric;
} else {
metric = iter->second;
}
AddMeasurement(metric, value);
AddMeasurement(metric, value);
}
void Metrics::AddMeasurement(Metric* metric, int64_t value)
{
const auto index = metric->measurementIndex;
void Metrics::AddMeasurement(Metric* metric, int64_t value) {
const auto index = metric->measurementIndex;
metric->measurements[index] = value;
metric->measurements[index] = value;
if (metric->max == -1 || value > metric->max)
{
metric->max = value;
}
else if (metric->min == -1 || metric->min > value)
{
metric->min = value;
}
if (metric->max == -1 || value > metric->max) {
metric->max = value;
} else if (metric->min == -1 || metric->min > value) {
metric->min = value;
}
if (metric->measurementSize < MAX_MEASURMENT_POINTS)
{
metric->measurementSize++;
}
if (metric->measurementSize < MAX_MEASURMENT_POINTS) {
metric->measurementSize++;
}
metric->measurementIndex = (index + 1) % MAX_MEASURMENT_POINTS;
metric->measurementIndex = (index + 1) % MAX_MEASURMENT_POINTS;
}
const Metric* Metrics::GetMetric(MetricVariable variable)
{
const auto& iter = m_Metrics.find(variable);
const Metric* Metrics::GetMetric(MetricVariable variable) {
const auto& iter = m_Metrics.find(variable);
if (iter == m_Metrics.end())
{
return nullptr;
}
if (iter == m_Metrics.end()) {
return nullptr;
}
Metric* metric = iter->second;
Metric* metric = iter->second;
int64_t average = 0;
int64_t average = 0;
for (size_t i = 0; i < metric->measurementSize; i++)
{
average += metric->measurements[i];
}
for (size_t i = 0; i < metric->measurementSize; i++) {
average += metric->measurements[i];
}
average /= metric->measurementSize;
average /= metric->measurementSize;
metric->average = average;
return metric;
metric->average = average;
return metric;
}
void Metrics::StartMeasurement(MetricVariable variable)
{
const auto& iter = m_Metrics.find(variable);
void Metrics::StartMeasurement(MetricVariable variable) {
const auto& iter = m_Metrics.find(variable);
Metric* metric;
Metric* metric;
if (iter == m_Metrics.end())
{
metric = new Metric();
if (iter == m_Metrics.end()) {
metric = new Metric();
m_Metrics[variable] = metric;
}
else
{
metric = iter->second;
}
m_Metrics[variable] = metric;
} else {
metric = iter->second;
}
metric->activeMeasurement = std::chrono::high_resolution_clock::now();
metric->activeMeasurement = std::chrono::high_resolution_clock::now();
}
void Metrics::EndMeasurement(MetricVariable variable)
{
const auto end = std::chrono::high_resolution_clock::now();
void Metrics::EndMeasurement(MetricVariable variable) {
const auto end = std::chrono::high_resolution_clock::now();
const auto& iter = m_Metrics.find(variable);
const auto& iter = m_Metrics.find(variable);
if (iter == m_Metrics.end())
{
return;
}
if (iter == m_Metrics.end()) {
return;
}
Metric* metric = iter->second;
Metric* metric = iter->second;
const auto elapsed = end - metric->activeMeasurement;
const auto elapsed = end - metric->activeMeasurement;
const auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
const auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
AddMeasurement(metric, nanoseconds);
AddMeasurement(metric, nanoseconds);
}
float Metrics::ToMiliseconds(int64_t nanoseconds)
{
return (float) nanoseconds / 1e6;
float Metrics::ToMiliseconds(int64_t nanoseconds) {
return (float)nanoseconds / 1e6;
}
std::string Metrics::MetricVariableToString(MetricVariable variable)
{
switch (variable)
{
case MetricVariable::GameLoop:
return "GameLoop";
case MetricVariable::PacketHandling:
return "PacketHandling";
case MetricVariable::UpdateEntities:
return "UpdateEntities";
case MetricVariable::UpdateSpawners:
return "UpdateSpawners";
case MetricVariable::Physics:
return "Physics";
case MetricVariable::UpdateReplica:
return "UpdateReplica";
case MetricVariable::Sleep:
return "Sleep";
case MetricVariable::CPUTime:
return "CPUTime";
case MetricVariable::Frame:
return "Frame";
case MetricVariable::Ghosting:
return "Ghosting";
default:
return "Invalid";
}
std::string Metrics::MetricVariableToString(MetricVariable variable) {
switch (variable) {
case MetricVariable::GameLoop:
return "GameLoop";
case MetricVariable::PacketHandling:
return "PacketHandling";
case MetricVariable::UpdateEntities:
return "UpdateEntities";
case MetricVariable::UpdateSpawners:
return "UpdateSpawners";
case MetricVariable::Physics:
return "Physics";
case MetricVariable::UpdateReplica:
return "UpdateReplica";
case MetricVariable::Sleep:
return "Sleep";
case MetricVariable::CPUTime:
return "CPUTime";
case MetricVariable::Frame:
return "Frame";
case MetricVariable::Ghosting:
return "Ghosting";
#ifdef BUILD_VISUAL_DEBUGGER
case MetricVariable::VisualDebugger:
return "VisualDebugger";
#endif
default:
return "Invalid";
}
}
const std::vector<MetricVariable>& Metrics::GetAllMetrics()
{
return m_Variables;
const std::vector<MetricVariable>& Metrics::GetAllMetrics() {
return m_Variables;
}
void Metrics::Clear()
{
for (const auto& pair : m_Metrics)
{
delete pair.second;
}
m_Metrics.clear();
void Metrics::Clear() {
for (const auto& pair : m_Metrics) {
delete pair.second;
}
m_Metrics.clear();
}
/* RSS Memory utilities
@@ -207,46 +189,44 @@ void Metrics::Clear()
#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
#endif
/**
* Returns the peak (maximum so far) resident set size (physical
* memory use) measured in bytes, or zero if the value cannot be
* determined on this OS.
*/
size_t Metrics::GetPeakRSS()
{
/**
* Returns the peak (maximum so far) resident set size (physical
* memory use) measured in bytes, or zero if the value cannot be
* determined on this OS.
*/
size_t Metrics::GetPeakRSS() {
#if defined(_WIN32)
/* Windows -------------------------------------------------- */
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
return (size_t)info.PeakWorkingSetSize;
/* Windows -------------------------------------------------- */
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
return (size_t)info.PeakWorkingSetSize;
#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
/* AIX and Solaris ------------------------------------------ */
struct psinfo psinfo;
int fd = -1;
if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
return (size_t)0L; /* Can't open? */
if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
{
close( fd );
return (size_t)0L; /* Can't read? */
}
close( fd );
return (size_t)(psinfo.pr_rssize * 1024L);
/* AIX and Solaris ------------------------------------------ */
struct psinfo psinfo;
int fd = -1;
if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1)
return (size_t)0L; /* Can't open? */
if (read(fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) {
close(fd);
return (size_t)0L; /* Can't read? */
}
close(fd);
return (size_t)(psinfo.pr_rssize * 1024L);
#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
/* BSD, Linux, and OSX -------------------------------------- */
struct rusage rusage;
getrusage( RUSAGE_SELF, &rusage );
/* BSD, Linux, and OSX -------------------------------------- */
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
#if defined(__APPLE__) && defined(__MACH__)
return (size_t)rusage.ru_maxrss;
return (size_t)rusage.ru_maxrss;
#else
return (size_t)(rusage.ru_maxrss * 1024L);
return (size_t)(rusage.ru_maxrss * 1024L);
#endif
#else
/* Unknown OS ----------------------------------------------- */
return (size_t)0L; /* Unsupported. */
/* Unknown OS ----------------------------------------------- */
return (size_t)0L; /* Unsupported. */
#endif
}
@@ -255,49 +235,46 @@ size_t Metrics::GetPeakRSS()
* Returns the current resident set size (physical memory use) measured
* in bytes, or zero if the value cannot be determined on this OS.
*/
size_t Metrics::GetCurrentRSS()
{
size_t Metrics::GetCurrentRSS() {
#if defined(_WIN32)
/* Windows -------------------------------------------------- */
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
return (size_t)info.WorkingSetSize;
/* Windows -------------------------------------------------- */
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
return (size_t)info.WorkingSetSize;
#elif defined(__APPLE__) && defined(__MACH__)
/* OSX ------------------------------------------------------ */
struct mach_task_basic_info info;
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
(task_info_t)&info, &infoCount ) != KERN_SUCCESS )
return (size_t)0L; /* Can't access? */
return (size_t)info.resident_size;
/* OSX ------------------------------------------------------ */
struct mach_task_basic_info info;
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
(task_info_t)&info, &infoCount) != KERN_SUCCESS)
return (size_t)0L; /* Can't access? */
return (size_t)info.resident_size;
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
/* Linux ---------------------------------------------------- */
long rss = 0L;
FILE* fp = NULL;
if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
return (size_t)0L; /* Can't open? */
if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
{
fclose( fp );
return (size_t)0L; /* Can't read? */
}
fclose( fp );
return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
/* Linux ---------------------------------------------------- */
long rss = 0L;
FILE* fp = NULL;
if ((fp = fopen("/proc/self/statm", "r")) == NULL)
return (size_t)0L; /* Can't open? */
if (fscanf(fp, "%*s%ld", &rss) != 1) {
fclose(fp);
return (size_t)0L; /* Can't read? */
}
fclose(fp);
return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
#else
/* AIX, BSD, Solaris, and Unknown OS ------------------------ */
return (size_t)0L; /* Unsupported. */
/* AIX, BSD, Solaris, and Unknown OS ------------------------ */
return (size_t)0L; /* Unsupported. */
#endif
}
size_t Metrics::GetProcessID()
{
size_t Metrics::GetProcessID() {
#if defined(_WIN32)
return GetCurrentProcessId();
return GetCurrentProcessId();
#else
return getpid();
return getpid();
#endif
}

View File

@@ -10,52 +10,55 @@
enum class MetricVariable : int32_t
{
GameLoop,
PacketHandling,
UpdateEntities,
UpdateSpawners,
Physics,
UpdateReplica,
Ghosting,
CPUTime,
Sleep,
Frame,
GameLoop,
PacketHandling,
UpdateEntities,
UpdateSpawners,
Physics,
UpdateReplica,
Ghosting,
CPUTime,
Sleep,
Frame,
#ifdef BUILD_VISUAL_DEBUGGER
VisualDebugger
#endif
};
struct Metric
{
int64_t measurements[MAX_MEASURMENT_POINTS] = {};
size_t measurementIndex = 0;
size_t measurementSize = 0;
int64_t max = -1;
int64_t min = -1;
int64_t average = 0;
std::chrono::time_point<std::chrono::high_resolution_clock> activeMeasurement;
int64_t measurements[MAX_MEASURMENT_POINTS] = {};
size_t measurementIndex = 0;
size_t measurementSize = 0;
int64_t max = -1;
int64_t min = -1;
int64_t average = 0;
std::chrono::time_point<std::chrono::high_resolution_clock> activeMeasurement;
};
class Metrics
{
public:
~Metrics();
~Metrics();
static void AddMeasurement(MetricVariable variable, int64_t value);
static void AddMeasurement(Metric* metric, int64_t value);
static const Metric* GetMetric(MetricVariable variable);
static void StartMeasurement(MetricVariable variable);
static void EndMeasurement(MetricVariable variable);
static float ToMiliseconds(int64_t nanoseconds);
static std::string MetricVariableToString(MetricVariable variable);
static const std::vector<MetricVariable>& GetAllMetrics();
static void AddMeasurement(MetricVariable variable, int64_t value);
static void AddMeasurement(Metric* metric, int64_t value);
static const Metric* GetMetric(MetricVariable variable);
static void StartMeasurement(MetricVariable variable);
static void EndMeasurement(MetricVariable variable);
static float ToMiliseconds(int64_t nanoseconds);
static std::string MetricVariableToString(MetricVariable variable);
static const std::vector<MetricVariable>& GetAllMetrics();
static size_t GetPeakRSS();
static size_t GetCurrentRSS();
static size_t GetProcessID();
static size_t GetPeakRSS();
static size_t GetCurrentRSS();
static size_t GetProcessID();
static void Clear();
static void Clear();
private:
Metrics();
Metrics();
static std::unordered_map<MetricVariable, Metric*> m_Metrics;
static std::vector<MetricVariable> m_Variables;
static std::unordered_map<MetricVariable, Metric*> m_Metrics;
static std::vector<MetricVariable> m_Variables;
};

View File

@@ -13,23 +13,23 @@ const NiPoint3 NiPoint3::UNIT_ALL(1.0f, 1.0f, 1.0f);
//! Initializer
NiPoint3::NiPoint3(void) {
this->x = 0;
this->y = 0;
this->z = 0;
this->x = 0;
this->y = 0;
this->z = 0;
}
//! Initializer
NiPoint3::NiPoint3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
this->x = x;
this->y = y;
this->z = z;
}
//! Copy Constructor
NiPoint3::NiPoint3(const NiPoint3& point) {
this->x = point.x;
this->y = point.y;
this->z = point.z;
this->x = point.x;
this->y = point.y;
this->z = point.z;
}
//! Destructor
@@ -39,68 +39,63 @@ NiPoint3::~NiPoint3(void) {}
//! Gets the X coordinate
float NiPoint3::GetX(void) const {
return this->x;
return this->x;
}
//! Sets the X coordinate
void NiPoint3::SetX(float x) {
this->x = x;
this->x = x;
}
//! Gets the Y coordinate
float NiPoint3::GetY(void) const {
return this->y;
return this->y;
}
//! Sets the Y coordinate
void NiPoint3::SetY(float y) {
this->y = y;
this->y = y;
}
//! Gets the Z coordinate
float NiPoint3::GetZ(void) const {
return this->z;
return this->z;
}
//! Sets the Z coordinate
void NiPoint3::SetZ(float z) {
this->z = z;
this->z = z;
}
// MARK: Functions
//! Gets the length of the vector
float NiPoint3::Length(void) const {
return sqrt(x*x + y*y + z*z);
return sqrt(x * x + y * y + z * z);
}
//! Gets the squared length of a vector
float NiPoint3::SquaredLength(void) const {
return (x*x + y*y + z*z);
return (x * x + y * y + z * z);
}
//! Returns the dot product of the vector dotted with another vector
float NiPoint3::DotProduct(const Vector3& vec) const {
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
float NiPoint3::DotProduct(const NiPoint3& vec) const {
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
}
//! Returns the cross product of the vector crossed with another vector
Vector3 NiPoint3::CrossProduct(const Vector3& vec) const {
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
((this->z * vec.x) - (this->x * vec.z)),
((this->x * vec.y) - (this->y * vec.x)));
NiPoint3 NiPoint3::CrossProduct(const NiPoint3& vec) const {
return NiPoint3(((this->y * vec.z) - (this->z * vec.y)),
((this->z * vec.x) - (this->x * vec.z)),
((this->x * vec.y) - (this->y * vec.x)));
}
//! Unitize the vector
NiPoint3 NiPoint3::Unitize(void) const {
NiPoint3 unitVec;
float length = this->Length();
float length = this->Length();
unitVec.x = length != 0 ? this->x / length : 0;
unitVec.y = length != 0 ? this->y / length : 0;
unitVec.z = length != 0 ? this->z / length : 0;
return unitVec;
return length != 0 ? *this / length : NiPoint3::ZERO;
}
@@ -108,57 +103,57 @@ NiPoint3 NiPoint3::Unitize(void) const {
//! Operator to check for equality
bool NiPoint3::operator==(const NiPoint3& point) const {
return point.x == this->x && point.y == this->y && point.z == this->z;
return point.x == this->x && point.y == this->y && point.z == this->z;
}
//! Operator to check for inequality
bool NiPoint3::operator!=(const NiPoint3& point) const {
return !(*this == point);
return !(*this == point);
}
//! Operator for subscripting
float& NiPoint3::operator[](int i) {
float * base = &x;
return (float&)base[i];
float* base = &x;
return (float&)base[i];
}
//! Operator for subscripting
const float& NiPoint3::operator[](int i) const {
const float * base = &x;
return (float&)base[i];
const float* base = &x;
return (float&)base[i];
}
//! Operator for addition of vectors
NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
}
//! Operator for subtraction of vectors
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
}
//! Operator for addition of a scalar on all vector components
NiPoint3 NiPoint3::operator+(float fScalar) const {
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
}
//! Operator for subtraction of a scalar on all vector components
NiPoint3 NiPoint3::operator-(float fScalar) const {
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
}
//! Operator for scalar multiplication of a vector
NiPoint3 NiPoint3::operator*(float fScalar) const {
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
}
//! Operator for scalar division of a vector
NiPoint3 NiPoint3::operator/(float fScalar) const {
float retX = this->x != 0 ? this->x / fScalar : 0;
float retY = this->y != 0 ? this->y / fScalar : 0;
float retZ = this->z != 0 ? this->z / fScalar : 0;
return NiPoint3(retX, retY, retZ);
float retX = this->x != 0 ? this->x / fScalar : 0;
float retY = this->y != 0 ? this->y / fScalar : 0;
float retZ = this->z != 0 ? this->z / fScalar : 0;
return NiPoint3(retX, retY, retZ);
}
@@ -166,96 +161,91 @@ NiPoint3 NiPoint3::operator/(float fScalar) const {
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) {
if (this->x < minPoint.x) return false;
if (this->x > maxPoint.x) return false;
if (this->y < minPoint.y) return false;
if (this->y > maxPoint.y) return false;
if (this->x < minPoint.x) return false;
if (this->x > maxPoint.x) return false;
if (this->y < minPoint.y) return false;
if (this->y > maxPoint.y) return false;
return (this->z < maxPoint.z && this->z > minPoint.z);
return (this->z < maxPoint.z&& this->z > minPoint.z);
}
//! Checks to see if the point (or vector) is within a sphere
bool NiPoint3::IsWithinSpehere(const NiPoint3& sphereCenter, float radius) {
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
return (diffVec.SquaredLength() <= (radius * radius));
NiPoint3 diffVec = NiPoint3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
return (diffVec.SquaredLength() <= (radius * radius));
}
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p)
{
if (a == b) return a;
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) {
if (a == b) return a;
const auto pa = p - a;
const auto ab = b - a;
const auto pa = p - a;
const auto ab = b - a;
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
if (t <= 0.0f) return a;
if (t >= 1.0f) return b;
return a + ab * t;
if (t <= 0.0f) return a;
if (t >= 1.0f) return b;
return a + ab * t;
}
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b)
{
const auto dot = a.DotProduct(b);
const auto lenA = a.SquaredLength();
const auto lenB = a.SquaredLength();
return acos(dot / sqrt(lenA * lenB));
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b) {
const auto dot = a.DotProduct(b);
const auto lenA = a.SquaredLength();
const auto lenB = a.SquaredLength();
return acos(dot / sqrt(lenA * lenB));
}
float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b)
{
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b) {
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
return std::sqrt(dx * dx + dy * dy + dz * dz);
return std::sqrt(dx * dx + dy * dy + dz * dz);
}
float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b)
{
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) {
const auto dx = a.x - b.x;
const auto dy = a.y - b.y;
const auto dz = a.z - b.z;
return dx * dx + dy * dy + dz * dz;
return dx * dx + dy * dy + dz * dz;
}
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta)
{
float dx = target.x - current.x;
float dy = target.y - current.y;
float dz = target.z - current.z;
float lengthSquared = (float) ((double) dx * (double) dx + (double) dy * (double) dy + (double) dz * (double) dz);
if ((double) lengthSquared == 0.0 || (double) maxDistanceDelta >= 0.0 && (double) lengthSquared <= (double) maxDistanceDelta * (double) maxDistanceDelta)
return target;
float length = (float) std::sqrt((double) lengthSquared);
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta) {
float dx = target.x - current.x;
float dy = target.y - current.y;
float dz = target.z - current.z;
float lengthSquared = (float)((double)dx * (double)dx + (double)dy * (double)dy + (double)dz * (double)dz);
if ((double)lengthSquared == 0.0 || (double)maxDistanceDelta >= 0.0 && (double)lengthSquared <= (double)maxDistanceDelta * (double)maxDistanceDelta)
return target;
float length = (float)std::sqrt((double)lengthSquared);
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
}
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) {
Vector3 vector;
float num12 = rotation.x + rotation.x;
float num2 = rotation.y + rotation.y;
float num = rotation.z + rotation.z;
float num11 = rotation.w * num12;
float num10 = rotation.w * num2;
float num9 = rotation.w * num;
float num8 = rotation.x * num12;
float num7 = rotation.x * num2;
float num6 = rotation.x * num;
float num5 = rotation.y * num2;
float num4 = rotation.y * num;
float num3 = rotation.z * num;
NiPoint3 vector;
float num12 = rotation.x + rotation.x;
float num2 = rotation.y + rotation.y;
float num = rotation.z + rotation.z;
float num11 = rotation.w * num12;
float num10 = rotation.w * num2;
float num9 = rotation.w * num;
float num8 = rotation.x * num12;
float num7 = rotation.x * num2;
float num6 = rotation.x * num;
float num5 = rotation.y * num2;
float num4 = rotation.y * num;
float num3 = rotation.z * num;
NiPoint3 value = *this;
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
vector.x = num15;
vector.y = num14;
vector.z = num13;
return vector;
}
NiPoint3 value = *this;
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
vector.x = num15;
vector.y = num14;
vector.z = num13;
return vector;
}

View File

@@ -7,182 +7,181 @@
class NiPoint3;
class NiQuaternion;
typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoint3 class, but typedef'd for clarity in some cases
//! A custom class the defines a point in space
class NiPoint3 {
public:
float x; //!< The x position
float y; //!< The y position
float z; //!< The z position
float x; //!< The x position
float y; //!< The y position
float z; //!< The z position
//! Initializer
NiPoint3(void);
//! Initializer
NiPoint3(void);
//! Initializer
/*!
\param x The x coordinate
\param y The y coordinate
\param z The z coordinate
*/
NiPoint3(float x, float y, float z);
//! Initializer
/*!
\param x The x coordinate
\param y The y coordinate
\param z The z coordinate
*/
NiPoint3(float x, float y, float z);
//! Copy Constructor
/*!
\param point The point to copy
*/
NiPoint3(const NiPoint3& point);
//! Copy Constructor
/*!
\param point The point to copy
*/
NiPoint3(const NiPoint3& point);
//! Destructor
~NiPoint3(void);
//! Destructor
~NiPoint3(void);
// MARK: Constants
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
// MARK: Constants
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
// MARK: Getters / Setters
// MARK: Getters / Setters
//! Gets the X coordinate
/*!
\return The x coordinate
*/
float GetX(void) const;
//! Gets the X coordinate
/*!
\return The x coordinate
*/
float GetX(void) const;
//! Sets the X coordinate
/*!
\param x The x coordinate
*/
void SetX(float x);
//! Sets the X coordinate
/*!
\param x The x coordinate
*/
void SetX(float x);
//! Gets the Y coordinate
/*!
\return The y coordinate
*/
float GetY(void) const;
//! Gets the Y coordinate
/*!
\return The y coordinate
*/
float GetY(void) const;
//! Sets the Y coordinate
/*!
\param y The y coordinate
*/
void SetY(float y);
//! Sets the Y coordinate
/*!
\param y The y coordinate
*/
void SetY(float y);
//! Gets the Z coordinate
/*!
\return The z coordinate
*/
float GetZ(void) const;
//! Gets the Z coordinate
/*!
\return The z coordinate
*/
float GetZ(void) const;
//! Sets the Z coordinate
/*!
\param z The z coordinate
*/
void SetZ(float z);
//! Sets the Z coordinate
/*!
\param z The z coordinate
*/
void SetZ(float z);
// MARK: Member Functions
// MARK: Member Functions
//! Gets the length of the vector
/*!
\return The scalar length of the vector
*/
float Length(void) const;
//! Gets the length of the vector
/*!
\return The scalar length of the vector
*/
float Length(void) const;
//! Gets the squared length of a vector
/*!
\return The squared length of a vector
*/
float SquaredLength(void) const;
//! Gets the squared length of a vector
/*!
\return The squared length of a vector
*/
float SquaredLength(void) const;
//! Returns the dot product of the vector dotted with another vector
/*!
\param vec The second vector
\return The dot product of the two vectors
*/
float DotProduct(const Vector3& vec) const;
//! Returns the dot product of the vector dotted with another vector
/*!
\param vec The second vector
\return The dot product of the two vectors
*/
float DotProduct(const NiPoint3& vec) const;
//! Returns the cross product of the vector crossed with another vector
/*!
\param vec The second vector
\return The cross product of the two vectors
*/
Vector3 CrossProduct(const Vector3& vec) const;
//! Returns the cross product of the vector crossed with another vector
/*!
\param vec The second vector
\return The cross product of the two vectors
*/
NiPoint3 CrossProduct(const NiPoint3& vec) const;
//! Unitize the vector
/*!
\returns The current vector
*/
NiPoint3 Unitize(void) const;
//! Unitize the vector
/*!
\returns The current vector
*/
NiPoint3 Unitize(void) const;
// MARK: Operators
// MARK: Operators
//! Operator to check for equality
bool operator==(const NiPoint3& point) const;
//! Operator to check for equality
bool operator==(const NiPoint3& point) const;
//! Operator to check for inequality
bool operator!=(const NiPoint3& point) const;
//! Operator to check for inequality
bool operator!=(const NiPoint3& point) const;
//! Operator for subscripting
float& operator[](int i);
//! Operator for subscripting
float& operator[](int i);
//! Operator for subscripting
const float& operator[](int i) const;
//! Operator for subscripting
const float& operator[](int i) const;
//! Operator for addition of vectors
NiPoint3 operator+(const NiPoint3& point) const;
//! Operator for addition of vectors
NiPoint3 operator+(const NiPoint3& point) const;
//! Operator for subtraction of vectors
NiPoint3 operator-(const NiPoint3& point) const;
//! Operator for subtraction of vectors
NiPoint3 operator-(const NiPoint3& point) const;
//! Operator for addition of a scalar on all vector components
NiPoint3 operator+(float fScalar) const;
//! Operator for addition of a scalar on all vector components
NiPoint3 operator+(float fScalar) const;
//! Operator for subtraction of a scalar on all vector components
NiPoint3 operator-(float fScalar) const;
//! Operator for subtraction of a scalar on all vector components
NiPoint3 operator-(float fScalar) const;
//! Operator for scalar multiplication of a vector
NiPoint3 operator*(float fScalar) const;
//! Operator for scalar multiplication of a vector
NiPoint3 operator*(float fScalar) const;
//! Operator for scalar division of a vector
NiPoint3 operator/(float fScalar) const;
//! Operator for scalar division of a vector
NiPoint3 operator/(float fScalar) const;
// MARK: Helper Functions
// MARK: Helper Functions
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
/*!
\param minPoint The minimum point of the bounding box
\param maxPoint The maximum point of the bounding box
\return Whether or not this point lies within the box
*/
bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
/*!
\param minPoint The minimum point of the bounding box
\param maxPoint The maximum point of the bounding box
\return Whether or not this point lies within the box
*/
bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
//! Checks to see if the point (or vector) is within a sphere
/*!
\param sphereCenter The sphere center
\param radius The radius
*/
bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
//! Checks to see if the point (or vector) is within a sphere
/*!
\param sphereCenter The sphere center
\param radius The radius
*/
bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
/*!
\param a Start of line
\param b End of line
\param p Refrence point
\return The point of line AB which is closest to P
*/
static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
/*!
\param a Start of line
\param b End of line
\param p Refrence point
\return The point of line AB which is closest to P
*/
static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
static float Angle(const NiPoint3& a, const NiPoint3& b);
static float Angle(const NiPoint3& a, const NiPoint3& b);
static float Distance(const NiPoint3& a, const NiPoint3& b);
static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
static float Distance(const NiPoint3& a, const NiPoint3& b);
static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
};

View File

@@ -8,18 +8,18 @@ const NiQuaternion NiQuaternion::IDENTITY(1, 0, 0, 0);
//! The initializer
NiQuaternion::NiQuaternion(void) {
this->w = 1;
this->x = 0;
this->y = 0;
this->z = 0;
this->w = 1;
this->x = 0;
this->y = 0;
this->z = 0;
}
//! The initializer
NiQuaternion::NiQuaternion(float w, float x, float y, float z) {
this->w = w;
this->x = x;
this->y = y;
this->z = z;
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
//! Destructor
@@ -30,98 +30,97 @@ NiQuaternion::~NiQuaternion(void) {}
//! Gets the W coordinate
float NiQuaternion::GetW(void) const {
return this->w;
return this->w;
}
//! Sets the W coordinate
void NiQuaternion::SetW(float w) {
this->w = w;
this->w = w;
}
//! Gets the X coordinate
float NiQuaternion::GetX(void) const {
return this->x;
return this->x;
}
//! Sets the X coordinate
void NiQuaternion::SetX(float x) {
this->x = x;
this->x = x;
}
//! Gets the Y coordinate
float NiQuaternion::GetY(void) const {
return this->y;
return this->y;
}
//! Sets the Y coordinate
void NiQuaternion::SetY(float y) {
this->y = y;
this->y = y;
}
//! Gets the Z coordinate
float NiQuaternion::GetZ(void) const {
return this->z;
return this->z;
}
//! Sets the Z coordinate
void NiQuaternion::SetZ(float z) {
this->z = z;
this->z = z;
}
// MARK: Member Functions
//! Returns the forward vector from the quaternion
Vector3 NiQuaternion::GetForwardVector(void) const {
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
NiPoint3 NiQuaternion::GetForwardVector(void) const {
return NiPoint3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
}
//! Returns the up vector from the quaternion
Vector3 NiQuaternion::GetUpVector(void) const {
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
NiPoint3 NiQuaternion::GetUpVector(void) const {
return NiPoint3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
}
//! Returns the right vector from the quaternion
Vector3 NiQuaternion::GetRightVector(void) const {
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
NiPoint3 NiQuaternion::GetRightVector(void) const {
return NiPoint3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
}
Vector3 NiQuaternion::GetEulerAngles() const {
Vector3 angles;
NiPoint3 NiQuaternion::GetEulerAngles() const {
NiPoint3 angles;
// roll (x-axis rotation)
const float sinr_cosp = 2 * (w * x + y * z);
const float cosr_cosp = 1 - 2 * (x * x + y * y);
angles.x = std::atan2(sinr_cosp, cosr_cosp);
// roll (x-axis rotation)
const float sinr_cosp = 2 * (w * x + y * z);
const float cosr_cosp = 1 - 2 * (x * x + y * y);
angles.x = std::atan2(sinr_cosp, cosr_cosp);
// pitch (y-axis rotation)
const float sinp = 2 * (w * y - z * x);
if (std::abs(sinp) >= 1) {
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
}
else {
angles.y = std::asin(sinp);
}
// pitch (y-axis rotation)
const float sinp = 2 * (w * y - z * x);
// yaw (z-axis rotation)
const float siny_cosp = 2 * (w * z + x * y);
const float cosy_cosp = 1 - 2 * (y * y + z * z);
angles.z = std::atan2(siny_cosp, cosy_cosp);
if (std::abs(sinp) >= 1) {
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
} else {
angles.y = std::asin(sinp);
}
return angles;
// yaw (z-axis rotation)
const float siny_cosp = 2 * (w * z + x * y);
const float cosy_cosp = 1 - 2 * (y * y + z * z);
angles.z = std::atan2(siny_cosp, cosy_cosp);
return angles;
}
// MARK: Operators
//! Operator to check for equality
bool NiQuaternion::operator==(const NiQuaternion& rot) const {
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
}
//! Operator to check for inequality
bool NiQuaternion::operator!=(const NiQuaternion& rot) const {
return !(*this == rot);
return !(*this == rot);
}
@@ -135,65 +134,63 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
source.y = 0.0f;
dest.y = 0.0f;
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector);
float rotAngle = static_cast<float>(acos(dot));
NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector);
float rotAngle = static_cast<float>(acos(dot));
NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
}
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint)
{
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector);
float rotAngle = static_cast<float>(acos(dot));
NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
NiPoint3 posZ = NiPoint3::UNIT_Z;
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
float dot = posZ.DotProduct(forwardVector);
float rotAngle = static_cast<float>(acos(dot));
NiPoint3 vecB = vecA.CrossProduct(posZ);
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
}
//! Creates a Quaternion from a specific axis and angle relative to that axis
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) {
float halfAngle = angle * 0.5f;
float s = static_cast<float>(sin(halfAngle));
NiQuaternion q;
q.x = axis.GetX() * s;
q.y = axis.GetY() * s;
q.z = axis.GetZ() * s;
q.w = static_cast<float>(cos(halfAngle));
return q;
NiQuaternion NiQuaternion::CreateFromAxisAngle(const NiPoint3& axis, float angle) {
float halfAngle = angle * 0.5f;
float s = static_cast<float>(sin(halfAngle));
NiQuaternion q;
q.x = axis.GetX() * s;
q.y = axis.GetY() * s;
q.z = axis.GetZ() * s;
q.w = static_cast<float>(cos(halfAngle));
return q;
}
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles)
{
// Abbreviations for the various angular functions
float cy = cos(eulerAngles.z * 0.5);
float sy = sin(eulerAngles.z * 0.5);
float cp = cos(eulerAngles.y * 0.5);
float sp = sin(eulerAngles.y * 0.5);
float cr = cos(eulerAngles.x * 0.5);
float sr = sin(eulerAngles.x * 0.5);
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) {
// Abbreviations for the various angular functions
float cy = cos(eulerAngles.z * 0.5);
float sy = sin(eulerAngles.z * 0.5);
float cp = cos(eulerAngles.y * 0.5);
float sp = sin(eulerAngles.y * 0.5);
float cr = cos(eulerAngles.x * 0.5);
float sr = sin(eulerAngles.x * 0.5);
NiQuaternion q;
q.w = cr * cp * cy + sr * sp * sy;
q.x = sr * cp * cy - cr * sp * sy;
q.y = cr * sp * cy + sr * cp * sy;
q.z = cr * cp * sy - sr * sp * cy;
NiQuaternion q;
q.w = cr * cp * cy + sr * sp * sy;
q.x = sr * cp * cy - cr * sp * sy;
q.y = cr * sp * cy + sr * cp * sy;
q.z = cr * cp * sy - sr * sp * cy;
return q;
return q;
}

View File

@@ -9,143 +9,142 @@
*/
class NiQuaternion;
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
//! A class that defines a rotation in space
class NiQuaternion {
public:
float w; //!< The w coordinate
float x; //!< The x coordinate
float y; //!< The y coordinate
float z; //!< The z coordinate
//! The initializer
NiQuaternion(void);
//! The initializer
/*!
\param w The w coordinate
\param x The x coordinate
\param y The y coordinate
\param z The z coordinate
*/
NiQuaternion(float w, float x, float y, float z);
//! Destructor
~NiQuaternion(void);
// MARK: Constants
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
// MARK: Setters / Getters
//! Gets the W coordinate
/*!
\return The w coordinate
*/
float GetW(void) const;
//! Sets the W coordinate
/*!
\param w The w coordinate
*/
void SetW(float w);
//! Gets the X coordinate
/*!
\return The x coordinate
*/
float GetX(void) const;
//! Sets the X coordinate
/*!
\param x The x coordinate
*/
void SetX(float x);
//! Gets the Y coordinate
/*!
\return The y coordinate
*/
float GetY(void) const;
//! Sets the Y coordinate
/*!
\param y The y coordinate
*/
void SetY(float y);
//! Gets the Z coordinate
/*!
\return The z coordinate
*/
float GetZ(void) const;
//! Sets the Z coordinate
/*!
\param z The z coordinate
*/
void SetZ(float z);
// MARK: Member Functions
//! Returns the forward vector from the quaternion
/*!
\return The forward vector of the quaternion
*/
Vector3 GetForwardVector(void) const;
//! Returns the up vector from the quaternion
/*!
\return The up vector fo the quaternion
*/
Vector3 GetUpVector(void) const;
//! Returns the right vector from the quaternion
/*!
\return The right vector of the quaternion
*/
Vector3 GetRightVector(void) const;
float w; //!< The w coordinate
float x; //!< The x coordinate
float y; //!< The y coordinate
float z; //!< The z coordinate
Vector3 GetEulerAngles() const;
// MARK: Operators
//! Operator to check for equality
bool operator==(const NiQuaternion& rot) const;
//! Operator to check for inequality
bool operator!=(const NiQuaternion& rot) const;
// MARK: Helper Functions
//! Look from a specific point in space to another point in space (Y-locked)
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Look from a specific point in space to another point in space
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Creates a Quaternion from a specific axis and angle relative to that axis
/*!
\param axis The axis that is used
\param angle The angle relative to this axis
\return A quaternion created from the axis and angle
*/
static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
//! The initializer
NiQuaternion(void);
//! The initializer
/*!
\param w The w coordinate
\param x The x coordinate
\param y The y coordinate
\param z The z coordinate
*/
NiQuaternion(float w, float x, float y, float z);
//! Destructor
~NiQuaternion(void);
// MARK: Constants
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
// MARK: Setters / Getters
//! Gets the W coordinate
/*!
\return The w coordinate
*/
float GetW(void) const;
//! Sets the W coordinate
/*!
\param w The w coordinate
*/
void SetW(float w);
//! Gets the X coordinate
/*!
\return The x coordinate
*/
float GetX(void) const;
//! Sets the X coordinate
/*!
\param x The x coordinate
*/
void SetX(float x);
//! Gets the Y coordinate
/*!
\return The y coordinate
*/
float GetY(void) const;
//! Sets the Y coordinate
/*!
\param y The y coordinate
*/
void SetY(float y);
//! Gets the Z coordinate
/*!
\return The z coordinate
*/
float GetZ(void) const;
//! Sets the Z coordinate
/*!
\param z The z coordinate
*/
void SetZ(float z);
// MARK: Member Functions
//! Returns the forward vector from the quaternion
/*!
\return The forward vector of the quaternion
*/
NiPoint3 GetForwardVector(void) const;
//! Returns the up vector from the quaternion
/*!
\return The up vector fo the quaternion
*/
NiPoint3 GetUpVector(void) const;
//! Returns the right vector from the quaternion
/*!
\return The right vector of the quaternion
*/
NiPoint3 GetRightVector(void) const;
NiPoint3 GetEulerAngles() const;
// MARK: Operators
//! Operator to check for equality
bool operator==(const NiQuaternion& rot) const;
//! Operator to check for inequality
bool operator!=(const NiQuaternion& rot) const;
// MARK: Helper Functions
//! Look from a specific point in space to another point in space (Y-locked)
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Look from a specific point in space to another point in space
/*!
\param sourcePoint The source location
\param destPoint The destination location
\return The Quaternion with the rotation towards the destination
*/
static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
//! Creates a Quaternion from a specific axis and angle relative to that axis
/*!
\param axis The axis that is used
\param angle The angle relative to this axis
\return A quaternion created from the axis and angle
*/
static NiQuaternion CreateFromAxisAngle(const NiPoint3& axis, float angle);
static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
};

View File

@@ -7,36 +7,36 @@
*/
enum class PermissionMap : uint64_t
{
/**
* Reserved for future use, bit 0-3.
*/
/**
* Reserved for future use, bit 0-3.
*/
/**
* The character has restricted trade acccess, bit 4.
*/
RestrictedTradeAccess = 0x1 << 4,
/**
* The character has restricted trade acccess, bit 4.
*/
RestrictedTradeAccess = 0x1 << 4,
/**
* The character has restricted mail access, bit 5.
*/
RestrictedMailAccess = 0x1 << 5,
/**
* The character has restricted mail access, bit 5.
*/
RestrictedMailAccess = 0x1 << 5,
/**
* The character has restricted chat access, bit 6.
*/
RestrictedChatAccess = 0x1 << 6,
/**
* The character has restricted chat access, bit 6.
*/
RestrictedChatAccess = 0x1 << 6,
//
// Combined permissions
//
//
// Combined permissions
//
/**
* The character is marked as 'old', restricted from trade and mail.
*/
Old = RestrictedTradeAccess | RestrictedMailAccess,
/**
* The character is marked as 'old', restricted from trade and mail.
*/
Old = RestrictedTradeAccess | RestrictedMailAccess,
/**
* The character is soft banned, restricted from trade, mail, and chat.
*/
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
/**
* The character is soft banned, restricted from trade, mail, and chat.
*/
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
};

View File

@@ -5,153 +5,148 @@
const unsigned long long SHA512::sha512_k[80] = //ULL = uint64
{ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
void SHA512::transform(const unsigned char *message, unsigned int block_nb)
{
uint64 w[80];
uint64 wv[8];
uint64 t1, t2;
const unsigned char *sub_block;
int i, j;
for (i = 0; i < (int)block_nb; i++) {
sub_block = message + (i << 7);
for (j = 0; j < 16; j++) {
SHA2_PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
}
for (j = 0; j < 8; j++) {
wv[j] = m_h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
m_h[j] += wv[j];
}
}
void SHA512::transform(const unsigned char* message, unsigned int block_nb) {
uint64 w[80];
uint64 wv[8];
uint64 t1, t2;
const unsigned char* sub_block;
int i, j;
for (i = 0; i < (int)block_nb; i++) {
sub_block = message + (i << 7);
for (j = 0; j < 16; j++) {
SHA2_PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
}
for (j = 0; j < 8; j++) {
wv[j] = m_h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
m_h[j] += wv[j];
}
}
}
void SHA512::init()
{
m_h[0] = 0x6a09e667f3bcc908ULL;
m_h[1] = 0xbb67ae8584caa73bULL;
m_h[2] = 0x3c6ef372fe94f82bULL;
m_h[3] = 0xa54ff53a5f1d36f1ULL;
m_h[4] = 0x510e527fade682d1ULL;
m_h[5] = 0x9b05688c2b3e6c1fULL;
m_h[6] = 0x1f83d9abfb41bd6bULL;
m_h[7] = 0x5be0cd19137e2179ULL;
m_len = 0;
m_tot_len = 0;
void SHA512::init() {
m_h[0] = 0x6a09e667f3bcc908ULL;
m_h[1] = 0xbb67ae8584caa73bULL;
m_h[2] = 0x3c6ef372fe94f82bULL;
m_h[3] = 0xa54ff53a5f1d36f1ULL;
m_h[4] = 0x510e527fade682d1ULL;
m_h[5] = 0x9b05688c2b3e6c1fULL;
m_h[6] = 0x1f83d9abfb41bd6bULL;
m_h[7] = 0x5be0cd19137e2179ULL;
m_len = 0;
m_tot_len = 0;
}
void SHA512::update(const unsigned char *message, unsigned int len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char *shifted_message;
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&m_block[m_len], message, rem_len);
if (m_len + len < SHA384_512_BLOCK_SIZE) {
m_len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_512_BLOCK_SIZE;
shifted_message = message + rem_len;
transform(m_block, 1);
transform(shifted_message, block_nb);
rem_len = new_len % SHA384_512_BLOCK_SIZE;
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
m_len = rem_len;
m_tot_len += (block_nb + 1) << 7;
void SHA512::update(const unsigned char* message, unsigned int len) {
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char* shifted_message;
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&m_block[m_len], message, rem_len);
if (m_len + len < SHA384_512_BLOCK_SIZE) {
m_len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_512_BLOCK_SIZE;
shifted_message = message + rem_len;
transform(m_block, 1);
transform(shifted_message, block_nb);
rem_len = new_len % SHA384_512_BLOCK_SIZE;
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
m_len = rem_len;
m_tot_len += (block_nb + 1) << 7;
}
void SHA512::final(unsigned char *digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
int i;
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
< (m_len % SHA384_512_BLOCK_SIZE));
len_b = (m_tot_len + m_len) << 3;
pm_len = block_nb << 7;
memset(m_block + m_len, 0, pm_len - m_len);
m_block[m_len] = 0x80;
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
transform(m_block, block_nb);
for (i = 0; i < 8; i++) {
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
}
void SHA512::final(unsigned char* digest) {
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
int i;
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
< (m_len % SHA384_512_BLOCK_SIZE));
len_b = (m_tot_len + m_len) << 3;
pm_len = block_nb << 7;
memset(m_block + m_len, 0, pm_len - m_len);
m_block[m_len] = 0x80;
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
transform(m_block, block_nb);
for (i = 0; i < 8; i++) {
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
}
}
std::string sha512(std::string input)
{
unsigned char digest[SHA512::DIGEST_SIZE];
memset(digest, 0, SHA512::DIGEST_SIZE);
class SHA512 ctx;
ctx.init();
ctx.update((unsigned char*)input.c_str(), input.length());
ctx.final(digest);
std::string sha512(std::string input) {
unsigned char digest[SHA512::DIGEST_SIZE];
memset(digest, 0, SHA512::DIGEST_SIZE);
class SHA512 ctx;
ctx.init();
ctx.update((unsigned char*)input.c_str(), input.length());
ctx.final(digest);
char buf[2 * SHA512::DIGEST_SIZE + 1];
buf[2 * SHA512::DIGEST_SIZE] = 0;
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
char buf[2 * SHA512::DIGEST_SIZE + 1];
buf[2 * SHA512::DIGEST_SIZE] = 0;
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
sprintf(buf + i * 2, "%02x", digest[i]);
return std::string(buf);
return std::string(buf);
}

View File

@@ -5,25 +5,25 @@
class SHA512 {
protected:
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
const static uint64 sha512_k[];
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
const static uint64 sha512_k[];
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
public:
void init();
void update(const unsigned char *message, unsigned int len);
void final(unsigned char *digest);
static const unsigned int DIGEST_SIZE = (512 / 8);
void init();
void update(const unsigned char* message, unsigned int len);
void final(unsigned char* digest);
static const unsigned int DIGEST_SIZE = (512 / 8);
protected:
void transform(const unsigned char *message, unsigned int block_nb);
unsigned int m_tot_len;
unsigned int m_len;
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
uint64 m_h[8];
void transform(const unsigned char* message, unsigned int block_nb);
unsigned int m_tot_len;
unsigned int m_len;
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
uint64 m_h[8];
};
std::string sha512(std::string input);

View File

@@ -6,22 +6,22 @@
std::string demangle(const char* name) {
int status = -4; // some arbitrary value to eliminate the compiler warning
int status = -4; // some arbitrary value to eliminate the compiler warning
// enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
// enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res{
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name ;
return (status == 0) ? res.get() : name;
}
#else
// does nothing if not g++
std::string demangle(const char* name) {
return name;
return name;
}
#endif

View File

@@ -8,5 +8,5 @@ std::string demangle(const char* name);
template <class T>
std::string type(const T& t) {
return demangle(typeid(t).name());
return demangle(typeid(t).name());
}

View File

@@ -1,73 +1,73 @@
#include "ZCompression.h"
#include "ZCompression.h"
#ifndef _WIN32
#include <zlib.h>
namespace ZCompression
{
int32_t GetMaxCompressedLength(int32_t nLenSrc)
{
int32_t n16kBlocks = (nLenSrc + 16383) / 16384; // round up any fraction of a block
return (nLenSrc + 6 + (n16kBlocks * 5));
}
namespace ZCompression {
int32_t GetMaxCompressedLength(int32_t nLenSrc) {
int32_t n16kBlocks = (nLenSrc + 16383) / 16384; // round up any fraction of a block
return (nLenSrc + 6 + (n16kBlocks * 5));
}
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst)
{
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = abDst;
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst) {
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = abDst;
int nErr, nRet = -1;
nErr = deflateInit(&zInfo, Z_DEFAULT_COMPRESSION); // zlib function
if (nErr == Z_OK) {
nErr = deflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
deflateEnd(&zInfo); // zlib function
return(nRet);
int nErr, nRet = -1;
nErr = deflateInit(&zInfo, Z_DEFAULT_COMPRESSION); // zlib function
if (nErr == Z_OK) {
nErr = deflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
deflateEnd(&zInfo); // zlib function
return(nRet);
}
}
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr)
{
// Get the size of the decompressed data
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = abDst;
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr) {
// Get the size of the decompressed data
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = abDst;
int nRet = -1;
nErr = inflateInit(&zInfo); // zlib function
if (nErr == Z_OK) {
nErr = inflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
inflateEnd(&zInfo); // zlib function
return(nRet);
/*
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = const_cast<Bytef*>(abDst);
int nRet = -1;
nErr = inflateInit(&zInfo); // zlib function
if (nErr == Z_OK) {
nErr = inflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
inflateEnd(&zInfo); // zlib function
return(nRet);
int nRet = -1;
nErr = inflateInit(&zInfo); // zlib function
if (nErr == Z_OK) {
nErr = inflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
inflateEnd(&zInfo); // zlib function
return(nRet); // -1 or len of output
*/
}
}
/*
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = const_cast<Bytef*>(abDst);
int nRet = -1;
nErr = inflateInit(&zInfo); // zlib function
if (nErr == Z_OK) {
nErr = inflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
inflateEnd(&zInfo); // zlib function
return(nRet); // -1 or len of output
*/
}
}
#endif

View File

@@ -1,12 +1,17 @@
#pragma once
#pragma once
#include <cstdint>
namespace ZCompression
{
#include "dPlatforms.h"
#ifndef DARKFLAME_PLATFORM_WIN32
namespace ZCompression {
int32_t GetMaxCompressedLength(int32_t nLenSrc);
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst);
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr);
}
#endif

View File

@@ -48,7 +48,9 @@ const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
typedef std::set<LWOOBJID> TSetObjID;
const float PI = 3.14159f;
#ifndef PI
#define PI 3.14159265358979323846f
#endif
#if defined(__unix) || defined(__APPLE__)
//For Linux:
@@ -103,61 +105,61 @@ private:
const LWOSCENEID LWOSCENEID_INVALID = -1;
struct LWONameValue {
uint32_t length = 0; //!< The length of the name
std::u16string name; //!< The name
LWONameValue(void) {}
LWONameValue(const std::u16string& name) {
this->name = name;
this->length = static_cast<uint32_t>(name.length());
}
~LWONameValue(void) {}
uint32_t length = 0; //!< The length of the name
std::u16string name; //!< The name
LWONameValue(void) {}
LWONameValue(const std::u16string& name) {
this->name = name;
this->length = static_cast<uint32_t>(name.length());
}
~LWONameValue(void) {}
};
struct FriendData {
public:
bool isOnline = false;
bool isBestFriend = false;
bool isFTP = false;
LWOZONEID zoneID;
LWOOBJID friendID;
std::string friendName;
bool isOnline = false;
bool isBestFriend = false;
bool isFTP = false;
LWOZONEID zoneID;
LWOOBJID friendID;
std::string friendName;
void Serialize(RakNet::BitStream& bitStream) {
bitStream.Write<uint8_t>(isOnline);
bitStream.Write<uint8_t>(isBestFriend);
bitStream.Write<uint8_t>(isFTP);
bitStream.Write<uint32_t>(0); //???
bitStream.Write<uint8_t>(0); //???
bitStream.Write(zoneID.GetMapID());
bitStream.Write(zoneID.GetInstanceID());
bitStream.Write(zoneID.GetCloneID());
bitStream.Write(friendID);
uint32_t maxSize = 33;
uint32_t size = static_cast<uint32_t>(friendName.length());
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
void Serialize(RakNet::BitStream& bitStream) {
bitStream.Write<uint8_t>(isOnline);
bitStream.Write<uint8_t>(isBestFriend);
bitStream.Write<uint8_t>(isFTP);
bitStream.Write<uint32_t>(0); //???
bitStream.Write<uint8_t>(0); //???
bitStream.Write(zoneID.GetMapID());
bitStream.Write(zoneID.GetInstanceID());
bitStream.Write(zoneID.GetCloneID());
bitStream.Write(friendID);
if (size > maxSize) size = maxSize;
uint32_t maxSize = 33;
uint32_t size = static_cast<uint32_t>(friendName.length());
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
for (uint32_t i = 0; i < size; ++i) {
bitStream.Write(static_cast<uint16_t>(friendName[i]));
}
if (size > maxSize) size = maxSize;
for (uint32_t j = 0; j < remSize; ++j) {
bitStream.Write(static_cast<uint16_t>(0));
}
for (uint32_t i = 0; i < size; ++i) {
bitStream.Write(static_cast<uint16_t>(friendName[i]));
}
bitStream.Write<uint32_t>(0); //???
bitStream.Write<uint16_t>(0); //???
}
for (uint32_t j = 0; j < remSize; ++j) {
bitStream.Write(static_cast<uint16_t>(0));
}
bitStream.Write<uint32_t>(0); //???
bitStream.Write<uint16_t>(0); //???
}
};
struct Brick {
uint32_t designerID;
uint32_t materialID;
uint32_t designerID;
uint32_t materialID;
};
//This union is used by the behavior system
@@ -169,26 +171,26 @@ union suchar {
//=========== DLU ENUMS ============
enum eGameMasterLevel : int32_t {
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates.
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates.
};
//=========== LU ENUMS ============
//! An enum for object ID bits
enum eObjectBits : int32_t {
OBJECT_BIT_PERSISTENT = 32, //!< The 32 bit index
OBJECT_BIT_CLIENT = 46, //!< The 46 bit index
OBJECT_BIT_SPAWNED = 58, //!< The 58 bit index
OBJECT_BIT_CHARACTER = 60 //!< The 60 bit index
OBJECT_BIT_PERSISTENT = 32, //!< The 32 bit index
OBJECT_BIT_CLIENT = 46, //!< The 46 bit index
OBJECT_BIT_SPAWNED = 58, //!< The 58 bit index
OBJECT_BIT_CHARACTER = 60 //!< The 60 bit index
};
//! An enum for MatchUpdate types
@@ -208,18 +210,18 @@ enum eCyclingMode : uint32_t {
};
enum eCinematicEvent : uint32_t {
STARTED,
WAYPOINT,
ENDED,
STARTED,
WAYPOINT,
ENDED,
};
//! An enum for character creation responses
enum eCreationResponse : uint8_t {
CREATION_RESPONSE_SUCCESS = 0, //!< The creation was successful
CREATION_RESPONSE_OBJECT_ID_UNAVAILABLE, //!< The Object ID can't be used
CREATION_RESPONSE_NAME_NOT_ALLOWED, //!< The name is not allowed
CREATION_RESPONSE_PREDEFINED_NAME_IN_USE, //!< The predefined name is already in use
CREATION_RESPONSE_CUSTOM_NAME_IN_USE //!< The custom name is already in use
CREATION_RESPONSE_SUCCESS = 0, //!< The creation was successful
CREATION_RESPONSE_OBJECT_ID_UNAVAILABLE, //!< The Object ID can't be used
CREATION_RESPONSE_NAME_NOT_ALLOWED, //!< The name is not allowed
CREATION_RESPONSE_PREDEFINED_NAME_IN_USE, //!< The predefined name is already in use
CREATION_RESPONSE_CUSTOM_NAME_IN_USE //!< The custom name is already in use
};
//! An enum for login responses
@@ -234,21 +236,21 @@ enum eLoginResponse : uint8_t {
//! An enum for character rename responses
enum eRenameResponse : uint8_t {
RENAME_RESPONSE_SUCCESS = 0, //!< The renaming was successful
RENAME_RESPONSE_UNKNOWN_ERROR, //!< There was an unknown error
RENAME_RESPONSE_NAME_UNAVAILABLE, //!< The name is unavailable
RENAME_RESPONSE_NAME_IN_USE //!< The name is already in use
RENAME_RESPONSE_SUCCESS = 0, //!< The renaming was successful
RENAME_RESPONSE_UNKNOWN_ERROR, //!< There was an unknown error
RENAME_RESPONSE_NAME_UNAVAILABLE, //!< The name is unavailable
RENAME_RESPONSE_NAME_IN_USE //!< The name is already in use
};
//! A replica packet type
enum eReplicaPacketType {
PACKET_TYPE_CONSTRUCTION, //!< A construction packet
PACKET_TYPE_SERIALIZATION, //!< A serialization packet
PACKET_TYPE_DESTRUCTION //!< A destruction packet
PACKET_TYPE_CONSTRUCTION, //!< A construction packet
PACKET_TYPE_SERIALIZATION, //!< A serialization packet
PACKET_TYPE_DESTRUCTION //!< A destruction packet
};
enum ServerDisconnectIdentifiers {
SERVER_DISCON_UNKNOWN_SERVER_ERROR = 0, //!< Unknown server error
SERVER_DISCON_UNKNOWN_SERVER_ERROR = 0, //!< Unknown server error
SERVER_DISCON_DUPLICATE_LOGIN = 4, //!< Used when another user with the same username is logged in (duplicate login)
SERVER_DISCON_SERVER_SHUTDOWN = 5, //!< Used when the server is shutdown
SERVER_DISCON_SERVER_MAP_LOAD_FAILURE = 6, //!< Used when the server cannot load a map
@@ -263,80 +265,80 @@ enum ServerDisconnectIdentifiers {
//! The Behavior Types for use with the AI system
enum eCombatBehaviorTypes : uint32_t {
PASSIVE = 0, //!< The object is passive
AGGRESSIVE = 1, //!< The object is aggressive
PASSIVE_TURRET = 2, //!< The object is a passive turret
AGGRESSIVE_TURRET = 3 //!< The object is an aggressive turret
PASSIVE = 0, //!< The object is passive
AGGRESSIVE = 1, //!< The object is aggressive
PASSIVE_TURRET = 2, //!< The object is a passive turret
AGGRESSIVE_TURRET = 3 //!< The object is an aggressive turret
};
//! The Combat Role Type for use with the AI system
enum eCombatRoleType : uint32_t {
MELEE = 0, //!< Used for melee attacks
RANGED = 1, //!< Used for range attacks
SUPPORT = 2 //!< Used for support
MELEE = 0, //!< Used for melee attacks
RANGED = 1, //!< Used for range attacks
SUPPORT = 2 //!< Used for support
};
//! The kill types for the Die packet
enum eKillType : uint32_t {
VIOLENT,
SILENT
VIOLENT,
SILENT
};
//! The various world states used throughout the server
enum eObjectWorldState {
WORLDSTATE_INWORLD, //!< Probably used when the object is in the world
WORLDSTATE_ATTACHED, //!< Probably used when the object is attached to another object
WORLDSTATE_INVENTORY //!< Probably used when the object is in an inventory
WORLDSTATE_INWORLD, //!< Probably used when the object is in the world
WORLDSTATE_ATTACHED, //!< Probably used when the object is attached to another object
WORLDSTATE_INVENTORY //!< Probably used when the object is in an inventory
};
//! The trigger stats (???)
enum eTriggerStat {
INVALID_STAT, //!< ???
HEALTH, //!< Probably used for health
ARMOR, //!< Probably used for armor
IMAGINATION //!< Probably used for imagination
INVALID_STAT, //!< ???
HEALTH, //!< Probably used for health
ARMOR, //!< Probably used for armor
IMAGINATION //!< Probably used for imagination
};
//! The trigger operations (???)
enum eTriggerOperator {
INVALID_OPER, //!< ???
EQUAL, //!< ???
NOT_EQUAL, //!< ???
GREATER, //!< ???
GREATER_EQUAL, //!< ???
LESS, //!< ???
LESS_EQUAL //!< ???
INVALID_OPER, //!< ???
EQUAL, //!< ???
NOT_EQUAL, //!< ???
GREATER, //!< ???
GREATER_EQUAL, //!< ???
LESS, //!< ???
LESS_EQUAL //!< ???
};
//! The various build types
enum eBuildType {
BUILD_NOWHERE, //!< Used if something can't be built anywhere
BUILD_IN_WORLD, //!< Used if something can be built in the world
BUILD_ON_PROPERTY //!< Used if something can be build on a property
BUILD_NOWHERE, //!< Used if something can't be built anywhere
BUILD_IN_WORLD, //!< Used if something can be built in the world
BUILD_ON_PROPERTY //!< Used if something can be build on a property
};
//! Quickbuild fail reasons
enum eFailReason : uint32_t {
REASON_NOT_GIVEN,
REASON_OUT_OF_IMAGINATION,
REASON_CANCELED_EARLY,
REASON_BUILD_ENDED
REASON_NOT_GIVEN,
REASON_OUT_OF_IMAGINATION,
REASON_CANCELED_EARLY,
REASON_BUILD_ENDED
};
//! Terminate interaction type
enum eTerminateType : uint32_t {
RANGE,
USER,
FROM_INTERACTION
RANGE,
USER,
FROM_INTERACTION
};
//! The combat state
enum eCombatState {
IDLE, //!< The AI is in an idle state
AGGRO, //!< The AI is in an aggressive state
TETHER, //!< The AI is being redrawn back to tether point
SPAWN, //!< The AI is spawning
DEAD //!< The AI is dead
IDLE, //!< The AI is in an idle state
AGGRO, //!< The AI is in an aggressive state
TETHER, //!< The AI is being redrawn back to tether point
SPAWN, //!< The AI is spawning
DEAD //!< The AI is dead
};
enum eControlSceme {
@@ -348,7 +350,7 @@ enum eControlSceme {
SCHEME_DRIVING,
SCHEME_TAMING,
SCHEME_MODULAR_BUILD,
SCHEME_WEAR_A_ROBOT //== freecam?
SCHEME_WEAR_A_ROBOT //== freecam?
};
enum eStunState {
@@ -357,110 +359,90 @@ enum eStunState {
};
enum eNotifyType {
NOTIFY_TYPE_SUCCESS,
NOTIFY_TYPE_QUIT,
NOTIFY_TYPE_FAILED,
NOTIFY_TYPE_BEGIN,
NOTIFY_TYPE_READY,
NOTIFY_TYPE_NAMINGPET
NOTIFY_TYPE_SUCCESS,
NOTIFY_TYPE_QUIT,
NOTIFY_TYPE_FAILED,
NOTIFY_TYPE_BEGIN,
NOTIFY_TYPE_READY,
NOTIFY_TYPE_NAMINGPET
};
enum eReplicaComponentType : int32_t {
COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1, //!< The ControllablePhysics Component
COMPONENT_TYPE_RENDER = 2, //!< The Render Component
COMPONENT_TYPE_SIMPLE_PHYSICS = 3, //!< The SimplePhysics Component
COMPONENT_TYPE_CHARACTER = 4, //!< The Character Component
COMPONENT_TYPE_SCRIPT = 5, //!< The Script Component
COMPONENT_TYPE_BOUNCER = 6, //!< The Bouncer Component
COMPONENT_TYPE_BUFF = 7, //!< The Buff Component
COMPONENT_TYPE_SKILL = 9, //!< The Skill Component
COMPONENT_TYPE_ITEM = 11, //!< The Item Component
COMPONENT_TYPE_VENDOR = 16, //!< The Vendor Component
COMPONENT_TYPE_INVENTORY = 17, //!< The Inventory Component
COMPONENT_TYPE_SHOOTING_GALLERY = 19, //!< The Shooting Gallery Component
COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20, //!< The RigidBodyPhantomPhysics Component
COMPONENT_TYPE_COLLECTIBLE = 23, //!< The Collectible Component
COMPONENT_TYPE_MOVING_PLATFORM = 25, //!< The MovingPlatform Component
COMPONENT_TYPE_PET = 26, //!< The Pet Component
COMPONENT_TYPE_VEHICLE_PHYSICS = 30, //!< The VehiclePhysics Component
COMPONENT_TYPE_MOVEMENT_AI = 31, //!< The MovementAI Component
COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component
COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component
COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component
COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component
COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component
COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component
COMPONENT_TYPE_SWITCH = 49, //!< The Switch Component
COMPONENT_TYPE_ZONE_CONTROL = 50, //!< The ZoneControl Component
COMPONENT_TYPE_PACKAGE = 53, //!< The Package Component
COMPONENT_TYPE_PLAYER_FLAG = 58, //!< The PlayerFlag Component
COMPONENT_TYPE_BASE_COMBAT_AI = 60, //!< The BaseCombatAI Component
COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component
COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component
COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component
COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component
COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component
COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component
COMPONENT_TYPE_RACING_STATS = 74, //!< The Exhibit Component
COMPONENT_TYPE_SOUND_TRIGGER = 77, //!< The Sound Trigger Component
COMPONENT_TYPE_PROXIMITY_MONITOR = 78, //!< The Proximity Monitor Component
COMPONENT_TYPE_MISSION = 84, //!< The Mission Component
COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen
COMPONENT_TYPE_RAIL_ACTIVATOR = 104,
COMPONENT_TYPE_POSSESSOR = 107, //!< The Component 107
COMPONENT_TYPE_POSSESSABLE = 108, //!< The Component 108
COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component
COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component
COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1, //!< The ControllablePhysics Component
COMPONENT_TYPE_RENDER = 2, //!< The Render Component
COMPONENT_TYPE_SIMPLE_PHYSICS = 3, //!< The SimplePhysics Component
COMPONENT_TYPE_CHARACTER = 4, //!< The Character Component
COMPONENT_TYPE_SCRIPT = 5, //!< The Script Component
COMPONENT_TYPE_BOUNCER = 6, //!< The Bouncer Component
COMPONENT_TYPE_BUFF = 7, //!< The Buff Component
COMPONENT_TYPE_SKILL = 9, //!< The Skill Component
COMPONENT_TYPE_ITEM = 11, //!< The Item Component
COMPONENT_TYPE_VENDOR = 16, //!< The Vendor Component
COMPONENT_TYPE_INVENTORY = 17, //!< The Inventory Component
COMPONENT_TYPE_SHOOTING_GALLERY = 19, //!< The Shooting Gallery Component
COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20, //!< The RigidBodyPhantomPhysics Component
COMPONENT_TYPE_COLLECTIBLE = 23, //!< The Collectible Component
COMPONENT_TYPE_MOVING_PLATFORM = 25, //!< The MovingPlatform Component
COMPONENT_TYPE_PET = 26, //!< The Pet Component
COMPONENT_TYPE_VEHICLE_PHYSICS = 30, //!< The VehiclePhysics Component
COMPONENT_TYPE_MOVEMENT_AI = 31, //!< The MovementAI Component
COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component
COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component
COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component
COMPONENT_TYPE_MODEL = 42, //!< The Model Component
COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component
COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component
COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component
COMPONENT_TYPE_SWITCH = 49, //!< The Switch Component
COMPONENT_TYPE_ZONE_CONTROL = 50, //!< The ZoneControl Component
COMPONENT_TYPE_PACKAGE = 53, //!< The Package Component
COMPONENT_TYPE_PLAYER_FLAG = 58, //!< The PlayerFlag Component
COMPONENT_TYPE_BASE_COMBAT_AI = 60, //!< The BaseCombatAI Component
COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component
COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component
COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component
COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component
COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component
COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component
COMPONENT_TYPE_RACING_STATS = 74, //!< The Racing Stats Component
COMPONENT_TYPE_SOUND_TRIGGER = 77, //!< The Sound Trigger Component
COMPONENT_TYPE_PROXIMITY_MONITOR = 78, //!< The Proximity Monitor Component
COMPONENT_TYPE_MISSION = 84, //!< The Mission Component
COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen
COMPONENT_TYPE_RAIL_ACTIVATOR = 104, //!< The Rail Activator Component
COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT = 106, //!< The Player Forced Movement Component
COMPONENT_TYPE_POSSESSABLE = 108, //!< The Possessable Component
COMPONENT_TYPE_LEVEL_PROGRESSION = 109, //!< The Level Progression Component
COMPONENT_TYPE_POSSESSOR = 110, //!< The Possessor Component
COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component
COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component
};
COMPONENT_TYPE_MODEL = 5398484 //look man idk
enum class UseItemResponse : uint32_t {
NoImaginationForPet = 1,
FailedPrecondition,
MountsNotAllowed
};
/**
* Represents the different types of inventories an entity may have
*/
enum eInventoryType : uint32_t {
ITEMS = 0,
VAULT_ITEMS,
BRICKS,
TEMP_ITEMS = 4,
MODELS,
TEMP_MODELS,
BEHAVIORS,
PROPERTY_DEEDS,
ITEMS = 0,
VAULT_ITEMS,
BRICKS,
TEMP_ITEMS = 4,
MODELS,
TEMP_MODELS,
BEHAVIORS,
PROPERTY_DEEDS,
VENDOR_BUYBACK = 11,
HIDDEN = 12, //Used for missional items
VAULT_MODELS = 14,
HIDDEN = 12, //Used for missional items
VAULT_MODELS = 14,
ITEM_SETS, //internal
INVALID // made up, for internal use!!!
};
enum eItemType : int32_t {
ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type
ITEM_TYPE_BRICK = 1, //!< A brick
ITEM_TYPE_HAT = 2, //!< A hat / head item
ITEM_TYPE_HAIR = 3, //!< A hair item
ITEM_TYPE_NECK = 4, //!< A neck item
ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item
ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item
ITEM_TYPE_LEGS = 7, //!< A pants item
ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item
ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item
ITEM_TYPE_BEHAVIOR = 10, //!< A behavior
ITEM_TYPE_PROPERTY = 11, //!< A property
ITEM_TYPE_MODEL = 12, //!< A model
ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item
ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item
ITEM_TYPE_CHEST = 15, //!< A chest item
ITEM_TYPE_EGG = 16, //!< An egg
ITEM_TYPE_PET_FOOD = 17, //!< A pet food item
ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item
ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item
ITEM_TYPE_PACKAGE = 20, //!< A package
ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model
ITEM_TYPE_VEHICLE = 22, //!< A vehicle
ITEM_TYPE_CURRENCY = 23 //!< Currency
};
enum eRebuildState : uint32_t {
REBUILD_OPEN,
REBUILD_COMPLETED = 2,
@@ -469,6 +451,34 @@ enum eRebuildState : uint32_t {
REBUILD_INCOMPLETE
};
/**
* The loot source's type.
*/
enum eLootSourceType : int32_t {
LOOT_SOURCE_NONE = 0,
LOOT_SOURCE_CHEST,
LOOT_SOURCE_MISSION,
LOOT_SOURCE_MAIL,
LOOT_SOURCE_CURRENCY,
LOOT_SOURCE_ACHIEVEMENT,
LOOT_SOURCE_TRADE,
LOOT_SOURCE_QUICKBUILD,
LOOT_SOURCE_DELETION,
LOOT_SOURCE_VENDOR,
LOOT_SOURCE_ACTIVITY,
LOOT_SOURCE_PICKUP,
LOOT_SOURCE_BRICK,
LOOT_SOURCE_PROPERTY,
LOOT_SOURCE_MODERATION,
LOOT_SOURCE_EXHIBIT,
LOOT_SOURCE_INVENTORY,
LOOT_SOURCE_CLAIMCODE,
LOOT_SOURCE_CONSUMPTION,
LOOT_SOURCE_CRAFTING,
LOOT_SOURCE_LEVEL_REWARD,
LOOT_SOURCE_RELOCATE
};
enum eGameActivities : uint32_t {
ACTIVITY_NONE,
ACTIVITY_QUICKBUILDING,
@@ -534,7 +544,7 @@ enum ePlayerFlags {
TOOLTIP_TALK_TO_SKYLAND_TO_GET_HAT = 52,
MODULAR_BUILD_PLAYER_PLACES_FIRST_MODEL_IN_SCRATCH = 53,
MODULAR_BUILD_FIRST_ARROW_DISPLAY_FOR_MODULE = 54,
AG_BEACON_QB,_SO_THE_PLAYER_CAN_ALWAYS_BUILD_THEM = 55,
AG_BEACON_QB_SO_THE_PLAYER_CAN_ALWAYS_BUILD_THEM = 55,
GF_PET_DIG_FLAG_1 = 56,
GF_PET_DIG_FLAG_2 = 57,
GF_PET_DIG_FLAG_3 = 58,
@@ -546,7 +556,7 @@ enum ePlayerFlags {
ENTER_BBB_FROM_PROPERTY_EDIT_CONFIRMATION_DIALOG = 64,
AG_FIRST_COMBAT_COMPLETE = 65,
AG_COMPLETE_BOB_MISSION = 66,
NJ_GARMADON_CINEMATIC_SEEN = 125,
NJ_GARMADON_CINEMATIC_SEEN = 125,
ELEPHANT_PET_3050 = 801,
CAT_PET_3054 = 802,
TRICERATOPS_PET_3195 = 803,
@@ -620,23 +630,23 @@ enum ePlayerFlags {
GF_BINOC_IN_CROC_AREA = 1308,
GF_BINOC_IN_JAIL_AREA = 1309,
GF_BINOC_TELESCOPE_NEXT_TO_CAPTAIN_JACK = 1310,
NT_PLINTH_REBUILD = 1919,
NT_FACTION_SPY_DUKE = 1974,
NT_FACTION_SPY_OVERBUILD = 1976,
NT_FACTION_SPY_HAEL = 1977,
NJ_EARTH_SPINJITZU = 2030,
NJ_LIGHTNING_SPINJITZU = 2031,
NJ_ICE_SPINJITZU = 2032,
NJ_FIRE_SPINJITZU = 2033,
NJ_WU_SHOW_DAILY_CHEST = 2099
NJ_EARTH_SPINJITZU = 2030,
NJ_LIGHTNING_SPINJITZU = 2031,
NJ_ICE_SPINJITZU = 2032,
NJ_FIRE_SPINJITZU = 2033,
NJ_WU_SHOW_DAILY_CHEST = 2099
};
//======== FUNC ===========
template<typename T>
inline T const& clamp(const T& val, const T& low, const T& high) {
if (val < low) return low;
else if (val > high) return high;
return val;
if (val < low) return low;
else if (val > high) return high;
return val;
}

View File

@@ -12,7 +12,7 @@ dConfig::dConfig(const std::string& filepath) {
if (line[0] != '#') ProcessLine(line);
}
}
}
}
dConfig::~dConfig(void) {
}
@@ -31,15 +31,15 @@ void dConfig::ProcessLine(const std::string& line) {
std::vector<std::string> seglist;
while (std::getline(ss, segment, '=')) {
seglist.push_back(segment);
seglist.push_back(segment);
}
if (seglist.size() != 2) return;
//Make sure that on Linux, we remove special characters:
if (!seglist[1].empty() && seglist[1][seglist[1].size() - 1] == '\r')
seglist[1].erase(seglist[1].size() - 1);
seglist[1].erase(seglist[1].size() - 1);
m_Keys.push_back(seglist[0]);
m_Values.push_back(seglist[1]);
}
}

View File

@@ -17,4 +17,4 @@ private:
std::vector<std::string> m_Keys;
std::vector<std::string> m_Values;
std::string m_EmptyString;
};
};

View File

@@ -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
@@ -9,7 +10,7 @@ dLogger::dLogger(const std::string& outpath, bool logToConsole) {
if (!mFile) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
#else
fp = fopen(outpath.c_str(), "wt");
if (fp == NULL) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
if (fp == NULL) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
#endif
}
@@ -24,114 +25,80 @@ dLogger::~dLogger() {
#endif
}
void dLogger::LogBasic(const std::string & message) {
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];
vsnprintf(message, 2048, format, args);
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);
char message[2048];
vsnprintf(message, 2048, format, args);
if (m_logToConsole) {
fputs("[", stdout);
fputs(timeStr, stdout);
fputs("] ", stdout);
fputs(message, stdout);
}
if (fp != nullptr) {
fputs("[", fp);
fputs(timeStr, fp);
fputs("] ", fp);
fputs(message, fp);
} else {
printf("Logger not initialized!\n");
}
#endif
}
void dLogger::LogBasic(const char* format, ...) {
va_list args;
va_start(args, format);
vLog(format, args);
va_end(args);
}
void dLogger::LogBasic(const std::string& message) {
LogBasic(message.c_str());
}
void dLogger::LogBasic(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::Log(const char* className, const char* format, ...) {
va_list args;
std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n";
va_start(args, format);
vsprintf_s(message, format, args);
vLog(log.c_str(), args);
va_end(args);
if (m_logToConsole) std::cout << "[" << "time machine broke" << "] " << message;
mFile << "[" << "time" << "] " << 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(message, stdout);
}
if (fp != nullptr) {
fputs("[", fp);
fputs(timeStr, fp);
fputs("] ", fp);
fputs(message, fp);
} else {
printf("Logger not initialized!\n");
}
#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];
va_list args;
va_start(args, format);
vsprintf_s(message, 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::Log(const std::string & className, const std::string & message) {
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();

View File

@@ -7,27 +7,32 @@
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;
#ifndef _WIN32
//Glorious linux can run with SPEED:
FILE* fp = nullptr;
#endif
};
#ifndef _WIN32
//Glorious linux can run with SPEED:
FILE* fp = nullptr;
#endif
};

29
dCommon/dPlatforms.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#if defined(_WIN32)
#define DARKFLAME_PLATFORM_WIN32
#elif defined(__APPLE__) && defined(__MACH__)
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define DARKFLAME_PLATFORM_IOS
#elif TARGET_OS_MAC
#define DARKFLAME_PLATFORM_MACOS
#else
#error unknown Apple operating system
#endif
#elif defined(__unix__)
#define DARKFLAME_PLATFORM_UNIX
#if defined(__ANDROID__)
#define DARKFLAME_PLATFORM_ANDROID
#elif defined(__linux__)
#define DARKFLAME_PLATFORM_LINUX
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define DARKFLAME_PLATFORM_FREEBSD
#elif defined(__CYGWIN__)
#define DARKFLAME_PLATFORM_CYGWIN
#else
#error unknown unix operating system
#endif
#else
#error unknown operating system
#endif

View File

@@ -0,0 +1,44 @@
#pragma once
#ifndef __EANINMATIONFLAGS__H__
#define __EANINMATIONFLAGS__H__
#include <cstdint>
enum class eAnimationFlags : uint32_t {
IDLE_INVALID = 0, // made up, for internal use!!!
IDLE_BASIC,
IDLE_SWIM,
IDLE_CARRY,
IDLE_SWORD,
IDLE_HAMMER,
IDLE_SPEAR,
IDLE_PISTOL,
IDLE_BOW,
IDLE_COMBAT,
IDLE_JETPACK,
IDLE_HORSE,
IDLE_SG,
IDLE_ORGAN,
IDLE_SKATEBOARD,
IDLE_DAREDEVIL,
IDLE_SAMURAI,
IDLE_SUMMONER,
IDLE_BUCCANEER,
IDLE_MISC,
IDLE_NINJA,
IDLE_MISC1,
IDLE_MISC2,
IDLE_MISC3,
IDLE_MISC4,
IDLE_MISC5,
IDLE_MISC6,
IDLE_MISC7,
IDLE_MISC8,
IDLE_MISC9,
IDLE_MISC10,
IDLE_MISC11,
IDLE_MISC12
};
#endif //!__EANINMATIONFLAGS__H__

36
dCommon/eItemType.h Normal file
View File

@@ -0,0 +1,36 @@
#pragma once
#ifndef __EITEMTYPE__H__
#define __EITEMTYPE__H__
#include <cstdint>
enum class eItemType : int32_t {
ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type
ITEM_TYPE_BRICK = 1, //!< A brick
ITEM_TYPE_HAT = 2, //!< A hat / head item
ITEM_TYPE_HAIR = 3, //!< A hair item
ITEM_TYPE_NECK = 4, //!< A neck item
ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item
ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item
ITEM_TYPE_LEGS = 7, //!< A pants item
ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item
ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item
ITEM_TYPE_BEHAVIOR = 10, //!< A behavior
ITEM_TYPE_PROPERTY = 11, //!< A property
ITEM_TYPE_MODEL = 12, //!< A model
ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item
ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item
ITEM_TYPE_CHEST = 15, //!< A chest item
ITEM_TYPE_EGG = 16, //!< An egg
ITEM_TYPE_PET_FOOD = 17, //!< A pet food item
ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item
ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item
ITEM_TYPE_PACKAGE = 20, //!< A package
ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model
ITEM_TYPE_VEHICLE = 22, //!< A vehicle
ITEM_TYPE_CURRENCY = 23, //!< Currency
ITEM_TYPE_MOUNT = 24 //!< A Mount
};
#endif //!__EITEMTYPE__H__

View File

@@ -0,0 +1,14 @@
#pragma once
#ifndef __EUNEQUIPPABLEACTIVETYPE__H__
#define __EUNEQUIPPABLEACTIVETYPE__H__
#include <cstdint>
enum class eUnequippableActiveType : int32_t {
INVALID = -1,
PET = 0,
MOUNT
};
#endif //!__EUNEQUIPPABLEACTIVETYPE__H__

View File

@@ -2,14 +2,19 @@
#include "CDComponentsRegistryTable.h"
// Static Variables
static CppSQLite3DB * conn = new CppSQLite3DB();
static CppSQLite3DB* conn = new CppSQLite3DB();
//! Opens a connection with the CDClient
void CDClientDatabase::Connect(const std::string& filename) {
conn->open(filename.c_str());
conn->open(filename.c_str());
}
//! Queries the CDClient
CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) {
return conn->execQuery(query.c_str());
return conn->execQuery(query.c_str());
}
//! Makes prepared statements
CppSQLite3Statement CDClientDatabase::CreatePreppedStmt(const std::string& query) {
return conn->compileStatement(query.c_str());
}

View File

@@ -13,10 +13,10 @@
#include <sstream>
#include <iostream>
// Enable this to cache all entries in each table for fast access, comes with more memory cost
//#define CDCLIENT_CACHE_ALL
// Enable this to cache all entries in each table for fast access, comes with more memory cost
//#define CDCLIENT_CACHE_ALL
// Enable this to skip some unused columns in some tables
// Enable this to skip some unused columns in some tables
#define UNUSED(v)
/*!
@@ -24,20 +24,26 @@
\brief An interface between the CDClient.sqlite file and the server
*/
//! The CDClient Database namespace
//! The CDClient Database namespace
namespace CDClientDatabase {
//! Opens a connection with the CDClient
/*!
\param filename The filename
*/
void Connect(const std::string& filename);
//! Queries the CDClient
/*!
\param query The query
\return The results of the query
*/
CppSQLite3Query ExecuteQuery(const std::string& query);
//! Opens a connection with the CDClient
/*!
\param filename The filename
*/
void Connect(const std::string& filename);
//! Queries the CDClient
/*!
\param query The query
\return The results of the query
*/
CppSQLite3Query ExecuteQuery(const std::string& query);
//! Queries the CDClient and parses arguments
/*!
\param query The query with formatted arguments
\return prepared SQLite Statement
*/
CppSQLite3Statement CreatePreppedStmt(const std::string& query);
};

View File

@@ -1,14 +1,14 @@
#include "CDClientManager.h"
// Static Variables
CDClientManager * CDClientManager::m_Address = nullptr;
CDClientManager* CDClientManager::m_Address = nullptr;
//! Initializes the manager
void CDClientManager::Initialize(void) {
tables.insert(std::make_pair("ActivityRewards", new CDActivityRewardsTable()));
UNUSED(tables.insert(std::make_pair("Animations", new CDAnimationsTable())));
tables.insert(std::make_pair("BehaviorParameter", new CDBehaviorParameterTable()));
UNUSED(tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable())));
tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable()));
tables.insert(std::make_pair("ComponentsRegistry", new CDComponentsRegistryTable()));
tables.insert(std::make_pair("CurrencyTable", new CDCurrencyTableTable()));
tables.insert(std::make_pair("DestructibleComponent", new CDDestructibleComponentTable()));

View File

@@ -52,45 +52,45 @@
\brief A manager for the CDClient tables
*/
//! Manages all data from the CDClient
//! Manages all data from the CDClient
class CDClientManager {
private:
static CDClientManager * m_Address; //!< The singleton address
std::unordered_map<std::string, CDTable*> tables; //!< The tables
static CDClientManager* m_Address; //!< The singleton address
std::unordered_map<std::string, CDTable*> tables; //!< The tables
public:
//! The singleton method
static CDClientManager * Instance() {
if (m_Address == 0) {
m_Address = new CDClientManager;
}
return m_Address;
}
//! Initializes the manager
void Initialize(void);
//! Fetches a CDClient table
/*!
This function uses typename T which must be a subclass of CDTable.
It returns the class that conforms to the class name
\param tableName The table name
\return The class or nullptr
*/
template<typename T>
T * GetTable(const std::string& tableName) {
static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!");
for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) {
if (itr->first == tableName) {
return dynamic_cast<T*>(itr->second);
}
}
return nullptr;
}
//! The singleton method
static CDClientManager* Instance() {
if (m_Address == 0) {
m_Address = new CDClientManager;
}
return m_Address;
}
//! Initializes the manager
void Initialize(void);
//! Fetches a CDClient table
/*!
This function uses typename T which must be a subclass of CDTable.
It returns the class that conforms to the class name
\param tableName The table name
\return The class or nullptr
*/
template<typename T>
T* GetTable(const std::string& tableName) {
static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!");
for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) {
if (itr->first == tableName) {
return dynamic_cast<T*>(itr->second);
}
}
return nullptr;
}
};

13
dDatabase/CMakeLists.txt Normal file
View File

@@ -0,0 +1,13 @@
set(DDATABASE_SOURCES "CDClientDatabase.cpp"
"CDClientManager.cpp"
"Database.cpp"
"MigrationRunner.cpp")
add_subdirectory(Tables)
foreach(file ${DDATABASE_TABLES_SOURCES})
set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "Tables/${file}")
endforeach()
add_library(dDatabase STATIC ${DDATABASE_SOURCES})
target_link_libraries(dDatabase sqlite3 mariadbConnCpp)

View File

@@ -6,11 +6,12 @@ using namespace std;
#pragma warning (disable:4251) //Disables SQL warnings
sql::Driver * Database::driver;
sql::Connection * Database::con;
sql::Driver* Database::driver;
sql::Connection* Database::con;
sql::Properties Database::props;
std::string Database::database;
void Database::Connect(const string& host, const string& database, const string& username, const string& password) {
driver = get_driver_instance();
//To bypass debug issues:
std::string newHost = "tcp://" + host;
@@ -19,16 +20,33 @@ void Database::Connect(const string& host, const string& database, const string&
const char* szUsername = username.c_str();
const char* szPassword = password.c_str();
con = driver->connect(szHost, szUsername, szPassword);
con->setSchema(szDatabase);
driver = sql::mariadb::get_driver_instance();
bool myTrue = true;
con->setClientOption("MYSQL_OPT_RECONNECT", &myTrue);
} //Connect
sql::Properties properties;
properties["hostName"] = szHost;
properties["user"] = szUsername;
properties["password"] = szPassword;
properties["autoReconnect"] = "true";
void Database::Destroy() {
Database::props = properties;
Database::database = database;
Database::Connect();
}
void Database::Connect() {
con = driver->connect(Database::props);
con->setSchema(Database::database);
}
void Database::Destroy(std::string source, bool log) {
if (!con) return;
cout << "Destroying MySQL connection!" << endl;
if (log) {
if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!", source.c_str());
else Game::logger->Log("Database", "Destroying MySQL connection!");
}
con->close();
delete con;
} //Destroy
@@ -44,33 +62,24 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
sql::SQLString str(test, size);
if (!con) {
//Connect to the MySQL Database
std::string mysql_host = Game::config->GetValue("mysql_host");
std::string mysql_database = Game::config->GetValue("mysql_database");
std::string mysql_username = Game::config->GetValue("mysql_username");
std::string mysql_password = Game::config->GetValue("mysql_password");
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
Game::logger->Log("Database", "Trying to reconnect to MySQL\n");
Connect();
Game::logger->Log("Database", "Trying to reconnect to MySQL");
}
if (!con->isValid() || con->isClosed())
{
if (!con->isValid() || con->isClosed()) {
delete con;
con = nullptr;
//Connect to the MySQL Database
std::string mysql_host = Game::config->GetValue("mysql_host");
std::string mysql_database = Game::config->GetValue("mysql_database");
std::string mysql_username = Game::config->GetValue("mysql_username");
std::string mysql_password = Game::config->GetValue("mysql_password");
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection\n");
Connect();
Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection");
}
auto* stmt = con->prepareStatement(str);
return stmt;
} //CreatePreppedStmt
} //CreatePreppedStmt
void Database::Commit() {
Database::con->commit();
}

View File

@@ -1,13 +1,7 @@
#pragma once
#include <string>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/sqlstring.h>
#include <conncpp.hpp>
class MySqlException : public std::runtime_error {
public:
@@ -17,12 +11,19 @@ public:
class Database {
private:
static sql::Driver *driver;
static sql::Connection *con;
static sql::Driver* driver;
static sql::Connection* con;
static sql::Properties props;
static std::string database;
public:
static void Connect(const std::string& host, const std::string& database, const std::string& username, const std::string& password);
static void Destroy();
static void Connect();
static void Destroy(std::string source = "", bool log = true);
static sql::Statement* CreateStmt();
static sql::PreparedStatement* CreatePreppedStmt(const std::string& query);
static void Commit();
static std::string GetDatabase() { return database; }
static sql::Properties GetProperties() { return props; }
};

View File

@@ -0,0 +1,77 @@
#include "MigrationRunner.h"
#include "GeneralUtils.h"
#include <fstream>
#include <algorithm>
#include <thread>
void MigrationRunner::RunMigrations() {
auto stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());");
stmt->executeQuery();
delete stmt;
sql::SQLString finalSQL = "";
Migration checkMigration{};
for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/")) {
auto migration = LoadMigration(entry);
if (migration.data.empty()) {
continue;
}
checkMigration = migration;
stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;");
stmt->setString(1, migration.name);
auto res = stmt->executeQuery();
bool doExit = res->next();
delete res;
delete stmt;
if (doExit) continue;
Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str());
finalSQL.append(migration.data);
finalSQL.append('\n');
stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);");
stmt->setString(1, entry);
stmt->execute();
delete stmt;
}
if (!finalSQL.empty()) {
try {
auto simpleStatement = Database::CreateStmt();
simpleStatement->execute(finalSQL);
delete simpleStatement;
} catch (sql::SQLException e) {
Game::logger->Log("MigrationRunner", "Encountered error running migration: %s", e.what());
}
}
}
Migration MigrationRunner::LoadMigration(std::string path) {
Migration migration{};
std::ifstream file("./migrations/" + path);
if (file.is_open()) {
std::hash<std::string> hash;
std::string line;
std::string total = "";
while (std::getline(file, line)) {
total += line;
}
file.close();
migration.name = path;
migration.data = total;
}
return migration;
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "Database.h"
#include "dCommonVars.h"
#include "Game.h"
#include "dCommonVars.h"
#include "dLogger.h"
struct Migration {
std::string data;
std::string name;
};
class MigrationRunner {
public:
static void RunMigrations();
static Migration LoadMigration(std::string path);
};

View File

@@ -49,7 +49,7 @@ CDActivitiesTable::CDActivitiesTable(void) {
}
//! Destructor
CDActivitiesTable::~CDActivitiesTable(void) { }
CDActivitiesTable::~CDActivitiesTable(void) {}
//! Returns the table's name
std::string CDActivitiesTable::GetName(void) const {

View File

@@ -2,59 +2,59 @@
//! Constructor
CDActivityRewardsTable::CDActivityRewardsTable(void) {
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
while (!tableData.eof()) {
CDActivityRewards entry;
entry.objectTemplate = tableData.getIntField(0, -1);
entry.ActivityRewardIndex = tableData.getIntField(1, -1);
entry.activityRating = tableData.getIntField(2, -1);
entry.LootMatrixIndex = tableData.getIntField(3, -1);
entry.CurrencyIndex = tableData.getIntField(4, -1);
entry.ChallengeRating = tableData.getIntField(5, -1);
entry.description = tableData.getStringField(6, "");
this->entries.push_back(entry);
tableData.nextRow();
}
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
while (!tableData.eof()) {
CDActivityRewards entry;
entry.objectTemplate = tableData.getIntField(0, -1);
entry.ActivityRewardIndex = tableData.getIntField(1, -1);
entry.activityRating = tableData.getIntField(2, -1);
entry.LootMatrixIndex = tableData.getIntField(3, -1);
entry.CurrencyIndex = tableData.getIntField(4, -1);
entry.ChallengeRating = tableData.getIntField(5, -1);
entry.description = tableData.getStringField(6, "");
this->entries.push_back(entry);
tableData.nextRow();
}
tableData.finalize();
}
//! Destructor
CDActivityRewardsTable::~CDActivityRewardsTable(void) { }
CDActivityRewardsTable::~CDActivityRewardsTable(void) {}
//! Returns the table's name
std::string CDActivityRewardsTable::GetName(void) const {
return "ActivityRewards";
return "ActivityRewards";
}
//! Queries the table with a custom "where" clause
std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(CDActivityRewards)> predicate) {
std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const {
return this->entries;
return this->entries;
}

View File

@@ -8,47 +8,47 @@
\brief Contains data for the ActivityRewards table
*/
//! ActivityRewards Entry Struct
//! ActivityRewards Entry Struct
struct CDActivityRewards {
unsigned int objectTemplate; //!< The object template (?)
unsigned int ActivityRewardIndex; //!< The activity reward index
int activityRating; //!< The activity rating
unsigned int LootMatrixIndex; //!< The loot matrix index
unsigned int CurrencyIndex; //!< The currency index
unsigned int ChallengeRating; //!< The challenge rating
std::string description; //!< The description
unsigned int objectTemplate; //!< The object template (?)
unsigned int ActivityRewardIndex; //!< The activity reward index
int activityRating; //!< The activity rating
unsigned int LootMatrixIndex; //!< The loot matrix index
unsigned int CurrencyIndex; //!< The currency index
unsigned int ChallengeRating; //!< The challenge rating
std::string description; //!< The description
};
//! ActivityRewards table
class CDActivityRewardsTable : public CDTable {
private:
std::vector<CDActivityRewards> entries;
std::vector<CDActivityRewards> entries;
public:
//! Constructor
CDActivityRewardsTable(void);
//! Destructor
~CDActivityRewardsTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDActivityRewards> GetEntries(void) const;
//! Constructor
CDActivityRewardsTable(void);
//! Destructor
~CDActivityRewardsTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDActivityRewards> GetEntries(void) const;
};

View File

@@ -2,65 +2,65 @@
//! Constructor
CDAnimationsTable::CDAnimationsTable(void) {
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
while (!tableData.eof()) {
CDAnimations entry;
entry.animationGroupID = tableData.getIntField(0, -1);
entry.animation_type = tableData.getStringField(1, "");
entry.animation_name = tableData.getStringField(2, "");
entry.chance_to_play = tableData.getFloatField(3, -1.0f);
entry.min_loops = tableData.getIntField(4, -1);
entry.max_loops = tableData.getIntField(5, -1);
entry.animation_length = tableData.getFloatField(6, -1.0f);
entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false;
entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false;
entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false;
entry.face_animation_name = tableData.getStringField(10, "");
entry.priority = tableData.getFloatField(11, -1.0f);
entry.blendTime = tableData.getFloatField(12, -1.0f);
this->entries.push_back(entry);
tableData.nextRow();
}
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
while (!tableData.eof()) {
CDAnimations entry;
entry.animationGroupID = tableData.getIntField(0, -1);
entry.animation_type = tableData.getStringField(1, "");
entry.animation_name = tableData.getStringField(2, "");
entry.chance_to_play = tableData.getFloatField(3, -1.0f);
entry.min_loops = tableData.getIntField(4, -1);
entry.max_loops = tableData.getIntField(5, -1);
entry.animation_length = tableData.getFloatField(6, -1.0f);
entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false;
entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false;
entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false;
entry.face_animation_name = tableData.getStringField(10, "");
entry.priority = tableData.getFloatField(11, -1.0f);
entry.blendTime = tableData.getFloatField(12, -1.0f);
this->entries.push_back(entry);
tableData.nextRow();
}
tableData.finalize();
}
//! Destructor
CDAnimationsTable::~CDAnimationsTable(void) { }
CDAnimationsTable::~CDAnimationsTable(void) {}
//! Returns the table's name
std::string CDAnimationsTable::GetName(void) const {
return "Animations";
return "Animations";
}
//! Queries the table with a custom "where" clause
std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimations)> predicate) {
std::vector<CDAnimations> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
std::vector<CDAnimations> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
std::vector<CDAnimations> CDAnimationsTable::GetEntries(void) const {
return this->entries;
return this->entries;
}

View File

@@ -8,53 +8,53 @@
\brief Contains data for the Animations table
*/
//! Animations Entry Struct
//! Animations Entry Struct
struct CDAnimations {
unsigned int animationGroupID; //!< The animation group ID
std::string animation_type; //!< The animation type
std::string animation_name; //!< The animation name
float chance_to_play; //!< The chance to play the animation
unsigned int min_loops; //!< The minimum number of loops
unsigned int max_loops; //!< The maximum number of loops
float animation_length; //!< The animation length
bool hideEquip; //!< Whether or not to hide the equip
bool ignoreUpperBody; //!< Whether or not to ignore the upper body
bool restartable; //!< Whether or not the animation is restartable
std::string face_animation_name; //!< The face animation name
float priority; //!< The priority
float blendTime; //!< The blend time
unsigned int animationGroupID; //!< The animation group ID
std::string animation_type; //!< The animation type
std::string animation_name; //!< The animation name
float chance_to_play; //!< The chance to play the animation
unsigned int min_loops; //!< The minimum number of loops
unsigned int max_loops; //!< The maximum number of loops
float animation_length; //!< The animation length
bool hideEquip; //!< Whether or not to hide the equip
bool ignoreUpperBody; //!< Whether or not to ignore the upper body
bool restartable; //!< Whether or not the animation is restartable
std::string face_animation_name; //!< The face animation name
float priority; //!< The priority
float blendTime; //!< The blend time
};
//! Animations table
class CDAnimationsTable : public CDTable {
private:
std::vector<CDAnimations> entries;
std::vector<CDAnimations> entries;
public:
//! Constructor
CDAnimationsTable(void);
//! Destructor
~CDAnimationsTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDAnimations> Query(std::function<bool(CDAnimations)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDAnimations> GetEntries(void) const;
//! Constructor
CDAnimationsTable(void);
//! Destructor
~CDAnimationsTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDAnimations> Query(std::function<bool(CDAnimations)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDAnimations> GetEntries(void) const;
};

View File

@@ -3,88 +3,67 @@
//! Constructor
CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
#ifdef CDCLIENT_CACHE_ALL
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
while (!tableData.eof()) {
CDBehaviorParameter entry;
entry.behaviorID = tableData.getIntField(0, -1);
entry.parameterID = tableData.getStringField(1, "");
entry.value = tableData.getFloatField(2, -1.0f);
//Check if we have an entry with this ID:
auto it = m_entries.find(entry.behaviorID);
if (it != m_entries.end()) {
it->second.insert(std::make_pair(entry.parameterID, entry.value));
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
size_t hash = 0;
while (!tableData.eof()) {
hash = 0;
CDBehaviorParameter entry;
entry.behaviorID = tableData.getIntField(0, -1);
auto candidateStringToAdd = std::string(tableData.getStringField(1, ""));
auto parameter = m_ParametersList.find(candidateStringToAdd);
if (parameter != m_ParametersList.end()) {
entry.parameterID = parameter;
} else {
entry.parameterID = m_ParametersList.insert(candidateStringToAdd).first;
}
else {
//Otherwise, insert it:
m_entries.insert(std::make_pair(entry.behaviorID, std::map<std::string, float>()));
auto jit = m_entries.find(entry.behaviorID);
entry.value = tableData.getFloatField(2, -1.0f);
//Add our value as well:
jit->second.insert(std::make_pair(entry.parameterID, entry.value));
}
GeneralUtils::hash_combine(hash, entry.behaviorID);
GeneralUtils::hash_combine(hash, *entry.parameterID);
tableData.nextRow();
}
auto it = m_Entries.find(entry.behaviorID);
m_ParametersList.insert(*entry.parameterID);
m_Entries.insert(std::make_pair(hash, entry));
tableData.nextRow();
}
tableData.finalize();
#endif
}
//! Destructor
CDBehaviorParameterTable::~CDBehaviorParameterTable(void) { }
CDBehaviorParameterTable::~CDBehaviorParameterTable(void) {}
//! Returns the table's name
std::string CDBehaviorParameterTable::GetName(void) const {
return "BehaviorParameter";
return "BehaviorParameter";
}
float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name)
{
CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
CDBehaviorParameter returnValue;
returnValue.behaviorID = 0;
returnValue.parameterID = m_ParametersList.end();
returnValue.value = defaultValue;
size_t hash = 0;
GeneralUtils::hash_combine(hash, behaviorID);
GeneralUtils::hash_combine(hash, name);
// Search for specific perameter
// Search for specific parameter
const auto& it = m_Entries.find(hash);
if (it != m_Entries.end()) {
return it->second;
}
// Check if this behavior has already been checked
const auto& itChecked = m_Entries.find(behaviorID);
if (itChecked != m_Entries.end()) {
return itChecked->second;
}
#ifndef CDCLIENT_CACHE_ALL
std::stringstream query;
query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(behaviorID);
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
m_Entries.insert_or_assign(behaviorID, 0);
while (!tableData.eof()) {
const std::string parameterID = tableData.getStringField(0, "");
const float value = tableData.getFloatField(1, 0);
size_t parameterHash = 0;
GeneralUtils::hash_combine(parameterHash, behaviorID);
GeneralUtils::hash_combine(parameterHash, parameterID);
m_Entries.insert_or_assign(parameterHash, value);
tableData.nextRow();
}
const auto& it2 = m_Entries.find(hash);
if (it2 != m_Entries.end()) {
return it2->second;
}
#endif
return 0;
return it != m_Entries.end() ? it->second : returnValue;
}
std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) {
size_t hash;
std::map<std::string, float> returnInfo;
for (auto parameterCandidate : m_ParametersList) {
hash = 0;
GeneralUtils::hash_combine(hash, behaviorID);
GeneralUtils::hash_combine(hash, parameterCandidate);
auto infoCandidate = m_Entries.find(hash);
if (infoCandidate != m_Entries.end()) {
returnInfo.insert(std::make_pair(*(infoCandidate->second.parameterID), infoCandidate->second.value));
}
}
return returnInfo;
}

View File

@@ -2,38 +2,41 @@
// Custom Classes
#include "CDTable.h"
#include <map>
#include <unordered_map>
#include <unordered_set>
/*!
\file CDBehaviorParameterTable.hpp
\brief Contains data for the BehaviorParameter table
*/
//! BehaviorParameter Entry Struct
//! BehaviorParameter Entry Struct
struct CDBehaviorParameter {
unsigned int behaviorID; //!< The Behavior ID
std::string parameterID; //!< The Parameter ID
float value; //!< The value of the behavior template
unsigned int behaviorID; //!< The Behavior ID
std::unordered_set<std::string>::iterator parameterID; //!< The Parameter ID
float value; //!< The value of the behavior template
};
//! BehaviorParameter table
class CDBehaviorParameterTable : public CDTable {
private:
std::map<size_t, float> m_Entries;
std::unordered_map<size_t, CDBehaviorParameter> m_Entries;
std::unordered_set<std::string> m_ParametersList;
public:
//! Constructor
CDBehaviorParameterTable(void);
//! Destructor
~CDBehaviorParameterTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
float GetEntry(const uint32_t behaviorID, const std::string& name);
//! Constructor
CDBehaviorParameterTable(void);
//! Destructor
~CDBehaviorParameterTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
CDBehaviorParameter GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);
std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID);
};

View File

@@ -2,56 +2,76 @@
//! Constructor
CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) {
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
while (!tableData.eof()) {
CDBehaviorTemplate entry;
entry.behaviorID = tableData.getIntField(0, -1);
entry.templateID = tableData.getIntField(1, -1);
entry.effectID = tableData.getIntField(2, -1);
entry.effectHandle = tableData.getStringField(3, "");
this->entries.push_back(entry);
tableData.nextRow();
}
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
while (!tableData.eof()) {
CDBehaviorTemplate entry;
entry.behaviorID = tableData.getIntField(0, -1);
entry.templateID = tableData.getIntField(1, -1);
entry.effectID = tableData.getIntField(2, -1);
auto candidateToAdd = tableData.getStringField(3, "");
auto parameter = m_EffectHandles.find(candidateToAdd);
if (parameter != m_EffectHandles.end()) {
entry.effectHandle = parameter;
} else {
entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first;
}
this->entries.push_back(entry);
this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry));
tableData.nextRow();
}
tableData.finalize();
}
//! Destructor
CDBehaviorTemplateTable::~CDBehaviorTemplateTable(void) { }
CDBehaviorTemplateTable::~CDBehaviorTemplateTable(void) {}
//! Returns the table's name
std::string CDBehaviorTemplateTable::GetName(void) const {
return "BehaviorTemplate";
return "BehaviorTemplate";
}
//! Queries the table with a custom "where" clause
std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<bool(CDBehaviorTemplate)> predicate) {
std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::GetEntries(void) const {
return this->entries;
return this->entries;
}
const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behaviorID) {
auto entry = this->entriesMappedByBehaviorID.find(behaviorID);
if (entry == this->entriesMappedByBehaviorID.end()) {
CDBehaviorTemplate entryToReturn;
entryToReturn.behaviorID = 0;
entryToReturn.effectHandle = m_EffectHandles.end();
entryToReturn.effectID = 0;
return entryToReturn;
} else {
return entry->second;
}
}

View File

@@ -2,50 +2,54 @@
// Custom Classes
#include "CDTable.h"
#include <unordered_map>
#include <unordered_set>
/*!
\file CDBehaviorTemplateTable.hpp
\brief Contains data for the BehaviorTemplate table
*/
//! BehaviorTemplate Entry Struct
//! BehaviorTemplate Entry Struct
struct CDBehaviorTemplate {
unsigned int behaviorID; //!< The Behavior ID
unsigned int templateID; //!< The Template ID (LOT)
unsigned int effectID; //!< The Effect ID attached
std::string effectHandle; //!< The effect handle
unsigned int behaviorID; //!< The Behavior ID
unsigned int templateID; //!< The Template ID (LOT)
unsigned int effectID; //!< The Effect ID attached
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
};
//! BehaviorTemplate table
class CDBehaviorTemplateTable : public CDTable {
private:
std::vector<CDBehaviorTemplate> entries;
std::vector<CDBehaviorTemplate> entries;
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
std::unordered_set<std::string> m_EffectHandles;
public:
//! Constructor
CDBehaviorTemplateTable(void);
//! Destructor
~CDBehaviorTemplateTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDBehaviorTemplate> GetEntries(void) const;
//! Constructor
CDBehaviorTemplateTable(void);
//! Destructor
~CDBehaviorTemplateTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDBehaviorTemplate> GetEntries(void) const;
const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID);
};

View File

@@ -11,9 +11,9 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) {
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
@@ -32,7 +32,7 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) {
}
//! Destructor
CDBrickIDTableTable::~CDBrickIDTableTable(void) { }
CDBrickIDTableTable::~CDBrickIDTableTable(void) {}
//! Returns the table's name
std::string CDBrickIDTableTable::GetName(void) const {

View File

@@ -4,33 +4,33 @@
//! Constructor
CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
#ifdef CDCLIENT_CACHE_ALL
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
//this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
while (!tableData.eof()) {
CDComponentsRegistry entry;
entry.id = tableData.getIntField(0, -1);
entry.component_type = tableData.getIntField(1, -1);
entry.component_id = tableData.getIntField(2, -1);
this->mappedEntries.insert_or_assign(((uint64_t) entry.component_type) << 32 | ((uint64_t) entry.id), entry.component_id);
//this->entries.push_back(entry);
#ifdef CDCLIENT_CACHE_ALL
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
//this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
while (!tableData.eof()) {
CDComponentsRegistry entry;
entry.id = tableData.getIntField(0, -1);
entry.component_type = tableData.getIntField(1, -1);
entry.component_id = tableData.getIntField(2, -1);
this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id);
//this->entries.push_back(entry);
/*
//Darwin's stuff:
@@ -48,27 +48,25 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
}
*/
tableData.nextRow();
}
tableData.nextRow();
}
tableData.finalize();
#endif
}
//! Destructor
CDComponentsRegistryTable::~CDComponentsRegistryTable(void) { }
CDComponentsRegistryTable::~CDComponentsRegistryTable(void) {}
//! Returns the table's name
std::string CDComponentsRegistryTable::GetName(void) const {
return "ComponentsRegistry";
return "ComponentsRegistry";
}
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue)
{
const auto& iter = this->mappedEntries.find(((uint64_t) componentType) << 32 | ((uint64_t) id));
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue) {
const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id));
if (iter == this->mappedEntries.end())
{
if (iter == this->mappedEntries.end()) {
return defaultValue;
}
@@ -85,19 +83,19 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
*/
#ifndef CDCLIENT_CACHE_ALL
// Now get the data
// Now get the data
std::stringstream query;
query << "SELECT * FROM ComponentsRegistry WHERE id = " << std::to_string(id);
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
while (!tableData.eof()) {
CDComponentsRegistry entry;
entry.id = tableData.getIntField(0, -1);
entry.component_type = tableData.getIntField(1, -1);
entry.component_id = tableData.getIntField(2, -1);
//this->entries.push_back(entry);
while (!tableData.eof()) {
CDComponentsRegistry entry;
entry.id = tableData.getIntField(0, -1);
entry.component_type = tableData.getIntField(1, -1);
entry.component_id = tableData.getIntField(2, -1);
//this->entries.push_back(entry);
//Darwin's stuff:
const auto& it = this->mappedEntries.find(entry.id);
@@ -106,15 +104,14 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
if (iter == it->second.end()) {
it->second.insert(std::make_pair(entry.component_type, entry.component_id));
}
}
else {
} else {
std::map<unsigned int, unsigned int> map;
map.insert(std::make_pair(entry.component_type, entry.component_id));
this->mappedEntries.insert(std::make_pair(entry.id, map));
}
tableData.nextRow();
}
tableData.nextRow();
}
tableData.finalize();

View File

@@ -8,33 +8,33 @@
\brief Contains data for the ComponentsRegistry table
*/
//! ComponentsRegistry Entry Struct
//! ComponentsRegistry Entry Struct
struct CDComponentsRegistry {
unsigned int id; //!< The LOT is used as the ID
unsigned int component_type; //!< See ComponentTypes enum for values
unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0
unsigned int id; //!< The LOT is used as the ID
unsigned int component_type; //!< See ComponentTypes enum for values
unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0
};
//! ComponentsRegistry table
class CDComponentsRegistryTable : public CDTable {
private:
//std::vector<CDComponentsRegistry> entries;
std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
public:
//! Constructor
CDComponentsRegistryTable(void);
//! Destructor
~CDComponentsRegistryTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//std::vector<CDComponentsRegistry> entries;
std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
int32_t GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue = 0);
public:
//! Constructor
CDComponentsRegistryTable(void);
//! Destructor
~CDComponentsRegistryTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
int32_t GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue = 0);
};

View File

@@ -2,57 +2,57 @@
//! Constructor
CDCurrencyTableTable::CDCurrencyTableTable(void) {
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
while (!tableData.eof()) {
CDCurrencyTable entry;
entry.currencyIndex = tableData.getIntField(0, -1);
entry.npcminlevel = tableData.getIntField(1, -1);
entry.minvalue = tableData.getIntField(2, -1);
entry.maxvalue = tableData.getIntField(3, -1);
entry.id = tableData.getIntField(4, -1);
this->entries.push_back(entry);
tableData.nextRow();
}
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
while (!tableData.eof()) {
CDCurrencyTable entry;
entry.currencyIndex = tableData.getIntField(0, -1);
entry.npcminlevel = tableData.getIntField(1, -1);
entry.minvalue = tableData.getIntField(2, -1);
entry.maxvalue = tableData.getIntField(3, -1);
entry.id = tableData.getIntField(4, -1);
this->entries.push_back(entry);
tableData.nextRow();
}
tableData.finalize();
}
//! Destructor
CDCurrencyTableTable::~CDCurrencyTableTable(void) { }
CDCurrencyTableTable::~CDCurrencyTableTable(void) {}
//! Returns the table's name
std::string CDCurrencyTableTable::GetName(void) const {
return "CurrencyTable";
return "CurrencyTable";
}
//! Queries the table with a custom "where" clause
std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCurrencyTable)> predicate) {
std::vector<CDCurrencyTable> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
std::vector<CDCurrencyTable> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const {
return this->entries;
return this->entries;
}

View File

@@ -8,44 +8,44 @@
\brief Contains data for the CurrencyTable table
*/
//! CurrencyTable Struct
//! CurrencyTable Struct
struct CDCurrencyTable {
unsigned int currencyIndex; //!< The Currency Index
unsigned int npcminlevel; //!< The minimum level of the npc
unsigned int minvalue; //!< The minimum currency
unsigned int maxvalue; //!< The maximum currency
unsigned int id; //!< The ID of the currency index
unsigned int currencyIndex; //!< The Currency Index
unsigned int npcminlevel; //!< The minimum level of the npc
unsigned int minvalue; //!< The minimum currency
unsigned int maxvalue; //!< The maximum currency
unsigned int id; //!< The ID of the currency index
};
//! CurrencyTable table
class CDCurrencyTableTable : public CDTable {
private:
std::vector<CDCurrencyTable> entries;
std::vector<CDCurrencyTable> entries;
public:
//! Constructor
CDCurrencyTableTable(void);
//! Destructor
~CDCurrencyTableTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDCurrencyTable> GetEntries(void) const;
//! Constructor
CDCurrencyTableTable(void);
//! Destructor
~CDCurrencyTableTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDCurrencyTable> GetEntries(void) const;
};

View File

@@ -2,66 +2,66 @@
//! Constructor
CDDestructibleComponentTable::CDDestructibleComponentTable(void) {
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
// First, get the size of the table
unsigned int size = 0;
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
while (!tableSize.eof()) {
size = tableSize.getIntField(0, 0);
tableSize.nextRow();
}
tableSize.finalize();
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
while (!tableData.eof()) {
CDDestructibleComponent entry;
entry.id = tableData.getIntField(0, -1);
entry.faction = tableData.getIntField(1, -1);
entry.factionList = tableData.getStringField(2, "");
entry.life = tableData.getIntField(3, -1);
entry.imagination = tableData.getIntField(4, -1);
entry.LootMatrixIndex = tableData.getIntField(5, -1);
entry.CurrencyIndex = tableData.getIntField(6, -1);
entry.level = tableData.getIntField(7, -1);
entry.armor = tableData.getFloatField(8, -1.0f);
entry.death_behavior = tableData.getIntField(9, -1);
entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false;
entry.attack_priority = tableData.getIntField(11, -1);
entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false;
entry.difficultyLevel = tableData.getIntField(13, -1);
this->entries.push_back(entry);
tableData.nextRow();
}
// Reserve the size
this->entries.reserve(size);
// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
while (!tableData.eof()) {
CDDestructibleComponent entry;
entry.id = tableData.getIntField(0, -1);
entry.faction = tableData.getIntField(1, -1);
entry.factionList = tableData.getStringField(2, "");
entry.life = tableData.getIntField(3, -1);
entry.imagination = tableData.getIntField(4, -1);
entry.LootMatrixIndex = tableData.getIntField(5, -1);
entry.CurrencyIndex = tableData.getIntField(6, -1);
entry.level = tableData.getIntField(7, -1);
entry.armor = tableData.getFloatField(8, -1.0f);
entry.death_behavior = tableData.getIntField(9, -1);
entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false;
entry.attack_priority = tableData.getIntField(11, -1);
entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false;
entry.difficultyLevel = tableData.getIntField(13, -1);
this->entries.push_back(entry);
tableData.nextRow();
}
tableData.finalize();
}
//! Destructor
CDDestructibleComponentTable::~CDDestructibleComponentTable(void) { }
CDDestructibleComponentTable::~CDDestructibleComponentTable(void) {}
//! Returns the table's name
std::string CDDestructibleComponentTable::GetName(void) const {
return "DestructibleComponent";
return "DestructibleComponent";
}
//! Queries the table with a custom "where" clause
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::function<bool(CDDestructibleComponent)> predicate) {
std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries)
>> cpplinq::where(predicate)
>> cpplinq::to_vector();
return data;
}
//! Gets all the entries in the table
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const {
return this->entries;
return this->entries;
}

View File

@@ -8,53 +8,53 @@
\brief Contains data for the DestructibleComponent table
*/
//! ItemComponent Struct
//! ItemComponent Struct
struct CDDestructibleComponent {
unsigned int id; //!< The component ID from the ComponentsRegistry Table
int faction; //!< The Faction ID of the object
std::string factionList; //!< A list of the faction IDs
int life; //!< The amount of life of the object
unsigned int imagination; //!< The amount of imagination of the object
int LootMatrixIndex; //!< The Loot Matrix Index
int CurrencyIndex; //!< The Currency Index
unsigned int level; //!< ???
float armor; //!< The amount of armor of the object
unsigned int death_behavior; //!< The behavior ID of the death behavior
bool isnpc; //!< Whether or not the object is an NPC
unsigned int attack_priority; //!< ???
bool isSmashable; //!< Whether or not the object is smashable
int difficultyLevel; //!< ???
unsigned int id; //!< The component ID from the ComponentsRegistry Table
int faction; //!< The Faction ID of the object
std::string factionList; //!< A list of the faction IDs
int life; //!< The amount of life of the object
unsigned int imagination; //!< The amount of imagination of the object
int LootMatrixIndex; //!< The Loot Matrix Index
int CurrencyIndex; //!< The Currency Index
unsigned int level; //!< ???
float armor; //!< The amount of armor of the object
unsigned int death_behavior; //!< The behavior ID of the death behavior
bool isnpc; //!< Whether or not the object is an NPC
unsigned int attack_priority; //!< ???
bool isSmashable; //!< Whether or not the object is smashable
int difficultyLevel; //!< ???
};
//! ItemComponent table
class CDDestructibleComponentTable : public CDTable {
private:
std::vector<CDDestructibleComponent> entries;
std::vector<CDDestructibleComponent> entries;
public:
//! Constructor
CDDestructibleComponentTable(void);
//! Destructor
~CDDestructibleComponentTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDDestructibleComponent> GetEntries(void) const;
//! Constructor
CDDestructibleComponentTable(void);
//! Destructor
~CDDestructibleComponentTable(void);
//! Returns the table's name
/*!
\return The table name
*/
std::string GetName(void) const override;
//! Queries the table with a custom "where" clause
/*!
\param predicate The predicate
*/
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
//! Gets all the entries in the table
/*!
\return The entries
*/
std::vector<CDDestructibleComponent> GetEntries(void) const;
};

Some files were not shown because too many files have changed in this diff Show More