mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 13:16:39 +00:00
Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d6bdaa5c6e | |||
| 593127fb7e | |||
| 67df6f62b7 | |||
| 4572dbc426 | |||
| e8cc160572 | |||
| 8c9adca852 | |||
| b53310e23b | |||
| 14f01dc2d7 | |||
| a4d6509e6d | |||
| fc835bfb0e | |||
| 9ec4e5ade0 | |||
| 6b65e93a06 | |||
| a0a28fef04 | |||
| 034feb4ff4 | |||
| 65c14b160e | |||
| c21d47f450 | |||
| 83ea9816b8 | |||
| e3f9b396ab | |||
| 2a6cf8c8e7 | |||
| be567af70d | |||
| 6494fbf916 | |||
| 2cc61ef8c1 | |||
| 5d7a7bb4b2 | |||
| 00f82f43a6 | |||
| d3ca636a70 | |||
| 01855d40df | |||
| 748602b04e | |||
| a97a9a0d1c | |||
| a78c754c0e | |||
| ef214f91e9 | |||
| 04a74df0b2 | |||
| c15bfe12eb | |||
| 5702f7bcd1 | |||
| 9a5bf53e11 | |||
| 69c6a7b89a | |||
| 2f0dbc5d15 | |||
| 93c79817cd | |||
| 3296287d70 | |||
| 774a7fa779 | |||
| 1ff4541a9f | |||
| 3448758c03 | |||
| ff4ccfa98f | |||
| d2c3c14ae0 | |||
| a470931fdd | |||
| 078db3460d | |||
| 0980a780d0 | |||
| 7f01bb509c | |||
| 4bb189cbf4 | |||
| b03e8ff0fb | |||
| 6179b7481e | |||
| 5f68e4a41a | |||
| e103422ca5 | |||
| 0cbfad975d | |||
| 2a20c69c69 | |||
| de2dfc1a7e | |||
| bad631df59 | |||
| e8f1aa253a | |||
| 889e57a5af | |||
| 5cfdeb928e | |||
| 7519b0225e | |||
| 04fdc54522 | |||
| f39155952f | |||
| 5acc181d64 | |||
| 2ae0b7dd3e | |||
| b0d4f095ef | |||
| 7c7a88650b | |||
| afaa8f4100 | |||
| 0d72295cc9 | |||
| 9d4f231619 | |||
| fcb0a47280 | |||
| 1e50f19f7e | |||
| 33bb5aa8e5 | |||
| 6a668f8aa5 | |||
| df499b22ab | |||
| 7bc00cb466 | |||
| 51f6108aab | |||
| c13f9f80d9 | |||
| 443abf9199 | |||
| 1556e05b2f | |||
| 1d645aa5f6 | |||
| 9f42da5bad | |||
| 4a8222f243 | |||
| db4c515853 | |||
| 462656a201 | |||
| ddd98be383 | |||
| 4ad3ebf36a | |||
| b5a2713a3a | |||
| 999fe10d86 | |||
| ce1472db1e | |||
| d6c6b78d8a | |||
| ee6c9a2ad7 | |||
| 3e4767269e | |||
| e0eb145081 | |||
| a6dd65435f | |||
| 26dc05c0dc | |||
| da20a6ab67 | |||
| 3949a31246 | |||
| e898be1ce9 | |||
| 2962575dda | |||
| 6a6045a21c | |||
| 717fe7dc8c | |||
| df69d12c0c | |||
| 99e49cb2ec | |||
| 5ee2856133 | |||
| 4a64048744 | |||
| 2ae795fd61 | |||
| 0829bc08b8 | |||
| 903a385229 | |||
| fafa33e190 | |||
| 90a01f7c53 | |||
| 19434197d4 | |||
| 18b62667f0 | |||
| 8ed7ca977f | |||
| 665e336946 | |||
| ccf8504dec | |||
| d107213fe1 | |||
| c115cbcd6a | |||
| 064ae7ba89 | |||
| 02302802b8 | |||
| 536e248424 | |||
| 5b56a23a8a | |||
| 97edb09fba | |||
| 85f7b10f90 | |||
| 0f49fbcfcd | |||
| e57979c3a8 | |||
| fc7c30977a | |||
| b3fd9dd88a | |||
| 4df9661903 | |||
| 8c363320d8 | |||
| d4afc78982 | |||
| 24de1d948a | |||
| ca0e85b4bc | |||
| 5b24d38d1e | |||
| 4a1d026215 | |||
| 5ef8f8c3a8 | |||
| 384de31989 | |||
| 5be3780a54 | |||
| 21e42714eb | |||
| 3474c00e7a | |||
| 3d6b0e5f74 | |||
| 9f619859d1 | |||
| 805a9c5f59 | |||
| 43329dc583 | |||
| 66fee56c47 | |||
| efb2ab57aa | |||
| 0a7d482299 | |||
| de047fb851 | |||
| 9836b5cf67 | |||
| c64591b8f7 | |||
| 3813162bac | |||
| 7099e17c7e | |||
| 2c75e8fcd4 | |||
| e8f01fb6ac | |||
| fd0764d4cb | |||
| 71b2bf6a64 | |||
| 2dcff247c8 | |||
| 93f19d3971 | |||
| bad44f35e2 | |||
| 4a339d49df | |||
| 57d0420399 | |||
| 90def9b882 | |||
| 84156829a7 | |||
| d210b1e5ff | |||
| 086538754e | |||
| 241f900dc4 | |||
| 604256a223 | |||
| 2dffc66c6f | |||
| 1bf24273d2 | |||
| c060280417 | |||
| bc6efd5f74 | |||
| efd6d2f9b1 | |||
| 9dd4cf71f1 | |||
| cfec31457c | |||
| 5ac5beb456 | |||
| 0e51131d67 | |||
| f9a87e26c9 | |||
| 9e16cd8ae8 | |||
| 9644f14746 | |||
| d9f545a5ec | |||
| 1cc32d92cf | |||
| 924e91cf64 | |||
| 9825c61a13 | |||
| 5a0a1b1ffd | |||
| a3bb7e7741 | |||
| a1251bdda8 | |||
| b90082d694 | |||
| a49fa42f35 | |||
| 7064a4156f | |||
| 106cb45b57 | |||
| 9a544650ee | |||
| 032d423add | |||
| 760b30ca0a | |||
| 6b08ca51cc | |||
| 268879b414 | |||
| 4c6dc960e4 | |||
| cc46b54f7f | |||
| 9e3b363d4a | |||
| b0d1dc5f04 | |||
| 158396937a | |||
| fb1467284c | |||
| 14addd4869 | |||
| 0a114fae9a | |||
| 2b224d42ad | |||
| 155ec9ac0d | |||
| 25b4b97c41 | |||
| 839f31b24d | |||
| 20728c31c4 | |||
| c6eb12ac16 | |||
| 34d21d4056 | |||
| d369b47ef4 | |||
| 404f7cada8 | |||
| 823e73336d | |||
| 0da6391be3 | |||
| 0348cb6b8e | |||
| b385a4385f | |||
| 6a9228ed6e | |||
| 8031bf0bcb | |||
| c1584da9cc | |||
| ee6f6f683c | |||
| 60707a14db | |||
| 54050924d8 | |||
| f727c9f75a | |||
| f410c89815 | |||
| 2e575652f6 | |||
| 8e831dce36 | |||
| 040c092795 | |||
| a25952910a | |||
| 66896a3121 | |||
| 4d2418af9d | |||
| 265b32f46f | |||
| 1cde55c535 | |||
| 369b5c2921 | |||
| bcc2e022dc | |||
| 0fef46a6c1 | |||
| b867d40774 | |||
| a489290eba | |||
| 549d731849 | |||
| 68a34565f9 | |||
| c05f951f81 | |||
| dc64561b3c | |||
| cb2aee2713 | |||
| 0730b6b588 | |||
| 826550acac | |||
| b71b3f5be0 | |||
| 1fe79f430c | |||
| e5dabe0afc |
@@ -4,9 +4,6 @@ kind: pipeline
|
|||||||
type: docker
|
type: docker
|
||||||
name: Build Linux
|
name: Build Linux
|
||||||
|
|
||||||
clone:
|
|
||||||
depth: 1
|
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||||
concurrency:
|
concurrency:
|
||||||
limit: 1
|
limit: 1
|
||||||
@@ -43,9 +40,6 @@ name: Build Windows
|
|||||||
concurrency:
|
concurrency:
|
||||||
limit: 1
|
limit: 1
|
||||||
|
|
||||||
clone:
|
|
||||||
depth: 1
|
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: windows
|
os: windows
|
||||||
arch: amd64
|
arch: amd64
|
||||||
|
|||||||
@@ -68,3 +68,6 @@ compile_flags.txt
|
|||||||
!utils/scripts/build/
|
!utils/scripts/build/
|
||||||
!utils/scripts/build/should-release/should-release
|
!utils/scripts/build/should-release/should-release
|
||||||
!utils/scripts/build/should-release/should-release.exe
|
!utils/scripts/build/should-release/should-release.exe
|
||||||
|
|
||||||
|
# CMake Files
|
||||||
|
cmake-build-relwithdebinfo/*
|
||||||
|
|||||||
+422
@@ -1,3 +1,425 @@
|
|||||||
|
## [22.4.5] - 03/03/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add additional Heroic Sta/Wis/Int bonuses for Bots. ([#3013](https://github.com/EQEmu/Server/pull/3013)) @Aeadoin 2023-03-01
|
||||||
|
* Cleanup AI_IdleCastCheck Logic ([#3004](https://github.com/EQEmu/Server/pull/3004)) @Aeadoin 2023-02-26
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Delete unused zone/skills.h ([#3007](https://github.com/EQEmu/Server/pull/3007)) @Kinglykrab 2023-02-27
|
||||||
|
* Remove DumpPacketProfile() from client.h ([#3000](https://github.com/EQEmu/Server/pull/3000)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove GetCombinedAC_TEST() from client.h ([#2999](https://github.com/EQEmu/Server/pull/2999)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove GetDamageMultiplier() from client.h ([#3001](https://github.com/EQEmu/Server/pull/3001)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove NumberOfAvailableTitles() from titles.h ([#3006](https://github.com/EQEmu/Server/pull/3006)) @Kinglykrab 2023-02-27
|
||||||
|
* Remove ReturnItemPacket from client.h/inventory.cpp ([#3002](https://github.com/EQEmu/Server/pull/3002)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove class EGNode from mob.h ([#3003](https://github.com/EQEmu/Server/pull/3003)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove unused ClientFactory in client.h ([#2998](https://github.com/EQEmu/Server/pull/2998)) @Kinglykrab 2023-02-26
|
||||||
|
* Remove unused iterator from LoadCharacterDisciplines ([#3012](https://github.com/EQEmu/Server/pull/3012)) @Aeadoin 2023-03-02
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash in CheckTradeskillLoreConflict ([#3009](https://github.com/EQEmu/Server/pull/3009)) @Aeadoin 2023-02-28
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Account for bad data in Tradeskill Recipe Entries ([#2991](https://github.com/EQEmu/Server/pull/2991)) @Aeadoin 2023-02-25
|
||||||
|
* Fix DoAnim quest method default speed ([#3016](https://github.com/EQEmu/Server/pull/3016)) @Kinglykrab 2023-03-01
|
||||||
|
* Fix an issue where EVENT_TIMER timers would not be cleaned up after zone ([#3018](https://github.com/EQEmu/Server/pull/3018)) @noudess 2023-03-03
|
||||||
|
* Fix for Discipline Loading from Database causing issues with slot_ids ([#3008](https://github.com/EQEmu/Server/pull/3008)) @Aeadoin 2023-02-28
|
||||||
|
* Fix for Lore Components where component is returned. ([#3005](https://github.com/EQEmu/Server/pull/3005)) @Aeadoin 2023-02-27
|
||||||
|
* Fix issue where quest saylink responses would occur before the NPC's response ([#3010](https://github.com/EQEmu/Server/pull/3010)) @Akkadius 2023-03-01
|
||||||
|
* Fix log messages when players join channel ([#2992](https://github.com/EQEmu/Server/pull/2992)) @Valorith 2023-03-03
|
||||||
|
* Fix npcfeature and playerfeature ([#3017](https://github.com/EQEmu/Server/pull/3017)) @Kinglykrab 2023-03-02
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GetDefaultRaceSize() to Perl/Lua ([#2993](https://github.com/EQEmu/Server/pull/2993)) @Kinglykrab 2023-02-27
|
||||||
|
* Add HasSpecialAbilities() to Perl/Lua ([#2994](https://github.com/EQEmu/Server/pull/2994)) @Kinglykrab 2023-02-27
|
||||||
|
* Add IsBerserk() to Perl/Lua ([#2997](https://github.com/EQEmu/Server/pull/2997)) @Kinglykrab 2023-03-01
|
||||||
|
* Add IsFindable() and IsTrackable() to Perl/Lua ([#2996](https://github.com/EQEmu/Server/pull/2996)) @Kinglykrab 2023-03-01
|
||||||
|
* Add IsUnderwaterOnly() to Perl/Lua ([#2995](https://github.com/EQEmu/Server/pull/2995)) @Kinglykrab 2023-03-01
|
||||||
|
|
||||||
|
## [22.4.4] - 02/24/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add Caster Range Command, and IsValidSpellRange Checks ([#2942](https://github.com/EQEmu/Server/pull/2942)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-23
|
||||||
|
* Cleanup BotDatabase::LoadBuffs ([#2981](https://github.com/EQEmu/Server/pull/2981)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-24
|
||||||
|
* Verify Bots Group Integrity on join ([#2980](https://github.com/EQEmu/Server/pull/2980)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-23
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Cleanup #peekinv Command ([#2969](https://github.com/EQEmu/Server/pull/2969)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-23
|
||||||
|
|
||||||
|
### Doors
|
||||||
|
|
||||||
|
* Fix doors triggering invalid zone fetches of dest_zone of "none" ([#2985](https://github.com/EQEmu/Server/pull/2985)) ([Akkadius](https://github.com/Akkadius)) 2023-02-24
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Adjust database manifest to include .sql extension ([Akkadius](https://github.com/Akkadius)) 2023-02-25
|
||||||
|
* Correct Mend reuse time and add reduction support. ([#2972](https://github.com/EQEmu/Server/pull/2972)) ([nytmyr](https://github.com/nytmyr)) 2023-02-23
|
||||||
|
* Fix Beneficial Target of Target procs ([#2987](https://github.com/EQEmu/Server/pull/2987)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-24
|
||||||
|
* Fix for undefined MySQL library behavior. ([#2834](https://github.com/EQEmu/Server/pull/2834)) ([KimLS](https://github.com/KimLS)) 2023-02-25
|
||||||
|
|
||||||
|
### Pathing
|
||||||
|
|
||||||
|
* Improve roambox logic ([#2983](https://github.com/EQEmu/Server/pull/2983)) ([Akkadius](https://github.com/Akkadius)) 2023-02-24
|
||||||
|
* More z-clip improvements, Wurm and Spectral Iksar race adjustments ([#2988](https://github.com/EQEmu/Server/pull/2988)) ([Akkadius](https://github.com/Akkadius)) 2023-02-25
|
||||||
|
* Smoother pathing z-correction ([#2982](https://github.com/EQEmu/Server/pull/2982)) ([Akkadius](https://github.com/Akkadius)) 2023-02-24
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Add QS processing, mutex tweaks ([#2984](https://github.com/EQEmu/Server/pull/2984)) ([Akkadius](https://github.com/Akkadius)) 2023-02-25
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add IsAutoAttackEnabled() to Perl/Lua ([#2979](https://github.com/EQEmu/Server/pull/2979)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-23
|
||||||
|
* Add IsAutoFireEnabled() to Perl/Lua ([#2978](https://github.com/EQEmu/Server/pull/2978)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-23
|
||||||
|
* Fix EVENT_TIMER crash when entity is no longer available ([#2986](https://github.com/EQEmu/Server/pull/2986)) ([Akkadius](https://github.com/Akkadius)) 2023-02-24
|
||||||
|
|
||||||
|
### Scaling
|
||||||
|
|
||||||
|
* Add support for zone ID and instance version to NPC Scaling ([#2968](https://github.com/EQEmu/Server/pull/2968)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-25
|
||||||
|
|
||||||
|
### Tradeskills
|
||||||
|
|
||||||
|
* Fix for Lore Conflict ([#2977](https://github.com/EQEmu/Server/pull/2977)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-24
|
||||||
|
|
||||||
|
## [22.4.3] - 02/21/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Change HasBotItem(item_id) to return slot_id instead of bool. ([#2966](https://github.com/EQEmu/Server/pull/2966)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-19
|
||||||
|
* Change SaveTimers to Replace instead of Insert. ([#2951](https://github.com/EQEmu/Server/pull/2951)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
||||||
|
* Fix output of ^spells while ^Enforcespellsettings is enabled ([#2959](https://github.com/EQEmu/Server/pull/2959)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash with EVENT_UNEQUIP_ITEM_BOT ([#2973](https://github.com/EQEmu/Server/pull/2973)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-20
|
||||||
|
* Fix world crash in player event processing ([#2960](https://github.com/EQEmu/Server/pull/2960)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Address deadlock in player events ([#2974](https://github.com/EQEmu/Server/pull/2974)) ([Akkadius](https://github.com/Akkadius)) 2023-02-21
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix MIR LDoN Theme Items on LDoN Merchants ([#2971](https://github.com/EQEmu/Server/pull/2971)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-20
|
||||||
|
* Fix OOCMute not functioning ([#2970](https://github.com/EQEmu/Server/pull/2970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-20
|
||||||
|
|
||||||
|
### Pathing
|
||||||
|
|
||||||
|
* Improvements to z-clipping, z-recovery and z-calculations ([#2975](https://github.com/EQEmu/Server/pull/2975)) ([Akkadius](https://github.com/Akkadius)) 2023-02-21
|
||||||
|
|
||||||
|
### Pets
|
||||||
|
|
||||||
|
* Client Pet summoned by NPC should not change guard location. ([#2967](https://github.com/EQEmu/Server/pull/2967)) ([noudess](https://github.com/noudess)) 2023-02-19
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Create new event ITEM_CREATION ([#2944](https://github.com/EQEmu/Server/pull/2944)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add client->SignalClient() overload to Perl ([#2963](https://github.com/EQEmu/Server/pull/2963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-19
|
||||||
|
* Fix Perl SetSimpleRoamBox Overloads ([#2961](https://github.com/EQEmu/Server/pull/2961)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-19
|
||||||
|
|
||||||
|
### Reload API
|
||||||
|
|
||||||
|
* Add world handlers for certain opcodes ([#2958](https://github.com/EQEmu/Server/pull/2958)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### SQL
|
||||||
|
|
||||||
|
* Add date to optional Drakkin Guktan Faction Update ([#2965](https://github.com/EQEmu/Server/pull/2965)) ([joligario](https://github.com/joligario)) 2023-02-19
|
||||||
|
|
||||||
|
## [22.4.2] - 02/18/2023
|
||||||
|
|
||||||
|
### Content
|
||||||
|
|
||||||
|
* Added optional SQL 2023_02_17_fix_sseru_mischief_doors.sql to fix sseru/mischief doors ([#2955](https://github.com/EQEmu/Server/pull/2955)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
* Remove noisy raid/group/forage errors ([#2952](https://github.com/EQEmu/Server/pull/2952)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### MySQL
|
||||||
|
|
||||||
|
* Add keepalives to UCS and Loginserver ([#2953](https://github.com/EQEmu/Server/pull/2953)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Add logging category to hold processing batch logs ([#2954](https://github.com/EQEmu/Server/pull/2954)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||||
|
|
||||||
|
### Tradeskills
|
||||||
|
|
||||||
|
* Fix regression caused by #2932 ([#2956](https://github.com/EQEmu/Server/pull/2956)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
||||||
|
|
||||||
|
## [22.4.1] - 02/17/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Set Taunt to enabled for SK/Paladin Bots by Default. ([#2941](https://github.com/EQEmu/Server/pull/2941)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-17
|
||||||
|
|
||||||
|
### DevTools
|
||||||
|
|
||||||
|
* Fix NPC targetting dev tools display window ([#2943](https://github.com/EQEmu/Server/pull/2943)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Issue with AssignRaidToInstance that was using the groups repository instead of raid ([#2947](https://github.com/EQEmu/Server/pull/2947)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
* Missing comma in schema list breaking dumps ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Fix issue with item instances not being validated properly before accessing causing crashes on handin ([#2945](https://github.com/EQEmu/Server/pull/2945)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
* Fix rare out of bound issue when loading event types ([#2946](https://github.com/EQEmu/Server/pull/2946)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
* Turn off KILLED_NPC (trash) off by default ([#2948](https://github.com/EQEmu/Server/pull/2948)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||||
|
|
||||||
|
## [22.4.0] - 02/17/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add Additional HeroicAgi/Dex Modifiers. ([#2838](https://github.com/EQEmu/Server/pull/2838)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||||
|
* Add Additional HeroicStr modifiers. ([#2837](https://github.com/EQEmu/Server/pull/2837)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||||
|
* Add IsBot() to methods in attack.cpp where applicable. ([#2840](https://github.com/EQEmu/Server/pull/2840)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||||
|
* Add Lore Check for Augments. ([#2874](https://github.com/EQEmu/Server/pull/2874)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
||||||
|
* Add Pet Power Support for Temp Pets. ([#2853](https://github.com/EQEmu/Server/pull/2853)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-11
|
||||||
|
* Add Support for TryTriggerOnCastFocusEffect ([#2864](https://github.com/EQEmu/Server/pull/2864)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||||
|
* Add TotalDominationBonus modifiers. ([#2852](https://github.com/EQEmu/Server/pull/2852)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||||
|
* ST_AreaClientOnly spells to land on Bots ([#2849](https://github.com/EQEmu/Server/pull/2849)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||||
|
* Update ResistSpell to use temp_level_diff client formula ([#2851](https://github.com/EQEmu/Server/pull/2851)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||||
|
|
||||||
|
### Bots & Mercenaries
|
||||||
|
|
||||||
|
* Add 100% Hit chance if sitting while attacked. ([#2839](https://github.com/EQEmu/Server/pull/2839)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||||
|
* Add Support for TrySympatheticProc ([#2866](https://github.com/EQEmu/Server/pull/2866)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||||
|
|
||||||
|
### CI
|
||||||
|
|
||||||
|
* Fix Windows stderr not bubbling properly ([#2925](https://github.com/EQEmu/Server/pull/2925)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Add IsOfClientBot() virtual method. ([#2845](https://github.com/EQEmu/Server/pull/2845)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||||
|
* Doors EVENT_CLICK_DOOR syntax adjustment ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Remove Unused Mod Hooks ([#2856](https://github.com/EQEmu/Server/pull/2856)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Crash fix where invalid input to #heromodel would crash zone ([#2937](https://github.com/EQEmu/Server/pull/2937)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||||
|
* Fix Bot Crash in Bot::Bot Constructor. ([#2868](https://github.com/EQEmu/Server/pull/2868)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
||||||
|
* Fix Crash in FindType ([#2867](https://github.com/EQEmu/Server/pull/2867)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||||
|
* Fix crash in Mob::CommonDamage when attacker was null ([#2872](https://github.com/EQEmu/Server/pull/2872)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||||
|
* Fix crash issue with dropping items and order of operations ([#2939](https://github.com/EQEmu/Server/pull/2939)) ([joligario](https://github.com/joligario)) 2023-02-16
|
||||||
|
* Fix issue where long short names overflow file_name ([Akkadius](https://github.com/Akkadius)) 2023-02-09
|
||||||
|
* Fix potential crash in Mob::CommonDamage ([#2848](https://github.com/EQEmu/Server/pull/2848)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||||
|
|
||||||
|
### Doors
|
||||||
|
|
||||||
|
* Fix issue where NPC's wouldn't open doors because door param overflow ([#2934](https://github.com/EQEmu/Server/pull/2934)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add IsOfClientBotMerc() virtual method. ([#2843](https://github.com/EQEmu/Server/pull/2843)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Another doors fix ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Fix CheckNumHitsRemaining() with 1H Blunt ([#2846](https://github.com/EQEmu/Server/pull/2846)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-07
|
||||||
|
* Fix Door opening regression caused by #2880 ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Fix EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE regression caused by #2897 ([#2928](https://github.com/EQEmu/Server/pull/2928)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Fix HP_EVENT regression ([#2927](https://github.com/EQEmu/Server/pull/2927)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Fix crash in EVENT_DISCOVER_ITEM ([#2933](https://github.com/EQEmu/Server/pull/2933)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-15
|
||||||
|
* Fix crash where dropped items crash Lua logic ([#2936](https://github.com/EQEmu/Server/pull/2936)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||||
|
* Fix for interrupting item casts to no longer lock the client if cast time of item greater than 0 ([#2921](https://github.com/EQEmu/Server/pull/2921)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-13
|
||||||
|
* Fix issue where Lore groundspawn pickups will desync ROF2+ ([#2929](https://github.com/EQEmu/Server/pull/2929)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Fix issue with EVENT_HP firing regression from #2904 ([#2924](https://github.com/EQEmu/Server/pull/2924)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
* Replace uses of SPELL_UNKNOWN with IsValidSpell() ([#2938](https://github.com/EQEmu/Server/pull/2938)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
||||||
|
* Self Only Spells will no longer check target level or buff restrictions ([#2931](https://github.com/EQEmu/Server/pull/2931)) ([noudess](https://github.com/noudess)) 2023-02-15
|
||||||
|
|
||||||
|
### Groundspawns
|
||||||
|
|
||||||
|
* Fix issue where groundspawns appear floating high off the ground ([#2930](https://github.com/EQEmu/Server/pull/2930)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
* Add raw opcode when emu translated opcode is not found (OP_Unknown) via (C->S) ([#2847](https://github.com/EQEmu/Server/pull/2847)) ([Akkadius](https://github.com/Akkadius)) 2023-02-08
|
||||||
|
* Implement Player Event Logging system ([#2833](https://github.com/EQEmu/Server/pull/2833)) ([Akkadius](https://github.com/Akkadius)) 2023-02-13
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* (Performance) Check equip or scale item events exist before export and execute ([#2898](https://github.com/EQEmu/Server/pull/2898)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_AA_BUY or EVENT_AA_GAIN exist before export and execute ([#2892](https://github.com/EQEmu/Server/pull/2892)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_AGGRO, EVENT_ATTACK, or EVENT_COMBAT exist before export and execute ([#2901](https://github.com/EQEmu/Server/pull/2901)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_COMBINE, EVENT_COMBINE_SUCCESS, EVENT_COMBINE_FAILURE, or EVENT_COMBINE_VALIDATE exist before export and execute ([#2896](https://github.com/EQEmu/Server/pull/2896)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_DEATH, EVENT_DEATH_COMPLETE, or EVENT_DEATH_ZONE exist before export and execute ([#2909](https://github.com/EQEmu/Server/pull/2909)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_ENVIRONMENTAL_DAMAGE exists before export and execute ([#2899](https://github.com/EQEmu/Server/pull/2899)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_FEIGN_DEATH exists before export and execute ([#2916](https://github.com/EQEmu/Server/pull/2916)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_ITEM_TICK or EVENT_WEAPON_PROC exist before export and execute ([#2914](https://github.com/EQEmu/Server/pull/2914)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_LANGUAGE_SKILL_UP, EVENT_SKILL_UP, or EVENT_USE_SKILL exist before export and execute ([#2894](https://github.com/EQEmu/Server/pull/2894)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_PAYLOAD or EVENT_SIGNAL exist before export and execute ([#2902](https://github.com/EQEmu/Server/pull/2902)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_SLAY exists before export and execute ([#2910](https://github.com/EQEmu/Server/pull/2910)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event EVENT_WAYPOINT_ARRIVE or EVENT_WAYPOINT_DEPART exist before export and execute ([#2905](https://github.com/EQEmu/Server/pull/2905)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_AGGRO_SAY, EVENT_SAY, and EVENT_PROXIMITY_SAY ([#2882](https://github.com/EQEmu/Server/pull/2882)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_BOT_CREATE ([#2886](https://github.com/EQEmu/Server/pull/2886)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_CLICK_DOOR and EVENT_CLICK_OBJECT ([#2880](https://github.com/EQEmu/Server/pull/2880)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_DESPAWN and EVENT_DESPAWN_ZONE ([#2887](https://github.com/EQEmu/Server/pull/2887)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_DISCOVER_ITEM ([#2912](https://github.com/EQEmu/Server/pull/2912)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_DUEL_LOSE and EVENT_DUEL_WIN ([#2915](https://github.com/EQEmu/Server/pull/2915)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_ENTER_ZONE and EVENT_ZONE ([#2900](https://github.com/EQEmu/Server/pull/2900)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_GM_COMMAND ([#2890](https://github.com/EQEmu/Server/pull/2890)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_GROUP_CHANGE ([#2884](https://github.com/EQEmu/Server/pull/2884)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_HP ([#2904](https://github.com/EQEmu/Server/pull/2904)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_KILLED_MERIT ([#2911](https://github.com/EQEmu/Server/pull/2911)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_LEVEL_UP and EVENT_LEVEL_DOWN ([#2889](https://github.com/EQEmu/Server/pull/2889)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_POPUP_RESPONSE ([#2881](https://github.com/EQEmu/Server/pull/2881)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_RESPAWN ([#2917](https://github.com/EQEmu/Server/pull/2917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_TICK ([#2919](https://github.com/EQEmu/Server/pull/2919)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_TIMER ([#2903](https://github.com/EQEmu/Server/pull/2903)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_TRADE ([#2906](https://github.com/EQEmu/Server/pull/2906)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_UNHANDLED_OPCODE ([#2918](https://github.com/EQEmu/Server/pull/2918)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_WARP ([#2907](https://github.com/EQEmu/Server/pull/2907)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute area events ([#2888](https://github.com/EQEmu/Server/pull/2888)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check merchant events exist before export and execute ([#2893](https://github.com/EQEmu/Server/pull/2893)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check spell or cast events exist before export and execute ([#2897](https://github.com/EQEmu/Server/pull/2897)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check task events exist before export and execute ([#2883](https://github.com/EQEmu/Server/pull/2883)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_CONNECT and EVENT_DISCONNECT ([#2913](https://github.com/EQEmu/Server/pull/2913)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* (Performance) Check event exists before export and execute EVENT_TEST_BUFF ([#2920](https://github.com/EQEmu/Server/pull/2920)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Add $target export to EVENT_INSPECT in Perl ([#2891](https://github.com/EQEmu/Server/pull/2891)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Add Additional XP Events EVENT_AA_EXP_GAIN, EVENT_EXP_GAIN ([#2865](https://github.com/EQEmu/Server/pull/2865)) ([Valorith](https://github.com/Valorith)) 2023-02-13
|
||||||
|
* Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. ([#2871](https://github.com/EQEmu/Server/pull/2871)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Add EVENT_DROP_ITEM_CLIENT to Perl/Lua ([#2869](https://github.com/EQEmu/Server/pull/2869)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Add Recipe-based methods to Perl/Lua. ([#2844](https://github.com/EQEmu/Server/pull/2844)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-08
|
||||||
|
* Export $door to EVENT_CLICKDOOR in Perl ([#2861](https://github.com/EQEmu/Server/pull/2861)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||||
|
* Export $hate_entity to EVENT_HATE_LIST in Perl ([#2885](https://github.com/EQEmu/Server/pull/2885)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $item and $augment to augment events in Perl ([#2895](https://github.com/EQEmu/Server/pull/2895)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $item and $corpse to EVENT_LOOT and EVENT_LOOT_ZONE in Perl ([#2878](https://github.com/EQEmu/Server/pull/2878)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $item to Client/Bot Equip Events in Perl ([#2860](https://github.com/EQEmu/Server/pull/2860)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||||
|
* Export $item to EVENT_DISCOVER_ITEM in Perl ([#2863](https://github.com/EQEmu/Server/pull/2863)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||||
|
* Export $item to EVENT_PLAYER_PICKUP in Perl. ([#2875](https://github.com/EQEmu/Server/pull/2875)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $item to Fishing and Forage Events in Perl ([#2876](https://github.com/EQEmu/Server/pull/2876)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $killed_npc to EVENT_NPC_SLAY to Perl ([#2879](https://github.com/EQEmu/Server/pull/2879)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export $object to EVENT_CLICK_OBJECT in Perl ([#2862](https://github.com/EQEmu/Server/pull/2862)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||||
|
* Export $spawned to EVENT_SPAWN_ZONE in Perl ([#2877](https://github.com/EQEmu/Server/pull/2877)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export target to EVENT_TARGET_CHANGE in Perl/Lua. ([#2870](https://github.com/EQEmu/Server/pull/2870)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Export targets to EVENT_CONSIDER and EVENT_CONSIDER_CORPSE ([#2908](https://github.com/EQEmu/Server/pull/2908)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
* Fix SetSimpleRoamBox in Perl to have optional params again ([#2935](https://github.com/EQEmu/Server/pull/2935)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Group/Raid Experience Rules ([#2850](https://github.com/EQEmu/Server/pull/2850)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||||
|
|
||||||
|
### Tradeskills
|
||||||
|
|
||||||
|
* Check if combine would result in lore conflict ([#2932](https://github.com/EQEmu/Server/pull/2932)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
* Fix MSVC compilation bug via workaround ([#2926](https://github.com/EQEmu/Server/pull/2926)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||||
|
|
||||||
|
## [22.3.0] - 02/06/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add GetAugmentIDsBySlotID & AddItem with table ref Methods. ([#2805](https://github.com/EQEmu/Server/pull/2805)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-29
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* #list now searches without case sensitivity ([#2825](https://github.com/EQEmu/Server/pull/2825)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Remove extraneous else from #weather ([#2819](https://github.com/EQEmu/Server/pull/2819)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix IsUnderwaterOnly crash where npc data references can be stale ([#2830](https://github.com/EQEmu/Server/pull/2830)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fix command crash with #npcedit weapon when second weapon not passed ni ([#2829](https://github.com/EQEmu/Server/pull/2829)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fix crash in bot command botdyearmor ([#2832](https://github.com/EQEmu/Server/pull/2832)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### DB Updates
|
||||||
|
|
||||||
|
* Add Windows MySQL path auto detection for users where the path is not found ([#2836](https://github.com/EQEmu/Server/pull/2836)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Doors
|
||||||
|
|
||||||
|
* Have NPCs trigger double doors ([#2821](https://github.com/EQEmu/Server/pull/2821)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Remove door dev tools spam on client controlled doors ([#2824](https://github.com/EQEmu/Server/pull/2824)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Min/Max Status to Merchants ([#2806](https://github.com/EQEmu/Server/pull/2806)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* #reload aa will now refresh the AA table properly for every client when changes are made ([#2814](https://github.com/EQEmu/Server/pull/2814)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||||
|
* #reload static should now properly fill the entity_lists for… ([#2815](https://github.com/EQEmu/Server/pull/2815)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||||
|
* BuffLevelRestrictions were restricting group buffs if mob targeted ([#2809](https://github.com/EQEmu/Server/pull/2809)) ([noudess](https://github.com/noudess)) 2023-01-29
|
||||||
|
* Fix does_augment_fit_slot method. ([#2817](https://github.com/EQEmu/Server/pull/2817)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-01
|
||||||
|
* Fix NPC ghosting at safe coordinates ([#2823](https://github.com/EQEmu/Server/pull/2823)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fixing % based mob see invis ([#2802](https://github.com/EQEmu/Server/pull/2802)) ([fryguy503](https://github.com/fryguy503)) 2023-01-29
|
||||||
|
* Resolve issue with max buff count being 25 in ROF2. ([#2800](https://github.com/EQEmu/Server/pull/2800)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-28
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 ([Akkadius](https://github.com/Akkadius)) 2023-02-01
|
||||||
|
|
||||||
|
### Lua
|
||||||
|
|
||||||
|
* Resolve stoi Exception ([#2736](https://github.com/EQEmu/Server/pull/2736)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Pathing
|
||||||
|
|
||||||
|
* Improvements to handling tight corridors pathing, clipping detection and recovery ([#2826](https://github.com/EQEmu/Server/pull/2826)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Augment Slot support to does_augment_fit ([#2813](https://github.com/EQEmu/Server/pull/2813)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-31
|
||||||
|
* Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. ([#2804](https://github.com/EQEmu/Server/pull/2804)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
* Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. ([#2810](https://github.com/EQEmu/Server/pull/2810)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-30
|
||||||
|
* Add EVENT_TASKACCEPTED to Player scope ([#2822](https://github.com/EQEmu/Server/pull/2822)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||||
|
* Add GetItemCooldown to return the time remaining on items… ([#2811](https://github.com/EQEmu/Server/pull/2811)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-30
|
||||||
|
* Add LDoN Methods to Perl/Lua ([#2799](https://github.com/EQEmu/Server/pull/2799)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
* Add Override Parameters to ScaleNPC() in Perl/Lua. ([#2816](https://github.com/EQEmu/Server/pull/2816)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||||
|
* Add rule AlternateAugmentationSealer for using a different bagtype ([#2831](https://github.com/EQEmu/Server/pull/2831)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-06
|
||||||
|
* Default ScaleNPC to always scale. ([#2818](https://github.com/EQEmu/Server/pull/2818)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-06
|
||||||
|
|
||||||
|
### Readme
|
||||||
|
|
||||||
|
* Update build badges with Drone ([Akkadius](https://github.com/Akkadius)) 2023-01-29
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add rule to ignore name filter on chat channel creation. ([#2820](https://github.com/EQEmu/Server/pull/2820)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||||
|
* Added rule to bypass level based haste caps ([#2835](https://github.com/EQEmu/Server/pull/2835)) ([jcr4990](https://github.com/jcr4990)) 2023-02-06
|
||||||
|
* Fix rule updates that affected bot booting checks ([#2841](https://github.com/EQEmu/Server/pull/2841)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
* Implement alternate currency rewards ([#2827](https://github.com/EQEmu/Server/pull/2827)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
## [22.2.0] - 01/27/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT ([#2796](https://github.com/EQEmu/Server/pull/2796)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-27
|
||||||
|
* ^create and ^viewcombos popup messages fix. ([#2797](https://github.com/EQEmu/Server/pull/2797)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-26
|
||||||
|
|
||||||
|
### Code Cleanup
|
||||||
|
|
||||||
|
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash issue with log formatting during character creation ([#2798](https://github.com/EQEmu/Server/pull/2798)) ([Akkadius](https://github.com/Akkadius)) 2023-01-27
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* ResetItemCooldown added to lua/perl and fix item re-cast times to show properly ([#2793](https://github.com/EQEmu/Server/pull/2793)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-26
|
||||||
|
|
||||||
|
### Git
|
||||||
|
|
||||||
|
* Add CMake Files to .gitignore ([#2792](https://github.com/EQEmu/Server/pull/2792)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-25
|
||||||
|
|
||||||
## [22.1.2] - 01/24/2023
|
## [22.1.2] - 01/24/2023
|
||||||
|
|
||||||
### CI/CD
|
### CI/CD
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
| Drone (Linux x64) | Drone (Windows x64) |
|
||||||
|:---:|:---:|:---:|
|
|:---:|:---:|
|
||||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMysql(database.getMySQL());
|
content_db.SetMySQL(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
@@ -183,7 +183,7 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (row[0] && atoi(row[0]) > 0) {
|
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase *db)
|
void ExportSkillCaps(SharedDatabase *db)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMysql(database.getMySQL());
|
content_db.SetMySQL(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
@@ -241,10 +241,10 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int class_id, skill_id, level, cap;
|
int class_id, skill_id, level, cap;
|
||||||
class_id = atoi(split[0].c_str());
|
class_id = Strings::ToInt(split[0].c_str());
|
||||||
skill_id = atoi(split[1].c_str());
|
skill_id = Strings::ToInt(split[1].c_str());
|
||||||
level = atoi(split[2].c_str());
|
level = Strings::ToInt(split[2].c_str());
|
||||||
cap = atoi(split[3].c_str());
|
cap = Strings::ToInt(split[3].c_str());
|
||||||
|
|
||||||
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
||||||
class_id, skill_id, level, cap);
|
class_id, skill_id, level, cap);
|
||||||
@@ -280,16 +280,16 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
int level, class_id;
|
int level, class_id;
|
||||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||||
|
|
||||||
level = atoi(split[0].c_str());
|
level = Strings::ToInt(split[0].c_str());
|
||||||
class_id = atoi(split[1].c_str());
|
class_id = Strings::ToInt(split[1].c_str());
|
||||||
hp = atof(split[2].c_str());
|
hp = Strings::ToFloat(split[2].c_str());
|
||||||
mana = atof(split[3].c_str());
|
mana = Strings::ToFloat(split[3].c_str());
|
||||||
end = atof(split[4].c_str());
|
end = Strings::ToFloat(split[4].c_str());
|
||||||
unk1 = atof(split[5].c_str());
|
unk1 = Strings::ToFloat(split[5].c_str());
|
||||||
unk2 = atof(split[6].c_str());
|
unk2 = Strings::ToFloat(split[6].c_str());
|
||||||
hp_fac = atof(split[7].c_str());
|
hp_fac = Strings::ToFloat(split[7].c_str());
|
||||||
mana_fac = atof(split[8].c_str());
|
mana_fac = Strings::ToFloat(split[8].c_str());
|
||||||
end_fac = atof(split[9].c_str());
|
end_fac = Strings::ToFloat(split[9].c_str());
|
||||||
|
|
||||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
||||||
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
||||||
@@ -339,8 +339,8 @@ void ImportDBStrings(SharedDatabase *db) {
|
|||||||
int id, type;
|
int id, type;
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
id = atoi(split[0].c_str());
|
id = Strings::ToInt(split[0].c_str());
|
||||||
type = atoi(split[1].c_str());
|
type = Strings::ToInt(split[1].c_str());
|
||||||
|
|
||||||
if(split.size() >= 3) {
|
if(split.size() >= 3) {
|
||||||
value = ::Strings::Escape(split[2]);
|
value = ::Strings::Escape(split[2]);
|
||||||
|
|||||||
+13
-8
@@ -33,9 +33,11 @@ SET(common_sources
|
|||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
|
events/player_event_logs.cpp
|
||||||
|
events/player_event_discord_formatter.cpp
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
discord_manager.cpp
|
discord/discord_manager.cpp
|
||||||
faction.cpp
|
faction.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
guild_base.cpp
|
guild_base.cpp
|
||||||
@@ -198,7 +200,6 @@ SET(repositories
|
|||||||
repositories/base/base_dynamic_zones_repository.h
|
repositories/base/base_dynamic_zones_repository.h
|
||||||
repositories/base/base_dynamic_zone_members_repository.h
|
repositories/base/base_dynamic_zone_members_repository.h
|
||||||
repositories/base/base_dynamic_zone_templates_repository.h
|
repositories/base/base_dynamic_zone_templates_repository.h
|
||||||
repositories/base/base_eventlog_repository.h
|
|
||||||
repositories/base/base_expeditions_repository.h
|
repositories/base/base_expeditions_repository.h
|
||||||
repositories/base/base_expedition_lockouts_repository.h
|
repositories/base/base_expedition_lockouts_repository.h
|
||||||
repositories/base/base_faction_association_repository.h
|
repositories/base/base_faction_association_repository.h
|
||||||
@@ -218,7 +219,6 @@ SET(repositories
|
|||||||
repositories/base/base_guilds_repository.h
|
repositories/base/base_guilds_repository.h
|
||||||
repositories/base/base_guild_ranks_repository.h
|
repositories/base/base_guild_ranks_repository.h
|
||||||
repositories/base/base_guild_relations_repository.h
|
repositories/base/base_guild_relations_repository.h
|
||||||
repositories/base/base_hackers_repository.h
|
|
||||||
repositories/base/base_horses_repository.h
|
repositories/base/base_horses_repository.h
|
||||||
repositories/base/base_instance_list_repository.h
|
repositories/base/base_instance_list_repository.h
|
||||||
repositories/base/base_instance_list_player_repository.h
|
repositories/base/base_instance_list_player_repository.h
|
||||||
@@ -264,6 +264,8 @@ SET(repositories
|
|||||||
repositories/base/base_pets_equipmentset_repository.h
|
repositories/base/base_pets_equipmentset_repository.h
|
||||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||||
repositories/base/base_player_titlesets_repository.h
|
repositories/base/base_player_titlesets_repository.h
|
||||||
|
repositories/base/base_player_event_log_settings_repository.h
|
||||||
|
repositories/base/base_player_event_logs_repository.h
|
||||||
repositories/base/base_quest_globals_repository.h
|
repositories/base/base_quest_globals_repository.h
|
||||||
repositories/base/base_raid_details_repository.h
|
repositories/base/base_raid_details_repository.h
|
||||||
repositories/base/base_raid_members_repository.h
|
repositories/base/base_raid_members_repository.h
|
||||||
@@ -376,7 +378,6 @@ SET(repositories
|
|||||||
repositories/dynamic_zones_repository.h
|
repositories/dynamic_zones_repository.h
|
||||||
repositories/dynamic_zone_members_repository.h
|
repositories/dynamic_zone_members_repository.h
|
||||||
repositories/dynamic_zone_templates_repository.h
|
repositories/dynamic_zone_templates_repository.h
|
||||||
repositories/eventlog_repository.h
|
|
||||||
repositories/expeditions_repository.h
|
repositories/expeditions_repository.h
|
||||||
repositories/expedition_lockouts_repository.h
|
repositories/expedition_lockouts_repository.h
|
||||||
repositories/faction_association_repository.h
|
repositories/faction_association_repository.h
|
||||||
@@ -396,7 +397,6 @@ SET(repositories
|
|||||||
repositories/guilds_repository.h
|
repositories/guilds_repository.h
|
||||||
repositories/guild_ranks_repository.h
|
repositories/guild_ranks_repository.h
|
||||||
repositories/guild_relations_repository.h
|
repositories/guild_relations_repository.h
|
||||||
repositories/hackers_repository.h
|
|
||||||
repositories/horses_repository.h
|
repositories/horses_repository.h
|
||||||
repositories/instance_list_repository.h
|
repositories/instance_list_repository.h
|
||||||
repositories/instance_list_player_repository.h
|
repositories/instance_list_player_repository.h
|
||||||
@@ -442,6 +442,8 @@ SET(repositories
|
|||||||
repositories/pets_equipmentset_repository.h
|
repositories/pets_equipmentset_repository.h
|
||||||
repositories/pets_equipmentset_entries_repository.h
|
repositories/pets_equipmentset_entries_repository.h
|
||||||
repositories/player_titlesets_repository.h
|
repositories/player_titlesets_repository.h
|
||||||
|
repositories/player_event_log_settings_repository.h
|
||||||
|
repositories/player_event_logs_repository.h
|
||||||
repositories/quest_globals_repository.h
|
repositories/quest_globals_repository.h
|
||||||
repositories/raid_details_repository.h
|
repositories/raid_details_repository.h
|
||||||
repositories/raid_members_repository.h
|
repositories/raid_members_repository.h
|
||||||
@@ -507,7 +509,7 @@ SET(common_headers
|
|||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
discord/discord.h
|
||||||
discord_manager.h
|
discord/discord_manager.h
|
||||||
dynamic_zone_base.h
|
dynamic_zone_base.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
emu_limits.h
|
emu_limits.h
|
||||||
@@ -530,6 +532,9 @@ SET(common_headers
|
|||||||
eq_stream_locator.h
|
eq_stream_locator.h
|
||||||
eq_stream_proxy.h
|
eq_stream_proxy.h
|
||||||
eqtime.h
|
eqtime.h
|
||||||
|
events/player_event_logs.h
|
||||||
|
events/player_event_discord_formatter.h
|
||||||
|
events/player_events.h
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
@@ -608,6 +613,7 @@ SET(common_headers
|
|||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
|
json/json_archive_single_line.h
|
||||||
json/json.h
|
json/json.h
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
net/console_server.h
|
net/console_server.h
|
||||||
@@ -661,8 +667,7 @@ SET(common_headers
|
|||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.h
|
util/uuid.h)
|
||||||
)
|
|
||||||
|
|
||||||
SOURCE_GROUP(Event FILES
|
SOURCE_GROUP(Event FILES
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ namespace cron
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return static_cast<cron_int>(std::stoul(text.data()));
|
return static_cast<cron_int>(Strings::ToUnsignedInt(text.data()));
|
||||||
}
|
}
|
||||||
catch (std::exception const & ex)
|
catch (std::exception const & ex)
|
||||||
{
|
{
|
||||||
|
|||||||
+64
-102
@@ -121,10 +121,10 @@ uint32 Database::CheckLogin(const char* name, const char* password, const char *
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
auto id = std::stoul(row[0]);
|
auto id = Strings::ToUnsignedInt(row[0]);
|
||||||
|
|
||||||
if (oStatus) {
|
if (oStatus) {
|
||||||
*oStatus = std::stoi(row[1]);
|
*oStatus = Strings::ToInt(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
@@ -202,11 +202,11 @@ int16 Database::CheckStatus(uint32 account_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
int16 status = std::stoi(row[0]);
|
int16 status = Strings::ToInt(row[0]);
|
||||||
int32 date_diff = 0;
|
int32 date_diff = 0;
|
||||||
|
|
||||||
if (row[1]) {
|
if (row[1]) {
|
||||||
date_diff = std::stoi(row[1]);
|
date_diff = Strings::ToInt(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (date_diff > 0) {
|
if (date_diff > 0) {
|
||||||
@@ -345,7 +345,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
|||||||
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (row[0] && atoi(row[0]) > 0){
|
if (row[0] && Strings::ToInt(row[0]) > 0){
|
||||||
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ bool Database::DeleteCharacter(char *character_name)
|
|||||||
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
character_id = atoi(row[0]);
|
character_id = Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character_id <= 0) {
|
if (character_id <= 0) {
|
||||||
@@ -787,7 +787,7 @@ uint32 Database::GetCharacterID(const char *name) {
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (results.RowCount() == 1)
|
if (results.RowCount() == 1)
|
||||||
{
|
{
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -812,10 +812,10 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
uint32 accountId = atoi(row[0]);
|
uint32 accountId = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
if (oCharID)
|
if (oCharID)
|
||||||
*oCharID = atoi(row[1]);
|
*oCharID = Strings::ToInt(row[1]);
|
||||||
|
|
||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
@@ -832,7 +832,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
||||||
@@ -852,14 +852,14 @@ uint32 Database::GetAccountIDByName(std::string account_name, std::string logins
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto account_id = std::stoul(row[0]);
|
auto account_id = Strings::ToUnsignedInt(row[0]);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
*status = static_cast<int16>(std::stoi(row[1]));
|
*status = static_cast<int16>(Strings::ToInt(row[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lsid) {
|
if (lsid) {
|
||||||
*lsid = row[2] ? std::stoul(row[2]) : 0;
|
*lsid = row[2] ? Strings::ToUnsignedInt(row[2]) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return account_id;
|
return account_id;
|
||||||
@@ -880,7 +880,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
|
|||||||
|
|
||||||
strcpy(name, row[0]);
|
strcpy(name, row[0]);
|
||||||
if (row[1] && oLSAccountID) {
|
if (row[1] && oLSAccountID) {
|
||||||
*oLSAccountID = atoi(row[1]);
|
*oLSAccountID = Strings::ToInt(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -968,7 +968,7 @@ bool Database::LoadVariables() {
|
|||||||
|
|
||||||
std::string key, value;
|
std::string key, value;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
varcache.last_update = atoi(row[2]); // ahh should we be comparing if this is newer?
|
varcache.last_update = Strings::ToInt(row[2]); // ahh should we be comparing if this is newer?
|
||||||
key = row[0];
|
key = row[0];
|
||||||
value = row[1];
|
value = row[1];
|
||||||
std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be
|
std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be
|
||||||
@@ -1052,15 +1052,15 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if(graveyard_zoneid != nullptr)
|
if(graveyard_zoneid != nullptr)
|
||||||
*graveyard_zoneid = atoi(row[0]);
|
*graveyard_zoneid = Strings::ToInt(row[0]);
|
||||||
if(graveyard_x != nullptr)
|
if(graveyard_x != nullptr)
|
||||||
*graveyard_x = atof(row[1]);
|
*graveyard_x = Strings::ToFloat(row[1]);
|
||||||
if(graveyard_y != nullptr)
|
if(graveyard_y != nullptr)
|
||||||
*graveyard_y = atof(row[2]);
|
*graveyard_y = Strings::ToFloat(row[2]);
|
||||||
if(graveyard_z != nullptr)
|
if(graveyard_z != nullptr)
|
||||||
*graveyard_z = atof(row[3]);
|
*graveyard_z = Strings::ToFloat(row[3]);
|
||||||
if(graveyard_heading != nullptr)
|
if(graveyard_heading != nullptr)
|
||||||
*graveyard_heading = atof(row[4]);
|
*graveyard_heading = Strings::ToFloat(row[4]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1168,13 +1168,13 @@ uint32 Database::GetAccountIDFromLSID(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
account_id = std::stoi(row[0]);
|
account_id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
if (in_account_name) {
|
if (in_account_name) {
|
||||||
strcpy(in_account_name, row[1]);
|
strcpy(in_account_name, row[1]);
|
||||||
}
|
}
|
||||||
if (in_status) {
|
if (in_status) {
|
||||||
*in_status = std::stoi(row[2]);
|
*in_status = Strings::ToInt(row[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1198,7 +1198,7 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
|
|||||||
if (oAccountName)
|
if (oAccountName)
|
||||||
strcpy(oAccountName, row[0]);
|
strcpy(oAccountName, row[0]);
|
||||||
if (oStatus)
|
if (oStatus)
|
||||||
*oStatus = atoi(row[1]);
|
*oStatus = Strings::ToInt(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::ClearMerchantTemp(){
|
void Database::ClearMerchantTemp(){
|
||||||
@@ -1244,7 +1244,7 @@ uint8 Database::GetServerType() {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
|
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
|
||||||
@@ -1281,44 +1281,6 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
|
|||||||
return results.RowsAffected() != 0;
|
return results.RowsAffected() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
|
|
||||||
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.RowsAffected() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
|
|
||||||
//Utilize the "hacker" table, but also give zone information.
|
|
||||||
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.RowsAffected() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
|
|
||||||
//Utilize the "hacker" table, but also give zone information.
|
|
||||||
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
|
|
||||||
accountname, charactername, hacked, zone);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.RowsAffected() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
||||||
{
|
{
|
||||||
uint16 race_cap = 0;
|
uint16 race_cap = 0;
|
||||||
@@ -1334,7 +1296,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
|
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
|
||||||
@@ -1350,12 +1312,12 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
|
|||||||
if (results.Success() && results.RowsAffected() != 0)
|
if (results.Success() && results.RowsAffected() != 0)
|
||||||
{
|
{
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
skill_level = atoi(row[0]);
|
skill_level = Strings::ToInt(row[0]);
|
||||||
skill_formula = atoi(row[1]);
|
skill_formula = Strings::ToInt(row[1]);
|
||||||
skill_cap = atoi(row[2]);
|
skill_cap = Strings::ToInt(row[2]);
|
||||||
if (atoi(row[3]) > skill_cap)
|
if (Strings::ToInt(row[3]) > skill_cap)
|
||||||
skill_cap2 = (atoi(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
|
skill_cap2 = (Strings::ToInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
|
||||||
skill_cap3 = atoi(row[4]);
|
skill_cap3 = Strings::ToInt(row[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int race_skill = GetRaceSkill(skillid,in_race);
|
int race_skill = GetRaceSkill(skillid,in_race);
|
||||||
@@ -1400,10 +1362,10 @@ uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto character_id = std::stoul(row[0]);
|
auto character_id = Strings::ToUnsignedInt(row[0]);
|
||||||
*account_id = std::stoul(row[1]);
|
*account_id = Strings::ToUnsignedInt(row[1]);
|
||||||
*zone_id = std::stoul(row[2]);
|
*zone_id = Strings::ToUnsignedInt(row[2]);
|
||||||
*instance_id = std::stoul(row[3]);
|
*instance_id = Strings::ToUnsignedInt(row[3]);
|
||||||
|
|
||||||
return character_id;
|
return character_id;
|
||||||
}
|
}
|
||||||
@@ -1526,7 +1488,7 @@ uint32 Database::GetGroupID(const char* name){
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
||||||
@@ -1540,7 +1502,7 @@ std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
|||||||
|
|
||||||
if (results.Success() && results.RowCount()) {
|
if (results.Success() && results.RowCount()) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
group_id = std::stoul(row[0]);
|
group_id = Strings::ToUnsignedInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!group_id) {
|
if (!group_id) {
|
||||||
@@ -1629,7 +1591,7 @@ char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* mainta
|
|||||||
strcpy(mentoree, row[5]);
|
strcpy(mentoree, row[5]);
|
||||||
|
|
||||||
if (mentor_percent)
|
if (mentor_percent)
|
||||||
*mentor_percent = atoi(row[6]);
|
*mentor_percent = Strings::ToInt(row[6]);
|
||||||
|
|
||||||
if(GLAA && results.LengthOfColumn(7) == sizeof(GroupLeadershipAA_Struct))
|
if(GLAA && results.LengthOfColumn(7) == sizeof(GroupLeadershipAA_Struct))
|
||||||
memcpy(GLAA, row[7], sizeof(GroupLeadershipAA_Struct));
|
memcpy(GLAA, row[7], sizeof(GroupLeadershipAA_Struct));
|
||||||
@@ -1676,7 +1638,7 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetAgreementFlag(uint32 acctid) {
|
void Database::SetAgreementFlag(uint32 acctid) {
|
||||||
@@ -1762,7 +1724,7 @@ uint32 Database::GetRaidID(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (row[0]) // would it ever be possible to have a null here?
|
if (row[0]) // would it ever be possible to have a null here?
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1845,7 +1807,7 @@ void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
|
|||||||
strcpy(mentoree, row[4]);
|
strcpy(mentoree, row[4]);
|
||||||
|
|
||||||
if (mentor_percent)
|
if (mentor_percent)
|
||||||
*mentor_percent = atoi(row[5]);
|
*mentor_percent = Strings::ToInt(row[5]);
|
||||||
|
|
||||||
if (GLAA && results.LengthOfColumn(6) == sizeof(GroupLeadershipAA_Struct))
|
if (GLAA && results.LengthOfColumn(6) == sizeof(GroupLeadershipAA_Struct))
|
||||||
memcpy(GLAA, row[6], sizeof(GroupLeadershipAA_Struct));
|
memcpy(GLAA, row[6], sizeof(GroupLeadershipAA_Struct));
|
||||||
@@ -2018,16 +1980,16 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
as->success.guk = atoi(row[0]);
|
as->success.guk = Strings::ToInt(row[0]);
|
||||||
as->success.mir = atoi(row[1]);
|
as->success.mir = Strings::ToInt(row[1]);
|
||||||
as->success.mmc = atoi(row[2]);
|
as->success.mmc = Strings::ToInt(row[2]);
|
||||||
as->success.ruj = atoi(row[3]);
|
as->success.ruj = Strings::ToInt(row[3]);
|
||||||
as->success.tak = atoi(row[4]);
|
as->success.tak = Strings::ToInt(row[4]);
|
||||||
as->failure.guk = atoi(row[5]);
|
as->failure.guk = Strings::ToInt(row[5]);
|
||||||
as->failure.mir = atoi(row[6]);
|
as->failure.mir = Strings::ToInt(row[6]);
|
||||||
as->failure.mmc = atoi(row[7]);
|
as->failure.mmc = Strings::ToInt(row[7]);
|
||||||
as->failure.ruj = atoi(row[8]);
|
as->failure.ruj = Strings::ToInt(row[8]);
|
||||||
as->failure.tak = atoi(row[9]);
|
as->failure.tak = Strings::ToInt(row[9]);
|
||||||
as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak;
|
as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak;
|
||||||
as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak;
|
as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak;
|
||||||
|
|
||||||
@@ -2046,7 +2008,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
||||||
@@ -2068,7 +2030,7 @@ uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
||||||
@@ -2082,7 +2044,7 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
|||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
return atoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2096,7 +2058,7 @@ int Database::CountInvSnapshots() {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
int64 count = atoll(row[0]);
|
int64 count = Strings::ToBigInt(row[0]);
|
||||||
if (count > 2147483647)
|
if (count > 2147483647)
|
||||||
return -2;
|
return -2;
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
@@ -2132,12 +2094,12 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
|||||||
else{
|
else{
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
eqTime.minute = atoi(row[0]);
|
eqTime.minute = Strings::ToInt(row[0]);
|
||||||
eqTime.hour = atoi(row[1]);
|
eqTime.hour = Strings::ToInt(row[1]);
|
||||||
eqTime.day = atoi(row[2]);
|
eqTime.day = Strings::ToInt(row[2]);
|
||||||
eqTime.month = atoi(row[3]);
|
eqTime.month = Strings::ToInt(row[3]);
|
||||||
eqTime.year = atoi(row[4]);
|
eqTime.year = Strings::ToInt(row[4]);
|
||||||
realtime = atoi(row[5]);
|
realtime = Strings::ToInt(row[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return eqTime;
|
return eqTime;
|
||||||
@@ -2164,7 +2126,7 @@ int Database::GetIPExemption(std::string account_ip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return std::stoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||||
@@ -2178,7 +2140,7 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (results.Success() && results.RowCount()) {
|
if (results.Success() && results.RowCount()) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
exemption_id = std::stoul(row[0]);
|
exemption_id = Strings::ToUnsignedInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
@@ -2204,7 +2166,7 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
|||||||
|
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return atoi(row[0]);;
|
return Strings::ToInt(row[0]);;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -34,8 +34,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//atoi is not uint32 or uint32 safe!!!!
|
|
||||||
#define atoul(str) strtoul(str, nullptr, 10)
|
|
||||||
|
|
||||||
class MySQLRequestResult;
|
class MySQLRequestResult;
|
||||||
class Client;
|
class Client;
|
||||||
@@ -108,9 +106,6 @@ public:
|
|||||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||||
bool ReserveName(uint32 account_id, char *name);
|
bool ReserveName(uint32 account_id, char *name);
|
||||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||||
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
|
|
||||||
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
|
|
||||||
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
|
|
||||||
bool UpdateName(const char *oldname, const char *newname);
|
bool UpdateName(const char *oldname, const char *newname);
|
||||||
bool CopyCharacter(
|
bool CopyCharacter(
|
||||||
const std::string& source_character_name,
|
const std::string& source_character_name,
|
||||||
|
|||||||
@@ -476,10 +476,11 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
CheckDatabaseConvertPPDeblob();
|
CheckDatabaseConvertPPDeblob();
|
||||||
CheckDatabaseConvertCorpseDeblob();
|
CheckDatabaseConvertCorpseDeblob();
|
||||||
|
|
||||||
RuleManager::Instance()->LoadRules(this, "default", false);
|
auto *r = RuleManager::Instance();
|
||||||
|
r->LoadRules(this, "default", false);
|
||||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
||||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||||
RuleManager::Instance()->SetRule("Bots:Enabled", "true", this, true, true);
|
r->SetRule("Bots:Enabled", "true", this, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run EQEmu Server script (Checks for database updates) */
|
/* Run EQEmu Server script (Checks for database updates) */
|
||||||
@@ -529,7 +530,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`");
|
rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`");
|
||||||
results = QueryDatabase(rquery);
|
results = QueryDatabase(rquery);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
number_of_characters = atoi(row[0]);
|
number_of_characters = Strings::ToInt(row[0]);
|
||||||
printf("Number of Characters in Database: %i \n", number_of_characters);
|
printf("Number of Characters in Database: %i \n", number_of_characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,19 +929,19 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
char_iter_count++;
|
char_iter_count++;
|
||||||
squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0]));
|
squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", Strings::ToInt(row[0]));
|
||||||
auto results2 = QueryDatabase(squery);
|
auto results2 = QueryDatabase(squery);
|
||||||
auto row2 = results2.begin();
|
auto row2 = results2.begin();
|
||||||
pp = (Convert::PlayerProfile_Struct*)row2[1];
|
pp = (Convert::PlayerProfile_Struct*)row2[1];
|
||||||
e_pp = (ExtendedProfile_Struct*)row2[11];
|
e_pp = (ExtendedProfile_Struct*)row2[11];
|
||||||
character_id = atoi(row[0]);
|
character_id = Strings::ToInt(row[0]);
|
||||||
account_id = atoi(row2[4]);
|
account_id = Strings::ToInt(row2[4]);
|
||||||
/* Convert some data from the character_ table that is still relevant */
|
/* Convert some data from the character_ table that is still relevant */
|
||||||
firstlogon = atoi(row2[5]);
|
firstlogon = Strings::ToInt(row2[5]);
|
||||||
lfg = atoi(row2[6]);
|
lfg = Strings::ToInt(row2[6]);
|
||||||
lfp = atoi(row2[7]);
|
lfp = Strings::ToInt(row2[7]);
|
||||||
mailkey = row2[8];
|
mailkey = row2[8];
|
||||||
xtargets = atoi(row2[9]);
|
xtargets = Strings::ToInt(row2[9]);
|
||||||
inspectmessage = row2[10];
|
inspectmessage = row2[10];
|
||||||
|
|
||||||
/* Verify PP Integrity */
|
/* Verify PP Integrity */
|
||||||
@@ -1566,7 +1567,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses");
|
rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses");
|
||||||
results = QueryDatabase(rquery);
|
results = QueryDatabase(rquery);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0]));
|
std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", Strings::ToInt(row[0]));
|
||||||
auto results2 = QueryDatabase(squery);
|
auto results2 = QueryDatabase(squery);
|
||||||
for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) {
|
for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) {
|
||||||
in_datasize = results2.LengthOfColumn(2);
|
in_datasize = results2.LengthOfColumn(2);
|
||||||
@@ -1598,7 +1599,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
c_type = "NULL";
|
c_type = "NULL";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << atoi(row2[0]) << std::endl;
|
std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << Strings::ToInt(row2[0]) << std::endl;
|
||||||
|
|
||||||
if (is_sof){
|
if (is_sof){
|
||||||
scquery = StringFormat("UPDATE `character_corpses` SET \n"
|
scquery = StringFormat("UPDATE `character_corpses` SET \n"
|
||||||
@@ -1669,7 +1670,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
dbpc->item_tint[6].color,
|
dbpc->item_tint[6].color,
|
||||||
dbpc->item_tint[7].color,
|
dbpc->item_tint[7].color,
|
||||||
dbpc->item_tint[8].color,
|
dbpc->item_tint[8].color,
|
||||||
atoi(row2[0])
|
Strings::ToInt(row2[0])
|
||||||
);
|
);
|
||||||
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
||||||
|
|
||||||
@@ -1681,7 +1682,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
||||||
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
||||||
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||||
atoi(row2[0]),
|
Strings::ToInt(row2[0]),
|
||||||
dbpc->items[i].equipSlot,
|
dbpc->items[i].equipSlot,
|
||||||
dbpc->items[i].item_id,
|
dbpc->items[i].item_id,
|
||||||
dbpc->items[i].charges,
|
dbpc->items[i].charges,
|
||||||
@@ -1697,7 +1698,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||||
atoi(row2[0]),
|
Strings::ToInt(row2[0]),
|
||||||
dbpc->items[i].equipSlot,
|
dbpc->items[i].equipSlot,
|
||||||
dbpc->items[i].item_id,
|
dbpc->items[i].item_id,
|
||||||
dbpc->items[i].charges,
|
dbpc->items[i].charges,
|
||||||
@@ -1777,7 +1778,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
dbpc_c->item_tint[6].color,
|
dbpc_c->item_tint[6].color,
|
||||||
dbpc_c->item_tint[7].color,
|
dbpc_c->item_tint[7].color,
|
||||||
dbpc_c->item_tint[8].color,
|
dbpc_c->item_tint[8].color,
|
||||||
atoi(row2[0])
|
Strings::ToInt(row2[0])
|
||||||
);
|
);
|
||||||
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
||||||
|
|
||||||
@@ -1790,7 +1791,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
||||||
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
||||||
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||||
atoi(row2[0]),
|
Strings::ToInt(row2[0]),
|
||||||
dbpc_c->items[i].equipSlot,
|
dbpc_c->items[i].equipSlot,
|
||||||
dbpc_c->items[i].item_id,
|
dbpc_c->items[i].item_id,
|
||||||
dbpc_c->items[i].charges,
|
dbpc_c->items[i].charges,
|
||||||
@@ -1806,7 +1807,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||||
atoi(row2[0]),
|
Strings::ToInt(row2[0]),
|
||||||
dbpc_c->items[i].equipSlot,
|
dbpc_c->items[i].equipSlot,
|
||||||
dbpc_c->items[i].item_id,
|
dbpc_c->items[i].item_id,
|
||||||
dbpc_c->items[i].charges,
|
dbpc_c->items[i].charges,
|
||||||
|
|||||||
@@ -167,8 +167,8 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (atoi(row[0]) <= max) {
|
if (Strings::ToInt(row[0]) <= max) {
|
||||||
instance_id = atoi(row[0]);
|
instance_id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
max_reserved_instance_id++;
|
max_reserved_instance_id++;
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row : results) {
|
||||||
if (max_reserved_instance_id < std::stoul(row[0])) {
|
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = max_reserved_instance_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -301,7 +301,7 @@ uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 versio
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return static_cast<uint16>(std::stoul(row[0]));
|
return static_cast<uint16>(Strings::ToUnsignedInt(row[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
||||||
@@ -328,7 +328,7 @@ std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row : results) {
|
||||||
l.push_back(static_cast<uint16>(std::stoul(row[0])));
|
l.push_back(static_cast<uint16>(Strings::ToUnsignedInt(row[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
@@ -409,7 +409,7 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
|||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
auto zone_id = GetInstanceZoneID(instance_id);
|
||||||
auto version = GetInstanceVersion(instance_id);
|
auto version = GetInstanceVersion(instance_id);
|
||||||
|
|
||||||
auto l = GroupIdRepository::GetWhere(
|
auto l = RaidMembersRepository::GetWhere(
|
||||||
*this,
|
*this,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"raidid = {}",
|
"raidid = {}",
|
||||||
|
|||||||
@@ -321,13 +321,11 @@ namespace DatabaseSchema {
|
|||||||
"discord_webhooks",
|
"discord_webhooks",
|
||||||
"dynamic_zone_members",
|
"dynamic_zone_members",
|
||||||
"dynamic_zones",
|
"dynamic_zones",
|
||||||
"eventlog",
|
|
||||||
"expedition_lockouts",
|
"expedition_lockouts",
|
||||||
"expeditions",
|
"expeditions",
|
||||||
"gm_ips",
|
"gm_ips",
|
||||||
"group_id",
|
"group_id",
|
||||||
"group_leaders",
|
"group_leaders",
|
||||||
"hackers",
|
|
||||||
"instance_list",
|
"instance_list",
|
||||||
"ip_exemptions",
|
"ip_exemptions",
|
||||||
"item_tick",
|
"item_tick",
|
||||||
@@ -343,6 +341,8 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
|
"player_event_log_settings",
|
||||||
|
"player_event_logs",
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
"shared_task_dynamic_zones",
|
"shared_task_dynamic_zones",
|
||||||
"shared_task_members",
|
"shared_task_members",
|
||||||
|
|||||||
+54
-48
@@ -34,14 +34,16 @@
|
|||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
{
|
{
|
||||||
mysql_init(&mysql);
|
mysql = mysql_init(nullptr);
|
||||||
pHost = nullptr;
|
mysqlOwner = true;
|
||||||
pUser = nullptr;
|
pHost = nullptr;
|
||||||
pPassword = nullptr;
|
pUser = nullptr;
|
||||||
pDatabase = nullptr;
|
pPassword = nullptr;
|
||||||
pCompress = false;
|
pDatabase = nullptr;
|
||||||
pSSL = false;
|
pCompress = false;
|
||||||
pStatus = Closed;
|
pSSL = false;
|
||||||
|
pStatus = Closed;
|
||||||
|
m_mutex = new Mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore()
|
||||||
@@ -51,16 +53,10 @@ DBcore::~DBcore()
|
|||||||
* are re-using the default database connection pointer when we dont have an
|
* are re-using the default database connection pointer when we dont have an
|
||||||
* external configuration setup ex: (content_database)
|
* external configuration setup ex: (content_database)
|
||||||
*/
|
*/
|
||||||
std::string mysql_connection_host;
|
if (mysqlOwner) {
|
||||||
if (mysql.host) {
|
mysql_close(mysql);
|
||||||
mysql_connection_host = mysql.host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetOriginHost() != mysql_connection_host) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mysql_close(&mysql);
|
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -70,17 +66,18 @@ DBcore::~DBcore()
|
|||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!MDatabase.trylock()) {
|
if (!m_mutex->trylock()) {
|
||||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mysql_ping(&mysql);
|
mysql_ping(mysql);
|
||||||
MDatabase.unlock();
|
m_mutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
||||||
{
|
{
|
||||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::DoesTableExist(std::string table_name)
|
bool DBcore::DoesTableExist(std::string table_name)
|
||||||
@@ -95,18 +92,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(&MDatabase);
|
LockMutex lock(m_mutex);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
Open();
|
Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// request query. != 0 indicates some kind of error.
|
// request query. != 0 indicates some kind of error.
|
||||||
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
if (mysql_real_query(mysql, query, querylen) != 0) {
|
||||||
unsigned int errorNumber = mysql_errno(&mysql);
|
unsigned int errorNumber = mysql_errno(mysql);
|
||||||
|
|
||||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
@@ -130,26 +125,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||||
|
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(mysql), errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error logging
|
* Error logging
|
||||||
*/
|
*/
|
||||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
|
||||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(&mysql), mysql_error(&mysql), query);
|
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// successful query. get results.
|
// successful query. get results.
|
||||||
MYSQL_RES *res = mysql_store_result(&mysql);
|
MYSQL_RES *res = mysql_store_result(mysql);
|
||||||
uint32 rowCount = 0;
|
uint32 rowCount = 0;
|
||||||
|
|
||||||
if (res != nullptr) {
|
if (res != nullptr) {
|
||||||
@@ -158,10 +153,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
MySQLRequestResult requestResult(
|
MySQLRequestResult requestResult(
|
||||||
res,
|
res,
|
||||||
(uint32) mysql_affected_rows(&mysql),
|
(uint32) mysql_affected_rows(mysql),
|
||||||
rowCount,
|
rowCount,
|
||||||
(uint32) mysql_field_count(&mysql),
|
(uint32) mysql_field_count(mysql),
|
||||||
(uint32) mysql_insert_id(&mysql)
|
(uint32) mysql_insert_id(mysql)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||||
@@ -207,7 +202,7 @@ uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen)
|
|||||||
{
|
{
|
||||||
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||||
// LockMutex lock(&MDatabase);
|
// LockMutex lock(&MDatabase);
|
||||||
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
return mysql_real_escape_string(mysql, tobuf, frombuf, fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::Open(
|
bool DBcore::Open(
|
||||||
@@ -222,7 +217,7 @@ bool DBcore::Open(
|
|||||||
bool iSSL
|
bool iSSL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LockMutex lock(&MDatabase);
|
LockMutex lock(m_mutex);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -242,13 +237,13 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
LockMutex lock(&MDatabase);
|
LockMutex lock(m_mutex);
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (GetStatus() == Error) {
|
if (GetStatus() == Error) {
|
||||||
mysql_close(&mysql);
|
mysql_close(mysql);
|
||||||
mysql_init(&mysql); // Initialize structure again
|
mysql_init(mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (!pHost) {
|
||||||
return false;
|
return false;
|
||||||
@@ -265,7 +260,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (pSSL) {
|
if (pSSL) {
|
||||||
flags |= CLIENT_SSL;
|
flags |= CLIENT_SSL;
|
||||||
}
|
}
|
||||||
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
|
|
||||||
std::string connected_origin_host = pHost;
|
std::string connected_origin_host = pHost;
|
||||||
@@ -275,21 +270,16 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (errnum) {
|
if (errnum) {
|
||||||
*errnum = mysql_errno(&mysql);
|
*errnum = mysql_errno(mysql);
|
||||||
}
|
}
|
||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
||||||
}
|
}
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetMysql(MYSQL *mysql)
|
|
||||||
{
|
|
||||||
DBcore::mysql = *mysql;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &DBcore::GetOriginHost() const
|
const std::string &DBcore::GetOriginHost() const
|
||||||
{
|
{
|
||||||
return origin_host;
|
return origin_host;
|
||||||
@@ -299,3 +289,19 @@ void DBcore::SetOriginHost(const std::string &origin_host)
|
|||||||
{
|
{
|
||||||
DBcore::origin_host = origin_host;
|
DBcore::origin_host = origin_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DBcore::Escape(const std::string& s)
|
||||||
|
{
|
||||||
|
const std::size_t s_len = s.length();
|
||||||
|
std::vector<char> temp((s_len * 2) + 1, '\0');
|
||||||
|
mysql_real_escape_string(mysql, temp.data(), s.c_str(), s_len);
|
||||||
|
|
||||||
|
return temp.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DBcore::SetMutex(Mutex *mutex)
|
||||||
|
{
|
||||||
|
safe_delete(m_mutex);
|
||||||
|
|
||||||
|
DBcore::m_mutex = mutex;
|
||||||
|
}
|
||||||
|
|||||||
+14
-4
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
@@ -27,16 +28,22 @@ public:
|
|||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
void TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
|
std::string Escape(const std::string& s);
|
||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
MYSQL *getMySQL() { return &mysql; }
|
|
||||||
void SetMysql(MYSQL *mysql);
|
|
||||||
|
|
||||||
const std::string &GetOriginHost() const;
|
const std::string &GetOriginHost() const;
|
||||||
void SetOriginHost(const std::string &origin_host);
|
void SetOriginHost(const std::string &origin_host);
|
||||||
|
|
||||||
bool DoesTableExist(std::string table_name);
|
bool DoesTableExist(std::string table_name);
|
||||||
|
|
||||||
|
void SetMySQL(const DBcore &o)
|
||||||
|
{
|
||||||
|
mysql = o.mysql;
|
||||||
|
mysqlOwner = false;
|
||||||
|
}
|
||||||
|
void SetMutex(Mutex *mutex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Open(
|
bool Open(
|
||||||
const char *iHost,
|
const char *iHost,
|
||||||
@@ -53,10 +60,13 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||||
|
|
||||||
MYSQL mysql;
|
MYSQL* mysql;
|
||||||
Mutex MDatabase;
|
bool mysqlOwner;
|
||||||
|
Mutex *m_mutex;
|
||||||
eStatus pStatus;
|
eStatus pStatus;
|
||||||
|
|
||||||
|
std::mutex m_query_lock{};
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
char *pHost;
|
||||||
|
|||||||
+93
-13
@@ -1,22 +1,17 @@
|
|||||||
|
#include <cereal/archives/json.hpp>
|
||||||
|
#include <cereal/archives/binary.hpp>
|
||||||
#include "discord.h"
|
#include "discord.h"
|
||||||
#include "../http/httplib.h"
|
#include "../http/httplib.h"
|
||||||
#include "../json/json.h"
|
#include "../json/json.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../events/player_event_logs.h"
|
||||||
|
|
||||||
constexpr int MAX_RETRIES = 10;
|
constexpr int MAX_RETRIES = 10;
|
||||||
|
|
||||||
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
||||||
{
|
{
|
||||||
// validate
|
if (!ValidateWebhookUrl(webhook_url)) {
|
||||||
if (webhook_url.empty()) {
|
|
||||||
LogDiscord("[webhook_url] is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate
|
|
||||||
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
|
|
||||||
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +23,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||||
|
|
||||||
// client
|
// client
|
||||||
httplib::Client cli(base_url.c_str());
|
httplib::Client cli(base_url);
|
||||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||||
cli.set_read_timeout(15, 0); // 15 seconds
|
cli.set_read_timeout(15, 0); // 15 seconds
|
||||||
cli.set_write_timeout(15, 0); // 15 seconds
|
cli.set_write_timeout(15, 0); // 15 seconds
|
||||||
@@ -46,9 +41,9 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
int retries = 0;
|
int retries = 0;
|
||||||
int retry_timer = 1000;
|
int retry_timer = 1000;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
|
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
|
||||||
if (res->status != 200 && res->status != 204) {
|
if (res->status != 200 && res->status != 204) {
|
||||||
LogError("Code [{}] Error [{}]", res->status, res->body);
|
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
|
||||||
}
|
}
|
||||||
if (res->status == 429) {
|
if (res->status == 429) {
|
||||||
if (!res->body.empty()) {
|
if (!res->body.empty()) {
|
||||||
@@ -62,7 +57,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
retry_timer = Strings::ToInt(response["retry_after"].asString()) + 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||||
@@ -81,6 +76,74 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Discord::SendPlayerEventMessage(
|
||||||
|
const PlayerEvent::PlayerEventContainer &e,
|
||||||
|
const std::string &webhook_url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!ValidateWebhookUrl(webhook_url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto s = Strings::Split(webhook_url, '/');
|
||||||
|
|
||||||
|
// url
|
||||||
|
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
||||||
|
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||||
|
|
||||||
|
// client
|
||||||
|
httplib::Client cli(base_url);
|
||||||
|
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||||
|
cli.set_read_timeout(15, 0); // 15 seconds
|
||||||
|
cli.set_write_timeout(15, 0); // 15 seconds
|
||||||
|
httplib::Headers headers = {
|
||||||
|
{"Content-Type", "application/json"}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
|
||||||
|
if (payload.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool retry = true;
|
||||||
|
int retries = 0;
|
||||||
|
int retry_timer = 1000;
|
||||||
|
while (retry) {
|
||||||
|
if (auto res = cli.Post(endpoint, payload, "application/json")) {
|
||||||
|
if (res->status != 200 && res->status != 204) {
|
||||||
|
LogError("Code [{}] Error [{}]", res->status, res->body);
|
||||||
|
}
|
||||||
|
if (res->status == 429) {
|
||||||
|
if (!res->body.empty()) {
|
||||||
|
std::stringstream ss(res->body);
|
||||||
|
Json::Value response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ss >> response;
|
||||||
|
}
|
||||||
|
catch (std::exception const &ex) {
|
||||||
|
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
retry_timer = Strings::ToInt(response["retry_after"].asString()) + 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
||||||
|
}
|
||||||
|
if (res->status == 204) {
|
||||||
|
retry = false;
|
||||||
|
}
|
||||||
|
if (retries > MAX_RETRIES) {
|
||||||
|
LogDiscord("Retries exceeded for player event message");
|
||||||
|
retry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
retries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
||||||
{
|
{
|
||||||
if (category_id == Logs::LogCategory::MySQLQuery) {
|
if (category_id == Logs::LogCategory::MySQLQuery) {
|
||||||
@@ -89,3 +152,20 @@ std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string
|
|||||||
|
|
||||||
return message + "\n";
|
return message + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
|
||||||
|
{
|
||||||
|
// validate
|
||||||
|
if (webhook_url.empty()) {
|
||||||
|
LogDiscord("[webhook_url] is empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
|
||||||
|
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,11 +4,16 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../http/httplib.h"
|
||||||
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
#include "../events/player_events.h"
|
||||||
|
|
||||||
class Discord {
|
class Discord {
|
||||||
public:
|
public:
|
||||||
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
||||||
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
||||||
|
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
|
||||||
|
static bool ValidateWebhookUrl(const std::string &webhook_url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "discord_manager.h"
|
#include "discord_manager.h"
|
||||||
#include "../common/discord/discord.h"
|
#include "../../common/discord/discord.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../events/player_event_logs.h"
|
||||||
#include "../common/strings.h"
|
|
||||||
|
|
||||||
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
||||||
{
|
{
|
||||||
@@ -55,7 +54,6 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
message = "";
|
message = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// final flush
|
// final flush
|
||||||
if (!message.empty()) {
|
if (!message.empty()) {
|
||||||
Discord::SendWebhookMessage(
|
Discord::SendWebhookMessage(
|
||||||
@@ -67,3 +65,11 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
webhook_message_queue.clear();
|
webhook_message_queue.clear();
|
||||||
webhook_queue_lock.unlock();
|
webhook_queue_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
||||||
|
{
|
||||||
|
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
||||||
|
if (!w.empty()) {
|
||||||
|
Discord::SendPlayerEventMessage(e, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,15 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../common/types.h"
|
#include "../../common/types.h"
|
||||||
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
#include "../events/player_events.h"
|
||||||
|
|
||||||
class DiscordManager {
|
class DiscordManager {
|
||||||
public:
|
public:
|
||||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
||||||
void ProcessMessageQueue();
|
void ProcessMessageQueue();
|
||||||
|
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
||||||
private:
|
private:
|
||||||
std::mutex webhook_queue_lock{};
|
std::mutex webhook_queue_lock{};
|
||||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
||||||
+27
-8
@@ -79,6 +79,8 @@
|
|||||||
#define ANIM_DEATH 0x73
|
#define ANIM_DEATH 0x73
|
||||||
#define ANIM_LOOT 0x69
|
#define ANIM_LOOT 0x69
|
||||||
|
|
||||||
|
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eaStanding = 0,
|
eaStanding = 0,
|
||||||
eaSitting, //1
|
eaSitting, //1
|
||||||
@@ -1015,15 +1017,32 @@ enum Anonymity : uint8
|
|||||||
Roleplaying
|
Roleplaying
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ZoningMessage : int8
|
enum ZoningMessage : int8 {
|
||||||
{
|
ZoneNoMessage = 0,
|
||||||
ZoneNoMessage = 0,
|
ZoneSuccess = 1,
|
||||||
ZoneSuccess = 1,
|
ZoneNotReady = -1,
|
||||||
ZoneNotReady = -1,
|
ZoneValidPC = -2,
|
||||||
ZoneValidPC = -2,
|
ZoneStoryZone = -3,
|
||||||
ZoneStoryZone = -3,
|
ZoneNoExpansion = -6,
|
||||||
ZoneNoExpansion = -6,
|
|
||||||
ZoneNoExperience = -7
|
ZoneNoExperience = -7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class RecipeCountType : uint8
|
||||||
|
{
|
||||||
|
Component,
|
||||||
|
Container,
|
||||||
|
Fail,
|
||||||
|
Salvage,
|
||||||
|
Success
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ALT_CURRENCY_ID_RADIANT 4
|
||||||
|
#define ALT_CURRENCY_ID_EBON 5
|
||||||
|
|
||||||
|
enum ResurrectionActions
|
||||||
|
{
|
||||||
|
Decline,
|
||||||
|
Accept
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
+13
-11
@@ -29,7 +29,7 @@
|
|||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 25;
|
static const uint32 BUFF_COUNT = 42;
|
||||||
static const uint32 PET_BUFF_COUNT = 30;
|
static const uint32 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
@@ -3632,17 +3632,19 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct MerchantList {
|
struct MerchantList {
|
||||||
uint32 id;
|
uint32 id;
|
||||||
uint32 slot;
|
uint32 slot;
|
||||||
uint32 item;
|
uint32 item;
|
||||||
int16 faction_required;
|
int16 faction_required;
|
||||||
int8 level_required;
|
int8 level_required;
|
||||||
uint16 alt_currency_cost;
|
uint8 min_status;
|
||||||
uint32 classes_required;
|
uint8 max_status;
|
||||||
uint8 probability;
|
uint16 alt_currency_cost;
|
||||||
|
uint32 classes_required;
|
||||||
|
uint8 probability;
|
||||||
std::string bucket_name;
|
std::string bucket_name;
|
||||||
std::string bucket_value;
|
std::string bucket_value;
|
||||||
uint8 bucket_comparison;
|
uint8 bucket_comparison;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TempMerchantList {
|
struct TempMerchantList {
|
||||||
@@ -4545,7 +4547,7 @@ struct ItemVerifyReply_Struct {
|
|||||||
struct ItemRecastDelay_Struct {
|
struct ItemRecastDelay_Struct {
|
||||||
/*000*/ uint32 recast_delay; // in seconds
|
/*000*/ uint32 recast_delay; // in seconds
|
||||||
/*004*/ uint32 recast_type;
|
/*004*/ uint32 recast_type;
|
||||||
/*008*/ uint32 unknown008;
|
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+19
-18
@@ -19,6 +19,7 @@
|
|||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -33,13 +34,13 @@ void EQEmuConfig::parse_config()
|
|||||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||||
LoginCount = 0;
|
LoginCount = 0;
|
||||||
|
|
||||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
LoginPort = Strings::ToInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||||
LoginLegacy = false;
|
LoginLegacy = false;
|
||||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||||
@@ -62,7 +63,7 @@ void EQEmuConfig::parse_config()
|
|||||||
|
|
||||||
auto loginconfig = new LoginConfig;
|
auto loginconfig = new LoginConfig;
|
||||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
loginconfig->LoginPort = Strings::ToInt(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||||
|
|
||||||
@@ -85,15 +86,15 @@ void EQEmuConfig::parse_config()
|
|||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
WorldTCPPort = Strings::ToInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||||
|
|
||||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
TelnetTCPPort = Strings::ToInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||||
TelnetEnabled = false;
|
TelnetEnabled = false;
|
||||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||||
|
|
||||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
WorldHTTPPort = Strings::ToInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||||
WorldHTTPEnabled = false;
|
WorldHTTPEnabled = false;
|
||||||
|
|
||||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||||
@@ -108,9 +109,9 @@ void EQEmuConfig::parse_config()
|
|||||||
* UCS
|
* UCS
|
||||||
*/
|
*/
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
ChatPort = Strings::ToInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
MailPort = Strings::ToInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
@@ -118,7 +119,7 @@ void EQEmuConfig::parse_config()
|
|||||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
DatabasePort = Strings::ToInt(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,14 +128,14 @@ void EQEmuConfig::parse_config()
|
|||||||
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
||||||
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
||||||
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
||||||
ContentDbPort = atoi(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
ContentDbPort = Strings::ToInt(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QS
|
* QS
|
||||||
*/
|
*/
|
||||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
QSDatabasePort = Strings::ToInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
@@ -142,9 +143,9 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Zones
|
* Zones
|
||||||
*/
|
*/
|
||||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
DefaultStatus = Strings::ToInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
ZonePortLow = Strings::ToInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
ZonePortHigh = Strings::ToInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Files
|
* Files
|
||||||
@@ -174,10 +175,10 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Launcher
|
* Launcher
|
||||||
*/
|
*/
|
||||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||||
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ namespace Logs {
|
|||||||
PacketServerToServer,
|
PacketServerToServer,
|
||||||
Bugs,
|
Bugs,
|
||||||
QuestErrors,
|
QuestErrors,
|
||||||
|
PlayerEvents,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,7 +231,8 @@ namespace Logs {
|
|||||||
"Packet C->S",
|
"Packet C->S",
|
||||||
"Packet S->S",
|
"Packet S->S",
|
||||||
"Bugs",
|
"Bugs",
|
||||||
"QuestErrors"
|
"QuestErrors",
|
||||||
|
"PlayerEvents",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -784,6 +784,16 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogPlayerEvents(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::PlayerEvents))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogPlayerEventsDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PlayerEvents))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,214 @@
|
|||||||
|
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||||
|
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "player_events.h"
|
||||||
|
#include "../repositories/base/base_player_event_logs_repository.h"
|
||||||
|
#include <cereal/archives/json.hpp>
|
||||||
|
#include <cereal/types/vector.hpp>
|
||||||
|
|
||||||
|
struct DiscordField {
|
||||||
|
std::string name;
|
||||||
|
std::string value;
|
||||||
|
bool is_inline;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(name),
|
||||||
|
CEREAL_NVP(value),
|
||||||
|
cereal::make_nvp("inline", is_inline)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiscordAuthor {
|
||||||
|
std::string name;
|
||||||
|
std::string icon_url;
|
||||||
|
std::string url;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(name),
|
||||||
|
CEREAL_NVP(icon_url),
|
||||||
|
CEREAL_NVP(url)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiscordEmbed {
|
||||||
|
std::vector<DiscordField> fields;
|
||||||
|
std::string title;
|
||||||
|
std::string description;
|
||||||
|
std::string timestamp;
|
||||||
|
DiscordAuthor author;
|
||||||
|
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(fields),
|
||||||
|
CEREAL_NVP(title),
|
||||||
|
CEREAL_NVP(description),
|
||||||
|
CEREAL_NVP(timestamp),
|
||||||
|
CEREAL_NVP(author)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiscordWebhook {
|
||||||
|
std::vector<DiscordEmbed> embeds;
|
||||||
|
std::string content;
|
||||||
|
std::string avatar_url;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(embeds),
|
||||||
|
CEREAL_NVP(avatar_url),
|
||||||
|
CEREAL_NVP(content)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerEventDiscordFormatter {
|
||||||
|
public:
|
||||||
|
static std::string GetCurrentTimestamp();
|
||||||
|
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
||||||
|
static std::string
|
||||||
|
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
||||||
|
static void BuildDiscordField(
|
||||||
|
std::vector<DiscordField> *f,
|
||||||
|
const std::string &name,
|
||||||
|
const std::string &value,
|
||||||
|
bool is_inline = true
|
||||||
|
);
|
||||||
|
static void BuildBaseEmbed(
|
||||||
|
std::vector<DiscordEmbed> *e,
|
||||||
|
const std::vector<DiscordField> &f,
|
||||||
|
PlayerEvent::PlayerEventContainer c
|
||||||
|
);
|
||||||
|
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
||||||
|
|
||||||
|
static std::string FormatAAGainedEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::AAGainedEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatAAPurchasedEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::AAPurchasedEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatDeathEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::DeathEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatFishSuccessEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::FishSuccessEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatForageSuccessEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::ForageSuccessEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatDestroyItemEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::DestroyItemEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatDiscoverItemEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::DiscoverItemEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatDroppedItemEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::DroppedItemEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatLevelGainedEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::LevelGainedEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatLevelLostEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::LevelLostEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatLootItemEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::LootItemEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatGroundSpawnPickupEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::GroundSpawnPickupEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatMerchantPurchaseEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::MerchantPurchaseEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatMerchantSellEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::MerchantSellEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatNPCHandinEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::HandinEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatSkillUpEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::SkillUpEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTaskAcceptEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TaskAcceptEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTaskCompleteEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TaskCompleteEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTaskUpdateEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TaskUpdateEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTradeEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TradeEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTraderPurchaseEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TraderPurchaseEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatTraderSellEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::TraderSellEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatResurrectAcceptEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::ResurrectAcceptEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatSplitMoneyEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::SplitMoneyEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatCombineEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::CombineEvent &e
|
||||||
|
);
|
||||||
|
static std::string FormatZoningEvent(
|
||||||
|
const PlayerEvent::PlayerEventContainer &c,
|
||||||
|
const PlayerEvent::ZoningEvent &e
|
||||||
|
);
|
||||||
|
static DiscordWebhook BuildDiscordWebhook(
|
||||||
|
const PlayerEvent::PlayerEventContainer &p,
|
||||||
|
std::vector<DiscordEmbed> &embeds
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||||
@@ -0,0 +1,708 @@
|
|||||||
|
#include <cereal/archives/json.hpp>
|
||||||
|
#include "player_event_logs.h"
|
||||||
|
#include "player_event_discord_formatter.h"
|
||||||
|
#include "../platform.h"
|
||||||
|
#include "../rulesys.h"
|
||||||
|
|
||||||
|
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
||||||
|
|
||||||
|
// general initialization routine
|
||||||
|
void PlayerEventLogs::Init()
|
||||||
|
{
|
||||||
|
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
||||||
|
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
||||||
|
|
||||||
|
ValidateDatabaseConnection();
|
||||||
|
|
||||||
|
// initialize settings array
|
||||||
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
|
m_settings[i].id = i;
|
||||||
|
m_settings[i].event_name = PlayerEvent::EventName[i];
|
||||||
|
m_settings[i].event_enabled = 1;
|
||||||
|
m_settings[i].retention_days = 0;
|
||||||
|
m_settings[i].discord_webhook_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSettingsDefaults();
|
||||||
|
|
||||||
|
// initialize settings from database
|
||||||
|
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
||||||
|
std::vector<int> db{};
|
||||||
|
db.reserve(s.size());
|
||||||
|
for (auto &e: s) {
|
||||||
|
if (e.id >= PlayerEvent::MAX) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_settings[e.id] = e;
|
||||||
|
db.emplace_back(e.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert entries that don't exist in database
|
||||||
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
|
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
||||||
|
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
|
||||||
|
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
|
||||||
|
|
||||||
|
// remove when deprecated
|
||||||
|
if (is_deprecated && is_in_database) {
|
||||||
|
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||||
|
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
||||||
|
}
|
||||||
|
// remove when unimplemented if present
|
||||||
|
if (!is_implemented && is_in_database) {
|
||||||
|
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||||
|
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||||
|
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||||
|
LogInfo(
|
||||||
|
"[New] PlayerEvent [{}] ({})",
|
||||||
|
PlayerEvent::EventName[i],
|
||||||
|
i
|
||||||
|
);
|
||||||
|
|
||||||
|
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||||
|
c.id = i;
|
||||||
|
c.event_name = PlayerEvent::EventName[i];
|
||||||
|
c.event_enabled = m_settings[i].event_enabled;
|
||||||
|
c.retention_days = m_settings[i].retention_days;
|
||||||
|
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||||
|
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||||
|
|
||||||
|
// on initial boot process truncation
|
||||||
|
if (processing_in_world || processing_in_qs) {
|
||||||
|
ProcessRetentionTruncation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the database object, during initialization
|
||||||
|
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_database = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validates whether the connection is valid or not, used in initialization
|
||||||
|
bool PlayerEventLogs::ValidateDatabaseConnection()
|
||||||
|
{
|
||||||
|
if (!m_database) {
|
||||||
|
LogError("No database connection");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determines if the passed in event is enabled or not
|
||||||
|
// this is used to gate logic or events from firing off
|
||||||
|
// this is used prior to building the events, we don't want to
|
||||||
|
// build the events, send them through the stack in a function call
|
||||||
|
// only to discard them immediately afterwards, very wasteful on resources
|
||||||
|
// the quest api currently does this
|
||||||
|
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
|
||||||
|
{
|
||||||
|
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this processes any current player events on the queue
|
||||||
|
void PlayerEventLogs::ProcessBatchQueue()
|
||||||
|
{
|
||||||
|
m_batch_queue_lock.lock();
|
||||||
|
if (m_record_batch_queue.empty()) {
|
||||||
|
m_batch_queue_lock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BenchTimer benchmark;
|
||||||
|
|
||||||
|
// flush many
|
||||||
|
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
||||||
|
LogPlayerEventsDetail(
|
||||||
|
"Processing batch player event log queue of [{}] took [{}]",
|
||||||
|
m_record_batch_queue.size(),
|
||||||
|
benchmark.elapsed()
|
||||||
|
);
|
||||||
|
|
||||||
|
// empty
|
||||||
|
m_record_batch_queue = {};
|
||||||
|
m_batch_queue_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds a player event to the queue
|
||||||
|
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
||||||
|
{
|
||||||
|
m_batch_queue_lock.lock();
|
||||||
|
m_record_batch_queue.emplace_back(log);
|
||||||
|
m_batch_queue_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fills common event data in the SendEvent function
|
||||||
|
void PlayerEventLogs::FillPlayerEvent(
|
||||||
|
const PlayerEvent::PlayerEvent &p,
|
||||||
|
PlayerEventLogsRepository::PlayerEventLogs &n
|
||||||
|
)
|
||||||
|
{
|
||||||
|
n.account_id = p.account_id;
|
||||||
|
n.character_id = p.character_id;
|
||||||
|
n.zone_id = p.zone_id;
|
||||||
|
n.instance_id = p.instance_id;
|
||||||
|
n.x = p.x;
|
||||||
|
n.y = p.y;
|
||||||
|
n.z = p.z;
|
||||||
|
n.heading = p.heading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// builds the dynamic packet used to ship the player event over the wire
|
||||||
|
// supports serializing the struct so it can be rebuilt on the other end
|
||||||
|
std::unique_ptr<ServerPacket>
|
||||||
|
PlayerEventLogs::BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e)
|
||||||
|
{
|
||||||
|
EQ::Net::DynamicPacket dyn_pack;
|
||||||
|
dyn_pack.PutSerialize(0, e);
|
||||||
|
auto pack_size = sizeof(ServerSendPlayerEvent_Struct) + dyn_pack.Length();
|
||||||
|
auto pack = std::make_unique<ServerPacket>(ServerOP_PlayerEvent, static_cast<uint32_t>(pack_size));
|
||||||
|
auto buf = reinterpret_cast<ServerSendPlayerEvent_Struct *>(pack->pBuffer);
|
||||||
|
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
|
||||||
|
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
|
||||||
|
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlayerEventLogSettingsRepository::PlayerEventLogSettings *PlayerEventLogs::GetSettings() const
|
||||||
|
{
|
||||||
|
return m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
|
||||||
|
{
|
||||||
|
// out of bounds check
|
||||||
|
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure webhook id is set
|
||||||
|
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure there is a matching webhook to begin with
|
||||||
|
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_type_id)
|
||||||
|
{
|
||||||
|
// out of bounds check
|
||||||
|
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure webhook id is set
|
||||||
|
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure there is a matching webhook to begin with
|
||||||
|
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
||||||
|
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// GM_COMMAND | [x] Implemented Formatter
|
||||||
|
// ZONING | [x] Implemented Formatter
|
||||||
|
// AA_GAIN | [x] Implemented Formatter
|
||||||
|
// AA_PURCHASE | [x] Implemented Formatter
|
||||||
|
// FORAGE_SUCCESS | [x] Implemented Formatter
|
||||||
|
// FORAGE_FAILURE | [x] Implemented Formatter
|
||||||
|
// FISH_SUCCESS | [x] Implemented Formatter
|
||||||
|
// FISH_FAILURE | [x] Implemented Formatter
|
||||||
|
// ITEM_DESTROY | [x] Implemented Formatter
|
||||||
|
// WENT_ONLINE | [x] Implemented Formatter
|
||||||
|
// WENT_OFFLINE | [x] Implemented Formatter
|
||||||
|
// LEVEL_GAIN | [x] Implemented Formatter
|
||||||
|
// LEVEL_LOSS | [x] Implemented Formatter
|
||||||
|
// LOOT_ITEM | [x] Implemented Formatter
|
||||||
|
// MERCHANT_PURCHASE | [x] Implemented Formatter
|
||||||
|
// MERCHANT_SELL | [x] Implemented Formatter
|
||||||
|
// GROUP_JOIN | [] Implemented Formatter
|
||||||
|
// GROUP_LEAVE | [] Implemented Formatter
|
||||||
|
// RAID_JOIN | [] Implemented Formatter
|
||||||
|
// RAID_LEAVE | [] Implemented Formatter
|
||||||
|
// GROUNDSPAWN_PICKUP | [x] Implemented Formatter
|
||||||
|
// NPC_HANDIN | [x] Implemented Formatter
|
||||||
|
// SKILL_UP | [x] Implemented Formatter
|
||||||
|
// TASK_ACCEPT | [x] Implemented Formatter
|
||||||
|
// TASK_UPDATE | [x] Implemented Formatter
|
||||||
|
// TASK_COMPLETE | [x] Implemented Formatter
|
||||||
|
// TRADE | [] Implemented Formatter
|
||||||
|
// GIVE_ITEM | [] Implemented Formatter
|
||||||
|
// SAY | [x] Implemented Formatter
|
||||||
|
// REZ_ACCEPTED | [x] Implemented Formatter
|
||||||
|
// DEATH | [x] Implemented Formatter
|
||||||
|
// COMBINE_FAILURE | [x] Implemented Formatter
|
||||||
|
// COMBINE_SUCCESS | [x] Implemented Formatter
|
||||||
|
// DROPPED_ITEM | [x] Implemented Formatter
|
||||||
|
// SPLIT_MONEY | [x] Implemented Formatter
|
||||||
|
// DZ_JOIN | [] Implemented Formatter
|
||||||
|
// DZ_LEAVE | [] Implemented Formatter
|
||||||
|
// TRADER_PURCHASE | [x] Implemented Formatter
|
||||||
|
// TRADER_SELL | [x] Implemented Formatter
|
||||||
|
// BANDOLIER_CREATE | [] Implemented Formatter
|
||||||
|
// BANDOLIER_SWAP | [] Implemented Formatter
|
||||||
|
// DISCOVER_ITEM | [X] Implemented Formatter
|
||||||
|
|
||||||
|
std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e)
|
||||||
|
{
|
||||||
|
std::string payload;
|
||||||
|
switch (e.player_event_log.event_type_id) {
|
||||||
|
case PlayerEvent::AA_GAIN: {
|
||||||
|
PlayerEvent::AAGainedEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatAAGainedEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::AA_PURCHASE: {
|
||||||
|
PlayerEvent::AAPurchasedEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatAAPurchasedEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::COMBINE_FAILURE:
|
||||||
|
case PlayerEvent::COMBINE_SUCCESS: {
|
||||||
|
PlayerEvent::CombineEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatCombineEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::DEATH: {
|
||||||
|
PlayerEvent::DeathEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatDeathEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::DISCOVER_ITEM: {
|
||||||
|
PlayerEvent::DiscoverItemEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatDiscoverItemEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::DROPPED_ITEM: {
|
||||||
|
PlayerEvent::DroppedItemEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::FISH_FAILURE: {
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::FISH_SUCCESS: {
|
||||||
|
PlayerEvent::FishSuccessEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::FORAGE_FAILURE: {
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::FORAGE_SUCCESS: {
|
||||||
|
PlayerEvent::ForageSuccessEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatForageSuccessEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::ITEM_DESTROY: {
|
||||||
|
PlayerEvent::DestroyItemEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatDestroyItemEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::LEVEL_GAIN: {
|
||||||
|
PlayerEvent::LevelGainedEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatLevelGainedEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::LEVEL_LOSS: {
|
||||||
|
PlayerEvent::LevelLostEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatLevelLostEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::LOOT_ITEM: {
|
||||||
|
PlayerEvent::LootItemEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatLootItemEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::GROUNDSPAWN_PICKUP: {
|
||||||
|
PlayerEvent::GroundSpawnPickupEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatGroundSpawnPickupEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::NPC_HANDIN: {
|
||||||
|
PlayerEvent::HandinEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatNPCHandinEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::SAY: {
|
||||||
|
PlayerEvent::SayEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatEventSay(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::GM_COMMAND: {
|
||||||
|
PlayerEvent::GMCommandEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatGMCommand(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::SKILL_UP: {
|
||||||
|
PlayerEvent::SkillUpEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatSkillUpEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::SPLIT_MONEY: {
|
||||||
|
PlayerEvent::SplitMoneyEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatSplitMoneyEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TASK_ACCEPT: {
|
||||||
|
PlayerEvent::TaskAcceptEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTaskAcceptEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TASK_COMPLETE: {
|
||||||
|
PlayerEvent::TaskCompleteEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTaskCompleteEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TASK_UPDATE: {
|
||||||
|
PlayerEvent::TaskUpdateEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTaskUpdateEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TRADE: {
|
||||||
|
PlayerEvent::TradeEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTradeEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TRADER_PURCHASE: {
|
||||||
|
PlayerEvent::TraderPurchaseEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTraderPurchaseEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::TRADER_SELL: {
|
||||||
|
PlayerEvent::TraderSellEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatTraderSellEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::REZ_ACCEPTED: {
|
||||||
|
PlayerEvent::ResurrectAcceptEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::WENT_ONLINE:
|
||||||
|
case PlayerEvent::WENT_OFFLINE: {
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::MERCHANT_PURCHASE: {
|
||||||
|
PlayerEvent::MerchantPurchaseEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatMerchantPurchaseEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::MERCHANT_SELL: {
|
||||||
|
PlayerEvent::MerchantSellEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatMerchantSellEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PlayerEvent::ZONING: {
|
||||||
|
PlayerEvent::ZoningEvent n{};
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << e.player_event_log.event_data;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
n.serialize(ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = PlayerEventDiscordFormatter::FormatZoningEvent(e, n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogInfo(
|
||||||
|
"Player event [{}] ({}) Discord formatter not implemented",
|
||||||
|
e.player_event_log.event_type_name,
|
||||||
|
e.player_event_log.event_type_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
||||||
|
void PlayerEventLogs::Process()
|
||||||
|
{
|
||||||
|
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||||
|
ProcessBatchQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_process_retention_truncation_timer.Check()) {
|
||||||
|
ProcessRetentionTruncation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||||
|
{
|
||||||
|
LogInfo("Running truncation");
|
||||||
|
|
||||||
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
|
if (m_settings[i].retention_days > 0) {
|
||||||
|
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
||||||
|
*m_database,
|
||||||
|
fmt::format(
|
||||||
|
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
||||||
|
i,
|
||||||
|
m_settings[i].retention_days
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (deleted_count > 0) {
|
||||||
|
LogInfo(
|
||||||
|
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
||||||
|
deleted_count,
|
||||||
|
PlayerEvent::EventName[i],
|
||||||
|
i,
|
||||||
|
m_settings[i].retention_days
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerEventLogs::ReloadSettings()
|
||||||
|
{
|
||||||
|
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||||
|
m_settings[e.id] = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t RETENTION_DAYS_DEFAULT = 7;
|
||||||
|
|
||||||
|
void PlayerEventLogs::SetSettingsDefaults()
|
||||||
|
{
|
||||||
|
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||||
|
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||||
|
|
||||||
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
|
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
|
#define EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
|
|
||||||
|
#include "../repositories/player_event_log_settings_repository.h"
|
||||||
|
#include "player_events.h"
|
||||||
|
#include "../servertalk.h"
|
||||||
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
#include "../timer.h"
|
||||||
|
#include "../json/json_archive_single_line.h"
|
||||||
|
#include <cereal/archives/json.hpp>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
class PlayerEventLogs {
|
||||||
|
public:
|
||||||
|
void Init();
|
||||||
|
void ReloadSettings();
|
||||||
|
PlayerEventLogs *SetDatabase(Database *db);
|
||||||
|
bool ValidateDatabaseConnection();
|
||||||
|
bool IsEventEnabled(PlayerEvent::EventType event);
|
||||||
|
|
||||||
|
void Process();
|
||||||
|
|
||||||
|
// batch queue
|
||||||
|
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
||||||
|
|
||||||
|
// main event record generic function
|
||||||
|
// can ingest any struct event types
|
||||||
|
template<typename T>
|
||||||
|
std::unique_ptr<ServerPacket> RecordEvent(
|
||||||
|
PlayerEvent::EventType t,
|
||||||
|
const PlayerEvent::PlayerEvent &p,
|
||||||
|
T e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto n = PlayerEventLogsRepository::NewEntity();
|
||||||
|
FillPlayerEvent(p, n);
|
||||||
|
n.event_type_id = t;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
cereal::JSONOutputArchiveSingleLine ar(ss);
|
||||||
|
e.serialize(ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
n.event_type_name = PlayerEvent::EventName[t];
|
||||||
|
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
|
||||||
|
n.created_at = std::time(nullptr);
|
||||||
|
|
||||||
|
auto c = PlayerEvent::PlayerEventContainer{
|
||||||
|
.player_event = p,
|
||||||
|
.player_event_log = n
|
||||||
|
};
|
||||||
|
|
||||||
|
return BuildPlayerEventPacket(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
||||||
|
bool IsEventDiscordEnabled(int32_t event_type_id);
|
||||||
|
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
||||||
|
|
||||||
|
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
||||||
|
private:
|
||||||
|
Database *m_database; // reference to database
|
||||||
|
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
||||||
|
|
||||||
|
// batch queue is used to record events in batch
|
||||||
|
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
|
||||||
|
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
|
||||||
|
static std::unique_ptr<ServerPacket>
|
||||||
|
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
||||||
|
|
||||||
|
// timers
|
||||||
|
Timer m_process_batch_events_timer; // events processing timer
|
||||||
|
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
||||||
|
|
||||||
|
// processing
|
||||||
|
std::mutex m_batch_queue_lock{};
|
||||||
|
void ProcessBatchQueue();
|
||||||
|
void ProcessRetentionTruncation();
|
||||||
|
void SetSettingsDefaults();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PlayerEventLogs player_event_logs;
|
||||||
|
|
||||||
|
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
@@ -0,0 +1,971 @@
|
|||||||
|
#ifndef EQEMU_PLAYER_EVENTS_H
|
||||||
|
#define EQEMU_PLAYER_EVENTS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cereal/cereal.hpp>
|
||||||
|
#include "../types.h"
|
||||||
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
|
||||||
|
namespace PlayerEvent {
|
||||||
|
|
||||||
|
enum EventType {
|
||||||
|
GM_COMMAND = 1,
|
||||||
|
ZONING,
|
||||||
|
AA_GAIN,
|
||||||
|
AA_PURCHASE,
|
||||||
|
FORAGE_SUCCESS,
|
||||||
|
FORAGE_FAILURE,
|
||||||
|
FISH_SUCCESS,
|
||||||
|
FISH_FAILURE,
|
||||||
|
ITEM_DESTROY,
|
||||||
|
WENT_ONLINE,
|
||||||
|
WENT_OFFLINE,
|
||||||
|
LEVEL_GAIN,
|
||||||
|
LEVEL_LOSS,
|
||||||
|
LOOT_ITEM,
|
||||||
|
MERCHANT_PURCHASE,
|
||||||
|
MERCHANT_SELL,
|
||||||
|
GROUP_JOIN, // unimplemented
|
||||||
|
GROUP_LEAVE, // unimplemented
|
||||||
|
RAID_JOIN, // unimplemented
|
||||||
|
RAID_LEAVE, // unimplemented
|
||||||
|
GROUNDSPAWN_PICKUP,
|
||||||
|
NPC_HANDIN,
|
||||||
|
SKILL_UP,
|
||||||
|
TASK_ACCEPT,
|
||||||
|
TASK_UPDATE,
|
||||||
|
TASK_COMPLETE,
|
||||||
|
TRADE,
|
||||||
|
GIVE_ITEM, // unimplemented
|
||||||
|
SAY,
|
||||||
|
REZ_ACCEPTED,
|
||||||
|
DEATH,
|
||||||
|
COMBINE_FAILURE,
|
||||||
|
COMBINE_SUCCESS,
|
||||||
|
DROPPED_ITEM,
|
||||||
|
SPLIT_MONEY,
|
||||||
|
DZ_JOIN, // unimplemented
|
||||||
|
DZ_LEAVE, // unimplemented
|
||||||
|
TRADER_PURCHASE,
|
||||||
|
TRADER_SELL,
|
||||||
|
BANDOLIER_CREATE, // unimplemented
|
||||||
|
BANDOLIER_SWAP, // unimplemented
|
||||||
|
DISCOVER_ITEM,
|
||||||
|
POSSIBLE_HACK,
|
||||||
|
KILLED_NPC,
|
||||||
|
KILLED_NAMED_NPC,
|
||||||
|
KILLED_RAID_NPC,
|
||||||
|
ITEM_CREATION,
|
||||||
|
MAX // dont remove
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't ever remove items, even if they are deprecated
|
||||||
|
// If event is deprecated just tag (Deprecated) in the name
|
||||||
|
// If event is unimplemented just tag (Unimplemented) in the name
|
||||||
|
// Events don't get saved to the database if unimplemented or deprecated
|
||||||
|
// Events tagged as deprecated will get automatically removed
|
||||||
|
static const char *EventName[PlayerEvent::MAX] = {
|
||||||
|
"None",
|
||||||
|
"GM Command",
|
||||||
|
"Zoning",
|
||||||
|
"AA Gain",
|
||||||
|
"AA Purchase",
|
||||||
|
"Forage Success",
|
||||||
|
"Forage Failure",
|
||||||
|
"Fish Success",
|
||||||
|
"Fish Failure",
|
||||||
|
"Item Destroy",
|
||||||
|
"Went Online",
|
||||||
|
"Went Offline",
|
||||||
|
"Level Gain",
|
||||||
|
"Level Loss",
|
||||||
|
"Loot Item",
|
||||||
|
"Merchant Purchase",
|
||||||
|
"Merchant Sell",
|
||||||
|
"Group Join (Unimplemented)",
|
||||||
|
"Group Leave (Unimplemented)",
|
||||||
|
"Raid Join (Unimplemented)",
|
||||||
|
"Raid Leave (Unimplemented)",
|
||||||
|
"Groundspawn Pickup",
|
||||||
|
"NPC Handin",
|
||||||
|
"Skill Up",
|
||||||
|
"Task Accept",
|
||||||
|
"Task Update",
|
||||||
|
"Task Complete",
|
||||||
|
"Trade",
|
||||||
|
"Given Item (Unimplemented)",
|
||||||
|
"Say",
|
||||||
|
"Rez Accepted",
|
||||||
|
"Death",
|
||||||
|
"Combine Failure",
|
||||||
|
"Combine Success",
|
||||||
|
"Dropped Item",
|
||||||
|
"Split Money",
|
||||||
|
"DZ Join (Unimplemented)",
|
||||||
|
"DZ Leave (Unimplemented)",
|
||||||
|
"Trader Purchase",
|
||||||
|
"Trader Sell",
|
||||||
|
"Bandolier Create (Unimplemented)",
|
||||||
|
"Bandolier Swap (Unimplemented)",
|
||||||
|
"Discover Item",
|
||||||
|
"Possible Hack",
|
||||||
|
"Killed NPC",
|
||||||
|
"Killed Named NPC",
|
||||||
|
"Killed Raid NPC",
|
||||||
|
"Item Creation"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generic struct used by all events
|
||||||
|
struct PlayerEvent {
|
||||||
|
int64 account_id;
|
||||||
|
std::string account_name;
|
||||||
|
int64 character_id;
|
||||||
|
std::string character_name;
|
||||||
|
int64 guild_id;
|
||||||
|
std::string guild_name;
|
||||||
|
int zone_id;
|
||||||
|
std::string zone_short_name;
|
||||||
|
std::string zone_long_name;
|
||||||
|
int instance_id;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float heading;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(account_id),
|
||||||
|
CEREAL_NVP(account_name),
|
||||||
|
CEREAL_NVP(character_id),
|
||||||
|
CEREAL_NVP(character_name),
|
||||||
|
CEREAL_NVP(guild_id),
|
||||||
|
CEREAL_NVP(guild_name),
|
||||||
|
CEREAL_NVP(zone_id),
|
||||||
|
CEREAL_NVP(zone_short_name),
|
||||||
|
CEREAL_NVP(zone_long_name),
|
||||||
|
CEREAL_NVP(instance_id),
|
||||||
|
CEREAL_NVP(x),
|
||||||
|
CEREAL_NVP(y),
|
||||||
|
CEREAL_NVP(z),
|
||||||
|
CEREAL_NVP(heading)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// contains metadata in use for things like log/discord formatters
|
||||||
|
// along with the actual event to be persisted
|
||||||
|
struct PlayerEventContainer {
|
||||||
|
PlayerEvent player_event;
|
||||||
|
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(player_event),
|
||||||
|
CEREAL_NVP(player_event_log)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// used in events with no extra data
|
||||||
|
struct EmptyEvent {
|
||||||
|
std::string noop; // noop, gets discard upstream
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(noop)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// used in Trade event
|
||||||
|
struct ItemCreationEvent {
|
||||||
|
int64 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint16 to_slot;
|
||||||
|
int16 charges;
|
||||||
|
uint32 aug1;
|
||||||
|
uint32 aug2;
|
||||||
|
uint32 aug3;
|
||||||
|
uint32 aug4;
|
||||||
|
uint32 aug5;
|
||||||
|
uint32 aug6;
|
||||||
|
bool attuned;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(to_slot),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(aug1),
|
||||||
|
CEREAL_NVP(aug2),
|
||||||
|
CEREAL_NVP(aug3),
|
||||||
|
CEREAL_NVP(aug4),
|
||||||
|
CEREAL_NVP(aug5),
|
||||||
|
CEREAL_NVP(aug6),
|
||||||
|
CEREAL_NVP(attuned)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// used in Trade event
|
||||||
|
struct TradeItem {
|
||||||
|
int64 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int32 slot;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(slot)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// used in Trade event
|
||||||
|
class TradeItemEntry {
|
||||||
|
public:
|
||||||
|
uint16 slot;
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint16 charges;
|
||||||
|
uint32 aug_1_item_id;
|
||||||
|
std::string aug_1_item_name;
|
||||||
|
uint32 aug_2_item_id;
|
||||||
|
std::string aug_2_item_name;
|
||||||
|
uint32 aug_3_item_id;
|
||||||
|
std::string aug_3_item_name;
|
||||||
|
uint32 aug_4_item_id;
|
||||||
|
std::string aug_4_item_name;
|
||||||
|
uint32 aug_5_item_id;
|
||||||
|
std::string aug_5_item_name;
|
||||||
|
uint32 aug_6_item_id;
|
||||||
|
std::string aug_6_item_name;
|
||||||
|
bool in_bag;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(slot),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(aug_1_item_id),
|
||||||
|
CEREAL_NVP(aug_2_item_id),
|
||||||
|
CEREAL_NVP(aug_3_item_id),
|
||||||
|
CEREAL_NVP(aug_4_item_id),
|
||||||
|
CEREAL_NVP(aug_5_item_id),
|
||||||
|
CEREAL_NVP(in_bag)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events
|
||||||
|
*/
|
||||||
|
struct Money {
|
||||||
|
int32 platinum;
|
||||||
|
int32 gold;
|
||||||
|
int32 silver;
|
||||||
|
int32 copper;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(platinum),
|
||||||
|
CEREAL_NVP(gold),
|
||||||
|
CEREAL_NVP(silver),
|
||||||
|
CEREAL_NVP(copper)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TradeEvent {
|
||||||
|
uint32 character_1_id;
|
||||||
|
std::string character_1_name;
|
||||||
|
uint32 character_2_id;
|
||||||
|
std::string character_2_name;
|
||||||
|
Money character_1_give_money;
|
||||||
|
Money character_2_give_money;
|
||||||
|
std::vector<TradeItemEntry> character_1_give_items;
|
||||||
|
std::vector<TradeItemEntry> character_2_give_items;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(character_1_id),
|
||||||
|
CEREAL_NVP(character_1_name),
|
||||||
|
CEREAL_NVP(character_2_id),
|
||||||
|
CEREAL_NVP(character_2_name),
|
||||||
|
CEREAL_NVP(character_1_give_money),
|
||||||
|
CEREAL_NVP(character_2_give_money),
|
||||||
|
CEREAL_NVP(character_1_give_items),
|
||||||
|
CEREAL_NVP(character_2_give_items)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GMCommandEvent {
|
||||||
|
std::string message;
|
||||||
|
std::string target;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(message),
|
||||||
|
CEREAL_NVP(target)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ZoningEvent {
|
||||||
|
std::string from_zone_long_name;
|
||||||
|
std::string from_zone_short_name;
|
||||||
|
int32 from_zone_id;
|
||||||
|
int32 from_instance_id;
|
||||||
|
int32 from_instance_version;
|
||||||
|
std::string to_zone_long_name;
|
||||||
|
std::string to_zone_short_name;
|
||||||
|
int32 to_zone_id;
|
||||||
|
int32 to_instance_id;
|
||||||
|
int32 to_instance_version;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(from_zone_long_name),
|
||||||
|
CEREAL_NVP(from_zone_short_name),
|
||||||
|
CEREAL_NVP(from_zone_id),
|
||||||
|
CEREAL_NVP(from_instance_id),
|
||||||
|
CEREAL_NVP(from_instance_version),
|
||||||
|
CEREAL_NVP(to_zone_long_name),
|
||||||
|
CEREAL_NVP(to_zone_short_name),
|
||||||
|
CEREAL_NVP(to_zone_id),
|
||||||
|
CEREAL_NVP(to_instance_id),
|
||||||
|
CEREAL_NVP(to_instance_version)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AAGainedEvent {
|
||||||
|
uint32 aa_gained;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(CEREAL_NVP(aa_gained));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AAPurchasedEvent {
|
||||||
|
int32 aa_id;
|
||||||
|
int32 aa_cost;
|
||||||
|
int32 aa_previous_id;
|
||||||
|
int32 aa_next_id;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(aa_id),
|
||||||
|
CEREAL_NVP(aa_cost),
|
||||||
|
CEREAL_NVP(aa_previous_id),
|
||||||
|
CEREAL_NVP(aa_next_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ForageSuccessEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FishSuccessEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DestroyItemEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int16 charges;
|
||||||
|
std::string reason;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(reason),
|
||||||
|
CEREAL_NVP(charges)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LevelGainedEvent {
|
||||||
|
uint32 from_level;
|
||||||
|
uint8 to_level;
|
||||||
|
int levels_gained;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(from_level),
|
||||||
|
CEREAL_NVP(to_level),
|
||||||
|
CEREAL_NVP(levels_gained)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LevelLostEvent {
|
||||||
|
uint32 from_level;
|
||||||
|
uint8 to_level;
|
||||||
|
int levels_lost;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(from_level),
|
||||||
|
CEREAL_NVP(to_level),
|
||||||
|
CEREAL_NVP(levels_lost)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LootItemEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int16 charges;
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string corpse_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(corpse_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MerchantPurchaseEvent {
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string merchant_name;
|
||||||
|
uint32 merchant_type;
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int16 charges;
|
||||||
|
uint32 cost;
|
||||||
|
uint32 alternate_currency_id;
|
||||||
|
uint64 player_money_balance;
|
||||||
|
uint64 player_currency_balance;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(merchant_name),
|
||||||
|
CEREAL_NVP(merchant_type),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(cost),
|
||||||
|
CEREAL_NVP(alternate_currency_id),
|
||||||
|
CEREAL_NVP(player_money_balance),
|
||||||
|
CEREAL_NVP(player_currency_balance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MerchantSellEvent {
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string merchant_name;
|
||||||
|
uint32 merchant_type;
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int16 charges;
|
||||||
|
uint32 cost;
|
||||||
|
uint32 alternate_currency_id;
|
||||||
|
uint64 player_money_balance;
|
||||||
|
uint64 player_currency_balance;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(merchant_name),
|
||||||
|
CEREAL_NVP(merchant_type),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(cost),
|
||||||
|
CEREAL_NVP(alternate_currency_id),
|
||||||
|
CEREAL_NVP(player_money_balance),
|
||||||
|
CEREAL_NVP(player_currency_balance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SkillUpEvent {
|
||||||
|
uint32 skill_id;
|
||||||
|
int value;
|
||||||
|
int16 max_skill;
|
||||||
|
std::string against_who;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(skill_id),
|
||||||
|
CEREAL_NVP(value),
|
||||||
|
CEREAL_NVP(max_skill),
|
||||||
|
CEREAL_NVP(against_who)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TaskAcceptEvent {
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string npc_name;
|
||||||
|
uint32 task_id;
|
||||||
|
std::string task_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(npc_name),
|
||||||
|
CEREAL_NVP(task_id),
|
||||||
|
CEREAL_NVP(task_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TaskUpdateEvent {
|
||||||
|
uint32 task_id;
|
||||||
|
std::string task_name;
|
||||||
|
uint32 activity_id;
|
||||||
|
uint32 done_count;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(task_id),
|
||||||
|
CEREAL_NVP(task_name),
|
||||||
|
CEREAL_NVP(activity_id),
|
||||||
|
CEREAL_NVP(done_count)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TaskCompleteEvent {
|
||||||
|
uint32 task_id;
|
||||||
|
std::string task_name;
|
||||||
|
uint32 activity_id;
|
||||||
|
uint32 done_count;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(task_id),
|
||||||
|
CEREAL_NVP(task_name),
|
||||||
|
CEREAL_NVP(activity_id),
|
||||||
|
CEREAL_NVP(done_count)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GroundSpawnPickupEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayEvent {
|
||||||
|
std::string message;
|
||||||
|
std::string target;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(message),
|
||||||
|
CEREAL_NVP(target)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ResurrectAcceptEvent {
|
||||||
|
std::string resurrecter_name;
|
||||||
|
std::string spell_name;
|
||||||
|
uint32 spell_id;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(resurrecter_name),
|
||||||
|
CEREAL_NVP(spell_name),
|
||||||
|
CEREAL_NVP(spell_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CombineEvent {
|
||||||
|
uint32 recipe_id;
|
||||||
|
std::string recipe_name;
|
||||||
|
uint32 made_count;
|
||||||
|
uint32 tradeskill_id;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(recipe_id),
|
||||||
|
CEREAL_NVP(recipe_name),
|
||||||
|
CEREAL_NVP(made_count),
|
||||||
|
CEREAL_NVP(tradeskill_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DroppedItemEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
int16 slot_id;
|
||||||
|
uint32 charges;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(slot_id),
|
||||||
|
CEREAL_NVP(charges)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeathEvent {
|
||||||
|
uint32 killer_id;
|
||||||
|
std::string killer_name;
|
||||||
|
int64 damage;
|
||||||
|
uint32 spell_id;
|
||||||
|
std::string spell_name;
|
||||||
|
int skill_id;
|
||||||
|
std::string skill_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(killer_id),
|
||||||
|
CEREAL_NVP(killer_name),
|
||||||
|
CEREAL_NVP(damage),
|
||||||
|
CEREAL_NVP(spell_id),
|
||||||
|
CEREAL_NVP(spell_name),
|
||||||
|
CEREAL_NVP(skill_id),
|
||||||
|
CEREAL_NVP(skill_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SplitMoneyEvent {
|
||||||
|
uint32 copper;
|
||||||
|
uint32 silver;
|
||||||
|
uint32 gold;
|
||||||
|
uint32 platinum;
|
||||||
|
uint64 player_money_balance;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(copper),
|
||||||
|
CEREAL_NVP(silver),
|
||||||
|
CEREAL_NVP(gold),
|
||||||
|
CEREAL_NVP(platinum),
|
||||||
|
CEREAL_NVP(player_money_balance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraderPurchaseEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint32 trader_id;
|
||||||
|
std::string trader_name;
|
||||||
|
uint32 price;
|
||||||
|
uint32 charges;
|
||||||
|
uint32 total_cost;
|
||||||
|
uint64 player_money_balance;
|
||||||
|
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(trader_id),
|
||||||
|
CEREAL_NVP(trader_name),
|
||||||
|
CEREAL_NVP(price),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(total_cost),
|
||||||
|
CEREAL_NVP(player_money_balance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraderSellEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint32 buyer_id;
|
||||||
|
std::string buyer_name;
|
||||||
|
uint32 price;
|
||||||
|
uint32 charges;
|
||||||
|
uint32 total_cost;
|
||||||
|
uint64 player_money_balance;
|
||||||
|
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(buyer_id),
|
||||||
|
CEREAL_NVP(buyer_name),
|
||||||
|
CEREAL_NVP(price),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(total_cost),
|
||||||
|
CEREAL_NVP(player_money_balance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiscoverItemEvent {
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HandinEntry {
|
||||||
|
public:
|
||||||
|
uint32 item_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint16 charges;
|
||||||
|
bool attuned;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(attuned)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HandinMoney {
|
||||||
|
public:
|
||||||
|
uint32 copper;
|
||||||
|
uint32 silver;
|
||||||
|
uint32 gold;
|
||||||
|
uint32 platinum;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(copper),
|
||||||
|
CEREAL_NVP(silver),
|
||||||
|
CEREAL_NVP(gold),
|
||||||
|
CEREAL_NVP(platinum)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HandinEvent {
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string npc_name;
|
||||||
|
std::vector<HandinEntry> handin_items;
|
||||||
|
HandinMoney handin_money;
|
||||||
|
std::vector<HandinEntry> return_items;
|
||||||
|
HandinMoney return_money;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(npc_name),
|
||||||
|
CEREAL_NVP(handin_items),
|
||||||
|
CEREAL_NVP(handin_money),
|
||||||
|
CEREAL_NVP(return_items),
|
||||||
|
CEREAL_NVP(return_money)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PossibleHackEvent {
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(message)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KilledNPCEvent {
|
||||||
|
uint32 npc_id;
|
||||||
|
std::string npc_name;
|
||||||
|
uint32 combat_time_seconds;
|
||||||
|
uint64 total_damage_per_second_taken;
|
||||||
|
uint64 total_heal_per_second_taken;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(npc_id),
|
||||||
|
CEREAL_NVP(npc_name),
|
||||||
|
CEREAL_NVP(combat_time_seconds),
|
||||||
|
CEREAL_NVP(total_damage_per_second_taken),
|
||||||
|
CEREAL_NVP(total_heal_per_second_taken)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //EQEMU_PLAYER_EVENTS_H
|
||||||
|
|
||||||
|
#define RecordPlayerEventLog(event_type, event_data) do {\
|
||||||
|
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||||
|
worldserver.SendPacket(\
|
||||||
|
player_event_logs.RecordEvent(\
|
||||||
|
event_type,\
|
||||||
|
GetPlayerEvent(),\
|
||||||
|
event_data\
|
||||||
|
).get()\
|
||||||
|
);\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
||||||
|
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||||
|
worldserver.SendPacket(\
|
||||||
|
player_event_logs.RecordEvent(\
|
||||||
|
event_type,\
|
||||||
|
(c)->GetPlayerEvent(),\
|
||||||
|
event_data\
|
||||||
|
).get()\
|
||||||
|
);\
|
||||||
|
}\
|
||||||
|
} while (0)
|
||||||
+1
-1
@@ -132,7 +132,7 @@ enum { //reuse times
|
|||||||
InstillDoubtReuseTime = 9,
|
InstillDoubtReuseTime = 9,
|
||||||
FishingReuseTime = 11,
|
FishingReuseTime = 11,
|
||||||
ForagingReuseTime = 50,
|
ForagingReuseTime = 50,
|
||||||
MendReuseTime = 290,
|
MendReuseTime = 360,
|
||||||
BashReuseTime = 5,
|
BashReuseTime = 5,
|
||||||
BackstabReuseTime = 9,
|
BackstabReuseTime = 9,
|
||||||
KickReuseTime = 5,
|
KickReuseTime = 5,
|
||||||
|
|||||||
+17
-17
@@ -61,7 +61,7 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
_CreateGuild(Strings::ToInt(row[0]), row[1], Strings::ToInt(row[2]), Strings::ToInt(row[3]), row[4], row[5], row[6], row[7]);
|
||||||
|
|
||||||
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
||||||
|
|
||||||
@@ -75,8 +75,8 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint32 guild_id = atoi(row[0]);
|
uint32 guild_id = Strings::ToInt(row[0]);
|
||||||
uint8 rankn = atoi(row[1]);
|
uint8 rankn = Strings::ToInt(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||||
@@ -131,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
info = _CreateGuild(guild_id, row[0], Strings::ToInt(row[1]), Strings::ToInt(row[2]), row[3], row[4], row[5], row[6]);
|
||||||
|
|
||||||
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
||||||
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
||||||
@@ -144,7 +144,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint8 rankn = atoi(row[1]);
|
uint8 rankn = Strings::ToInt(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||||
@@ -787,7 +787,7 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
bool IsBanker = atoi(row[0]);
|
bool IsBanker = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return IsBanker;
|
return IsBanker;
|
||||||
}
|
}
|
||||||
@@ -817,7 +817,7 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
bool IsAlt = atoi(row[0]);
|
bool IsAlt = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return IsAlt;
|
return IsAlt;
|
||||||
}
|
}
|
||||||
@@ -873,19 +873,19 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
|||||||
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
||||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||||
//fields from `characer_`
|
//fields from `characer_`
|
||||||
into.char_id = atoi(row[0]);
|
into.char_id = Strings::ToInt(row[0]);
|
||||||
into.char_name = row[1];
|
into.char_name = row[1];
|
||||||
into.class_ = atoi(row[2]);
|
into.class_ = Strings::ToInt(row[2]);
|
||||||
into.level = atoi(row[3]);
|
into.level = Strings::ToInt(row[3]);
|
||||||
into.time_last_on = atoul(row[4]);
|
into.time_last_on = Strings::ToUnsignedInt(row[4]);
|
||||||
into.zone_id = atoi(row[5]);
|
into.zone_id = Strings::ToInt(row[5]);
|
||||||
|
|
||||||
//fields from `guild_members`, leave at defaults if missing
|
//fields from `guild_members`, leave at defaults if missing
|
||||||
into.guild_id = row[6] ? atoi(row[6]) : GUILD_NONE;
|
into.guild_id = row[6] ? Strings::ToInt(row[6]) : GUILD_NONE;
|
||||||
into.rank = row[7] ? atoi(row[7]) : (GUILD_MAX_RANK+1);
|
into.rank = row[7] ? Strings::ToInt(row[7]) : (GUILD_MAX_RANK+1);
|
||||||
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
||||||
into.total_tribute = row[9] ? atoi(row[9]) : 0;
|
into.total_tribute = row[9] ? Strings::ToInt(row[9]) : 0;
|
||||||
into.last_tribute = row[10]? atoul(row[10]) : 0; //timestamp
|
into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp
|
||||||
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
||||||
into.public_note = row[12]? row[12] : "";
|
into.public_note = row[12]? row[12] : "";
|
||||||
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
||||||
@@ -1258,7 +1258,7 @@ uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto guild_id = std::stoul(row[0]);
|
auto guild_id = Strings::ToUnsignedInt(row[0]);
|
||||||
return guild_id;
|
return guild_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -272,6 +272,8 @@ inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) {
|
|||||||
#include <brotli/encode.h>
|
#include <brotli/encode.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../strings.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declaration
|
* Declaration
|
||||||
*/
|
*/
|
||||||
@@ -3812,12 +3814,12 @@ inline bool brotli_decompressor::decompress(const char *data,
|
|||||||
if (std::regex_match(b, e, cm, re_another_range)) {
|
if (std::regex_match(b, e, cm, re_another_range)) {
|
||||||
ssize_t first = -1;
|
ssize_t first = -1;
|
||||||
if (!cm.str(1).empty()) {
|
if (!cm.str(1).empty()) {
|
||||||
first = static_cast<ssize_t>(std::stoll(cm.str(1)));
|
first = static_cast<ssize_t>(Strings::ToBigInt(cm.str(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t last = -1;
|
ssize_t last = -1;
|
||||||
if (!cm.str(2).empty()) {
|
if (!cm.str(2).empty()) {
|
||||||
last = static_cast<ssize_t>(std::stoll(cm.str(2)));
|
last = static_cast<ssize_t>(Strings::ToBigInt(cm.str(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first != -1 && last != -1 && first > last) {
|
if (first != -1 && last != -1 && first > last) {
|
||||||
|
|||||||
+50
-16
@@ -24,16 +24,16 @@
|
|||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "shareddb.h"
|
#include "shareddb.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
#include "util/uuid.h"
|
||||||
//#include "../common/light_source.h"
|
//#include "../common/light_source.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
//#include <iostream>
|
//#include <iostream>
|
||||||
|
|
||||||
int32 NextItemInstSerialNumber = 1;
|
uint32 NextItemInstSerialNumber = 1;
|
||||||
|
|
||||||
static inline int32 GetNextItemInstSerialNumber() {
|
static inline uint32 GetNextItemInstSerialNumber() {
|
||||||
|
|
||||||
// The Bazaar relies on each item a client has up for Trade having a unique
|
// The Bazaar relies on each item a client has up for Trade having a unique
|
||||||
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
||||||
@@ -45,7 +45,7 @@ static inline int32 GetNextItemInstSerialNumber() {
|
|||||||
// NextItemInstSerialNumber is the next one to hand out.
|
// NextItemInstSerialNumber is the next one to hand out.
|
||||||
//
|
//
|
||||||
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
||||||
if(NextItemInstSerialNumber >= INT_MAX)
|
if(NextItemInstSerialNumber >= UINT_MAX)
|
||||||
NextItemInstSerialNumber = 1;
|
NextItemInstSerialNumber = 1;
|
||||||
else
|
else
|
||||||
NextItemInstSerialNumber++;
|
NextItemInstSerialNumber++;
|
||||||
@@ -56,13 +56,21 @@ static inline int32 GetNextItemInstSerialNumber() {
|
|||||||
//
|
//
|
||||||
// class EQ::ItemInstance
|
// class EQ::ItemInstance
|
||||||
//
|
//
|
||||||
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
EQ::ItemInstance::ItemInstance(const ItemData* item, const std::string& guid, int16 charges) {
|
||||||
m_use_type = ItemInstNormal;
|
m_use_type = ItemInstNormal;
|
||||||
if(item) {
|
if(item) {
|
||||||
m_item = new ItemData(*item);
|
m_item = new ItemData(*item);
|
||||||
} else {
|
} else {
|
||||||
m_item = nullptr;
|
m_item = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (guid.empty()) {
|
||||||
|
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_guid = guid;
|
||||||
|
}
|
||||||
|
|
||||||
m_charges = charges;
|
m_charges = charges;
|
||||||
m_price = 0;
|
m_price = 0;
|
||||||
m_attuned = false;
|
m_attuned = false;
|
||||||
@@ -72,7 +80,7 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
|||||||
else
|
else
|
||||||
m_color = 0;
|
m_color = 0;
|
||||||
m_merchantcount = 1;
|
m_merchantcount = 1;
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_serial_number = GetNextItemInstSerialNumber();
|
||||||
|
|
||||||
m_exp = 0;
|
m_exp = 0;
|
||||||
m_evolveLvl = 0;
|
m_evolveLvl = 0;
|
||||||
@@ -85,9 +93,10 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
|||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
m_recast_timestamp = 0;
|
m_recast_timestamp = 0;
|
||||||
m_new_id_file = 0;
|
m_new_id_file = 0;
|
||||||
|
m_currentslot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
|
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, const std::string& guid, int16 charges) {
|
||||||
m_use_type = ItemInstNormal;
|
m_use_type = ItemInstNormal;
|
||||||
m_item = db->GetItem(item_id);
|
m_item = db->GetItem(item_id);
|
||||||
if(m_item) {
|
if(m_item) {
|
||||||
@@ -97,6 +106,13 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
|||||||
m_item = nullptr;
|
m_item = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (guid.empty()) {
|
||||||
|
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_guid = guid;
|
||||||
|
}
|
||||||
|
|
||||||
m_charges = charges;
|
m_charges = charges;
|
||||||
m_price = 0;
|
m_price = 0;
|
||||||
m_merchantslot = 0;
|
m_merchantslot = 0;
|
||||||
@@ -106,7 +122,7 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
|||||||
else
|
else
|
||||||
m_color = 0;
|
m_color = 0;
|
||||||
m_merchantcount = 1;
|
m_merchantcount = 1;
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_serial_number = GetNextItemInstSerialNumber();
|
||||||
|
|
||||||
m_exp = 0;
|
m_exp = 0;
|
||||||
m_evolveLvl = 0;
|
m_evolveLvl = 0;
|
||||||
@@ -119,17 +135,20 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
|||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
m_recast_timestamp = 0;
|
m_recast_timestamp = 0;
|
||||||
m_new_id_file = 0;
|
m_new_id_file = 0;
|
||||||
|
m_currentslot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
||||||
m_use_type = use_type;
|
m_use_type = use_type;
|
||||||
|
|
||||||
|
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||||
m_item = nullptr;
|
m_item = nullptr;
|
||||||
m_charges = 0;
|
m_charges = 0;
|
||||||
m_price = 0;
|
m_price = 0;
|
||||||
m_attuned = false;
|
m_attuned = false;
|
||||||
m_merchantslot = 0;
|
m_merchantslot = 0;
|
||||||
m_color = 0;
|
m_color = 0;
|
||||||
|
m_serial_number = 0;
|
||||||
m_exp = 0;
|
m_exp = 0;
|
||||||
m_evolveLvl = 0;
|
m_evolveLvl = 0;
|
||||||
m_activated = false;
|
m_activated = false;
|
||||||
@@ -141,6 +160,8 @@ EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
|||||||
m_ornament_hero_model = 0;
|
m_ornament_hero_model = 0;
|
||||||
m_recast_timestamp = 0;
|
m_recast_timestamp = 0;
|
||||||
m_new_id_file = 0;
|
m_new_id_file = 0;
|
||||||
|
m_currentslot = 0;
|
||||||
|
m_merchantcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a copy of an EQ::ItemInstance object
|
// Make a copy of an EQ::ItemInstance object
|
||||||
@@ -152,6 +173,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
else
|
else
|
||||||
m_item = nullptr;
|
m_item = nullptr;
|
||||||
|
|
||||||
|
m_guid = copy.m_guid;
|
||||||
m_charges=copy.m_charges;
|
m_charges=copy.m_charges;
|
||||||
m_price=copy.m_price;
|
m_price=copy.m_price;
|
||||||
m_color=copy.m_color;
|
m_color=copy.m_color;
|
||||||
@@ -176,7 +198,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
||||||
m_custom_data[iter->first] = iter->second;
|
m_custom_data[iter->first] = iter->second;
|
||||||
}
|
}
|
||||||
m_SerialNumber = copy.m_SerialNumber;
|
m_serial_number = copy.m_serial_number;
|
||||||
m_custom_data = copy.m_custom_data;
|
m_custom_data = copy.m_custom_data;
|
||||||
m_timers = copy.m_timers;
|
m_timers = copy.m_timers;
|
||||||
|
|
||||||
@@ -358,15 +380,27 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
|||||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon())
|
if (!m_item || !m_item->IsClassCommon()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
|
if (
|
||||||
|
(
|
||||||
|
!GetItem(slot) &&
|
||||||
|
m_item->AugSlotVisible[slot]
|
||||||
|
) &&
|
||||||
|
augment_type == -1 ||
|
||||||
|
(
|
||||||
|
m_item->AugSlotType[slot] &&
|
||||||
|
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||||
|
)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve item inside container
|
// Retrieve item inside container
|
||||||
@@ -598,7 +632,7 @@ bool EQ::ItemInstance::UpdateOrnamentationInfo() {
|
|||||||
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
|
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
|
||||||
if (strlen(ornamentItem->IDFile) > 2)
|
if (strlen(ornamentItem->IDFile) > 2)
|
||||||
{
|
{
|
||||||
SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2]));
|
SetOrnamentationIDFile(Strings::ToInt(&ornamentItem->IDFile[2]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-7
@@ -69,9 +69,9 @@ namespace EQ
|
|||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
// Constructors/Destructor
|
// Constructors/Destructor
|
||||||
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
|
ItemInstance(const ItemData* item, const std::string& guid, int16 charges);
|
||||||
|
|
||||||
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
ItemInstance(SharedDatabase *db, uint32 item_id, const std::string &guid, int16 charges);
|
||||||
|
|
||||||
ItemInstance(ItemInstTypes use_type);
|
ItemInstance(ItemInstTypes use_type);
|
||||||
|
|
||||||
@@ -79,6 +79,8 @@ namespace EQ
|
|||||||
|
|
||||||
~ItemInstance();
|
~ItemInstance();
|
||||||
|
|
||||||
|
inline std::string GetGuid() const { return m_guid; }
|
||||||
|
|
||||||
// Query item type
|
// Query item type
|
||||||
bool IsType(item::ItemClass item_class) const;
|
bool IsType(item::ItemClass item_class) const;
|
||||||
|
|
||||||
@@ -101,8 +103,8 @@ namespace EQ
|
|||||||
//
|
//
|
||||||
bool IsAugmentable() const;
|
bool IsAugmentable() const;
|
||||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||||
int8 AvailableAugmentSlot(int32 augtype) const;
|
int8 AvailableAugmentSlot(int32 augment_type) const;
|
||||||
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
||||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||||
|
|
||||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||||
@@ -225,8 +227,8 @@ namespace EQ
|
|||||||
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
||||||
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||||
|
|
||||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
inline int32 GetSerialNumber() const { return m_serial_number; }
|
||||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
inline void SetSerialNumber(int32 id) { m_serial_number = id; }
|
||||||
|
|
||||||
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
|
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
|
||||||
void SetTimer(std::string name, uint32 time);
|
void SetTimer(std::string name, uint32 time);
|
||||||
@@ -303,6 +305,7 @@ namespace EQ
|
|||||||
|
|
||||||
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
||||||
|
|
||||||
|
std::string m_guid;
|
||||||
ItemInstTypes m_use_type; // Usage type for item
|
ItemInstTypes m_use_type; // Usage type for item
|
||||||
const ItemData* m_item; // Ptr to item data
|
const ItemData* m_item; // Ptr to item data
|
||||||
int16 m_charges; // # of charges for chargeable items
|
int16 m_charges; // # of charges for chargeable items
|
||||||
@@ -312,7 +315,7 @@ namespace EQ
|
|||||||
int16 m_currentslot;
|
int16 m_currentslot;
|
||||||
bool m_attuned;
|
bool m_attuned;
|
||||||
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||||
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
|
uint32 m_serial_number; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||||
uint32 m_exp;
|
uint32 m_exp;
|
||||||
int8 m_evolveLvl;
|
int8 m_evolveLvl;
|
||||||
bool m_activated;
|
bool m_activated;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
std::map<int,std::string> DBFieldNames;
|
std::map<int,std::string> DBFieldNames;
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ static char *temp=nullptr;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
uint32 id = atoi(field[id_pos].c_str());
|
uint32 id = Strings::ToInt(field[id_pos].c_str());
|
||||||
items[id]=field;
|
items[id]=field;
|
||||||
|
|
||||||
for(i=0;i<10;i++) {
|
for(i=0;i<10;i++) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@@ -130,7 +131,7 @@ bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf
|
|||||||
if (*oIP == 0)
|
if (*oIP == 0)
|
||||||
return false;
|
return false;
|
||||||
if (oPort)
|
if (oPort)
|
||||||
*oPort = atoi(sep.arg[1]);
|
*oPort = Strings::ToInt(sep.arg[1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -2095,13 +2095,13 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = atoi(&emu->lastName[2]);
|
val = Strings::ToInt(&emu->lastName[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sep[0] = nullptr;
|
sep[0] = nullptr;
|
||||||
ofs = atoi(&emu->lastName[2]);
|
ofs = Strings::ToInt(&emu->lastName[2]);
|
||||||
sep[0] = '=';
|
sep[0] = '=';
|
||||||
if ((sep[1] < '0') || (sep[1] > '9'))
|
if ((sep[1] < '0') || (sep[1] > '9'))
|
||||||
{
|
{
|
||||||
@@ -2109,7 +2109,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = atoi(&sep[1]);
|
val = Strings::ToInt(&sep[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-11
@@ -22,26 +22,31 @@
|
|||||||
|
|
||||||
EQEmuExePlatform exe_platform = ExePlatformNone;
|
EQEmuExePlatform exe_platform = ExePlatformNone;
|
||||||
|
|
||||||
void RegisterExecutablePlatform(EQEmuExePlatform p) {
|
void RegisterExecutablePlatform(EQEmuExePlatform p)
|
||||||
|
{
|
||||||
exe_platform = p;
|
exe_platform = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EQEmuExePlatform& GetExecutablePlatform() {
|
const EQEmuExePlatform &GetExecutablePlatform()
|
||||||
|
{
|
||||||
return exe_platform;
|
return exe_platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int GetExecutablePlatformInt()
|
||||||
* @return
|
{
|
||||||
*/
|
|
||||||
int GetExecutablePlatformInt(){
|
|
||||||
return exe_platform;
|
return exe_platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool IsWorld()
|
||||||
* Returns platform name by string
|
{
|
||||||
*
|
return exe_platform == EQEmuExePlatform::ExePlatformWorld;
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
|
bool IsQueryServ()
|
||||||
|
{
|
||||||
|
return exe_platform == EQEmuExePlatform::ExePlatformQueryServ;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetPlatformName()
|
std::string GetPlatformName()
|
||||||
{
|
{
|
||||||
switch (GetExecutablePlatformInt()) {
|
switch (GetExecutablePlatformInt()) {
|
||||||
|
|||||||
@@ -44,5 +44,7 @@ void RegisterExecutablePlatform(EQEmuExePlatform p);
|
|||||||
const EQEmuExePlatform& GetExecutablePlatform();
|
const EQEmuExePlatform& GetExecutablePlatform();
|
||||||
int GetExecutablePlatformInt();
|
int GetExecutablePlatformInt();
|
||||||
std::string GetPlatformName();
|
std::string GetPlatformName();
|
||||||
|
bool IsWorld();
|
||||||
|
bool IsQueryServ();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -288,7 +288,7 @@ bool PTimerList::Load(Database *db) {
|
|||||||
PersistentTimer *cur;
|
PersistentTimer *cur;
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
type = atoi(row[0]);
|
type = Strings::ToInt(row[0]);
|
||||||
start_time = strtoul(row[1], nullptr, 10);
|
start_time = strtoul(row[1], nullptr, 10);
|
||||||
timer_time = strtoul(row[2], nullptr, 10);
|
timer_time = strtoul(row[2], nullptr, 10);
|
||||||
enabled = (row[3][0] == '1');
|
enabled = (row[3][0] == '1');
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
int32_t expansion_bitmask;
|
int32_t expansion_bitmask;
|
||||||
uint8_t enforce_spell_settings;
|
uint8_t enforce_spell_settings;
|
||||||
uint8_t archery_setting;
|
uint8_t archery_setting;
|
||||||
|
uint32_t caster_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -129,6 +130,7 @@ public:
|
|||||||
"expansion_bitmask",
|
"expansion_bitmask",
|
||||||
"enforce_spell_settings",
|
"enforce_spell_settings",
|
||||||
"archery_setting",
|
"archery_setting",
|
||||||
|
"caster_range",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +187,7 @@ public:
|
|||||||
"expansion_bitmask",
|
"expansion_bitmask",
|
||||||
"enforce_spell_settings",
|
"enforce_spell_settings",
|
||||||
"archery_setting",
|
"archery_setting",
|
||||||
|
"caster_range",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +278,7 @@ public:
|
|||||||
e.expansion_bitmask = -1;
|
e.expansion_bitmask = -1;
|
||||||
e.enforce_spell_settings = 0;
|
e.enforce_spell_settings = 0;
|
||||||
e.archery_setting = 0;
|
e.archery_setting = 0;
|
||||||
|
e.caster_range = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -361,6 +365,7 @@ public:
|
|||||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||||
|
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -443,6 +448,7 @@ public:
|
|||||||
v.push_back(columns[47] + " = " + std::to_string(e.expansion_bitmask));
|
v.push_back(columns[47] + " = " + std::to_string(e.expansion_bitmask));
|
||||||
v.push_back(columns[48] + " = " + std::to_string(e.enforce_spell_settings));
|
v.push_back(columns[48] + " = " + std::to_string(e.enforce_spell_settings));
|
||||||
v.push_back(columns[49] + " = " + std::to_string(e.archery_setting));
|
v.push_back(columns[49] + " = " + std::to_string(e.archery_setting));
|
||||||
|
v.push_back(columns[50] + " = " + std::to_string(e.caster_range));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -514,6 +520,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
v.push_back(std::to_string(e.expansion_bitmask));
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
v.push_back(std::to_string(e.archery_setting));
|
||||||
|
v.push_back(std::to_string(e.caster_range));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -593,6 +600,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
v.push_back(std::to_string(e.expansion_bitmask));
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
v.push_back(std::to_string(e.archery_setting));
|
||||||
|
v.push_back(std::to_string(e.caster_range));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -676,6 +684,7 @@ public:
|
|||||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||||
|
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -750,6 +759,7 @@ public:
|
|||||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||||
|
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,412 +0,0 @@
|
|||||||
/**
|
|
||||||
* DO NOT MODIFY THIS FILE
|
|
||||||
*
|
|
||||||
* This repository was automatically generated and is NOT to be modified directly.
|
|
||||||
* Any repository modifications are meant to be made to the repository extending the base.
|
|
||||||
* Any modifications to base repositories are to be made by the generator only
|
|
||||||
*
|
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
|
||||||
#define EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
|
||||||
|
|
||||||
#include "../../database.h"
|
|
||||||
#include "../../strings.h"
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
class BaseEventlogRepository {
|
|
||||||
public:
|
|
||||||
struct Eventlog {
|
|
||||||
uint32_t id;
|
|
||||||
std::string accountname;
|
|
||||||
uint32_t accountid;
|
|
||||||
int32_t status;
|
|
||||||
std::string charname;
|
|
||||||
std::string target;
|
|
||||||
std::string time;
|
|
||||||
std::string descriptiontype;
|
|
||||||
std::string description;
|
|
||||||
int32_t event_nid;
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
|
||||||
{
|
|
||||||
return std::string("id");
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> Columns()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"id",
|
|
||||||
"accountname",
|
|
||||||
"accountid",
|
|
||||||
"status",
|
|
||||||
"charname",
|
|
||||||
"target",
|
|
||||||
"time",
|
|
||||||
"descriptiontype",
|
|
||||||
"description",
|
|
||||||
"event_nid",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> SelectColumns()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"id",
|
|
||||||
"accountname",
|
|
||||||
"accountid",
|
|
||||||
"status",
|
|
||||||
"charname",
|
|
||||||
"target",
|
|
||||||
"time",
|
|
||||||
"descriptiontype",
|
|
||||||
"description",
|
|
||||||
"event_nid",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string ColumnsRaw()
|
|
||||||
{
|
|
||||||
return std::string(Strings::Implode(", ", Columns()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string SelectColumnsRaw()
|
|
||||||
{
|
|
||||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string TableName()
|
|
||||||
{
|
|
||||||
return std::string("eventlog");
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string BaseSelect()
|
|
||||||
{
|
|
||||||
return fmt::format(
|
|
||||||
"SELECT {} FROM {}",
|
|
||||||
SelectColumnsRaw(),
|
|
||||||
TableName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string BaseInsert()
|
|
||||||
{
|
|
||||||
return fmt::format(
|
|
||||||
"INSERT INTO {} ({}) ",
|
|
||||||
TableName(),
|
|
||||||
ColumnsRaw()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eventlog NewEntity()
|
|
||||||
{
|
|
||||||
Eventlog e{};
|
|
||||||
|
|
||||||
e.id = 0;
|
|
||||||
e.accountname = "";
|
|
||||||
e.accountid = 0;
|
|
||||||
e.status = 0;
|
|
||||||
e.charname = "";
|
|
||||||
e.target = "None";
|
|
||||||
e.time = std::time(nullptr);
|
|
||||||
e.descriptiontype = "";
|
|
||||||
e.description = "";
|
|
||||||
e.event_nid = 0;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eventlog GetEventlog(
|
|
||||||
const std::vector<Eventlog> &eventlogs,
|
|
||||||
int eventlog_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
for (auto &eventlog : eventlogs) {
|
|
||||||
if (eventlog.id == eventlog_id) {
|
|
||||||
return eventlog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eventlog FindOne(
|
|
||||||
Database& db,
|
|
||||||
int eventlog_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"{} WHERE id = {} LIMIT 1",
|
|
||||||
BaseSelect(),
|
|
||||||
eventlog_id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
if (results.RowCount() == 1) {
|
|
||||||
Eventlog e{};
|
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
|
||||||
e.accountname = row[1] ? row[1] : "";
|
|
||||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
|
||||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
|
||||||
e.charname = row[4] ? row[4] : "";
|
|
||||||
e.target = row[5] ? row[5] : "";
|
|
||||||
e.time = row[6] ? row[6] : "";
|
|
||||||
e.descriptiontype = row[7] ? row[7] : "";
|
|
||||||
e.description = row[8] ? row[8] : "";
|
|
||||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int DeleteOne(
|
|
||||||
Database& db,
|
|
||||||
int eventlog_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"DELETE FROM {} WHERE {} = {}",
|
|
||||||
TableName(),
|
|
||||||
PrimaryKey(),
|
|
||||||
eventlog_id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int UpdateOne(
|
|
||||||
Database& db,
|
|
||||||
const Eventlog &e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
|
|
||||||
auto columns = Columns();
|
|
||||||
|
|
||||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.accountname) + "'");
|
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.accountid));
|
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.status));
|
|
||||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.charname) + "'");
|
|
||||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.target) + "'");
|
|
||||||
v.push_back(columns[6] + " = '" + Strings::Escape(e.time) + "'");
|
|
||||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.descriptiontype) + "'");
|
|
||||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.description) + "'");
|
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.event_nid));
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"UPDATE {} SET {} WHERE {} = {}",
|
|
||||||
TableName(),
|
|
||||||
Strings::Implode(", ", v),
|
|
||||||
PrimaryKey(),
|
|
||||||
e.id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eventlog InsertOne(
|
|
||||||
Database& db,
|
|
||||||
Eventlog e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
|
||||||
v.push_back("'" + Strings::Escape(e.accountname) + "'");
|
|
||||||
v.push_back(std::to_string(e.accountid));
|
|
||||||
v.push_back(std::to_string(e.status));
|
|
||||||
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.target) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.time) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
|
||||||
v.push_back(std::to_string(e.event_nid));
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"{} VALUES ({})",
|
|
||||||
BaseInsert(),
|
|
||||||
Strings::Implode(",", v)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (results.Success()) {
|
|
||||||
e.id = results.LastInsertedID();
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = NewEntity();
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int InsertMany(
|
|
||||||
Database& db,
|
|
||||||
const std::vector<Eventlog> &entries
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::vector<std::string> insert_chunks;
|
|
||||||
|
|
||||||
for (auto &e: entries) {
|
|
||||||
std::vector<std::string> v;
|
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
|
||||||
v.push_back("'" + Strings::Escape(e.accountname) + "'");
|
|
||||||
v.push_back(std::to_string(e.accountid));
|
|
||||||
v.push_back(std::to_string(e.status));
|
|
||||||
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.target) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.time) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
|
|
||||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
|
||||||
v.push_back(std::to_string(e.event_nid));
|
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> v;
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"{} VALUES {}",
|
|
||||||
BaseInsert(),
|
|
||||||
Strings::Implode(",", insert_chunks)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<Eventlog> All(Database& db)
|
|
||||||
{
|
|
||||||
std::vector<Eventlog> all_entries;
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"{}",
|
|
||||||
BaseSelect()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
all_entries.reserve(results.RowCount());
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
Eventlog e{};
|
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
|
||||||
e.accountname = row[1] ? row[1] : "";
|
|
||||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
|
||||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
|
||||||
e.charname = row[4] ? row[4] : "";
|
|
||||||
e.target = row[5] ? row[5] : "";
|
|
||||||
e.time = row[6] ? row[6] : "";
|
|
||||||
e.descriptiontype = row[7] ? row[7] : "";
|
|
||||||
e.description = row[8] ? row[8] : "";
|
|
||||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return all_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<Eventlog> GetWhere(Database& db, const std::string &where_filter)
|
|
||||||
{
|
|
||||||
std::vector<Eventlog> all_entries;
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"{} WHERE {}",
|
|
||||||
BaseSelect(),
|
|
||||||
where_filter
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
all_entries.reserve(results.RowCount());
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
Eventlog e{};
|
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
|
||||||
e.accountname = row[1] ? row[1] : "";
|
|
||||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
|
||||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
|
||||||
e.charname = row[4] ? row[4] : "";
|
|
||||||
e.target = row[5] ? row[5] : "";
|
|
||||||
e.time = row[6] ? row[6] : "";
|
|
||||||
e.descriptiontype = row[7] ? row[7] : "";
|
|
||||||
e.description = row[8] ? row[8] : "";
|
|
||||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return all_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int DeleteWhere(Database& db, const std::string &where_filter)
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"DELETE FROM {} WHERE {}",
|
|
||||||
TableName(),
|
|
||||||
where_filter
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Truncate(Database& db)
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"TRUNCATE TABLE {}",
|
|
||||||
TableName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64 GetMaxId(Database& db)
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
|
||||||
PrimaryKey(),
|
|
||||||
TableName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64 Count(Database& db, const std::string &where_filter = "")
|
|
||||||
{
|
|
||||||
auto results = db.QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"SELECT COUNT(*) FROM {} {}",
|
|
||||||
TableName(),
|
|
||||||
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseMerchantlistRepository {
|
class BaseMerchantlistRepository {
|
||||||
public:
|
public:
|
||||||
struct Merchantlist {
|
struct Merchantlist {
|
||||||
@@ -24,6 +25,8 @@ public:
|
|||||||
int32_t item;
|
int32_t item;
|
||||||
int16_t faction_required;
|
int16_t faction_required;
|
||||||
uint8_t level_required;
|
uint8_t level_required;
|
||||||
|
uint8_t min_status;
|
||||||
|
uint8_t max_status;
|
||||||
uint16_t alt_currency_cost;
|
uint16_t alt_currency_cost;
|
||||||
int32_t classes_required;
|
int32_t classes_required;
|
||||||
int32_t probability;
|
int32_t probability;
|
||||||
@@ -49,6 +52,8 @@ public:
|
|||||||
"item",
|
"item",
|
||||||
"faction_required",
|
"faction_required",
|
||||||
"level_required",
|
"level_required",
|
||||||
|
"min_status",
|
||||||
|
"max_status",
|
||||||
"alt_currency_cost",
|
"alt_currency_cost",
|
||||||
"classes_required",
|
"classes_required",
|
||||||
"probability",
|
"probability",
|
||||||
@@ -70,6 +75,8 @@ public:
|
|||||||
"item",
|
"item",
|
||||||
"faction_required",
|
"faction_required",
|
||||||
"level_required",
|
"level_required",
|
||||||
|
"min_status",
|
||||||
|
"max_status",
|
||||||
"alt_currency_cost",
|
"alt_currency_cost",
|
||||||
"classes_required",
|
"classes_required",
|
||||||
"probability",
|
"probability",
|
||||||
@@ -125,6 +132,8 @@ public:
|
|||||||
e.item = 0;
|
e.item = 0;
|
||||||
e.faction_required = -100;
|
e.faction_required = -100;
|
||||||
e.level_required = 0;
|
e.level_required = 0;
|
||||||
|
e.min_status = 0;
|
||||||
|
e.max_status = 255;
|
||||||
e.alt_currency_cost = 0;
|
e.alt_currency_cost = 0;
|
||||||
e.classes_required = 65535;
|
e.classes_required = 65535;
|
||||||
e.probability = 100;
|
e.probability = 100;
|
||||||
@@ -160,8 +169,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
merchantlist_id
|
merchantlist_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -175,16 +185,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -223,16 +235,18 @@ public:
|
|||||||
v.push_back(columns[2] + " = " + std::to_string(e.item));
|
v.push_back(columns[2] + " = " + std::to_string(e.item));
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
|
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
|
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.alt_currency_cost));
|
v.push_back(columns[5] + " = " + std::to_string(e.min_status));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.classes_required));
|
v.push_back(columns[6] + " = " + std::to_string(e.max_status));
|
||||||
v.push_back(columns[7] + " = " + std::to_string(e.probability));
|
v.push_back(columns[7] + " = " + std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
v.push_back(columns[8] + " = " + std::to_string(e.classes_required));
|
||||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
v.push_back(columns[9] + " = " + std::to_string(e.probability));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.bucket_comparison));
|
v.push_back(columns[10] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.min_expansion));
|
v.push_back(columns[11] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
||||||
v.push_back(columns[12] + " = " + std::to_string(e.max_expansion));
|
v.push_back(columns[12] + " = " + std::to_string(e.bucket_comparison));
|
||||||
v.push_back(columns[13] + " = '" + Strings::Escape(e.content_flags) + "'");
|
v.push_back(columns[13] + " = " + std::to_string(e.min_expansion));
|
||||||
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
v.push_back(columns[14] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[16] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -259,6 +273,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.item));
|
v.push_back(std::to_string(e.item));
|
||||||
v.push_back(std::to_string(e.faction_required));
|
v.push_back(std::to_string(e.faction_required));
|
||||||
v.push_back(std::to_string(e.level_required));
|
v.push_back(std::to_string(e.level_required));
|
||||||
|
v.push_back(std::to_string(e.min_status));
|
||||||
|
v.push_back(std::to_string(e.max_status));
|
||||||
v.push_back(std::to_string(e.alt_currency_cost));
|
v.push_back(std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(std::to_string(e.classes_required));
|
v.push_back(std::to_string(e.classes_required));
|
||||||
v.push_back(std::to_string(e.probability));
|
v.push_back(std::to_string(e.probability));
|
||||||
@@ -303,6 +319,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.item));
|
v.push_back(std::to_string(e.item));
|
||||||
v.push_back(std::to_string(e.faction_required));
|
v.push_back(std::to_string(e.faction_required));
|
||||||
v.push_back(std::to_string(e.level_required));
|
v.push_back(std::to_string(e.level_required));
|
||||||
|
v.push_back(std::to_string(e.min_status));
|
||||||
|
v.push_back(std::to_string(e.max_status));
|
||||||
v.push_back(std::to_string(e.alt_currency_cost));
|
v.push_back(std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(std::to_string(e.classes_required));
|
v.push_back(std::to_string(e.classes_required));
|
||||||
v.push_back(std::to_string(e.probability));
|
v.push_back(std::to_string(e.probability));
|
||||||
@@ -351,16 +369,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -390,16 +410,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,14 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseNpcScaleGlobalBaseRepository {
|
class BaseNpcScaleGlobalBaseRepository {
|
||||||
public:
|
public:
|
||||||
struct NpcScaleGlobalBase {
|
struct NpcScaleGlobalBase {
|
||||||
int32_t type;
|
int32_t type;
|
||||||
int32_t level;
|
int32_t level;
|
||||||
|
std::string zone_id_list;
|
||||||
|
std::string instance_version_list;
|
||||||
int32_t ac;
|
int32_t ac;
|
||||||
int32_t hp;
|
int32_t hp;
|
||||||
int32_t accuracy;
|
int32_t accuracy;
|
||||||
@@ -59,6 +62,8 @@ public:
|
|||||||
return {
|
return {
|
||||||
"type",
|
"type",
|
||||||
"level",
|
"level",
|
||||||
|
"zone_id_list",
|
||||||
|
"instance_version_list",
|
||||||
"ac",
|
"ac",
|
||||||
"hp",
|
"hp",
|
||||||
"accuracy",
|
"accuracy",
|
||||||
@@ -93,6 +98,8 @@ public:
|
|||||||
return {
|
return {
|
||||||
"type",
|
"type",
|
||||||
"level",
|
"level",
|
||||||
|
"zone_id_list",
|
||||||
|
"instance_version_list",
|
||||||
"ac",
|
"ac",
|
||||||
"hp",
|
"hp",
|
||||||
"accuracy",
|
"accuracy",
|
||||||
@@ -159,34 +166,36 @@ public:
|
|||||||
{
|
{
|
||||||
NpcScaleGlobalBase e{};
|
NpcScaleGlobalBase e{};
|
||||||
|
|
||||||
e.type = 0;
|
e.type = 0;
|
||||||
e.level = 0;
|
e.level = 0;
|
||||||
e.ac = 0;
|
e.zone_id_list = "";
|
||||||
e.hp = 0;
|
e.instance_version_list = "";
|
||||||
e.accuracy = 0;
|
e.ac = 0;
|
||||||
e.slow_mitigation = 0;
|
e.hp = 0;
|
||||||
e.attack = 0;
|
e.accuracy = 0;
|
||||||
e.strength = 0;
|
e.slow_mitigation = 0;
|
||||||
e.stamina = 0;
|
e.attack = 0;
|
||||||
e.dexterity = 0;
|
e.strength = 0;
|
||||||
e.agility = 0;
|
e.stamina = 0;
|
||||||
e.intelligence = 0;
|
e.dexterity = 0;
|
||||||
e.wisdom = 0;
|
e.agility = 0;
|
||||||
e.charisma = 0;
|
e.intelligence = 0;
|
||||||
e.magic_resist = 0;
|
e.wisdom = 0;
|
||||||
e.cold_resist = 0;
|
e.charisma = 0;
|
||||||
e.fire_resist = 0;
|
e.magic_resist = 0;
|
||||||
e.poison_resist = 0;
|
e.cold_resist = 0;
|
||||||
e.disease_resist = 0;
|
e.fire_resist = 0;
|
||||||
e.corruption_resist = 0;
|
e.poison_resist = 0;
|
||||||
e.physical_resist = 0;
|
e.disease_resist = 0;
|
||||||
e.min_dmg = 0;
|
e.corruption_resist = 0;
|
||||||
e.max_dmg = 0;
|
e.physical_resist = 0;
|
||||||
e.hp_regen_rate = 0;
|
e.min_dmg = 0;
|
||||||
e.attack_delay = 0;
|
e.max_dmg = 0;
|
||||||
e.spell_scale = 100;
|
e.hp_regen_rate = 0;
|
||||||
e.heal_scale = 100;
|
e.attack_delay = 0;
|
||||||
e.special_abilities = "";
|
e.spell_scale = 100;
|
||||||
|
e.heal_scale = 100;
|
||||||
|
e.special_abilities = "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -212,8 +221,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
npc_scale_global_base_id
|
npc_scale_global_base_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -222,34 +232,36 @@ public:
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
NpcScaleGlobalBase e{};
|
NpcScaleGlobalBase e{};
|
||||||
|
|
||||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
e.zone_id_list = row[2] ? row[2] : "";
|
||||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
e.instance_version_list = row[3] ? row[3] : "";
|
||||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
e.hp = static_cast<int32_t>(atoi(row[5]));
|
||||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
|
||||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.special_abilities = row[27] ? row[27] : "";
|
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
|
||||||
|
e.special_abilities = row[29] ? row[29] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -285,32 +297,34 @@ public:
|
|||||||
|
|
||||||
v.push_back(columns[0] + " = " + std::to_string(e.type));
|
v.push_back(columns[0] + " = " + std::to_string(e.type));
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.level));
|
v.push_back(columns[1] + " = " + std::to_string(e.level));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.ac));
|
v.push_back(columns[2] + " = '" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.hp));
|
v.push_back(columns[3] + " = '" + Strings::Escape(e.instance_version_list) + "'");
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.accuracy));
|
v.push_back(columns[4] + " = " + std::to_string(e.ac));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.slow_mitigation));
|
v.push_back(columns[5] + " = " + std::to_string(e.hp));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.attack));
|
v.push_back(columns[6] + " = " + std::to_string(e.accuracy));
|
||||||
v.push_back(columns[7] + " = " + std::to_string(e.strength));
|
v.push_back(columns[7] + " = " + std::to_string(e.slow_mitigation));
|
||||||
v.push_back(columns[8] + " = " + std::to_string(e.stamina));
|
v.push_back(columns[8] + " = " + std::to_string(e.attack));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.dexterity));
|
v.push_back(columns[9] + " = " + std::to_string(e.strength));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.agility));
|
v.push_back(columns[10] + " = " + std::to_string(e.stamina));
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.intelligence));
|
v.push_back(columns[11] + " = " + std::to_string(e.dexterity));
|
||||||
v.push_back(columns[12] + " = " + std::to_string(e.wisdom));
|
v.push_back(columns[12] + " = " + std::to_string(e.agility));
|
||||||
v.push_back(columns[13] + " = " + std::to_string(e.charisma));
|
v.push_back(columns[13] + " = " + std::to_string(e.intelligence));
|
||||||
v.push_back(columns[14] + " = " + std::to_string(e.magic_resist));
|
v.push_back(columns[14] + " = " + std::to_string(e.wisdom));
|
||||||
v.push_back(columns[15] + " = " + std::to_string(e.cold_resist));
|
v.push_back(columns[15] + " = " + std::to_string(e.charisma));
|
||||||
v.push_back(columns[16] + " = " + std::to_string(e.fire_resist));
|
v.push_back(columns[16] + " = " + std::to_string(e.magic_resist));
|
||||||
v.push_back(columns[17] + " = " + std::to_string(e.poison_resist));
|
v.push_back(columns[17] + " = " + std::to_string(e.cold_resist));
|
||||||
v.push_back(columns[18] + " = " + std::to_string(e.disease_resist));
|
v.push_back(columns[18] + " = " + std::to_string(e.fire_resist));
|
||||||
v.push_back(columns[19] + " = " + std::to_string(e.corruption_resist));
|
v.push_back(columns[19] + " = " + std::to_string(e.poison_resist));
|
||||||
v.push_back(columns[20] + " = " + std::to_string(e.physical_resist));
|
v.push_back(columns[20] + " = " + std::to_string(e.disease_resist));
|
||||||
v.push_back(columns[21] + " = " + std::to_string(e.min_dmg));
|
v.push_back(columns[21] + " = " + std::to_string(e.corruption_resist));
|
||||||
v.push_back(columns[22] + " = " + std::to_string(e.max_dmg));
|
v.push_back(columns[22] + " = " + std::to_string(e.physical_resist));
|
||||||
v.push_back(columns[23] + " = " + std::to_string(e.hp_regen_rate));
|
v.push_back(columns[23] + " = " + std::to_string(e.min_dmg));
|
||||||
v.push_back(columns[24] + " = " + std::to_string(e.attack_delay));
|
v.push_back(columns[24] + " = " + std::to_string(e.max_dmg));
|
||||||
v.push_back(columns[25] + " = " + std::to_string(e.spell_scale));
|
v.push_back(columns[25] + " = " + std::to_string(e.hp_regen_rate));
|
||||||
v.push_back(columns[26] + " = " + std::to_string(e.heal_scale));
|
v.push_back(columns[26] + " = " + std::to_string(e.attack_delay));
|
||||||
v.push_back(columns[27] + " = '" + Strings::Escape(e.special_abilities) + "'");
|
v.push_back(columns[27] + " = " + std::to_string(e.spell_scale));
|
||||||
|
v.push_back(columns[28] + " = " + std::to_string(e.heal_scale));
|
||||||
|
v.push_back(columns[29] + " = '" + Strings::Escape(e.special_abilities) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -334,6 +348,8 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.level));
|
v.push_back(std::to_string(e.level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.instance_version_list) + "'");
|
||||||
v.push_back(std::to_string(e.ac));
|
v.push_back(std::to_string(e.ac));
|
||||||
v.push_back(std::to_string(e.hp));
|
v.push_back(std::to_string(e.hp));
|
||||||
v.push_back(std::to_string(e.accuracy));
|
v.push_back(std::to_string(e.accuracy));
|
||||||
@@ -391,6 +407,8 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.level));
|
v.push_back(std::to_string(e.level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.instance_version_list) + "'");
|
||||||
v.push_back(std::to_string(e.ac));
|
v.push_back(std::to_string(e.ac));
|
||||||
v.push_back(std::to_string(e.hp));
|
v.push_back(std::to_string(e.hp));
|
||||||
v.push_back(std::to_string(e.accuracy));
|
v.push_back(std::to_string(e.accuracy));
|
||||||
@@ -450,34 +468,36 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
NpcScaleGlobalBase e{};
|
NpcScaleGlobalBase e{};
|
||||||
|
|
||||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
e.zone_id_list = row[2] ? row[2] : "";
|
||||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
e.instance_version_list = row[3] ? row[3] : "";
|
||||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
e.hp = static_cast<int32_t>(atoi(row[5]));
|
||||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
|
||||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.special_abilities = row[27] ? row[27] : "";
|
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
|
||||||
|
e.special_abilities = row[29] ? row[29] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -502,34 +522,36 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
NpcScaleGlobalBase e{};
|
NpcScaleGlobalBase e{};
|
||||||
|
|
||||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
e.zone_id_list = row[2] ? row[2] : "";
|
||||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
e.instance_version_list = row[3] ? row[3] : "";
|
||||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
e.hp = static_cast<int32_t>(atoi(row[5]));
|
||||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
|
||||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.special_abilities = row[27] ? row[27] : "";
|
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
|
||||||
|
e.special_abilities = row[29] ? row[29] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-86
@@ -9,22 +9,21 @@
|
|||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_HACKERS_REPOSITORY_H
|
#ifndef EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
#define EQEMU_BASE_HACKERS_REPOSITORY_H
|
#define EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
|
|
||||||
#include "../../database.h"
|
#include "../../database.h"
|
||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
class BaseHackersRepository {
|
class BasePlayerEventLogSettingsRepository {
|
||||||
public:
|
public:
|
||||||
struct Hackers {
|
struct PlayerEventLogSettings {
|
||||||
int32_t id;
|
int64_t id;
|
||||||
std::string account;
|
std::string event_name;
|
||||||
std::string name;
|
int8_t event_enabled;
|
||||||
std::string hacked;
|
int32_t retention_days;
|
||||||
std::string zone;
|
int32_t discord_webhook_id;
|
||||||
std::string date;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -36,11 +35,10 @@ public:
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"account",
|
"event_name",
|
||||||
"name",
|
"event_enabled",
|
||||||
"hacked",
|
"retention_days",
|
||||||
"zone",
|
"discord_webhook_id",
|
||||||
"date",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +46,10 @@ public:
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"account",
|
"event_name",
|
||||||
"name",
|
"event_enabled",
|
||||||
"hacked",
|
"retention_days",
|
||||||
"zone",
|
"discord_webhook_id",
|
||||||
"date",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +65,7 @@ public:
|
|||||||
|
|
||||||
static std::string TableName()
|
static std::string TableName()
|
||||||
{
|
{
|
||||||
return std::string("hackers");
|
return std::string("player_event_log_settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string BaseSelect()
|
static std::string BaseSelect()
|
||||||
@@ -89,57 +86,56 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hackers NewEntity()
|
static PlayerEventLogSettings NewEntity()
|
||||||
{
|
{
|
||||||
Hackers e{};
|
PlayerEventLogSettings e{};
|
||||||
|
|
||||||
e.id = 0;
|
e.id = 0;
|
||||||
e.account = "";
|
e.event_name = "";
|
||||||
e.name = "";
|
e.event_enabled = 0;
|
||||||
e.hacked = "";
|
e.retention_days = 0;
|
||||||
e.zone = "";
|
e.discord_webhook_id = 0;
|
||||||
e.date = std::time(nullptr);
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hackers GetHackers(
|
static PlayerEventLogSettings GetPlayerEventLogSettings(
|
||||||
const std::vector<Hackers> &hackerss,
|
const std::vector<PlayerEventLogSettings> &player_event_log_settingss,
|
||||||
int hackers_id
|
int player_event_log_settings_id
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (auto &hackers : hackerss) {
|
for (auto &player_event_log_settings : player_event_log_settingss) {
|
||||||
if (hackers.id == hackers_id) {
|
if (player_event_log_settings.id == player_event_log_settings_id) {
|
||||||
return hackers;
|
return player_event_log_settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewEntity();
|
return NewEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hackers FindOne(
|
static PlayerEventLogSettings FindOne(
|
||||||
Database& db,
|
Database& db,
|
||||||
int hackers_id
|
int player_event_log_settings_id
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
hackers_id
|
PrimaryKey(),
|
||||||
|
player_event_log_settings_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
Hackers e{};
|
PlayerEventLogSettings e{};
|
||||||
|
|
||||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
e.account = row[1] ? row[1] : "";
|
e.event_name = row[1] ? row[1] : "";
|
||||||
e.name = row[2] ? row[2] : "";
|
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||||
e.hacked = row[3] ? row[3] : "";
|
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.zone = row[4] ? row[4] : "";
|
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.date = row[5] ? row[5] : "";
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -149,7 +145,7 @@ public:
|
|||||||
|
|
||||||
static int DeleteOne(
|
static int DeleteOne(
|
||||||
Database& db,
|
Database& db,
|
||||||
int hackers_id
|
int player_event_log_settings_id
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
@@ -157,7 +153,7 @@ public:
|
|||||||
"DELETE FROM {} WHERE {} = {}",
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
TableName(),
|
TableName(),
|
||||||
PrimaryKey(),
|
PrimaryKey(),
|
||||||
hackers_id
|
player_event_log_settings_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -166,18 +162,18 @@ public:
|
|||||||
|
|
||||||
static int UpdateOne(
|
static int UpdateOne(
|
||||||
Database& db,
|
Database& db,
|
||||||
const Hackers &e
|
const PlayerEventLogSettings &e
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
auto columns = Columns();
|
auto columns = Columns();
|
||||||
|
|
||||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.account) + "'");
|
v.push_back(columns[0] + " = " + std::to_string(e.id));
|
||||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.name) + "'");
|
v.push_back(columns[1] + " = '" + Strings::Escape(e.event_name) + "'");
|
||||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.hacked) + "'");
|
v.push_back(columns[2] + " = " + std::to_string(e.event_enabled));
|
||||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.zone) + "'");
|
v.push_back(columns[3] + " = " + std::to_string(e.retention_days));
|
||||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.date) + "'");
|
v.push_back(columns[4] + " = " + std::to_string(e.discord_webhook_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -192,19 +188,18 @@ public:
|
|||||||
return (results.Success() ? results.RowsAffected() : 0);
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hackers InsertOne(
|
static PlayerEventLogSettings InsertOne(
|
||||||
Database& db,
|
Database& db,
|
||||||
Hackers e
|
PlayerEventLogSettings e
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back("'" + Strings::Escape(e.account) + "'");
|
v.push_back("'" + Strings::Escape(e.event_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
v.push_back(std::to_string(e.event_enabled));
|
||||||
v.push_back("'" + Strings::Escape(e.hacked) + "'");
|
v.push_back(std::to_string(e.retention_days));
|
||||||
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
v.push_back("'" + Strings::Escape(e.date) + "'");
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -226,7 +221,7 @@ public:
|
|||||||
|
|
||||||
static int InsertMany(
|
static int InsertMany(
|
||||||
Database& db,
|
Database& db,
|
||||||
const std::vector<Hackers> &entries
|
const std::vector<PlayerEventLogSettings> &entries
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::vector<std::string> insert_chunks;
|
std::vector<std::string> insert_chunks;
|
||||||
@@ -235,11 +230,10 @@ public:
|
|||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back("'" + Strings::Escape(e.account) + "'");
|
v.push_back("'" + Strings::Escape(e.event_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
v.push_back(std::to_string(e.event_enabled));
|
||||||
v.push_back("'" + Strings::Escape(e.hacked) + "'");
|
v.push_back(std::to_string(e.retention_days));
|
||||||
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
v.push_back("'" + Strings::Escape(e.date) + "'");
|
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -257,9 +251,9 @@ public:
|
|||||||
return (results.Success() ? results.RowsAffected() : 0);
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Hackers> All(Database& db)
|
static std::vector<PlayerEventLogSettings> All(Database& db)
|
||||||
{
|
{
|
||||||
std::vector<Hackers> all_entries;
|
std::vector<PlayerEventLogSettings> all_entries;
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -271,14 +265,13 @@ public:
|
|||||||
all_entries.reserve(results.RowCount());
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Hackers e{};
|
PlayerEventLogSettings e{};
|
||||||
|
|
||||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
e.account = row[1] ? row[1] : "";
|
e.event_name = row[1] ? row[1] : "";
|
||||||
e.name = row[2] ? row[2] : "";
|
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||||
e.hacked = row[3] ? row[3] : "";
|
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.zone = row[4] ? row[4] : "";
|
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.date = row[5] ? row[5] : "";
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -286,9 +279,9 @@ public:
|
|||||||
return all_entries;
|
return all_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Hackers> GetWhere(Database& db, const std::string &where_filter)
|
static std::vector<PlayerEventLogSettings> GetWhere(Database& db, const std::string &where_filter)
|
||||||
{
|
{
|
||||||
std::vector<Hackers> all_entries;
|
std::vector<PlayerEventLogSettings> all_entries;
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -301,14 +294,13 @@ public:
|
|||||||
all_entries.reserve(results.RowCount());
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Hackers e{};
|
PlayerEventLogSettings e{};
|
||||||
|
|
||||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
e.account = row[1] ? row[1] : "";
|
e.event_name = row[1] ? row[1] : "";
|
||||||
e.name = row[2] ? row[2] : "";
|
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||||
e.hacked = row[3] ? row[3] : "";
|
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.zone = row[4] ? row[4] : "";
|
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
e.date = row[5] ? row[5] : "";
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -369,4 +361,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_HACKERS_REPOSITORY_H
|
#endif //EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
@@ -0,0 +1,465 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <cereal/cereal.hpp>
|
||||||
|
|
||||||
|
class BasePlayerEventLogsRepository {
|
||||||
|
public:
|
||||||
|
struct PlayerEventLogs {
|
||||||
|
int64_t id;
|
||||||
|
int64_t account_id;
|
||||||
|
int64_t character_id;
|
||||||
|
int32_t zone_id;
|
||||||
|
int32_t instance_id;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float heading;
|
||||||
|
int32_t event_type_id;
|
||||||
|
std::string event_type_name;
|
||||||
|
std::string event_data;
|
||||||
|
time_t created_at;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(id),
|
||||||
|
CEREAL_NVP(account_id),
|
||||||
|
CEREAL_NVP(character_id),
|
||||||
|
CEREAL_NVP(zone_id),
|
||||||
|
CEREAL_NVP(instance_id),
|
||||||
|
CEREAL_NVP(x),
|
||||||
|
CEREAL_NVP(y),
|
||||||
|
CEREAL_NVP(z),
|
||||||
|
CEREAL_NVP(heading),
|
||||||
|
CEREAL_NVP(event_type_id),
|
||||||
|
CEREAL_NVP(event_type_name),
|
||||||
|
CEREAL_NVP(event_data),
|
||||||
|
CEREAL_NVP(created_at)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"account_id",
|
||||||
|
"character_id",
|
||||||
|
"zone_id",
|
||||||
|
"instance_id",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z",
|
||||||
|
"heading",
|
||||||
|
"event_type_id",
|
||||||
|
"event_type_name",
|
||||||
|
"event_data",
|
||||||
|
"created_at",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"account_id",
|
||||||
|
"character_id",
|
||||||
|
"zone_id",
|
||||||
|
"instance_id",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z",
|
||||||
|
"heading",
|
||||||
|
"event_type_id",
|
||||||
|
"event_type_name",
|
||||||
|
"event_data",
|
||||||
|
"UNIX_TIMESTAMP(created_at)",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("player_event_logs");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlayerEventLogs NewEntity()
|
||||||
|
{
|
||||||
|
PlayerEventLogs e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.account_id = 0;
|
||||||
|
e.character_id = 0;
|
||||||
|
e.zone_id = 0;
|
||||||
|
e.instance_id = 0;
|
||||||
|
e.x = 0;
|
||||||
|
e.y = 0;
|
||||||
|
e.z = 0;
|
||||||
|
e.heading = 0;
|
||||||
|
e.event_type_id = 0;
|
||||||
|
e.event_type_name = "";
|
||||||
|
e.event_data = "";
|
||||||
|
e.created_at = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlayerEventLogs GetPlayerEventLogs(
|
||||||
|
const std::vector<PlayerEventLogs> &player_event_logss,
|
||||||
|
int player_event_logs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &player_event_logs : player_event_logss) {
|
||||||
|
if (player_event_logs.id == player_event_logs_id) {
|
||||||
|
return player_event_logs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlayerEventLogs FindOne(
|
||||||
|
Database& db,
|
||||||
|
int player_event_logs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
player_event_logs_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
PlayerEventLogs e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.account_id = strtoll(row[1], nullptr, 10);
|
||||||
|
e.character_id = strtoll(row[2], nullptr, 10);
|
||||||
|
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
|
e.x = strtof(row[5], nullptr);
|
||||||
|
e.y = strtof(row[6], nullptr);
|
||||||
|
e.z = strtof(row[7], nullptr);
|
||||||
|
e.heading = strtof(row[8], nullptr);
|
||||||
|
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||||
|
e.event_type_name = row[10] ? row[10] : "";
|
||||||
|
e.event_data = row[11] ? row[11] : "";
|
||||||
|
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int player_event_logs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
player_event_logs_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const PlayerEventLogs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.account_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.character_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.zone_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.instance_id));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.x));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.y));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.z));
|
||||||
|
v.push_back(columns[8] + " = " + std::to_string(e.heading));
|
||||||
|
v.push_back(columns[9] + " = " + std::to_string(e.event_type_id));
|
||||||
|
v.push_back(columns[10] + " = '" + db.Escape(e.event_type_name) + "'");
|
||||||
|
v.push_back(columns[11] + " = '" + db.Escape(e.event_data) + "'");
|
||||||
|
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PlayerEventLogs InsertOne(
|
||||||
|
Database& db,
|
||||||
|
PlayerEventLogs e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
|
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
||||||
|
v.push_back("'" + db.Escape(e.event_data) + "'");
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<PlayerEventLogs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
|
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
||||||
|
v.push_back("'" + db.Escape(e.event_data) + "'");
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<PlayerEventLogs> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<PlayerEventLogs> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
PlayerEventLogs e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.account_id = strtoll(row[1], nullptr, 10);
|
||||||
|
e.character_id = strtoll(row[2], nullptr, 10);
|
||||||
|
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
|
e.x = strtof(row[5], nullptr);
|
||||||
|
e.y = strtof(row[6], nullptr);
|
||||||
|
e.z = strtof(row[7], nullptr);
|
||||||
|
e.heading = strtof(row[8], nullptr);
|
||||||
|
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||||
|
e.event_type_name = row[10] ? row[10] : "";
|
||||||
|
e.event_data = row[11] ? row[11] : "";
|
||||||
|
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<PlayerEventLogs> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<PlayerEventLogs> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {}",
|
||||||
|
BaseSelect(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
PlayerEventLogs e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.account_id = strtoll(row[1], nullptr, 10);
|
||||||
|
e.character_id = strtoll(row[2], nullptr, 10);
|
||||||
|
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||||
|
e.x = strtof(row[5], nullptr);
|
||||||
|
e.y = strtof(row[6], nullptr);
|
||||||
|
e.z = strtof(row[7], nullptr);
|
||||||
|
e.heading = strtof(row[8], nullptr);
|
||||||
|
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||||
|
e.event_type_name = row[10] ? row[10] : "";
|
||||||
|
e.event_data = row[11] ? row[11] : "";
|
||||||
|
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "base/base_character_data_repository.h"
|
#include "base/base_character_data_repository.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CharacterDataRepository: public BaseCharacterDataRepository {
|
class CharacterDataRepository: public BaseCharacterDataRepository {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -44,7 +46,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Custom extended repository methods here
|
// Custom extended repository methods here
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public:
|
|||||||
DELETE FROM {}
|
DELETE FROM {}
|
||||||
WHERE dynamic_zone_id IN ({});
|
WHERE dynamic_zone_id IN ({});
|
||||||
),
|
),
|
||||||
TableName(), fmt::join(dynamic_zone_ids, ",")
|
TableName(), Strings::Join(dynamic_zone_ids, ",")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
FROM expedition_lockouts
|
FROM expedition_lockouts
|
||||||
WHERE expedition_id IN ({})
|
WHERE expedition_id IN ({})
|
||||||
),
|
),
|
||||||
fmt::join(expedition_ids, ",")
|
Strings::Join(expedition_ids, ",")
|
||||||
));
|
));
|
||||||
|
|
||||||
all_entries.reserve(results.RowCount());
|
all_entries.reserve(results.RowCount());
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
std::vector<CharacterExpedition> entries;
|
std::vector<CharacterExpedition> entries;
|
||||||
|
|
||||||
auto joined_character_names = fmt::format("'{}'", fmt::join(character_names, "','"));
|
auto joined_character_names = fmt::format("'{}'", Strings::Join(character_names, "','"));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(fmt::format(SQL(
|
auto results = db.QueryDatabase(fmt::format(SQL(
|
||||||
SELECT
|
SELECT
|
||||||
|
|||||||
+9
-9
@@ -1,11 +1,11 @@
|
|||||||
#ifndef EQEMU_EVENTLOG_REPOSITORY_H
|
#ifndef EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
#define EQEMU_EVENTLOG_REPOSITORY_H
|
#define EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
|
|
||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "base/base_eventlog_repository.h"
|
#include "base/base_player_event_log_settings_repository.h"
|
||||||
|
|
||||||
class EventlogRepository: public BaseEventlogRepository {
|
class PlayerEventLogSettingsRepository: public BasePlayerEventLogSettingsRepository {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,10 +32,10 @@ public:
|
|||||||
*
|
*
|
||||||
* Example custom methods in a repository
|
* Example custom methods in a repository
|
||||||
*
|
*
|
||||||
* EventlogRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
* PlayerEventLogSettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||||
* EventlogRepository::GetWhereNeverExpires()
|
* PlayerEventLogSettingsRepository::GetWhereNeverExpires()
|
||||||
* EventlogRepository::GetWhereXAndY()
|
* PlayerEventLogSettingsRepository::GetWhereXAndY()
|
||||||
* EventlogRepository::DeleteWhereXAndY()
|
* PlayerEventLogSettingsRepository::DeleteWhereXAndY()
|
||||||
*
|
*
|
||||||
* Most of the above could be covered by base methods, but if you as a developer
|
* Most of the above could be covered by base methods, but if you as a developer
|
||||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||||
@@ -47,4 +47,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_EVENTLOG_REPOSITORY_H
|
#endif //EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
+9
-9
@@ -1,11 +1,11 @@
|
|||||||
#ifndef EQEMU_HACKERS_REPOSITORY_H
|
#ifndef EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
#define EQEMU_HACKERS_REPOSITORY_H
|
#define EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
|
|
||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "base/base_hackers_repository.h"
|
#include "base/base_player_event_logs_repository.h"
|
||||||
|
|
||||||
class HackersRepository: public BaseHackersRepository {
|
class PlayerEventLogsRepository: public BasePlayerEventLogsRepository {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,10 +32,10 @@ public:
|
|||||||
*
|
*
|
||||||
* Example custom methods in a repository
|
* Example custom methods in a repository
|
||||||
*
|
*
|
||||||
* HackersRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
* PlayerEventLogsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||||
* HackersRepository::GetWhereNeverExpires()
|
* PlayerEventLogsRepository::GetWhereNeverExpires()
|
||||||
* HackersRepository::GetWhereXAndY()
|
* PlayerEventLogsRepository::GetWhereXAndY()
|
||||||
* HackersRepository::DeleteWhereXAndY()
|
* PlayerEventLogsRepository::DeleteWhereXAndY()
|
||||||
*
|
*
|
||||||
* Most of the above could be covered by base methods, but if you as a developer
|
* Most of the above could be covered by base methods, but if you as a developer
|
||||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||||
@@ -47,4 +47,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_HACKERS_REPOSITORY_H
|
#endif //EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
+12
-3
@@ -141,11 +141,11 @@ bool RuleManager::SetRule(const std::string &rule_name, const std::string &rule_
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IntRule:
|
case IntRule:
|
||||||
m_RuleIntValues[index] = atoi(rule_value.c_str());
|
m_RuleIntValues[index] = Strings::ToInt(rule_value.c_str());
|
||||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
||||||
break;
|
break;
|
||||||
case RealRule:
|
case RealRule:
|
||||||
m_RuleRealValues[index] = atof(rule_value.c_str());
|
m_RuleRealValues[index] = Strings::ToFloat(rule_value.c_str());
|
||||||
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
|
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
|
||||||
break;
|
break;
|
||||||
case BoolRule:
|
case BoolRule:
|
||||||
@@ -385,7 +385,16 @@ void RuleManager::_SaveRule(Database *db, RuleType type, uint16 index) {
|
|||||||
e.rule_value = rule_value;
|
e.rule_value = rule_value;
|
||||||
e.notes = rule_notes;
|
e.notes = rule_notes;
|
||||||
|
|
||||||
RuleValuesRepository::UpdateOne(*db, e);
|
db->QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE rule_values SET rule_value = '{}', notes = '{}' WHERE ruleset_id = {} AND rule_name = '{}'",
|
||||||
|
rule_value,
|
||||||
|
Strings::Escape(rule_notes),
|
||||||
|
e.ruleset_id,
|
||||||
|
e.rule_name
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-2
@@ -93,6 +93,12 @@ RULE_INT(Character, ItemEnduranceRegenCap, 15, "Limit on endurance regeneration
|
|||||||
RULE_INT(Character, ItemExtraDmgCap, 150, "Cap for bonuses to melee skills like Bash, Frenzy, etc.")
|
RULE_INT(Character, ItemExtraDmgCap, 150, "Cap for bonuses to melee skills like Bash, Frenzy, etc.")
|
||||||
RULE_INT(Character, HasteCap, 100, "Haste cap for non-v3(over haste) haste")
|
RULE_INT(Character, HasteCap, 100, "Haste cap for non-v3(over haste) haste")
|
||||||
RULE_INT(Character, Hastev3Cap, 25, "Haste cap for v3(over haste) haste")
|
RULE_INT(Character, Hastev3Cap, 25, "Haste cap for v3(over haste) haste")
|
||||||
|
RULE_REAL(Character, HeroicStrengthMultiplier, 1.00, "Multplier scales benefits from Heroic Strength. Grants 25 Base Endurance, 0.05 Endurance Regen, 1 Melee Damage each Hit, and 1 Shield AC per 10 Heroic Strength.")
|
||||||
|
RULE_REAL(Character, HeroicStaminaMultiplier, 1.00, "Multplier scales benefits from Heroic Stamina. Grants 25 Base Endurance, 0.05 Endurance Regen, 100 Base HP, and 0.5 HP Regen per 10 Heroic Stamina.")
|
||||||
|
RULE_REAL(Character, HeroicAgilityMultiplier, 1.00, "Multplier scales benefits from Heroic Agility. Grants 25 Base Endurance, 0.05 Endurance Regen, and 1 Avoidance AC per 10 Heroic Agility. (Rule does not change Dodge Chance)")
|
||||||
|
RULE_REAL(Character, HeroicDexterityMultiplier, 1.00, "Multplier scales benefits from Heroic Dexterity. Grants 25 Base Endurance, 0.05 Endurance Regen, and 1 Archery/Throwing Damage each hit per 10 Heroic Dexterity. (Rule does not change Assassinate/Headshot/Block/Parry/Riposte Chances)")
|
||||||
|
RULE_REAL(Character, HeroicWisdomMultiplier, 1.00, "Multplier scales benefits from Heroic Wisdom. Grants 250 Base Mana, 1 Mana Regen per 25 Heroic Wisdom.")
|
||||||
|
RULE_REAL(Character, HeroicIntelligenceMultiplier, 1.00, "Multplier scales benefits from Heroic Intelligence. Grants 250 Base Mana, 1 Mana Regen per 25 Heroic Intelligence.")
|
||||||
RULE_INT(Character, SkillUpModifier, 100, "The probability for a skill-up is multiplied by value/100")
|
RULE_INT(Character, SkillUpModifier, 100, "The probability for a skill-up is multiplied by value/100")
|
||||||
RULE_BOOL(Character, SharedBankPlat, false, "Shared bank platinum. Off by default to prevent duplication")
|
RULE_BOOL(Character, SharedBankPlat, false, "Shared bank platinum. Off by default to prevent duplication")
|
||||||
RULE_BOOL(Character, BindAnywhere, false, "Allows players to bind their soul anywhere in the world")
|
RULE_BOOL(Character, BindAnywhere, false, "Allows players to bind their soul anywhere in the world")
|
||||||
@@ -197,9 +203,14 @@ RULE_BOOL(Character, PetZoneWithOwner, true, "Should Pets Zone with Owner")
|
|||||||
RULE_BOOL(Character, FullManaOnDeath, true, "On death set mana to full")
|
RULE_BOOL(Character, FullManaOnDeath, true, "On death set mana to full")
|
||||||
RULE_BOOL(Character, FullEndurOnDeath, true, "On death set endurance to full")
|
RULE_BOOL(Character, FullEndurOnDeath, true, "On death set endurance to full")
|
||||||
RULE_INT(Character, ExperiencePercentCapPerKill, -1, "Caps the percentage of experience that can be gained per kill. -1 disables the cap; 0 blocks all (non-aa) xp.")
|
RULE_INT(Character, ExperiencePercentCapPerKill, -1, "Caps the percentage of experience that can be gained per kill. -1 disables the cap; 0 blocks all (non-aa) xp.")
|
||||||
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier based on number of players in group, default is true")
|
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier in group, default is true")
|
||||||
|
RULE_BOOL(Character, EnableGroupMemberEXPModifier, true, "Enable or disable the group member experience modifier based on number of players in group, default is true")
|
||||||
RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2")
|
RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2")
|
||||||
RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16")
|
RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16")
|
||||||
|
RULE_BOOL(Character, IgnoreLevelBasedHasteCaps, false, "Ignores hard coded level based haste caps.")
|
||||||
|
RULE_BOOL(Character, EnableRaidEXPModifier, true, "Enable or disable the raid experience modifier, default is true")
|
||||||
|
RULE_BOOL(Character, EnableRaidMemberEXPModifier, true, "Enable or disable the raid experience modifier based on members in raid, default is true")
|
||||||
|
RULE_BOOL(Character, LeaveCursorMoneyOnCorpse, false, "Enable or disable leaving cursor money on player corpses")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@@ -315,8 +326,8 @@ RULE_CATEGORY_END()
|
|||||||
RULE_CATEGORY(Map)
|
RULE_CATEGORY(Map)
|
||||||
RULE_BOOL(Map, FixPathingZOnSendTo, false, "Try to repair Z coordinates in the SendTo routine as well")
|
RULE_BOOL(Map, FixPathingZOnSendTo, false, "Try to repair Z coordinates in the SendTo routine as well")
|
||||||
RULE_BOOL(Map, FixZWhenPathing, true, "Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)")
|
RULE_BOOL(Map, FixZWhenPathing, true, "Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)")
|
||||||
RULE_REAL(Map, DistanceCanTravelBeforeAdjustment, 10.0, "Distance a mob can path before FixZ is called, depends on FixZWhenPathing")
|
|
||||||
RULE_BOOL(Map, MobZVisualDebug, false, "Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)")
|
RULE_BOOL(Map, MobZVisualDebug, false, "Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)")
|
||||||
|
RULE_BOOL(Map, MobPathingVisualDebug, false, "Displays nodes in pathing points in realtime to help with visual debugging")
|
||||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20, "At runtime in SendTo: maximum change in Z to allow the BestZ code to apply")
|
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20, "At runtime in SendTo: maximum change in Z to allow the BestZ code to apply")
|
||||||
RULE_INT(Map, FindBestZHeightAdjust, 1, "Adds this to the current Z before seeking the best Z position")
|
RULE_INT(Map, FindBestZHeightAdjust, 1, "Adds this to the current Z before seeking the best Z position")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
@@ -430,6 +441,7 @@ RULE_BOOL(Spells, IllusionsAlwaysPersist, false, "Allows Illusions to persist be
|
|||||||
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
|
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
|
||||||
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
|
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
|
||||||
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
||||||
|
RULE_BOOL(Spells, ResurrectionEffectsBlock, true, "If enabled, resurrection effects cannot be overwritten.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
@@ -583,6 +595,7 @@ RULE_INT(Range, SongMessages, 75, "The packet range in which song messages are s
|
|||||||
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
|
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
|
||||||
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
|
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
|
||||||
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")
|
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")
|
||||||
|
RULE_INT(Range, MaxDistanceToClickDoors, 100, "Max distance that a client can click a door from (Client says 'You can't reach that' at roughly 25-50 for most doors)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Bots)
|
RULE_CATEGORY(Bots)
|
||||||
@@ -623,6 +636,7 @@ RULE_BOOL(Chat, EnableVoiceMacros, true, "Enable voice macros")
|
|||||||
RULE_BOOL(Chat, EnableMailKeyIPVerification, true, "Setting whether the authenticity of the client should be verified via its IP address when accessing the InGame mailbox")
|
RULE_BOOL(Chat, EnableMailKeyIPVerification, true, "Setting whether the authenticity of the client should be verified via its IP address when accessing the InGame mailbox")
|
||||||
RULE_BOOL(Chat, EnableAntiSpam, true, "Enable anti-spam system for chat")
|
RULE_BOOL(Chat, EnableAntiSpam, true, "Enable anti-spam system for chat")
|
||||||
RULE_BOOL(Chat, SuppressCommandErrors, false, "Do not suppress command errors by default")
|
RULE_BOOL(Chat, SuppressCommandErrors, false, "Do not suppress command errors by default")
|
||||||
|
RULE_BOOL(Chat, ChannelsIgnoreNameFilter, false, "Ignore name filtering when creating new chat channels")
|
||||||
RULE_INT(Chat, MaxPermanentPlayerChannels, 0, "Maximum number of permanent chat channels a player can make. Default 0.")
|
RULE_INT(Chat, MaxPermanentPlayerChannels, 0, "Maximum number of permanent chat channels a player can make. Default 0.")
|
||||||
RULE_INT(Chat, MinStatusToBypassAntiSpam, 100, "Minimum status to bypass the anti-spam system")
|
RULE_INT(Chat, MinStatusToBypassAntiSpam, 100, "Minimum status to bypass the anti-spam system")
|
||||||
RULE_INT(Chat, MinimumMessagesPerInterval, 4, "Minimum number of chat messages allowed per interval. The karma value is added to this value")
|
RULE_INT(Chat, MinimumMessagesPerInterval, 4, "Minimum number of chat messages allowed per interval. The karma value is added to this value")
|
||||||
@@ -744,6 +758,7 @@ RULE_BOOL(Inventory, DeleteTransformationMold, true, "False if you want mold to
|
|||||||
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
||||||
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
||||||
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
||||||
|
RULE_INT(Inventory, AlternateAugmentationSealer, 53, "Allows RoF+ clients to augment items from a special container type")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Client)
|
RULE_CATEGORY(Client)
|
||||||
@@ -773,6 +788,9 @@ RULE_CATEGORY_END()
|
|||||||
RULE_CATEGORY(Logging)
|
RULE_CATEGORY(Logging)
|
||||||
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
|
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
|
||||||
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
|
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
|
||||||
|
RULE_BOOL(Logging, PlayerEventsQSProcess, false, "Have query server process player events instead of world. Useful when wanting to use a dedicated server and database for processing player events on separate disk")
|
||||||
|
RULE_INT(Logging, BatchPlayerEventProcessIntervalSeconds, 5, "This is the interval in which player events are processed in world or qs")
|
||||||
|
RULE_INT(Logging, BatchPlayerEventProcessChunkSize, 10000, "This is the cap of events that can be inserted into the queue before a force flush. This is to keep from hitting MySQL max_allowed_packet and killing the connection")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(HotReload)
|
RULE_CATEGORY(HotReload)
|
||||||
|
|||||||
+20
-12
@@ -281,6 +281,9 @@
|
|||||||
#define ServerOP_QSSendQuery 0x5006
|
#define ServerOP_QSSendQuery 0x5006
|
||||||
#define ServerOP_QSPlayerDropItem 0x5007
|
#define ServerOP_QSPlayerDropItem 0x5007
|
||||||
|
|
||||||
|
// player events
|
||||||
|
#define ServerOP_PlayerEvent 0x5100
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CZUpdateType_Character,
|
CZUpdateType_Character,
|
||||||
CZUpdateType_Group,
|
CZUpdateType_Group,
|
||||||
@@ -1308,10 +1311,10 @@ struct Server_Speech_Struct {
|
|||||||
char message[0];
|
char message[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QSTradeItems_Struct {
|
struct PlayerLogTradeItemsEntry_Struct {
|
||||||
uint32 from_id;
|
uint32 from_character_id;
|
||||||
uint16 from_slot;
|
uint16 from_slot;
|
||||||
uint32 to_id;
|
uint32 to_character_id;
|
||||||
uint16 to_slot;
|
uint16 to_slot;
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
uint16 charges;
|
uint16 charges;
|
||||||
@@ -1322,15 +1325,15 @@ struct QSTradeItems_Struct {
|
|||||||
uint32 aug_5;
|
uint32 aug_5;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QSPlayerLogTrade_Struct {
|
struct PlayerLogTrade_Struct {
|
||||||
uint32 char1_id;
|
uint32 character_1_id;
|
||||||
MoneyUpdate_Struct char1_money;
|
MoneyUpdate_Struct character_1_money;
|
||||||
uint16 char1_count;
|
uint16 character_1_item_count;
|
||||||
uint32 char2_id;
|
uint32 character_2_id;
|
||||||
MoneyUpdate_Struct char2_money;
|
MoneyUpdate_Struct character_2_money;
|
||||||
uint16 char2_count;
|
uint16 character_2_item_count;
|
||||||
uint16 _detail_count;
|
uint16 _detail_count;
|
||||||
QSTradeItems_Struct items[0];
|
PlayerLogTradeItemsEntry_Struct item_entries[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QSDropItems_Struct {
|
struct QSDropItems_Struct {
|
||||||
@@ -1806,6 +1809,11 @@ struct ServerDzCreateSerialized_Struct {
|
|||||||
char cereal_data[0];
|
char cereal_data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ServerSendPlayerEvent_Struct {
|
||||||
|
uint32_t cereal_size;
|
||||||
|
char cereal_data[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct ServerFlagUpdate_Struct {
|
struct ServerFlagUpdate_Struct {
|
||||||
uint32 account_id;
|
uint32 account_id;
|
||||||
int16 admin;
|
int16 admin;
|
||||||
|
|||||||
+416
-407
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -139,7 +139,7 @@ public:
|
|||||||
uint32 aug6 = 0,
|
uint32 aug6 = 0,
|
||||||
bool attuned = 0
|
bool attuned = 0
|
||||||
);
|
);
|
||||||
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
|
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, const std::string &guid, int16 charges);
|
||||||
|
|
||||||
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
||||||
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||||
|
|||||||
+113
-15
@@ -191,24 +191,23 @@ std::string Strings::Escape(const std::string &s)
|
|||||||
|
|
||||||
bool Strings::IsNumber(const std::string &s)
|
bool Strings::IsNumber(const std::string &s)
|
||||||
{
|
{
|
||||||
try {
|
for (char const &c: s) {
|
||||||
auto r = stoi(s);
|
if (c == s[0] && s[0] == '-') {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
if (std::isdigit(c) == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Strings::IsFloat(const std::string &s)
|
bool Strings::IsFloat(const std::string &s)
|
||||||
{
|
{
|
||||||
try {
|
char* ptr;
|
||||||
auto r = stof(s);
|
strtof(s.c_str(), &ptr);
|
||||||
return true;
|
return (*ptr) == '\0';
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Strings::Join(const std::vector<std::string> &ar, const std::string &delim)
|
std::string Strings::Join(const std::vector<std::string> &ar, const std::string &delim)
|
||||||
@@ -225,6 +224,20 @@ std::string Strings::Join(const std::vector<std::string> &ar, const std::string
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Strings::Join(const std::vector<uint32_t> &ar, const std::string &delim)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
for (size_t i = 0; i < ar.size(); ++i) {
|
||||||
|
if (i != 0) {
|
||||||
|
ret += delim;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += std::to_string(ar[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Strings::FindReplace(std::string &string_subject, const std::string &search_string, const std::string &replace_string)
|
Strings::FindReplace(std::string &string_subject, const std::string &search_string, const std::string &replace_string)
|
||||||
{
|
{
|
||||||
@@ -714,7 +727,7 @@ uint32 Strings::TimeToSeconds(std::string time_string)
|
|||||||
time_unit.end()
|
time_unit.end()
|
||||||
);
|
);
|
||||||
|
|
||||||
auto unit = std::stoul(time_unit);
|
auto unit = Strings::ToUnsignedInt(time_unit);
|
||||||
uint32 duration = 0;
|
uint32 duration = 0;
|
||||||
|
|
||||||
if (Strings::Contains(time_string, "s")) {
|
if (Strings::Contains(time_string, "s")) {
|
||||||
@@ -741,7 +754,7 @@ bool Strings::ToBool(std::string bool_string)
|
|||||||
Strings::Contains(bool_string, "on") ||
|
Strings::Contains(bool_string, "on") ||
|
||||||
Strings::Contains(bool_string, "enable") ||
|
Strings::Contains(bool_string, "enable") ||
|
||||||
Strings::Contains(bool_string, "enabled") ||
|
Strings::Contains(bool_string, "enabled") ||
|
||||||
(Strings::IsNumber(bool_string) && std::stoi(bool_string))
|
(Strings::IsNumber(bool_string) && Strings::ToInt(bool_string))
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -763,3 +776,88 @@ std::string Strings::Random(size_t length)
|
|||||||
std::generate_n(str.begin(), length, randchar);
|
std::generate_n(str.begin(), length, randchar);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a wrapper for stoi which will return a fallback if the string
|
||||||
|
// fails to cast to a number
|
||||||
|
int Strings::ToInt(const std::string &s, int fallback)
|
||||||
|
{
|
||||||
|
if (!Strings::IsNumber(s)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stoi(s);
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 Strings::ToBigInt(const std::string &s, int64 fallback)
|
||||||
|
{
|
||||||
|
if (!Strings::IsNumber(s)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stoll(s);
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Strings::ToUnsignedInt(const std::string &s, uint32 fallback)
|
||||||
|
{
|
||||||
|
if (!Strings::IsNumber(s)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stoul(s);
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 Strings::ToUnsignedBigInt(const std::string &s, uint64 fallback)
|
||||||
|
{
|
||||||
|
if (!Strings::IsNumber(s)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stoull(s);
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Strings::ToFloat(const std::string &s, float fallback)
|
||||||
|
{
|
||||||
|
if (!Strings::IsFloat(s)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return std::stof(s);
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Strings::RemoveNumbers(std::string s)
|
||||||
|
{
|
||||||
|
int current = 0;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (!isdigit(s[i])) {
|
||||||
|
s[current] = s[i];
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.substr(0, current);
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,7 +86,13 @@ class Strings {
|
|||||||
public:
|
public:
|
||||||
static bool Contains(std::vector<std::string> container, std::string element);
|
static bool Contains(std::vector<std::string> container, std::string element);
|
||||||
static bool Contains(const std::string& subject, const std::string& search);
|
static bool Contains(const std::string& subject, const std::string& search);
|
||||||
|
static int ToInt(const std::string &s, int fallback = 0);
|
||||||
|
static int64 ToBigInt(const std::string &s, int64 fallback = 0);
|
||||||
|
static uint32 ToUnsignedInt(const std::string &s, uint32 fallback = 0);
|
||||||
|
static uint64 ToUnsignedBigInt(const std::string &s, uint64 fallback = 0);
|
||||||
|
static float ToFloat(const std::string &s, float fallback = 0.0f);
|
||||||
static bool IsNumber(const std::string &s);
|
static bool IsNumber(const std::string &s);
|
||||||
|
static std::string RemoveNumbers(std::string s);
|
||||||
static bool IsFloat(const std::string &s);
|
static bool IsFloat(const std::string &s);
|
||||||
static const std::string ToLower(std::string s);
|
static const std::string ToLower(std::string s);
|
||||||
static const std::string ToUpper(std::string s);
|
static const std::string ToUpper(std::string s);
|
||||||
@@ -106,6 +112,7 @@ public:
|
|||||||
static std::string GetBetween(const std::string &s, std::string start_delim, std::string stop_delim);
|
static std::string GetBetween(const std::string &s, std::string start_delim, std::string stop_delim);
|
||||||
static std::string Implode(std::string glue, std::vector<std::string> src);
|
static std::string Implode(std::string glue, std::vector<std::string> src);
|
||||||
static std::string Join(const std::vector<std::string> &ar, const std::string &delim);
|
static std::string Join(const std::vector<std::string> &ar, const std::string &delim);
|
||||||
|
static std::string Join(const std::vector<uint32_t> &ar, const std::string &delim);
|
||||||
static std::string MillisecondsToTime(int duration);
|
static std::string MillisecondsToTime(int duration);
|
||||||
static std::string Money(uint32 platinum, uint32 gold = 0, uint32 silver = 0, uint32 copper = 0);
|
static std::string Money(uint32 platinum, uint32 gold = 0, uint32 silver = 0, uint32 copper = 0);
|
||||||
static std::string NumberToWords(unsigned long long int n);
|
static std::string NumberToWords(unsigned long long int n);
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ bool atobool(const char *iBool)
|
|||||||
if (!strcasecmp(iBool, "n")) {
|
if (!strcasecmp(iBool, "n")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (atoi(iBool)) {
|
if (Strings::ToInt(iBool)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -42,6 +42,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
inline bool g_is_forced_tty = std::getenv("IS_TTY");
|
||||||
|
|
||||||
namespace rang {
|
namespace rang {
|
||||||
|
|
||||||
/* For better compability with most of terminals do not use any style settings
|
/* For better compability with most of terminals do not use any style settings
|
||||||
@@ -220,6 +222,10 @@ inline bool isMsysPty(int fd) noexcept
|
|||||||
|
|
||||||
inline bool isTerminal(const std::streambuf *osbuf) noexcept
|
inline bool isTerminal(const std::streambuf *osbuf) noexcept
|
||||||
{
|
{
|
||||||
|
if (g_is_forced_tty) {
|
||||||
|
return g_is_forced_tty;
|
||||||
|
}
|
||||||
|
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::clog;
|
using std::clog;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
// Disgrace: for windows compile
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|||||||
+3
-3
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "22.1.2-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.4.5-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9217
|
#define CURRENT_BINARY_DATABASE_VERSION 9222
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9037
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ uint32 AccountManagement::CheckExternalLoginserverUserCredentials(
|
|||||||
auto s = Strings::Split(server.options.GetEQEmuLoginServerAddress(), ':');
|
auto s = Strings::Split(server.options.GetEQEmuLoginServerAddress(), ':');
|
||||||
if (s.size() == 2) {
|
if (s.size() == 2) {
|
||||||
auto address = s[0];
|
auto address = s[0];
|
||||||
auto port = std::stoi(s[1]);
|
auto port = Strings::ToInt(s[1]);
|
||||||
|
|
||||||
EQ::Net::DNSLookup(
|
EQ::Net::DNSLookup(
|
||||||
address, port, false, [&](const std::string &addr) {
|
address, port, false, [&](const std::string &addr) {
|
||||||
|
|||||||
@@ -26,10 +26,11 @@ bool Client::Process()
|
|||||||
{
|
{
|
||||||
EQApplicationPacket *app = m_connection->PopPacket();
|
EQApplicationPacket *app = m_connection->PopPacket();
|
||||||
while (app) {
|
while (app) {
|
||||||
|
auto o = m_connection->GetOpcodeManager();
|
||||||
LogPacketClientServer(
|
LogPacketClientServer(
|
||||||
"[{}] [{:#06x}] Size [{}] {}",
|
"[{}] [{:#06x}] Size [{}] {}",
|
||||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||||
m_connection->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
o->EmuToEQ(app->GetOpcode()) == 0 ? app->GetProtocolOpcode() : o->EmuToEQ(app->GetOpcode()),
|
||||||
app->Size(),
|
app->Size(),
|
||||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||||
);
|
);
|
||||||
|
|||||||
+11
-11
@@ -32,7 +32,7 @@ Database::Database(
|
|||||||
user.c_str(),
|
user.c_str(),
|
||||||
pass.c_str(),
|
pass.c_str(),
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
std::stoi(port),
|
Strings::ToInt(port),
|
||||||
&errnum,
|
&errnum,
|
||||||
errbuf
|
errbuf
|
||||||
)
|
)
|
||||||
@@ -93,7 +93,7 @@ bool Database::GetLoginDataFromAccountInfo(
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
id = atoi(row[0]);
|
id = Strings::ToInt(row[0]);
|
||||||
password = row[1];
|
password = row[1];
|
||||||
|
|
||||||
LogDebug(
|
LogDebug(
|
||||||
@@ -145,7 +145,7 @@ bool Database::GetLoginTokenDataFromToken(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(row[2], "login_server_id") == 0) {
|
if (strcmp(row[2], "login_server_id") == 0) {
|
||||||
db_account_id = atoi(row[3]);
|
db_account_id = Strings::ToInt(row[3]);
|
||||||
found_login_id = true;
|
found_login_id = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ unsigned int Database::GetFreeID(const std::string &loginserver)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return std::stoi(row[0]);
|
return Strings::ToInt(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -368,12 +368,12 @@ Database::DbWorldRegistration Database::GetWorldRegistration(
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
r.loaded = true;
|
r.loaded = true;
|
||||||
r.server_id = std::stoi(row[0]);
|
r.server_id = Strings::ToInt(row[0]);
|
||||||
r.server_description = row[1];
|
r.server_description = row[1];
|
||||||
r.server_list_type = std::stoi(row[3]);
|
r.server_list_type = Strings::ToInt(row[3]);
|
||||||
r.is_server_trusted = std::stoi(row[2]) > 0;
|
r.is_server_trusted = Strings::ToInt(row[2]) > 0;
|
||||||
r.server_list_description = row[4];
|
r.server_list_description = row[4];
|
||||||
r.server_admin_id = std::stoi(row[5]);
|
r.server_admin_id = Strings::ToInt(row[5]);
|
||||||
|
|
||||||
if (r.server_admin_id <= 0) {
|
if (r.server_admin_id <= 0) {
|
||||||
return r;
|
return r;
|
||||||
@@ -513,7 +513,7 @@ bool Database::CreateWorldRegistration(
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
id = std::stoi(row[0]);
|
id = Strings::ToInt(row[0]);
|
||||||
auto insert_query = fmt::format(
|
auto insert_query = fmt::format(
|
||||||
"INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n"
|
"INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n"
|
||||||
"login_server_list_type_id = 3, login_server_admin_id = {4}, is_server_trusted = 0, tag_description = ''",
|
"login_server_list_type_id = 3, login_server_admin_id = {4}, is_server_trusted = 0, tag_description = ''",
|
||||||
@@ -647,7 +647,7 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
r.loaded = true;
|
r.loaded = true;
|
||||||
r.id = std::stoi(row[0]);
|
r.id = Strings::ToInt(row[0]);
|
||||||
r.account_name = row[1];
|
r.account_name = row[1];
|
||||||
r.account_password = row[2];
|
r.account_password = row[2];
|
||||||
r.first_name = row[3];
|
r.first_name = row[3];
|
||||||
@@ -683,7 +683,7 @@ Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName(
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
r.loaded = true;
|
r.loaded = true;
|
||||||
r.id = std::stoi(row[0]);
|
r.id = Strings::ToInt(row[0]);
|
||||||
r.account_name = row[1];
|
r.account_name = row[1];
|
||||||
r.account_password = row[2];
|
r.account_password = row[2];
|
||||||
r.account_email = row[3];
|
r.account_email = row[3];
|
||||||
|
|||||||
@@ -480,8 +480,8 @@ namespace LoginserverWebserver {
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
LoginserverWebserver::TokenManager::token_data token_data;
|
LoginserverWebserver::TokenManager::token_data token_data;
|
||||||
token_data.token = row[0];
|
token_data.token = row[0];
|
||||||
token_data.can_write = std::stoi(row[1]) > 0;
|
token_data.can_write = Strings::ToInt(row[1]) > 0;
|
||||||
token_data.can_read = std::stoi(row[2]) > 0;
|
token_data.can_read = Strings::ToInt(row[2]) > 0;
|
||||||
|
|
||||||
LogDebug(
|
LogDebug(
|
||||||
"Inserting api token to internal list [{0}] write {1} read {2}",
|
"Inserting api token to internal list [{0}] write {1} read {2}",
|
||||||
|
|||||||
@@ -288,9 +288,16 @@ int main(int argc, char **argv)
|
|||||||
LogInfo("[Config] [Security] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed());
|
LogInfo("[Config] [Security] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed());
|
||||||
LogInfo("[Config] [Security] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords());
|
LogInfo("[Config] [Security] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords());
|
||||||
|
|
||||||
|
Timer keepalive(INTERSERVER_TIMER); // does auto-reconnect
|
||||||
|
|
||||||
auto loop_fn = [&](EQ::Timer* t) {
|
auto loop_fn = [&](EQ::Timer* t) {
|
||||||
Timer::SetCurrentTime();
|
Timer::SetCurrentTime();
|
||||||
|
|
||||||
|
if (keepalive.Check()) {
|
||||||
|
keepalive.Start();
|
||||||
|
server.db->ping();
|
||||||
|
}
|
||||||
|
|
||||||
if (!run_server) {
|
if (!run_server) {
|
||||||
EQ::EventLoop::Get().Shutdown();
|
EQ::EventLoop::Get().Shutdown();
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.1.2",
|
"version": "22.4.5",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
+9
-10
@@ -50,7 +50,6 @@
|
|||||||
#include "../common/strings.h"
|
#include "../common/strings.h"
|
||||||
#include "../common/servertalk.h"
|
#include "../common/servertalk.h"
|
||||||
|
|
||||||
|
|
||||||
void QSDatabase::AddSpeech(
|
void QSDatabase::AddSpeech(
|
||||||
const char *from,
|
const char *from,
|
||||||
const char *to,
|
const char *to,
|
||||||
@@ -125,7 +124,7 @@ void QSDatabase::LogPlayerDropItem(QSPlayerDropItem_Struct *QS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSDatabase::LogPlayerTrade(QSPlayerLogTrade_Struct *QS, uint32 detailCount)
|
void QSDatabase::LogPlayerTrade(PlayerLogTrade_Struct *QS, uint32 detailCount)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
@@ -134,10 +133,10 @@ void QSDatabase::LogPlayerTrade(QSPlayerLogTrade_Struct *QS, uint32 detailCount)
|
|||||||
"`char1_sp` = '%i', `char1_cp` = '%i', `char1_items` = '%i', "
|
"`char1_sp` = '%i', `char1_cp` = '%i', `char1_items` = '%i', "
|
||||||
"`char2_id` = '%i', `char2_pp` = '%i', `char2_gp` = '%i', "
|
"`char2_id` = '%i', `char2_pp` = '%i', `char2_gp` = '%i', "
|
||||||
"`char2_sp` = '%i', `char2_cp` = '%i', `char2_items` = '%i'",
|
"`char2_sp` = '%i', `char2_cp` = '%i', `char2_items` = '%i'",
|
||||||
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold,
|
QS->character_1_id, QS->character_1_money.platinum, QS->character_1_money.gold,
|
||||||
QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
QS->character_1_money.silver, QS->character_1_money.copper, QS->character_1_item_count,
|
||||||
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold,
|
QS->character_2_id, QS->character_2_money.platinum, QS->character_2_money.gold,
|
||||||
QS->char2_money.silver, QS->char2_money.copper, QS->char2_count
|
QS->character_2_money.silver, QS->character_2_money.copper, QS->character_2_item_count
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -157,10 +156,10 @@ void QSDatabase::LogPlayerTrade(QSPlayerLogTrade_Struct *QS, uint32 detailCount)
|
|||||||
"`from_id` = '%i', `from_slot` = '%i', `to_id` = '%i', `to_slot` = '%i', "
|
"`from_id` = '%i', `from_slot` = '%i', `to_id` = '%i', `to_slot` = '%i', "
|
||||||
"`item_id` = '%i', `charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', "
|
"`item_id` = '%i', `charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', "
|
||||||
"`aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
"`aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||||
lastIndex, QS->items[i].from_id, QS->items[i].from_slot,
|
lastIndex, QS->item_entries[i].from_character_id, QS->item_entries[i].from_slot,
|
||||||
QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
QS->item_entries[i].to_character_id, QS->item_entries[i].to_slot, QS->item_entries[i].item_id,
|
||||||
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2,
|
QS->item_entries[i].charges, QS->item_entries[i].aug_1, QS->item_entries[i].aug_2,
|
||||||
QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5
|
QS->item_entries[i].aug_3, QS->item_entries[i].aug_4, QS->item_entries[i].aug_5
|
||||||
);
|
);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
|
|||||||
@@ -33,13 +33,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//atoi is not uint32 or uint32 safe!!!!
|
|
||||||
#define atoul(str) strtoul(str, nullptr, 10)
|
|
||||||
|
|
||||||
class QSDatabase : public Database {
|
class QSDatabase : public Database {
|
||||||
public:
|
public:
|
||||||
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
||||||
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount);
|
void LogPlayerTrade(PlayerLogTrade_Struct* QS, uint32 DetailCount);
|
||||||
void LogPlayerDropItem(QSPlayerDropItem_Struct* QS);
|
void LogPlayerDropItem(QSPlayerDropItem_Struct* QS);
|
||||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
||||||
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ bool LFGuildManager::LoadDatabase()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
uint32 type = atoul(row[0]);
|
uint32 type = Strings::ToUnsignedInt(row[0]);
|
||||||
if(type == 0)
|
if(type == 0)
|
||||||
{
|
{
|
||||||
PlayerLookingForGuild p(row[1], row[2], atoul(row[3]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8]));
|
PlayerLookingForGuild p(row[1], row[2], Strings::ToUnsignedInt(row[3]), Strings::ToUnsignedInt(row[5]), Strings::ToUnsignedInt(row[6]), Strings::ToUnsignedInt(row[7]), Strings::ToUnsignedInt(row[8]));
|
||||||
Players.push_back(p);
|
Players.push_back(p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuildLookingForPlayers g(row[1], row[2], atoul(row[3]), atoul(row[4]), atoul(row[5]), atoul(row[6]), atoul(row[7]), atoul(row[8]));
|
GuildLookingForPlayers g(row[1], row[2], Strings::ToUnsignedInt(row[3]), Strings::ToUnsignedInt(row[4]), Strings::ToUnsignedInt(row[5]), Strings::ToUnsignedInt(row[6]), Strings::ToUnsignedInt(row[7]), Strings::ToUnsignedInt(row[8]));
|
||||||
Guilds.push_back(g);
|
Guilds.push_back(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "../common/path_manager.h"
|
#include "../common/path_manager.h"
|
||||||
#include "../common/zone_store.h"
|
#include "../common/zone_store.h"
|
||||||
|
#include "../common/events/player_event_logs.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -47,6 +48,7 @@ WorldServer *worldserver = 0;
|
|||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
|
PlayerEventLogs player_event_logs;
|
||||||
|
|
||||||
void CatchSignal(int sig_num)
|
void CatchSignal(int sig_num)
|
||||||
{
|
{
|
||||||
@@ -106,6 +108,9 @@ int main()
|
|||||||
/* Load Looking For Guild Manager */
|
/* Load Looking For Guild Manager */
|
||||||
lfguildmanager.LoadDatabase();
|
lfguildmanager.LoadDatabase();
|
||||||
|
|
||||||
|
Timer player_event_process_timer(1000);
|
||||||
|
player_event_logs.SetDatabase(&database)->Init();
|
||||||
|
|
||||||
auto loop_fn = [&](EQ::Timer* t) {
|
auto loop_fn = [&](EQ::Timer* t) {
|
||||||
Timer::SetCurrentTime();
|
Timer::SetCurrentTime();
|
||||||
|
|
||||||
@@ -117,6 +122,10 @@ int main()
|
|||||||
if (LFGuildExpireTimer.Check()) {
|
if (LFGuildExpireTimer.Check()) {
|
||||||
lfguildmanager.ExpireEntries();
|
lfguildmanager.ExpireEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player_event_process_timer.Check()) {
|
||||||
|
player_event_logs.Process();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EQ::Timer process_timer(loop_fn);
|
EQ::Timer process_timer(loop_fn);
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "lfguild.h"
|
#include "lfguild.h"
|
||||||
#include "queryservconfig.h"
|
#include "queryservconfig.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
|
#include "../common/events/player_events.h"
|
||||||
|
#include "../common/events/player_event_logs.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -89,6 +91,17 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
case 0: {
|
case 0: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_PlayerEvent: {
|
||||||
|
auto n = PlayerEvent::PlayerEventContainer{};
|
||||||
|
auto s = (ServerSendPlayerEvent_Struct *) p.Data();
|
||||||
|
EQ::Util::MemoryStreamReader ss(s->cereal_data, s->cereal_size);
|
||||||
|
cereal::BinaryInputArchive archive(ss);
|
||||||
|
archive(n);
|
||||||
|
|
||||||
|
player_event_logs.AddToQueue(n.player_event_log);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_KeepAlive: {
|
case ServerOP_KeepAlive: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -100,7 +113,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogTrades: {
|
case ServerOP_QSPlayerLogTrades: {
|
||||||
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct *) p.Data();
|
PlayerLogTrade_Struct *QS = (PlayerLogTrade_Struct *) p.Data();
|
||||||
database.LogPlayerTrade(QS, QS->_detail_count);
|
database.LogPlayerTrade(QS, QS->_detail_count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMysql(database.getMySQL());
|
content_db.SetMySQL(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
|
|||||||
+4
-3
@@ -46,8 +46,7 @@ int main()
|
|||||||
auto ConfigLoadResult = EQEmuConfig::LoadConfig();
|
auto ConfigLoadResult = EQEmuConfig::LoadConfig();
|
||||||
Config = EQEmuConfig::get();
|
Config = EQEmuConfig::get();
|
||||||
try {
|
try {
|
||||||
std::ofstream outfile("test_output.txt");
|
std::unique_ptr<Test::Output> output(new Test::TextOutput(Test::TextOutput::Verbose));
|
||||||
std::unique_ptr<Test::Output> output(new Test::TextOutput(Test::TextOutput::Verbose, outfile));
|
|
||||||
Test::Suite tests;
|
Test::Suite tests;
|
||||||
tests.add(new MemoryMappedFileTest());
|
tests.add(new MemoryMappedFileTest());
|
||||||
tests.add(new IPCMutexTest());
|
tests.add(new IPCMutexTest());
|
||||||
@@ -60,7 +59,9 @@ int main()
|
|||||||
tests.add(new SkillsUtilsTest());
|
tests.add(new SkillsUtilsTest());
|
||||||
tests.add(new TaskStateTest());
|
tests.add(new TaskStateTest());
|
||||||
tests.run(*output, true);
|
tests.run(*output, true);
|
||||||
} catch (...) {
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
LogError("Test Failure [{}]", ex.what());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public:
|
|||||||
TEST_ADD(StringUtilTest::SearchDeliminatedStringTest);
|
TEST_ADD(StringUtilTest::SearchDeliminatedStringTest);
|
||||||
TEST_ADD(StringUtilTest::SplitStringTest);
|
TEST_ADD(StringUtilTest::SplitStringTest);
|
||||||
TEST_ADD(StringUtilTest::FromCharsTest);
|
TEST_ADD(StringUtilTest::FromCharsTest);
|
||||||
|
TEST_ADD(StringUtilTest::TestIsFloat);
|
||||||
|
TEST_ADD(StringUtilTest::TestIsNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
~StringUtilTest() {
|
~StringUtilTest() {
|
||||||
@@ -116,6 +118,26 @@ public:
|
|||||||
TEST_ASSERT(float_value == 3.14f);
|
TEST_ASSERT(float_value == 3.14f);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestIsFloat() {
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat("0.23424523"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat("12312312313.23424523"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat("12312312313"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat(".234234"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat(".234234f"), false);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsFloat("Johnson"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIsNumber() {
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("0.23424523"), false);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("12312312313.23424523"), false);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("12312312313"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("12312312313f"), false); // character at end
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("18446744073709551616"), true); // 64
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("-18"), true);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("-f18"), false);
|
||||||
|
TEST_ASSERT_EQUALS(Strings::IsNumber("-18446744073709551616"), true); // 64
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+7
-7
@@ -48,10 +48,10 @@ ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string in
|
|||||||
m_moderated = false;
|
m_moderated = false;
|
||||||
|
|
||||||
LogDebug(
|
LogDebug(
|
||||||
"New ChatChannel created: Name: [{}], Owner: [{}], Password: [{}], MinStatus: [{}]",
|
"New ChatChannel created: Name: [{}] Owner: [{}] Password: [{}] MinStatus: [{}]",
|
||||||
m_name.c_str(),
|
m_name,
|
||||||
m_owner.c_str(),
|
m_owner,
|
||||||
m_password.c_str(),
|
m_password,
|
||||||
m_minimum_status
|
m_minimum_status
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ ChatChannel *ChatChannelList::CreateChannel(
|
|||||||
{
|
{
|
||||||
uint8 max_perm_player_channels = RuleI(Chat, MaxPermanentPlayerChannels);
|
uint8 max_perm_player_channels = RuleI(Chat, MaxPermanentPlayerChannels);
|
||||||
|
|
||||||
if (!database.CheckChannelNameFilter(name)) {
|
if (!RuleB(Chat, ChannelsIgnoreNameFilter) && !database.CheckChannelNameFilter(name)) {
|
||||||
if (!(owner == SYSTEM_OWNER)) {
|
if (!(owner == SYSTEM_OWNER)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -657,7 +657,7 @@ ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_chan
|
|||||||
std::string channel_name = in_channel_name;
|
std::string channel_name = in_channel_name;
|
||||||
|
|
||||||
if (in_channel_name.length() > 0 && isdigit(channel_name[0])) {
|
if (in_channel_name.length() > 0 && isdigit(channel_name[0])) {
|
||||||
channel_name = c->ChannelSlotName(atoi(in_channel_name.c_str()));
|
channel_name = c->ChannelSlotName(Strings::ToInt(in_channel_name.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *required_channel = FindChannel(channel_name);
|
auto *required_channel = FindChannel(channel_name);
|
||||||
@@ -667,7 +667,7 @@ ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_chan
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogDebug("Client [{}] removed from channel [{}]. Channel is owned by {}. Command directed: {}", c->GetName(), channel_name, required_channel->GetOwnerName(), command_directed);
|
LogDebug("Client [{}] removed from channel [{}]. Channel is owned by {}. Command directed: {}", c->GetName(), channel_name, required_channel->GetOwnerName(), command_directed);
|
||||||
if (c->GetName() == required_channel->GetOwnerName() && command_directed) { // Check if the client that is leaving is the the channel owner
|
if (c->GetName() == required_channel->GetOwnerName() && command_directed) { // Check if the client that is leaving is the channel owner
|
||||||
LogDebug("Owner left the channel [{}], removing channel from database...", channel_name);
|
LogDebug("Owner left the channel [{}], removing channel from database...", channel_name);
|
||||||
database.DeleteChatChannel(channel_name); // Remove the channel from the database.
|
database.DeleteChatChannel(channel_name); // Remove the channel from the database.
|
||||||
LogDebug("Flagging [{}] channel as temporary...", channel_name);
|
LogDebug("Flagging [{}] channel as temporary...", channel_name);
|
||||||
|
|||||||
+20
-16
@@ -379,14 +379,14 @@ static void ProcessSetMessageStatus(std::string SetMessageCommand) {
|
|||||||
|
|
||||||
if (NumEnd == std::string::npos) {
|
if (NumEnd == std::string::npos) {
|
||||||
|
|
||||||
MessageNumber = atoi(SetMessageCommand.substr(NumStart).c_str());
|
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart).c_str());
|
||||||
|
|
||||||
database.SetMessageStatus(MessageNumber, Status);
|
database.SetMessageStatus(MessageNumber, Status);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageNumber = atoi(SetMessageCommand.substr(NumStart, NumEnd - NumStart).c_str());
|
MessageNumber = Strings::ToInt(SetMessageCommand.substr(NumStart, NumEnd - NumStart).c_str());
|
||||||
|
|
||||||
database.SetMessageStatus(MessageNumber, Status);
|
database.SetMessageStatus(MessageNumber, Status);
|
||||||
|
|
||||||
@@ -643,10 +643,11 @@ void Clientlist::Process()
|
|||||||
while (KeyValid && !(*it)->GetForceDisconnect() && (app = (*it)->ClientStream->PopPacket())) {
|
while (KeyValid && !(*it)->GetForceDisconnect() && (app = (*it)->ClientStream->PopPacket())) {
|
||||||
EmuOpcode opcode = app->GetOpcode();
|
EmuOpcode opcode = app->GetOpcode();
|
||||||
|
|
||||||
|
auto o = (*it)->ClientStream->GetOpcodeManager();
|
||||||
LogPacketClientServer(
|
LogPacketClientServer(
|
||||||
"[{}] [{:#06x}] Size [{}] {}",
|
"[{}] [{:#06x}] Size [{}] {}",
|
||||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||||
(*it)->ClientStream->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
o->EmuToEQ(app->GetOpcode()) == 0 ? app->GetProtocolOpcode() : o->EmuToEQ(app->GetOpcode()),
|
||||||
app->Size(),
|
app->Size(),
|
||||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||||
);
|
);
|
||||||
@@ -792,7 +793,10 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
case CommandJoin:
|
case CommandJoin:
|
||||||
if (!command_directed) {
|
if (!command_directed) {
|
||||||
//Append saved channels to params
|
//Append saved channels to params
|
||||||
parameters = parameters + ", " + database.CurrentPlayerChannels(c->GetName());
|
const auto saved_channels = database.CurrentPlayerChannels(c->GetName());
|
||||||
|
if (!saved_channels.empty()) {
|
||||||
|
parameters += fmt::format(", {}", Strings::Join(saved_channels, ", "));
|
||||||
|
}
|
||||||
parameters = RemoveDuplicateChannels(parameters);
|
parameters = RemoveDuplicateChannels(parameters);
|
||||||
}
|
}
|
||||||
c->JoinChannels(parameters, command_directed);
|
c->JoinChannels(parameters, command_directed);
|
||||||
@@ -872,7 +876,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CommandGetBody:
|
case CommandGetBody:
|
||||||
database.SendBody(c, atoi(parameters.c_str()));
|
database.SendBody(c, Strings::ToInt(parameters.c_str()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommandMailTo:
|
case CommandMailTo:
|
||||||
@@ -887,7 +891,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string command_string, boo
|
|||||||
case CommandSelectMailBox:
|
case CommandSelectMailBox:
|
||||||
{
|
{
|
||||||
std::string::size_type NumStart = parameters.find_first_of("0123456789");
|
std::string::size_type NumStart = parameters.find_first_of("0123456789");
|
||||||
c->ChangeMailBox(atoi(parameters.substr(NumStart).c_str()));
|
c->ChangeMailBox(Strings::ToInt(parameters.substr(NumStart).c_str()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CommandSetMailForwarding:
|
case CommandSetMailForwarding:
|
||||||
@@ -1249,7 +1253,7 @@ void Client::ProcessChannelList(std::string Input) {
|
|||||||
std::string ChannelName = Input;
|
std::string ChannelName = Input;
|
||||||
|
|
||||||
if (isdigit(ChannelName[0]))
|
if (isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1410,7 +1414,7 @@ void Client::SendChannelMessageByNumber(std::string Message) {
|
|||||||
if (MessageStart == std::string::npos)
|
if (MessageStart == std::string::npos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int ChannelNumber = atoi(Message.substr(0, MessageStart).c_str());
|
int ChannelNumber = Strings::ToInt(Message.substr(0, MessageStart).c_str());
|
||||||
|
|
||||||
if ((ChannelNumber < 1) || (ChannelNumber > MAX_JOINED_CHANNELS)) {
|
if ((ChannelNumber < 1) || (ChannelNumber > MAX_JOINED_CHANNELS)) {
|
||||||
|
|
||||||
@@ -1653,7 +1657,7 @@ void Client::SetChannelPassword(std::string ChannelPassword) {
|
|||||||
std::string ChannelName = ChannelPassword.substr(ChannelStart);
|
std::string ChannelName = ChannelPassword.substr(ChannelStart);
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
std::string Message;
|
std::string Message;
|
||||||
|
|
||||||
@@ -1718,7 +1722,7 @@ void Client::SetChannelOwner(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
LogInfo("Set owner of channel [[{}]] to [[{}]]", ChannelName.c_str(), NewOwner.c_str());
|
LogInfo("Set owner of channel [[{}]] to [[{}]]", ChannelName.c_str(), NewOwner.c_str());
|
||||||
|
|
||||||
@@ -1764,7 +1768,7 @@ void Client::OPList(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1807,7 +1811,7 @@ void Client::ChannelInvite(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
LogInfo("[[{}]] invites [[{}]] to channel [[{}]]", GetName().c_str(), Invitee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] invites [[{}]] to channel [[{}]]", GetName().c_str(), Invitee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -1877,7 +1881,7 @@ void Client::ChannelModerate(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
|
||||||
|
|
||||||
@@ -1935,7 +1939,7 @@ void Client::ChannelGrantModerator(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
LogInfo("[[{}]] gives [[{}]] moderator rights to channel [[{}]]", GetName().c_str(), Moderator.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] gives [[{}]] moderator rights to channel [[{}]]", GetName().c_str(), Moderator.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -2016,7 +2020,7 @@ void Client::ChannelGrantVoice(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
LogInfo("[[{}]] gives [[{}]] voice to channel [[{}]]", GetName().c_str(), Voicee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] gives [[{}]] voice to channel [[{}]]", GetName().c_str(), Voicee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
@@ -2104,7 +2108,7 @@ void Client::ChannelKick(std::string CommandString) {
|
|||||||
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
std::string ChannelName = CapitaliseName(CommandString.substr(ChannelStart));
|
||||||
|
|
||||||
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
if ((ChannelName.length() > 0) && isdigit(ChannelName[0]))
|
||||||
ChannelName = ChannelSlotName(atoi(ChannelName.c_str()));
|
ChannelName = ChannelSlotName(Strings::ToInt(ChannelName.c_str()));
|
||||||
|
|
||||||
LogInfo("[[{}]] kicks [[{}]] from channel [[{}]]", GetName().c_str(), Kickee.c_str(), ChannelName.c_str());
|
LogInfo("[[{}]] kicks [[{}]] from channel [[{}]]", GetName().c_str(), Kickee.c_str(), ChannelName.c_str());
|
||||||
|
|
||||||
|
|||||||
+23
-20
@@ -84,10 +84,10 @@ void UCSDatabase::GetAccountStatus(Client *client)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
client->SetAccountStatus(atoi(row[0]));
|
client->SetAccountStatus(Strings::ToInt(row[0]));
|
||||||
client->SetHideMe(atoi(row[1]) != 0);
|
client->SetHideMe(Strings::ToInt(row[1]) != 0);
|
||||||
client->SetKarma(atoi(row[2]));
|
client->SetKarma(Strings::ToInt(row[2]));
|
||||||
client->SetRevoked((atoi(row[3]) == 1 ? true : false));
|
client->SetRevoked((Strings::ToInt(row[3]) == 1 ? true : false));
|
||||||
|
|
||||||
LogDebug(
|
LogDebug(
|
||||||
"Set account status to [{}], hideme to [{}] and karma to [{}] for [{}]",
|
"Set account status to [{}], hideme to [{}] and karma to [{}] for [{}]",
|
||||||
@@ -119,9 +119,9 @@ int UCSDatabase::FindAccount(const char *characterName, Client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
client->AddCharacter(atoi(row[0]), characterName, atoi(row[2]));
|
client->AddCharacter(Strings::ToInt(row[0]), characterName, Strings::ToInt(row[2]));
|
||||||
|
|
||||||
int accountID = atoi(row[1]);
|
int accountID = Strings::ToInt(row[1]);
|
||||||
|
|
||||||
LogInfo("Account ID for [{}] is [{}]", characterName, accountID);
|
LogInfo("Account ID for [{}] is [{}]", characterName, accountID);
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ int UCSDatabase::FindAccount(const char *characterName, Client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
client->AddCharacter(atoi(row[0]), row[1], atoi(row[2]));
|
client->AddCharacter(Strings::ToInt(row[0]), row[1], Strings::ToInt(row[2]));
|
||||||
|
|
||||||
return accountID;
|
return accountID;
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ int UCSDatabase::FindCharacter(const char *characterName)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
int characterID = atoi(row[0]);
|
int characterID = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return characterID;
|
return characterID;
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,9 @@ bool UCSDatabase::GetVariable(const char *varname, char *varvalue, uint16 varval
|
|||||||
|
|
||||||
bool UCSDatabase::LoadChatChannels()
|
bool UCSDatabase::LoadChatChannels()
|
||||||
{
|
{
|
||||||
LoadFilteredNamesFromDB();
|
if (!RuleB(Chat, ChannelsIgnoreNameFilter)) {
|
||||||
|
LoadFilteredNamesFromDB();
|
||||||
|
}
|
||||||
LoadReservedNamesFromDB();
|
LoadReservedNamesFromDB();
|
||||||
LogInfo("Loading chat channels from the database");
|
LogInfo("Loading chat channels from the database");
|
||||||
|
|
||||||
@@ -242,7 +244,7 @@ bool UCSDatabase::LoadChatChannels()
|
|||||||
auto channel_min_status = row[3];
|
auto channel_min_status = row[3];
|
||||||
|
|
||||||
if (!ChannelList->FindChannel(channel_name)) {
|
if (!ChannelList->FindChannel(channel_name)) {
|
||||||
ChannelList->CreateChannel(channel_name, channel_owner, channel_password, true, atoi(channel_min_status), false);
|
ChannelList->CreateChannel(channel_name, channel_owner, channel_password, true, Strings::ToInt(channel_min_status), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -334,16 +336,17 @@ void UCSDatabase::DeleteChatChannel(const std::string& channel_name)
|
|||||||
LogInfo("Deleting channel [{}] from the database.", channel_name);
|
LogInfo("Deleting channel [{}] from the database.", channel_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string UCSDatabase::CurrentPlayerChannels(const std::string& player_name) {
|
std::vector<std::string> UCSDatabase::CurrentPlayerChannels(const std::string& player_name) {
|
||||||
int current_player_channel_count = CurrentPlayerChannelCount(player_name);
|
auto rows = ChatchannelsRepository::GetWhere(*this, fmt::format("`owner` = '{}'", Strings::Escape(player_name)));
|
||||||
if (current_player_channel_count == 0) {
|
if (rows.empty()) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
const auto rquery = fmt::format("SELECT GROUP_CONCAT(`name` SEPARATOR ', ') FROM chatchannels WHERE `owner` = '{}'; ", Strings::Escape(player_name));
|
std::vector<std::string> channels = {};
|
||||||
auto results = QueryDatabase(rquery);
|
channels.reserve(rows.size());
|
||||||
auto row = results.begin();
|
for (auto &e: rows) {
|
||||||
std::string channels = row[0];
|
channels.emplace_back(e.name);
|
||||||
LogDebug("Player [{}] has the following permanent channels saved to the database: [{}].", player_name, channels);
|
}
|
||||||
|
LogDebug("Player [{}] has the following [{}] permanent channels saved to the database: [{}].", player_name, rows.size(), Strings::Join(channels, ", "));
|
||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,7 +743,7 @@ void UCSDatabase::GetFriendsAndIgnore(const int& charID, std::vector<std::string
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
std::string name = row[1];
|
std::string name = row[1];
|
||||||
|
|
||||||
if (atoi(row[0]) == 0) {
|
if (Strings::ToInt(row[0]) == 0) {
|
||||||
ignorees.push_back(name);
|
ignorees.push_back(name);
|
||||||
LogInfo("Added Ignoree from DB [{}]", name.c_str());
|
LogInfo("Added Ignoree from DB [{}]", name.c_str());
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+2
-3
@@ -30,12 +30,11 @@
|
|||||||
#include "../common/database.h"
|
#include "../common/database.h"
|
||||||
#include "clientlist.h"
|
#include "clientlist.h"
|
||||||
#include "chatchannel.h"
|
#include "chatchannel.h"
|
||||||
|
#include "../common/shareddb.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//atoi is not uint32 or uint32 safe!!!!
|
|
||||||
#define atoul(str) strtoul(str, nullptr, 10)
|
|
||||||
|
|
||||||
class UCSDatabase : public Database {
|
class UCSDatabase : public Database {
|
||||||
public:
|
public:
|
||||||
@@ -51,7 +50,7 @@ public:
|
|||||||
void SaveChatChannel(const std::string& channel_name, const std::string& channel_owner, const std::string& channel_password, const uint16& min_status);
|
void SaveChatChannel(const std::string& channel_name, const std::string& channel_owner, const std::string& channel_password, const uint16& min_status);
|
||||||
void DeleteChatChannel(const std::string& channel_name);
|
void DeleteChatChannel(const std::string& channel_name);
|
||||||
int CurrentPlayerChannelCount(const std::string& player_name);
|
int CurrentPlayerChannelCount(const std::string& player_name);
|
||||||
std::string CurrentPlayerChannels(const std::string& player_name);
|
std::vector<std::string> CurrentPlayerChannels(const std::string& player_name);
|
||||||
void GetAccountStatus(Client *c);
|
void GetAccountStatus(Client *c);
|
||||||
void SetChannelPassword(const std::string& channel_name, const std::string& password);
|
void SetChannelPassword(const std::string& channel_name, const std::string& password);
|
||||||
void SetChannelOwner(const std::string& channel_name, const std::string& owner);
|
void SetChannelOwner(const std::string& channel_name, const std::string& owner);
|
||||||
|
|||||||
+10
-4
@@ -37,9 +37,10 @@
|
|||||||
|
|
||||||
#include "../common/net/tcp_server.h"
|
#include "../common/net/tcp_server.h"
|
||||||
#include "../common/net/servertalk_client_connection.h"
|
#include "../common/net/servertalk_client_connection.h"
|
||||||
#include "../common/discord_manager.h"
|
#include "../common/discord/discord_manager.h"
|
||||||
#include "../common/path_manager.h"
|
#include "../common/path_manager.h"
|
||||||
#include "../common/zone_store.h"
|
#include "../common/zone_store.h"
|
||||||
|
#include "../common/events/player_event_logs.h"
|
||||||
|
|
||||||
ChatChannelList *ChannelList;
|
ChatChannelList *ChannelList;
|
||||||
Clientlist *g_Clientlist;
|
Clientlist *g_Clientlist;
|
||||||
@@ -49,6 +50,7 @@ WorldServer *worldserver = nullptr;
|
|||||||
DiscordManager discord_manager;
|
DiscordManager discord_manager;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
|
PlayerEventLogs player_event_logs;
|
||||||
|
|
||||||
const ucsconfig *Config;
|
const ucsconfig *Config;
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ void CatchSignal(int sig_num) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscordQueueListener() {
|
void PlayerEventQueueListener() {
|
||||||
while (caught_loop == 0) {
|
while (caught_loop == 0) {
|
||||||
discord_manager.ProcessMessageQueue();
|
discord_manager.ProcessMessageQueue();
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
@@ -112,7 +114,7 @@ int main() {
|
|||||||
Timer ChannelListProcessTimer(60000);
|
Timer ChannelListProcessTimer(60000);
|
||||||
Timer ClientConnectionPruneTimer(60000);
|
Timer ClientConnectionPruneTimer(60000);
|
||||||
|
|
||||||
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
Timer keepalive(INTERSERVER_TIMER); // does auto-reconnect
|
||||||
|
|
||||||
LogInfo("Starting EQEmu Universal Chat Server");
|
LogInfo("Starting EQEmu Universal Chat Server");
|
||||||
|
|
||||||
@@ -177,7 +179,7 @@ int main() {
|
|||||||
std::signal(SIGKILL, CatchSignal);
|
std::signal(SIGKILL, CatchSignal);
|
||||||
std::signal(SIGSEGV, CatchSignal);
|
std::signal(SIGSEGV, CatchSignal);
|
||||||
|
|
||||||
std::thread(DiscordQueueListener).detach();
|
std::thread(PlayerEventQueueListener).detach();
|
||||||
|
|
||||||
worldserver = new WorldServer;
|
worldserver = new WorldServer;
|
||||||
|
|
||||||
@@ -186,6 +188,10 @@ int main() {
|
|||||||
// crash_test.detach();
|
// crash_test.detach();
|
||||||
|
|
||||||
auto loop_fn = [&](EQ::Timer* t) {
|
auto loop_fn = [&](EQ::Timer* t) {
|
||||||
|
if (keepalive.Check()) {
|
||||||
|
keepalive.Start();
|
||||||
|
database.ping();
|
||||||
|
}
|
||||||
|
|
||||||
Timer::SetCurrentTime();
|
Timer::SetCurrentTime();
|
||||||
|
|
||||||
|
|||||||
+14
-1
@@ -26,7 +26,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "clientlist.h"
|
#include "clientlist.h"
|
||||||
#include "ucsconfig.h"
|
#include "ucsconfig.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "../common/discord_manager.h"
|
#include "../common/discord/discord_manager.h"
|
||||||
|
#include "../common/events/player_event_logs.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -76,6 +77,18 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
case ServerOP_ReloadLogs: {
|
case ServerOP_ReloadLogs: {
|
||||||
LogSys.LoadLogDatabaseSettings();
|
LogSys.LoadLogDatabaseSettings();
|
||||||
|
player_event_logs.ReloadSettings();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ServerOP_PlayerEvent: {
|
||||||
|
auto n = PlayerEvent::PlayerEventContainer{};
|
||||||
|
auto s = (ServerSendPlayerEvent_Struct*) pack->pBuffer;
|
||||||
|
EQ::Util::MemoryStreamReader ss(s->cereal_data, s->cereal_size);
|
||||||
|
cereal::BinaryInputArchive archive(ss);
|
||||||
|
archive(n);
|
||||||
|
|
||||||
|
discord_manager.QueuePlayerEventMessage(n);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_DiscordWebhookMessage: {
|
case ServerOP_DiscordWebhookMessage: {
|
||||||
|
|||||||
@@ -507,11 +507,11 @@ void MainFrame::SaveActivity(wxCommandEvent& event)
|
|||||||
ourAct.optional = mActivityOptional->GetValue();
|
ourAct.optional = mActivityOptional->GetValue();
|
||||||
|
|
||||||
getStr = mActID->GetValue();
|
getStr = mActID->GetValue();
|
||||||
ourAct.activityId = atoi(getStr.mb_str());
|
ourAct.activityId = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mActStep->GetValue();
|
getStr = mActStep->GetValue();
|
||||||
ourAct.step = atoi(getStr.mb_str());
|
ourAct.step = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
int type = mActType->GetSelection();
|
int type = mActType->GetSelection();
|
||||||
@@ -530,17 +530,17 @@ void MainFrame::SaveActivity(wxCommandEvent& event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
getStr = mActDeliver->GetValue();
|
getStr = mActDeliver->GetValue();
|
||||||
ourAct.deliverToNpc = atoi(getStr.mb_str());
|
ourAct.deliverToNpc = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
ourAct.goalmethod = mActMethod->GetSelection();
|
ourAct.goalmethod = mActMethod->GetSelection();
|
||||||
|
|
||||||
getStr = mActGoalID->GetValue();
|
getStr = mActGoalID->GetValue();
|
||||||
ourAct.goalid = atoi(getStr.mb_str());
|
ourAct.goalid = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mActGoalCount->GetValue();
|
getStr = mActGoalCount->GetValue();
|
||||||
ourAct.goalcount = atoi(getStr.mb_str());
|
ourAct.goalcount = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
if(ourAct.activityId == openedActivity.activityid && ourAct.id == openedActivity.id){
|
if(ourAct.activityId == openedActivity.activityid && ourAct.id == openedActivity.id){
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ bool MainFrame::LoadItems(){
|
|||||||
while ((row = mysql_fetch_row(res)) != NULL){
|
while ((row = mysql_fetch_row(res)) != NULL){
|
||||||
eqitem newIT;
|
eqitem newIT;
|
||||||
strcpy(newIT.name, row[0]);
|
strcpy(newIT.name, row[0]);
|
||||||
newIT.id = atoi(row[1]);
|
newIT.id = Strings::ToInt(row[1]);
|
||||||
itemList.push_back(newIT);
|
itemList.push_back(newIT);
|
||||||
itemsLoaded++;
|
itemsLoaded++;
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ bool MainFrame::LoadZones()
|
|||||||
eqtask_zones newZ;
|
eqtask_zones newZ;
|
||||||
strcpy(newZ.name, row[0]);
|
strcpy(newZ.name, row[0]);
|
||||||
|
|
||||||
newZ.id = atoi(row[1]);
|
newZ.id = Strings::ToInt(row[1]);
|
||||||
taskZoneList.push_back(newZ);
|
taskZoneList.push_back(newZ);
|
||||||
|
|
||||||
int * zoneId = new int;
|
int * zoneId = new int;
|
||||||
@@ -168,7 +168,7 @@ bool MainFrame::LoadTasks()
|
|||||||
res = mysql_use_result(mMysql);
|
res = mysql_use_result(mMysql);
|
||||||
while ((row = mysql_fetch_row(res)) != NULL){
|
while ((row = mysql_fetch_row(res)) != NULL){
|
||||||
eqtask newT;
|
eqtask newT;
|
||||||
newT.id = atoi(row[0]);
|
newT.id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
//This isn't all that safe
|
//This isn't all that safe
|
||||||
//Working under the assumption that:
|
//Working under the assumption that:
|
||||||
@@ -185,15 +185,15 @@ bool MainFrame::LoadTasks()
|
|||||||
if(newT.id > highestIndex)
|
if(newT.id > highestIndex)
|
||||||
highestIndex = newT.id;
|
highestIndex = newT.id;
|
||||||
|
|
||||||
newT.rewardid = atoi(row[4]);
|
newT.rewardid = Strings::ToInt(row[4]);
|
||||||
newT.cashreward = atoi(row[5]);
|
newT.cashreward = Strings::ToInt(row[5]);
|
||||||
newT.xpreward = atoi(row[6]);
|
newT.xpreward = Strings::ToInt(row[6]);
|
||||||
newT.rewardmethod = atoi(row[7]);
|
newT.rewardmethod = Strings::ToInt(row[7]);
|
||||||
newT.startzone = atoi(row[8]);
|
newT.startzone = Strings::ToInt(row[8]);
|
||||||
newT.duration = atoi(row[9]);
|
newT.duration = Strings::ToInt(row[9]);
|
||||||
newT.level_min = atoi(row[10]);
|
newT.level_min = Strings::ToInt(row[10]);
|
||||||
newT.level_max = atoi(row[11]);
|
newT.level_max = Strings::ToInt(row[11]);
|
||||||
newT.repeatable = atoi(row[12]) ? true : false;
|
newT.repeatable = Strings::ToInt(row[12]) ? true : false;
|
||||||
|
|
||||||
taskList.push_back(newT);
|
taskList.push_back(newT);
|
||||||
|
|
||||||
@@ -225,8 +225,8 @@ bool MainFrame::LoadGoals()
|
|||||||
res = mysql_use_result(mMysql);
|
res = mysql_use_result(mMysql);
|
||||||
while ((row = mysql_fetch_row(res)) != NULL){
|
while ((row = mysql_fetch_row(res)) != NULL){
|
||||||
eqtask_goallist newGL;
|
eqtask_goallist newGL;
|
||||||
newGL.id = atoi(row[0]);
|
newGL.id = Strings::ToInt(row[0]);
|
||||||
newGL.value = atoi(row[1]);
|
newGL.value = Strings::ToInt(row[1]);
|
||||||
goalTaskList.push_back(newGL);
|
goalTaskList.push_back(newGL);
|
||||||
|
|
||||||
goalsLoaded++;
|
goalsLoaded++;
|
||||||
@@ -258,19 +258,19 @@ bool MainFrame::LoadActivities() {
|
|||||||
while ((row = mysql_fetch_row(res)) != NULL) {
|
while ((row = mysql_fetch_row(res)) != NULL) {
|
||||||
eqtask_activities newAL;
|
eqtask_activities newAL;
|
||||||
|
|
||||||
newAL.id = atoi(row[0]);
|
newAL.id = Strings::ToInt(row[0]);
|
||||||
newAL.activityId = atoi(row[1]);
|
newAL.activityId = Strings::ToInt(row[1]);
|
||||||
newAL.step = atoi(row[2]);
|
newAL.step = Strings::ToInt(row[2]);
|
||||||
newAL.activityType = atoi(row[3]);
|
newAL.activityType = Strings::ToInt(row[3]);
|
||||||
strcpy(newAL.text1, row[4]);
|
strcpy(newAL.text1, row[4]);
|
||||||
strcpy(newAL.text2, row[5]);
|
strcpy(newAL.text2, row[5]);
|
||||||
strcpy(newAL.text3, row[6]);
|
strcpy(newAL.text3, row[6]);
|
||||||
newAL.goalid = atoi(row[7]);
|
newAL.goalid = Strings::ToInt(row[7]);
|
||||||
newAL.goalmethod = atoi(row[8]);
|
newAL.goalmethod = Strings::ToInt(row[8]);
|
||||||
newAL.goalcount = atoi(row[9]);
|
newAL.goalcount = Strings::ToInt(row[9]);
|
||||||
newAL.deliverToNpc = atoi(row[10]);
|
newAL.deliverToNpc = Strings::ToInt(row[10]);
|
||||||
newAL.zoneid = atoi(row[11]);
|
newAL.zoneid = Strings::ToInt(row[11]);
|
||||||
newAL.optional = atoi(row[12]) ? true : false;
|
newAL.optional = Strings::ToInt(row[12]) ? true : false;
|
||||||
|
|
||||||
taskActivitiesList.push_back(newAL);
|
taskActivitiesList.push_back(newAL);
|
||||||
activitiesLoaded++;
|
activitiesLoaded++;
|
||||||
@@ -301,8 +301,8 @@ bool MainFrame::LoadProximity()
|
|||||||
while ((row = mysql_fetch_row(res)) != NULL){
|
while ((row = mysql_fetch_row(res)) != NULL){
|
||||||
eqtask_proximity newPR;
|
eqtask_proximity newPR;
|
||||||
|
|
||||||
newPR.zoneid = atoi(row[0]);
|
newPR.zoneid = Strings::ToInt(row[0]);
|
||||||
newPR.exploreid = atoi(row[1]);
|
newPR.exploreid = Strings::ToInt(row[1]);
|
||||||
newPR.minx = atof(row[2]);
|
newPR.minx = atof(row[2]);
|
||||||
newPR.maxx = atof(row[3]);
|
newPR.maxx = atof(row[3]);
|
||||||
newPR.miny = atof(row[4]);
|
newPR.miny = atof(row[4]);
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ void MainFrame::SaveProximity(wxCommandEvent& event)
|
|||||||
|
|
||||||
inStr.Clear();
|
inStr.Clear();
|
||||||
inStr = mProxId->GetValue();
|
inStr = mProxId->GetValue();
|
||||||
toSave.exploreid = atoi(inStr.mb_str());
|
toSave.exploreid = Strings::ToInt(inStr.mb_str());
|
||||||
|
|
||||||
inStr.Clear();
|
inStr.Clear();
|
||||||
inStr = mProxMinx->GetValue();
|
inStr = mProxMinx->GetValue();
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void MainFrame::OnRewardButton(wxCommandEvent& event)
|
|||||||
{
|
{
|
||||||
wxString ridStr = mRewardID->GetValue();
|
wxString ridStr = mRewardID->GetValue();
|
||||||
int rtype = mRewardMethod->GetCurrentSelection();
|
int rtype = mRewardMethod->GetCurrentSelection();
|
||||||
int rid = atoi(ridStr.mb_str());
|
int rid = Strings::ToInt(ridStr.mb_str());
|
||||||
|
|
||||||
ShowRewardChange(rtype,rid);
|
ShowRewardChange(rtype,rid);
|
||||||
}
|
}
|
||||||
@@ -224,15 +224,15 @@ void MainFrame::SaveTask(wxCommandEvent& event)
|
|||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mTaskMinLvl->GetValue();
|
getStr = mTaskMinLvl->GetValue();
|
||||||
ourTask.level_min = atoi(getStr.mb_str());
|
ourTask.level_min = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mTaskMaxLvl->GetValue();
|
getStr = mTaskMaxLvl->GetValue();
|
||||||
ourTask.level_max = atoi(getStr.mb_str());
|
ourTask.level_max = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mTaskDuration->GetValue();
|
getStr = mTaskDuration->GetValue();
|
||||||
ourTask.duration = atoi(getStr.mb_str());
|
ourTask.duration = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mRewardName->GetValue();
|
getStr = mRewardName->GetValue();
|
||||||
@@ -240,15 +240,15 @@ void MainFrame::SaveTask(wxCommandEvent& event)
|
|||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mRewardID->GetValue();
|
getStr = mRewardID->GetValue();
|
||||||
ourTask.rewardid = atoi(getStr.mb_str());
|
ourTask.rewardid = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mRewardCash->GetValue();
|
getStr = mRewardCash->GetValue();
|
||||||
ourTask.cashreward = atoi(getStr.mb_str());
|
ourTask.cashreward = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
getStr = mRewardXP->GetValue();
|
getStr = mRewardXP->GetValue();
|
||||||
ourTask.xpreward = atoi(getStr.mb_str());
|
ourTask.xpreward = Strings::ToInt(getStr.mb_str());
|
||||||
getStr.Clear();
|
getStr.Clear();
|
||||||
|
|
||||||
int * i = (int*)mStartZone->GetClientData(mStartZone->GetSelection());
|
int * i = (int*)mStartZone->GetClientData(mStartZone->GetSelection());
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ bool load_paths_from_db(MYSQL *m, Map *map, const char *zone, list<PathGraph*> &
|
|||||||
cur->x = atof(row[0]);
|
cur->x = atof(row[0]);
|
||||||
cur->y = atof(row[1]);
|
cur->y = atof(row[1]);
|
||||||
cur->z = atof(row[2]);
|
cur->z = atof(row[2]);
|
||||||
cur_g = atoi(row[3]);
|
cur_g = Strings::ToInt(row[3]);
|
||||||
if(cur_g != last_g) {
|
if(cur_g != last_g) {
|
||||||
if(g != NULL) {
|
if(g != NULL) {
|
||||||
//if we have a first and last node for this path
|
//if we have a first and last node for this path
|
||||||
@@ -206,8 +206,8 @@ bool load_hints_from_db(MYSQL *m, const char *zone, list<PathNode*> &db_spawns)
|
|||||||
cur->x = atof(row[0]);
|
cur->x = atof(row[0]);
|
||||||
cur->y = atof(row[1]);
|
cur->y = atof(row[1]);
|
||||||
cur->z = atof(row[2]);
|
cur->z = atof(row[2]);
|
||||||
cur->forced = atoi(row[3])?true:false;
|
cur->forced = Strings::ToInt(row[3])?true:false;
|
||||||
cur->disjoint = atoi(row[4])?true:false;
|
cur->disjoint = Strings::ToInt(row[4])?true:false;
|
||||||
db_spawns.push_back(cur);
|
db_spawns.push_back(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,27 +242,27 @@ bool load_settings_from_db(MYSQL *m, const char *zone) {
|
|||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
if((row = mysql_fetch_row(res))) {
|
if((row = mysql_fetch_row(res))) {
|
||||||
INCLUDE_DOORS = atoi(row[r++])?true:false;
|
INCLUDE_DOORS = Strings::ToInt(row[r++])?true:false;
|
||||||
MIN_FIX_Z = atof(row[r++]);
|
MIN_FIX_Z = atof(row[r++]);
|
||||||
FEAR_MAXIMUM_DISTANCE = atof(row[r++]);
|
FEAR_MAXIMUM_DISTANCE = atof(row[r++]);
|
||||||
IMAGE_SCALE = atoi(row[r++]);
|
IMAGE_SCALE = Strings::ToInt(row[r++]);
|
||||||
SPLIT_INVALID_PATHS = atoi(row[r++])?true:false;
|
SPLIT_INVALID_PATHS = Strings::ToInt(row[r++])?true:false;
|
||||||
LINK_PATH_ENDPOINTS = atoi(row[r++])?true:false;
|
LINK_PATH_ENDPOINTS = Strings::ToInt(row[r++])?true:false;
|
||||||
ENDPOINT_CONNECT_MAX_DISTANCE = atof(row[r++]);
|
ENDPOINT_CONNECT_MAX_DISTANCE = atof(row[r++]);
|
||||||
SPLIT_LINE_LENGTH = atof(row[r++]);
|
SPLIT_LINE_LENGTH = atof(row[r++]);
|
||||||
SPLIT_LINE_INTERVAL = atof(row[r++]);
|
SPLIT_LINE_INTERVAL = atof(row[r++]);
|
||||||
CLOSE_ENOUGH = atof(row[r++]);
|
CLOSE_ENOUGH = atof(row[r++]);
|
||||||
CLOSE_ENOUGH_COMBINE = atof(row[r++]);
|
CLOSE_ENOUGH_COMBINE = atof(row[r++]);
|
||||||
MERGE_MIN_SECOND_DIST = atof(row[r++]);
|
MERGE_MIN_SECOND_DIST = atof(row[r++]);
|
||||||
COMBINE_CHECK_ALL_LOS = atoi(row[r++])?true:false;
|
COMBINE_CHECK_ALL_LOS = Strings::ToInt(row[r++])?true:false;
|
||||||
CROSS_REDUCE_COUNT = atoi(row[r++]);
|
CROSS_REDUCE_COUNT = Strings::ToInt(row[r++]);
|
||||||
CROSS_MIN_LENGTH = atof(row[r++]);
|
CROSS_MIN_LENGTH = atof(row[r++]);
|
||||||
CROSS_MAX_Z_DIFF = atof(row[r++]);
|
CROSS_MAX_Z_DIFF = atof(row[r++]);
|
||||||
CLOSE_ENOUGH_CROSS = atof(row[r++]);
|
CLOSE_ENOUGH_CROSS = atof(row[r++]);
|
||||||
|
|
||||||
SPAWN_MIN_SECOND_DIST = atof(row[r++]);
|
SPAWN_MIN_SECOND_DIST = atof(row[r++]);
|
||||||
MAX_LINK_SPAWN_DIST = atof(row[r++]);
|
MAX_LINK_SPAWN_DIST = atof(row[r++]);
|
||||||
int sc = atoi(row[r++]);
|
int sc = Strings::ToInt(row[r++]);
|
||||||
SPAWN_LINK_TWICE = sc >= 2?true:false;
|
SPAWN_LINK_TWICE = sc >= 2?true:false;
|
||||||
SPAWN_LINK_THRICE = sc >= 3?true:false;
|
SPAWN_LINK_THRICE = sc >= 3?true:false;
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
|
|||||||
@@ -1118,7 +1118,7 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
|||||||
if((ch==EOF)||(ch=='\n')) {
|
if((ch==EOF)||(ch=='\n')) {
|
||||||
IniBuffer[StrIndex] = '\0';
|
IniBuffer[StrIndex] = '\0';
|
||||||
if(State == ReadingModelNumbers) {
|
if(State == ReadingModelNumbers) {
|
||||||
ModelNumber = atoi(IniBuffer);
|
ModelNumber = Strings::ToInt(IniBuffer);
|
||||||
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
||||||
{
|
{
|
||||||
fileloader->model_data.models[ModelNumber]->IncludeInMap = true;
|
fileloader->model_data.models[ModelNumber]->IncludeInMap = true;
|
||||||
@@ -1146,7 +1146,7 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ModelNumber = atoi(IniBuffer);
|
ModelNumber = Strings::ToInt(IniBuffer);
|
||||||
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
||||||
{
|
{
|
||||||
fileloader->model_data.models[ModelNumber]->IncludeInMap = true;
|
fileloader->model_data.models[ModelNumber]->IncludeInMap = true;
|
||||||
@@ -1323,7 +1323,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
|||||||
Group = true;
|
Group = true;
|
||||||
strcpy(IniBuffer, IniBuffer+1);
|
strcpy(IniBuffer, IniBuffer+1);
|
||||||
}
|
}
|
||||||
ModelNumber = atoi(IniBuffer);
|
ModelNumber = Strings::ToInt(IniBuffer);
|
||||||
if(!Group)
|
if(!Group)
|
||||||
{
|
{
|
||||||
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
||||||
@@ -1369,7 +1369,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
|||||||
Group = true;
|
Group = true;
|
||||||
strcpy(IniBuffer, IniBuffer+1);
|
strcpy(IniBuffer, IniBuffer+1);
|
||||||
}
|
}
|
||||||
ModelNumber = atoi(IniBuffer);
|
ModelNumber = Strings::ToInt(IniBuffer);
|
||||||
if(!Group)
|
if(!Group)
|
||||||
{
|
{
|
||||||
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
if((ModelNumber >= 0) && (ModelNumber < fileloader->model_data.model_count))
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ int DATLoader::Open(char *base_path, char *zone_name, Archive *archive) {
|
|||||||
if(Token == "*QUADSPERTILE")
|
if(Token == "*QUADSPERTILE")
|
||||||
{
|
{
|
||||||
Token = GetToken(ZonBuffer, ZonPosition);
|
Token = GetToken(ZonBuffer, ZonPosition);
|
||||||
QuadsPerTile = atoi(Token.c_str());
|
QuadsPerTile = Strings::ToInt(Token.c_str());
|
||||||
#ifdef DEBUGDAT
|
#ifdef DEBUGDAT
|
||||||
printf("Set QuadsPerTile to %i\n", QuadsPerTile);
|
printf("Set QuadsPerTile to %i\n", QuadsPerTile);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ FRAG_CONSTRUCTOR(Data15) {
|
|||||||
plac->scale[1] = hdr->scale[1];
|
plac->scale[1] = hdr->scale[1];
|
||||||
plac->scale[2] = hdr->scale[1];
|
plac->scale[2] = hdr->scale[1];
|
||||||
|
|
||||||
plac->model = atoi((const char*)&wld->sHash[-(int)hdr->ref]);
|
plac->model = Strings::ToInt((const char*)&wld->sHash[-(int)hdr->ref]);
|
||||||
|
|
||||||
pl = new Placeable *[wld->model_data.plac_count + 1];
|
pl = new Placeable *[wld->model_data.plac_count + 1];
|
||||||
memcpy(pl, wld->model_data.placeable, sizeof(Placeable *) * wld->model_data.plac_count);
|
memcpy(pl, wld->model_data.placeable, sizeof(Placeable *) * wld->model_data.plac_count);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if(argc != 3)
|
if(argc != 3)
|
||||||
usage();
|
usage();
|
||||||
int charid = atoi(argv[1]);
|
int charid = Strings::ToInt(argv[1]);
|
||||||
if(charid == 0)
|
if(charid == 0)
|
||||||
usage();
|
usage();
|
||||||
outfile = argv[2];
|
outfile = argv[2];
|
||||||
@@ -91,7 +91,7 @@ int main(int argc, char *argv[]) {
|
|||||||
header.y = atof(row[4]);
|
header.y = atof(row[4]);
|
||||||
header.z = atof(row[5]);
|
header.z = atof(row[5]);
|
||||||
strcpy(header.zone_name, row[6]);
|
strcpy(header.zone_name, row[6]);
|
||||||
header.zone_id = atoi(row[7]);
|
header.zone_id = Strings::ToInt(row[7]);
|
||||||
//copy in blobs
|
//copy in blobs
|
||||||
ppbuffer = new char[header.profile_length];
|
ppbuffer = new char[header.profile_length];
|
||||||
eppbuffer = new char[header.extprofile_length];
|
eppbuffer = new char[header.extprofile_length];
|
||||||
@@ -114,8 +114,8 @@ int main(int argc, char *argv[]) {
|
|||||||
vector<FactionValueRecord> fr;
|
vector<FactionValueRecord> fr;
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
FactionValueRecord r;
|
FactionValueRecord r;
|
||||||
r.faction_id = atoi(row[0]);
|
r.faction_id = Strings::ToInt(row[0]);
|
||||||
r.current_value = atoi(row[1]);
|
r.current_value = Strings::ToInt(row[1]);
|
||||||
fr.push_back(r);
|
fr.push_back(r);
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
@@ -134,15 +134,15 @@ int main(int argc, char *argv[]) {
|
|||||||
vector<InventoryEntry> inv;
|
vector<InventoryEntry> inv;
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
InventoryEntry r;
|
InventoryEntry r;
|
||||||
r.slotid = atoi(row[0]);
|
r.slotid = Strings::ToInt(row[0]);
|
||||||
r.itemid = atoi(row[1]);
|
r.itemid = Strings::ToInt(row[1]);
|
||||||
r.charges = atoi(row[2]);
|
r.charges = Strings::ToInt(row[2]);
|
||||||
r.colors = atoi(row[3]);
|
r.colors = Strings::ToInt(row[3]);
|
||||||
r.augs[0] = atoi(row[4]);
|
r.augs[0] = Strings::ToInt(row[4]);
|
||||||
r.augs[1] = atoi(row[5]);
|
r.augs[1] = Strings::ToInt(row[5]);
|
||||||
r.augs[2] = atoi(row[6]);
|
r.augs[2] = Strings::ToInt(row[6]);
|
||||||
r.augs[3] = atoi(row[7]);
|
r.augs[3] = Strings::ToInt(row[7]);
|
||||||
r.augs[4] = atoi(row[8]);
|
r.augs[4] = Strings::ToInt(row[8]);
|
||||||
inv.push_back(r);
|
inv.push_back(r);
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
@@ -161,14 +161,14 @@ int main(int argc, char *argv[]) {
|
|||||||
vector<InventoryEntry> sb;
|
vector<InventoryEntry> sb;
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
InventoryEntry r;
|
InventoryEntry r;
|
||||||
r.slotid = atoi(row[0]);
|
r.slotid = Strings::ToInt(row[0]);
|
||||||
r.itemid = atoi(row[1]);
|
r.itemid = Strings::ToInt(row[1]);
|
||||||
r.charges = atoi(row[2]);
|
r.charges = Strings::ToInt(row[2]);
|
||||||
r.augs[0] = atoi(row[3]);
|
r.augs[0] = Strings::ToInt(row[3]);
|
||||||
r.augs[1] = atoi(row[4]);
|
r.augs[1] = Strings::ToInt(row[4]);
|
||||||
r.augs[2] = atoi(row[5]);
|
r.augs[2] = Strings::ToInt(row[5]);
|
||||||
r.augs[3] = atoi(row[6]);
|
r.augs[3] = Strings::ToInt(row[6]);
|
||||||
r.augs[4] = atoi(row[7]);
|
r.augs[4] = Strings::ToInt(row[7]);
|
||||||
sb.push_back(r);
|
sb.push_back(r);
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
@@ -187,11 +187,11 @@ int main(int argc, char *argv[]) {
|
|||||||
vector<QuestGlobalEntry> qg;
|
vector<QuestGlobalEntry> qg;
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
QuestGlobalEntry r;
|
QuestGlobalEntry r;
|
||||||
r.npcid = atoi(row[0]);
|
r.npcid = Strings::ToInt(row[0]);
|
||||||
r.zoneid = atoi(row[1]);
|
r.zoneid = Strings::ToInt(row[1]);
|
||||||
strcpy(r.name, row[2]);
|
strcpy(r.name, row[2]);
|
||||||
strcpy(r.value, row[3]);
|
strcpy(r.value, row[3]);
|
||||||
r.expdate = atoi(row[4]);
|
r.expdate = Strings::ToInt(row[4]);
|
||||||
qg.push_back(r);
|
qg.push_back(r);
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if(argc != 3)
|
if(argc != 3)
|
||||||
usage();
|
usage();
|
||||||
int accountid = atoi(argv[1]);
|
int accountid = Strings::ToInt(argv[1]);
|
||||||
if(accountid == 0)
|
if(accountid == 0)
|
||||||
usage();
|
usage();
|
||||||
infile = argv[2];
|
infile = argv[2];
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ bool atobool(char* iBool) {
|
|||||||
return true;
|
return true;
|
||||||
if (!strcasecmp(iBool, "n"))
|
if (!strcasecmp(iBool, "n"))
|
||||||
return false;
|
return false;
|
||||||
if (atoi(iBool))
|
if (Strings::ToInt(iBool))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void EQEmuDatabase::GetPlayer(std::string name)
|
|||||||
while ((row = mysql_fetch_row(res)) != NULL)
|
while ((row = mysql_fetch_row(res)) != NULL)
|
||||||
{
|
{
|
||||||
player_entry pe;
|
player_entry pe;
|
||||||
pe.id = atoi(row[1]);
|
pe.id = Strings::ToInt(row[1]);
|
||||||
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
||||||
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
||||||
player_list.push_back(pe);
|
player_list.push_back(pe);
|
||||||
@@ -97,7 +97,7 @@ void EQEmuDatabase::GetPlayers()
|
|||||||
while ((row = mysql_fetch_row(res)) != NULL)
|
while ((row = mysql_fetch_row(res)) != NULL)
|
||||||
{
|
{
|
||||||
player_entry pe;
|
player_entry pe;
|
||||||
pe.id = atoi(row[1]);
|
pe.id = Strings::ToInt(row[1]);
|
||||||
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
||||||
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
||||||
player_list.push_back(pe);
|
player_list.push_back(pe);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ int main() {
|
|||||||
|
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
lengths = mysql_fetch_lengths(res);
|
lengths = mysql_fetch_lengths(res);
|
||||||
unsigned long id = atoi(row[0]);
|
unsigned long id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
int curlen = lengths[2];
|
int curlen = lengths[2];
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ int main() {
|
|||||||
|
|
||||||
while((row = mysql_fetch_row(res))) {
|
while((row = mysql_fetch_row(res))) {
|
||||||
lengths = mysql_fetch_lengths(res);
|
lengths = mysql_fetch_lengths(res);
|
||||||
unsigned long id = atoi(row[0]);
|
unsigned long id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
int curlen = lengths[2];
|
int curlen = lengths[2];
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ int main(int argc, char** argv) {
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
spid = atoi(argv[1]);
|
spid = Strings::ToInt(argv[1]);
|
||||||
|
|
||||||
|
|
||||||
int tempid=0;
|
int tempid=0;
|
||||||
@@ -35,7 +35,7 @@ int main(int argc, char** argv) {
|
|||||||
if(spell_line[0]=='\0')
|
if(spell_line[0]=='\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tempid = atoi(sep.arg[0]);
|
tempid = Strings::ToInt(sep.arg[0]);
|
||||||
if(tempid != spid)
|
if(tempid != spid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -55,75 +55,75 @@ int main(int argc, char** argv) {
|
|||||||
sp.aoerange=atof(sep.arg[10]);
|
sp.aoerange=atof(sep.arg[10]);
|
||||||
sp.pushback=atof(sep.arg[11]);
|
sp.pushback=atof(sep.arg[11]);
|
||||||
sp.pushup=atof(sep.arg[12]);
|
sp.pushup=atof(sep.arg[12]);
|
||||||
sp.cast_time=atoi(sep.arg[13]);
|
sp.cast_time=Strings::ToInt(sep.arg[13]);
|
||||||
sp.recovery_time=atoi(sep.arg[14]);
|
sp.recovery_time=Strings::ToInt(sep.arg[14]);
|
||||||
sp.recast_time=atoi(sep.arg[15]);
|
sp.recast_time=Strings::ToInt(sep.arg[15]);
|
||||||
sp.buffdurationformula=atoi(sep.arg[16]);
|
sp.buffdurationformula=Strings::ToInt(sep.arg[16]);
|
||||||
sp.buffduration=atoi(sep.arg[17]);
|
sp.buffduration=Strings::ToInt(sep.arg[17]);
|
||||||
sp.AEDuration=atoi(sep.arg[18]);
|
sp.AEDuration=Strings::ToInt(sep.arg[18]);
|
||||||
sp.mana=atoi(sep.arg[19]);
|
sp.mana=Strings::ToInt(sep.arg[19]);
|
||||||
|
|
||||||
int y=0;
|
int y=0;
|
||||||
for(y=0; y < EFFECT_COUNT;y++)
|
for(y=0; y < EFFECT_COUNT;y++)
|
||||||
sp.base[y]=atoi(sep.arg[20+y]);
|
sp.base[y]=Strings::ToInt(sep.arg[20+y]);
|
||||||
for(y=0;y<11;y++)
|
for(y=0;y<11;y++)
|
||||||
sp.base2[y]=atoi(sep.arg[33+y]);
|
sp.base2[y]=Strings::ToInt(sep.arg[33+y]);
|
||||||
for(y=0; y < EFFECT_COUNT;y++)
|
for(y=0; y < EFFECT_COUNT;y++)
|
||||||
sp.max[y]=atoi(sep.arg[44+y]);
|
sp.max[y]=Strings::ToInt(sep.arg[44+y]);
|
||||||
|
|
||||||
sp.icon=atoi(sep.arg[56]);
|
sp.icon=Strings::ToInt(sep.arg[56]);
|
||||||
sp.memicon=atoi(sep.arg[57]);
|
sp.memicon=Strings::ToInt(sep.arg[57]);
|
||||||
|
|
||||||
for(y=0; y< 4;y++)
|
for(y=0; y< 4;y++)
|
||||||
sp.components[y]=atoi(sep.arg[58+y]);
|
sp.components[y]=Strings::ToInt(sep.arg[58+y]);
|
||||||
|
|
||||||
for(y=0; y< 4;y++)
|
for(y=0; y< 4;y++)
|
||||||
sp.component_counts[y]=atoi(sep.arg[62+y]);
|
sp.component_counts[y]=Strings::ToInt(sep.arg[62+y]);
|
||||||
|
|
||||||
for(y=0; y< 4;y++)
|
for(y=0; y< 4;y++)
|
||||||
sp.NoexpendReagent[y]=atoi(sep.arg[66+y]);
|
sp.NoexpendReagent[y]=Strings::ToInt(sep.arg[66+y]);
|
||||||
|
|
||||||
for(y=0; y< 12;y++)
|
for(y=0; y< 12;y++)
|
||||||
sp.formula[y]=atoi(sep.arg[70+y]);
|
sp.formula[y]=Strings::ToInt(sep.arg[70+y]);
|
||||||
|
|
||||||
sp.LightType=atoi(sep.arg[82]);
|
sp.LightType=Strings::ToInt(sep.arg[82]);
|
||||||
sp.goodEffect=atoi(sep.arg[83]);
|
sp.goodEffect=Strings::ToInt(sep.arg[83]);
|
||||||
sp.Activated=atoi(sep.arg[84]);
|
sp.Activated=Strings::ToInt(sep.arg[84]);
|
||||||
sp.resisttype=atoi(sep.arg[85]);
|
sp.resisttype=Strings::ToInt(sep.arg[85]);
|
||||||
|
|
||||||
for(y=0; y< 12;y++)
|
for(y=0; y< 12;y++)
|
||||||
sp.effectid[y]=atoi(sep.arg[86+y]);
|
sp.effectid[y]=Strings::ToInt(sep.arg[86+y]);
|
||||||
|
|
||||||
sp.targettype=(SpellTargetType)atoi(sep.arg[98]);
|
sp.targettype=(SpellTargetType)Strings::ToInt(sep.arg[98]);
|
||||||
sp.basediff=atoi(sep.arg[99]);
|
sp.basediff=Strings::ToInt(sep.arg[99]);
|
||||||
sp.skill=(SkillType)atoi(sep.arg[100]);
|
sp.skill=(SkillType)Strings::ToInt(sep.arg[100]);
|
||||||
sp.zonetype=atoi(sep.arg[101]);
|
sp.zonetype=Strings::ToInt(sep.arg[101]);
|
||||||
sp.EnvironmentType=atoi(sep.arg[102]);
|
sp.EnvironmentType=Strings::ToInt(sep.arg[102]);
|
||||||
sp.TimeOfDay=atoi(sep.arg[103]);
|
sp.TimeOfDay=Strings::ToInt(sep.arg[103]);
|
||||||
|
|
||||||
for(y=0; y< 16;y++)
|
for(y=0; y< 16;y++)
|
||||||
sp.classes[y]=atoi(sep.arg[104+y]);
|
sp.classes[y]=Strings::ToInt(sep.arg[104+y]);
|
||||||
|
|
||||||
sp.CastingAnim=atoi(sep.arg[120]);
|
sp.CastingAnim=Strings::ToInt(sep.arg[120]);
|
||||||
sp.TargetAnim=atoi(sep.arg[121]);
|
sp.TargetAnim=Strings::ToInt(sep.arg[121]);
|
||||||
sp.TravelType=atoi(sep.arg[122]);
|
sp.TravelType=Strings::ToInt(sep.arg[122]);
|
||||||
sp.SpellAffectIndex=atoi(sep.arg[123]);
|
sp.SpellAffectIndex=Strings::ToInt(sep.arg[123]);
|
||||||
|
|
||||||
for(y=0; y< 23;y++) {
|
for(y=0; y< 23;y++) {
|
||||||
sp.spacing124[y]=atoi(sep.arg[124+y]);
|
sp.spacing124[y]=Strings::ToInt(sep.arg[124+y]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sp.ResistDiff=atoi(sep.arg[147]);
|
sp.ResistDiff=Strings::ToInt(sep.arg[147]);
|
||||||
sp.dot_stacking_exempt=atoi(sep.arg[148]);
|
sp.dot_stacking_exempt=Strings::ToInt(sep.arg[148]);
|
||||||
sp.deletable=atoi(sep.arg[149]);
|
sp.deletable=Strings::ToInt(sep.arg[149]);
|
||||||
|
|
||||||
sp.RecourseLink = atoi(sep.arg[150]);
|
sp.RecourseLink = Strings::ToInt(sep.arg[150]);
|
||||||
sp.descnum = atoi(sep.arg[155]);
|
sp.descnum = Strings::ToInt(sep.arg[155]);
|
||||||
sp.typedescnum = atoi(sep.arg[156]);
|
sp.typedescnum = Strings::ToInt(sep.arg[156]);
|
||||||
sp.effectdescnum = atoi(sep.arg[157]);
|
sp.effectdescnum = Strings::ToInt(sep.arg[157]);
|
||||||
|
|
||||||
// for(y=0; y< 17;y++)
|
// for(y=0; y< 17;y++)
|
||||||
// sp.Spacing4[y] = atoi(sep.arg[158+y]);
|
// sp.Spacing4[y] = Strings::ToInt(sep.arg[158+y]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ zip -j eqemu-server-linux-x64.zip ./build/bin/*
|
|||||||
ls -lsh | grep zip
|
ls -lsh | grep zip
|
||||||
sudo apt-get update && sudo apt-get install -y rclone
|
sudo apt-get update && sudo apt-get install -y rclone
|
||||||
rclone config create remote ftp env_auth true > /dev/null
|
rclone config create remote ftp env_auth true > /dev/null
|
||||||
rclone copy eqemu-server-linux-x64.zip remote:
|
rclone copy eqemu-server-linux-x64.zip remote: 2>&1
|
||||||
rclone ls remote:
|
rclone ls remote: 2>&1
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user