Compare commits

...

303 Commits

Author SHA1 Message Date
Chris Miles a1f154749c [Release] 22.16.0 (#3457) 2023-06-28 17:51:05 -04:00
Alex King 42a2e19e73 [Commands] Consolidate #findX commands to a singular #find Command (#3452)
* Push up example for Kingly

* Update aa.cpp

* Update find.cpp

* Bulk push.

* Update aa.cpp

* Cleanup

* Repository method.

* Static aliasing

* Aliases

* Fix alias error.

* Update zone.cpp

* Update command.cpp

* Update find.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-06-27 21:53:20 -05:00
mibastian c56b2e3e03 [Fix] Fix error in 023_01_21_bots_raid_members.sql (#3453)
world process did not start. An strace showed something wrong in 023_01_21_bots_raid_members.sql.  Seemed like a snap&paste error.
2023-06-27 21:52:27 -05:00
Alex King b05f1d3218 [Bug Fix] Merchant Open Flag set only for regular Merchants (#3454)
* [Bug Fix] Merchant Open Flag set only for regular Merchants

* Update npc.cpp
2023-06-27 16:23:48 -04:00
Alex King a004924112 [Bug Fix] Fix NPC Item Stat Bonuses (#3444)
* [Bug Fix] Fix NPC Item Stat Bonuses

# Notes
- Due to https://github.com/EQEmu/Server/pull/3136 NPCs/Mercs were not receiving stat bonuses from their items, this fixes that.

* Update npc.h

* Changes.

* Cleanup

* Cleanup

* Update loottables.cpp

* Update npc.cpp

* Update loottables.cpp
2023-06-26 00:22:10 -04:00
Alex King 8d986c95cd [Commands] Add #finddeity Command (#3435)
# Notes
- Add `#finddeity` command.
- Remove `ConvertDeityTypeBitToDeityType` as it's unused.
- Rename `ConvertDeityTypeToDeityTypeBit` to `GetDeityBitmask`.
2023-06-25 23:00:32 -05:00
Alex King ef7a3cae17 [Commands] Cleanup #showbuffs Command (#3439)
* [Commands] Cleanup #showbuffs Command

# Notes
- Cleaned up messages and logic.
- Removed unnecessary itembonuses/spellbonuses stuff.
- Removed `Mob::ShowBuffList` as it's just a copy of this method.

* Update mob.cpp

* Further cleanup.

* Update mob.cpp

* Update mob.cpp
2023-06-25 22:59:47 -05:00
Alex King 050aba65b6 [Commands] Cleanup #viewcurrencies Command (#3441)
# Notes
- Utilize Dialogue Window table for cleanliness and readability.
2023-06-24 20:26:41 -04:00
Alex King 9154c90418 [Commands] Add #findlanguage Command (#3434)
# Notes
- Add `#findlanguage` command.
2023-06-24 20:26:29 -04:00
Alex King d558f9ece2 [Rules] Add ClientPetsUserOwnerNameInLastName rule (#3442)
* [Rules] Add ClientPetsUserOwnerNameInLastName rule

# Notes
- This rule defaults to `true` and maintains `Kinglykrab's Pet` as my pet's name, disabling allows you to manually modify the last name or have pets with no last name.

* Update npc.cpp
2023-06-24 20:01:40 -04:00
Alex King 327dacdbe1 [Cleanup] Remove GetACAvoid() from zone/merc.h (#3447)
- This is unused.
2023-06-24 20:00:56 -04:00
Alex King f2ff4245c0 [Commands] Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop (#3433)
* [Commands] Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop

# Notes
- `#merchant_close_shop` and `#merchant_open_shop` are now consolidated into `#merchantshop`.
- Command now works on any type of merchant instead of just regular merchants.
- Can be used on Merchants, Discord Merchants, Adventure Merchants, Norrath's Keepers Merchants, Dark Reign Merchants, and Alternate Currency Merchants.

* Update merchantshop.cpp

* Update merchantshop.cpp

* Update merchantshop.cpp
2023-06-24 13:14:19 -05:00
Alex King 3ceb743195 [Commands] Add #showspells Command (#3429)
* [Commands] Add #showspells Command

# Notes
- Add `#showspells` command to show your or your target's memorized spells or learned disciplines.

* Update client.cpp
2023-06-24 13:13:02 -05:00
Alex King 021f04c17d [Cleanup] Remove command_unlock from zone/command.h (#3431)
# Notes
- This is unused.
2023-06-24 13:10:19 -05:00
Alex King f7e2dbdce6 [Cleanup] Remove command_packetprofile from zone/command.h (#3432)
* [Cleanup] Remove command_packetprofile from zone/command.h

# Notes
- This is unused.

* Update command.h
2023-06-24 13:10:05 -05:00
Alex King 2a679f1002 [Cleanup] Remove command_showpetspell in zone/command.h (#3430)
# Notes
- This is unused.
2023-06-24 13:09:51 -05:00
Alex King 8c9849ec73 [Commands] Delete #showbonusstats Command (#3437)
# Notes
- Never seen this used, also missing 99% of the bonuses data.
2023-06-24 13:09:39 -05:00
Alex King 10086ce97c [Commands] Delete #spellinfo Command (#3438)
# Notes
- Never seen this used, also missing 99% of the spell data.
2023-06-24 13:09:23 -05:00
Alex King 223ae22f73 [Cleanup] Delete common/worldconn.cpp (#3436)
# Notes
- This is unused.
2023-06-24 13:05:45 -05:00
Alex King 4330494f57 [Commands] Cleanup #shownpcgloballoot and #showzonegloballoot Commands (#3440)
# Notes
- Cleanup messages and logic.
- Utilize Dialogue Window tables.
2023-06-24 13:03:37 -05:00
Alex King 64ae7e4529 [Cleanup] Remove _ClearWaypints() from zone/npc.h (#3445)
# Notes
- This is unused.
2023-06-24 12:58:28 -05:00
Alex King 58c3e267e1 [Cleanup] Remove GetACMit() from zone/merc.h (#3446)
# Notes
- This is unused.
2023-06-24 12:58:13 -05:00
Alex King 598483a1a4 [Cleanup] Remove acmod() from zone/merc.h (#3448)
# Notes
- This is unused.
2023-06-24 12:57:43 -05:00
Alex King c1122022b9 [Cleanup] Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h (#3449)
* [Cleanup] Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h

# Notes
- This is unused.

* Update npc.h
2023-06-24 12:57:21 -05:00
Chris Miles f2c4babd8d [Database] Fix database version checking edge case issue (#3428) 2023-06-22 18:00:23 -05:00
Akkadius 5249b065d3 [Release] 22.15.3 2023-06-19 19:15:42 -05:00
Alex King 9312261444 [Bug Fix] Fix improper condition in Water LOS checks (#3426)
# Notes
- Oversight on my part, should've been `==`, not `&&`.
2023-06-19 18:53:19 -04:00
Akkadius 85054fedf8 [Release] 22.15.2 (Hotfix) 2023-06-19 12:00:41 -05:00
Chris Miles 6d7beb1796 [Database] Fix multi-statement error reporting (#3425) 2023-06-19 11:55:32 -05:00
JJ 66e377fd4a [Readme] Update new location of database updates (#3424) 2023-06-19 12:12:59 -04:00
Akkadius 67c4c26f70 [Release] 22.15.1 2023-06-19 02:21:09 -05:00
Akkadius b1c8e3890a [Release] 22.15.0 2023-06-19 01:41:55 -05:00
Alex King d6e06a19a7 [Commands] Add missing subcommands to #npcedit (#3423)
# Notes
- Add `#npcedit model [Race ID]` to edit an NPC's race model.
- Add `#npcedit heroic_strikethrough [Heroic Strikethrough]` to edit an NPC's heroic strikethrough.
- Add `#npcedit faction_amount [Faction Amount]` to edit an NPC's faction amount.
2023-06-19 01:40:27 -05:00
Akkadius 4092b3a2cb [Release] 22.15.0 2023-06-19 01:38:12 -05:00
Alex King f4f0619618 [Bug Fix] Fix possible crash with #npcedit weapon (#3421)
# Notes
- Using `#npcedit weapon` without the secondary model had a chance to crash the zone you were in, i.e `#npcedit weapon 1`.

# Crash Logs
```txt
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802548]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802549]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802550]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802551]
[06-18-2023 16:26:55] [Zone] [Crash] [Thread debugging using libthread_db enabled]
[06-18-2023 16:26:55] [Zone] [Crash] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[06-18-2023 16:26:55] [Zone] [Crash] 0x00007f22b2b14207 in __GI___wait4 (pid=819104, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:26:55] [Zone] [Crash] [Current thread is 1 (Thread 0x7f22b29eab00 (LWP 802540))]
[06-18-2023 16:26:55] [Zone] [Crash] #0  0x00007f22b2b14207 in __GI___wait4 (pid=819104, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:26:55] [Zone] [Crash] #1  0x000055e4451b6b6e in print_trace () at /home/eqemu/code/common/crash.cpp:281
[06-18-2023 16:26:55] [Zone] [Crash] #2  <signal handler called>
[06-18-2023 16:26:55] [Zone] [Crash] #3  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[06-18-2023 16:26:55] [Zone] [Crash] #4  0x00007f22b2a6e537 in __GI_abort () at abort.c:79
[06-18-2023 16:26:55] [Zone] [Crash] #5  0x00007f22b2e067ec in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #6  0x00007f22b2e11966 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #7  0x00007f22b2e119d1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #8  0x00007f22b2e11c65 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #9  0x00007f22b2e08faa in std::__throw_logic_error(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #10 0x000055e444216b48 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.tcc:212
[06-18-2023 16:26:55] [Zone] [Crash] #11 0x000055e44420dd09 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:247
[06-18-2023 16:26:55] [Zone] [Crash] #12 0x000055e444203977 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:266
[06-18-2023 16:26:55] [Zone] [Crash] #13 0x000055e4441f93ef in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> > (this=0x7fff9bd06620, __s=0x0, __a=...) at /usr/include/c++/10/bits/basic_string.h:527
[06-18-2023 16:26:55] [Zone] [Crash] #14 0x000055e4445469df in command_npcedit (c=0x55e448292480, sep=0x7fff9bd09a20) at /home/eqemu/code/zone/gm_commands/npcedit.cpp:540
[06-18-2023 16:26:55] [Zone] [Crash] #15 0x000055e4444e2039 in command_realdispatch (c=0x55e448292480, message="#npcedit weapon 1", ignore_status=false) at /home/eqemu/code/zone/command.cpp:602
[06-18-2023 16:26:55] [Zone] [Crash] #16 0x000055e4443b03d3 in Client::ChannelMessageReceived (this=0x55e448292480, chan_num=8 '\b', language=0 '\000', lang_skill=100 'd', orig_message=0x55e44a69e314 "#npcedit weapon 1", targetname=0x55e44a69e280 "a_willowisp000", is_silent=false) at /home/eqemu/code/zone/client.cpp:1122
[06-18-2023 16:26:55] [Zone] [Crash] #17 0x000055e444454597 in Client::Handle_OP_ChannelMessage (this=0x55e448292480, app=0x55e449156a70) at /home/eqemu/code/zone/client_packet.cpp:4478
[06-18-2023 16:26:55] [Zone] [Crash] #18 0x000055e44443c5d2 in Client::HandlePacket (this=0x55e448292480, app=0x55e449156a70) at /home/eqemu/code/zone/client_packet.cpp:495
[06-18-2023 16:26:55] [Zone] [Crash] #19 0x000055e4444b7add in Client::Process (this=0x55e448292480) at /home/eqemu/code/zone/client_process.cpp:587
[06-18-2023 16:26:55] [Zone] [Crash] #20 0x000055e44472df12 in EntityList::MobProcess (this=0x55e445df07c0 <entity_list>) at /home/eqemu/code/zone/entity.cpp:510
[06-18-2023 16:26:55] [Zone] [Crash] #21 0x000055e444c149b0 in operator() (__closure=0x55e448dc9170, t=0x7fff9bd0c4a0) at /home/eqemu/code/zone/main.cpp:562
[06-18-2023 16:26:55] [Zone] [Crash] #22 0x000055e444c19fd2 in std::__invoke_impl<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/10/bits/invoke.h:60
[06-18-2023 16:26:55] [Zone] [Crash] #23 0x000055e444c19da1 in std::__invoke_r<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(struct {...} &) (__fn=...) at /usr/include/c++/10/bits/invoke.h:110
[06-18-2023 16:26:55] [Zone] [Crash] #24 0x000055e444c19ac8 in std::_Function_handler<void(EQ::Timer*), main(int, char**)::<lambda(EQ::Timer*)> >::_M_invoke(const std::_Any_data &, EQ::Timer *&&) (__functor=..., __args#0=@0x7fff9bd0bea0: 0x7fff9bd0c4a0) at /usr/include/c++/10/bits/std_function.h:291
[06-18-2023 16:26:55] [Zone] [Crash] #25 0x000055e444c1f4c5 in std::function<void (EQ::Timer*)>::operator()(EQ::Timer*) const (this=0x7fff9bd0c4a8, __args#0=0x7fff9bd0c4a0) at /usr/include/c++/10/bits/std_function.h:622
[06-18-2023 16:26:55] [Zone] [Crash] #26 0x000055e444c1d265 in EQ::Timer::Execute (this=0x7fff9bd0c4a0) at /home/eqemu/code/zone/../common/net/../event/timer.h:61
[06-18-2023 16:26:55] [Zone] [Crash] #27 0x000055e444c1d023 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::operator()(uv_timer_s*) const (__closure=0x0, handle=0x55e44832b570) at /home/eqemu/code/zone/../common/net/../event/timer.h:38
[06-18-2023 16:26:55] [Zone] [Crash] #28 0x000055e444c1d043 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::_FUN(uv_timer_s*) () at /home/eqemu/code/zone/../common/net/../event/timer.h:39
[06-18-2023 16:26:55] [Zone] [Crash] #29 0x000055e4454afb5d in uv__run_timers (loop=loop@entry=0x7f22b29ea7a8) at /home/eqemu/code/submodules/libuv/src/timer.c:178
[06-18-2023 16:26:55] [Zone] [Crash] #30 0x000055e4454b3182 in uv_run (loop=0x7f22b29ea7a8, mode=UV_RUN_DEFAULT) at /home/eqemu/code/submodules/libuv/src/unix/core.c:393
[06-18-2023 16:26:55] [Zone] [Crash] #31 0x000055e444c1ceeb in EQ::EventLoop::Run (this=0x7f22b29ea7a8) at /home/eqemu/code/zone/../common/net/../event/event_loop.h:25
[06-18-2023 16:26:55] [Zone] [Crash] #32 0x000055e444c18b6e in main (argc=1, argv=0x7fff9bd0d568) at /home/eqemu/code/zone/main.cpp:591
[06-18-2023 16:26:55] [Zone] [Crash] [Inferior 1 (process 802540) detached]
```

```txt
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819434]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819436]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819438]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819440]
[06-18-2023 16:29:51] [Zone] [Crash] [Thread debugging using libthread_db enabled]
[06-18-2023 16:29:51] [Zone] [Crash] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[06-18-2023 16:29:51] [Zone] [Crash] 0x00007f489d185207 in __GI___wait4 (pid=819646, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:29:51] [Zone] [Crash] [Current thread is 1 (Thread 0x7f489d05bb00 (LWP 819417))]
[06-18-2023 16:29:51] [Zone] [Crash] #0  0x00007f489d185207 in __GI___wait4 (pid=819646, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:29:51] [Zone] [Crash] #1  0x000055d58e442b6e in print_trace () at /home/eqemu/code/common/crash.cpp:281
[06-18-2023 16:29:51] [Zone] [Crash] #2  <signal handler called>
[06-18-2023 16:29:51] [Zone] [Crash] #3  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[06-18-2023 16:29:51] [Zone] [Crash] #4  0x00007f489d0df537 in __GI_abort () at abort.c:79
[06-18-2023 16:29:51] [Zone] [Crash] #5  0x00007f489d4777ec in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #6  0x00007f489d482966 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #7  0x00007f489d4829d1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #8  0x00007f489d482c65 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #9  0x00007f489d479faa in std::__throw_logic_error(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #10 0x000055d58d4a2b48 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.tcc:212
[06-18-2023 16:29:51] [Zone] [Crash] #11 0x000055d58d499d09 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:247
[06-18-2023 16:29:51] [Zone] [Crash] #12 0x000055d58d48f977 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:266
[06-18-2023 16:29:51] [Zone] [Crash] #13 0x000055d58d4853ef in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> > (this=0x7ffdbbca2500, __s=0x0, __a=...) at /usr/include/c++/10/bits/basic_string.h:527
[06-18-2023 16:29:51] [Zone] [Crash] #14 0x000055d58d7d29df in command_npcedit (c=0x55d59219f080, sep=0x7ffdbbca5900) at /home/eqemu/code/zone/gm_commands/npcedit.cpp:540
[06-18-2023 16:29:51] [Zone] [Crash] #15 0x000055d58d76e039 in command_realdispatch (c=0x55d59219f080, message="#npcedit weapon 1", ignore_status=false) at /home/eqemu/code/zone/command.cpp:602
[06-18-2023 16:29:51] [Zone] [Crash] #16 0x000055d58d63c3d3 in Client::ChannelMessageReceived (this=0x55d59219f080, chan_num=8 '\b', language=0 '\000', lang_skill=100 'd', orig_message=0x55d591b59b44 "#npcedit weapon 1", targetname=0x55d591b59ab0 "a_whiskered_bat002", is_silent=false) at /home/eqemu/code/zone/client.cpp:1122
[06-18-2023 16:29:51] [Zone] [Crash] #17 0x000055d58d6e0597 in Client::Handle_OP_ChannelMessage (this=0x55d59219f080, app=0x55d592711c60) at /home/eqemu/code/zone/client_packet.cpp:4478
[06-18-2023 16:29:51] [Zone] [Crash] #18 0x000055d58d6c85d2 in Client::HandlePacket (this=0x55d59219f080, app=0x55d592711c60) at /home/eqemu/code/zone/client_packet.cpp:495
[06-18-2023 16:29:51] [Zone] [Crash] #19 0x000055d58d743add in Client::Process (this=0x55d59219f080) at /home/eqemu/code/zone/client_process.cpp:587
[06-18-2023 16:29:51] [Zone] [Crash] #20 0x000055d58d9b9f12 in EntityList::MobProcess (this=0x55d58f07c7c0 <entity_list>) at /home/eqemu/code/zone/entity.cpp:510
[06-18-2023 16:29:51] [Zone] [Crash] #21 0x000055d58dea09b0 in operator() (__closure=0x55d591a07f10, t=0x7ffdbbca8380) at /home/eqemu/code/zone/main.cpp:562
[06-18-2023 16:29:51] [Zone] [Crash] #22 0x000055d58dea5fd2 in std::__invoke_impl<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/10/bits/invoke.h:60
[06-18-2023 16:29:51] [Zone] [Crash] #23 0x000055d58dea5da1 in std::__invoke_r<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(struct {...} &) (__fn=...) at /usr/include/c++/10/bits/invoke.h:110
[06-18-2023 16:29:51] [Zone] [Crash] #24 0x000055d58dea5ac8 in std::_Function_handler<void(EQ::Timer*), main(int, char**)::<lambda(EQ::Timer*)> >::_M_invoke(const std::_Any_data &, EQ::Timer *&&) (__functor=..., __args#0=@0x7ffdbbca7d80: 0x7ffdbbca8380) at /usr/include/c++/10/bits/std_function.h:291
[06-18-2023 16:29:51] [Zone] [Crash] #25 0x000055d58deab4c5 in std::function<void (EQ::Timer*)>::operator()(EQ::Timer*) const (this=0x7ffdbbca8388, __args#0=0x7ffdbbca8380) at /usr/include/c++/10/bits/std_function.h:622
[06-18-2023 16:29:51] [Zone] [Crash] #26 0x000055d58dea9265 in EQ::Timer::Execute (this=0x7ffdbbca8380) at /home/eqemu/code/zone/../common/net/../event/timer.h:61
[06-18-2023 16:29:51] [Zone] [Crash] #27 0x000055d58dea9023 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::operator()(uv_timer_s*) const (__closure=0x0, handle=0x55d590f6a610) at /home/eqemu/code/zone/../common/net/../event/timer.h:38
[06-18-2023 16:29:51] [Zone] [Crash] #28 0x000055d58dea9043 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::_FUN(uv_timer_s*) () at /home/eqemu/code/zone/../common/net/../event/timer.h:39
[06-18-2023 16:29:51] [Zone] [Crash] #29 0x000055d58e73bb5d in uv__run_timers (loop=loop@entry=0x7f489d05b7a8) at /home/eqemu/code/submodules/libuv/src/timer.c:178
[06-18-2023 16:29:51] [Zone] [Crash] #30 0x000055d58e73f182 in uv_run (loop=0x7f489d05b7a8, mode=UV_RUN_DEFAULT) at /home/eqemu/code/submodules/libuv/src/unix/core.c:393
[06-18-2023 16:29:51] [Zone] [Crash] #31 0x000055d58dea8eeb in EQ::EventLoop::Run (this=0x7f489d05b7a8) at /home/eqemu/code/zone/../common/net/../event/event_loop.h:25
[06-18-2023 16:29:51] [Zone] [Crash] #32 0x000055d58dea4b6e in main (argc=1, argv=0x7ffdbbca9448) at /home/eqemu/code/zone/main.cpp:591
[06-18-2023 16:29:51] [Zone] [Crash] [Inferior 1 (process 819417) detached]
```
2023-06-19 01:32:36 -05:00
Alex King 71ca7f9b39 [Cleanup] Default skill type to Hand to Hand in #npcedit meleetype (#3422)
# Notes
- We default to `28` in the database, so we need to default to this in `#npcedit meleetype` in case the operator only sets the first melee type this avoids the NPC hitting with `1H Blunt (Skill ID 0)`.
2023-06-19 01:32:13 -05:00
Chris Miles 5fcc83b4b6 [Database] Implement native database migrations in server (#2857)
* [Database] Implement native database updates in server

* Cleanup

* Delete db_update_manifest.txt

* Bots updates

* Final tweaks

* Revert manifest

* Tweaks

* Remove code from eqemu_server.pl

* Update database_update.cpp

* Add user prompt update skipping with timeouts

* Add termcolor IS_TTY is check

* Update database_conversions.cpp

* Remove large migrations

* Push

* fix headers.

* Remove last of non-bot large migrations

* Update database_update_manifest.cpp

* More purging

* Tweaks

* Bot migrations

* More work

* Tweaks

* Implement multi-statement query execution only for migrations

* Add CLI database:updates

* Add bootstrap commands

* Upload bootstrap sql's

* Update bot_tables_bootstrap.sql

* Update bot_tables_bootstrap.sql

* Add mercs:bootstrap and bots:bootstrap

* Update bot_tables_bootstrap.sql

* Update database.cpp

* Update bot_tables_bootstrap.sql

* More cleanup

* Add mercs:disable and bots:disable

* Update eqemu_server.pl

* Update eqemu_server.pl

* Update eqemu_server.pl

* Test cases

* Update eqemu_server.pl

* Delete 2023_05_08_character_tribute_primary_key.sql

* Post rebase fixes

* Post rebase tweaks

* Delete errant files

* Rebase files from master

* More adjustments

* Delete files no longer used

* Add missing migrations

* bots:bootstrap is now bots:enable

---------

Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com>
2023-06-19 01:31:07 -05:00
Chris Miles 1f25639dd3 [Release] 22.14.1 (#3420) 2023-06-18 15:38:50 -05:00
Chris Miles 2a176835b1 [CI] Build static linux binaries (#3419)
* [CI] Build static linux binaries

* Fix tests

* Update linux-build.sh
2023-06-18 15:19:25 -05:00
Chris Miles fff3e77a6e [Binaries] Add support for static linking (portable) binaries (#3417)
* [Binaries] Add support for static linking (portable) binaries

* Update CMakeLists.txt
2023-06-18 14:41:39 -05:00
Alex King 6efb9ec228 [Quest API] Add convert_money_to_string() to Perl/Lua (#3418)
* [Quest API] Add convert_money_to_string() to Perl/Lua

# Perl
- Add `quest::convert_money_to_string(money_hash)`.

# Lua
- Add `eq.convert_money_to_string(money_table)`.

# Notes
- Allows operators to convert money in to a readable string using `Strings::Money`.

# Examples

## Perl
```pl
sub EVENT_SAY {
	if ($text=~/#a/i) {
		my %money_data = (
			"platinum" => 3123,
			"gold" => 5692,
			"copper" => 9
		);
		quest::message(315, quest::convert_money_to_string(%money_data));
	}
}
```

## Lua
```lua
function event_say(e)
	if e.message:find("#a") then
		local money_data = {
			gold = 12,
			silver = 523904,
			copper = 3
		}
		eq.message(315, "Lua: " .. eq.convert_money_to_string(money_data))
	end
end```

* Update lua_general.cpp
2023-06-18 15:29:14 -04:00
Chris Miles a663c822e8 [CLI] Add mercs:enable and mercs:disable commands (#3416)
* [CLI] Add `mercs:enable` and `mercs:disable` commands

* Update descriptions
2023-06-17 19:30:36 -05:00
Chris Miles cf49b2fe49 [CLI] Add bots:enable and bots:disable commands (#3415)
* [CLI] Add `bots:enable` and `bots:disable` commands

* Add input warning
2023-06-17 18:48:47 -05:00
Chris Miles b45e0e80b5 [Database] Add query multi statement execution support (#3414) 2023-06-17 18:20:13 -05:00
Chris Miles 3200145d01 [CLI] Console menu validation fixes (#3413) 2023-06-17 18:19:55 -05:00
Chris Miles 53563b9720 [Backups] Move world database:dump to use MySQL credentials file (#3410) 2023-06-17 18:16:29 -05:00
Chris Miles 1e22baf267 [Logging] Logging improvements, console silencing, terminal coloring (#3412) 2023-06-17 18:16:21 -05:00
Chris Miles d99c3145ad [Strings] Add more test cases for string utils (#3411) 2023-06-17 18:16:14 -05:00
Alex King 57243c6799 [Telnet] Add cross zone/world wide cast and move functionality to Telnet (#3409)
* [Telnet] Add cross zone/world wide cast and move functionality to Telnet

# Notes
- Add `czcast`, `czmove`, `wwcast`, and `wwmove` to Telnet functionality.
- Allows operators to cast spells across zone/world-wide and move players across zone/world-wide from telnet.

* Update console.cpp

* Update console.cpp

* Validation

* Update console.cpp
2023-06-17 17:50:37 -05:00
Paul Coene 1100668f21 [Targeting] Fix bug when using /tar on invalid target (#3407)
* [Targetting] Fix bug when using /tar on invalid target

* Removed instrumentation.
2023-06-17 16:53:59 -05:00
nytmyr 0cf454dc29 [Feature] Add Water Line of Sight Checks (#3408)
* [Feature] Add Water Line of Sight Checks

This adds rules to enable or disable checks for spells and autofire to prevent casting or autofire from landing if the player or bot do not match their targets plane in regards to water.

Currently players and bots can cast or autofire if they are not in the water but their target is and vice versa, this should not be possible.

RuleB(Combat, WaterMatchRequiredForAutoFireLoS) set to True (default) checks that both parties are in or out of the water for AutoFire to work.

RuleB(Spells, WaterMatchRequiredForLoS) set to True (default) checks that both parties are in or out of the water for spells to land.

* Cleanup.

* Cleanup.

* Cleanup.

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-06-17 12:32:15 -05:00
Paul Coene 75391d96f4 [Release] 22.13.1 (#3406)
* Update version.h for /target Emergency release 22.13.1

* Update CHANGELOG.md for 22.13.1 release

* Update package.json for 22.13.1 emergency patch release

* Update CHANGELOG.md using tool as instructed
2023-06-13 17:50:33 -04:00
Paul Coene 81b07a5aa0 [Targeting] Revert #3383 (#3405) 2023-06-13 15:48:35 -05:00
Alex King 774aa99b29 [Release] 22.13.0 (#3404)
* [Release] 22.13.0

* Update CHANGELOG.md
2023-06-12 20:56:43 -04:00
Alex King 756e835144 [Quest API/Cleanup] Add several spell methods to Perl/Lua (#3379)
* [Quest API/Cleanup] Add several spell methods to Perl/Lua

- Add `quest::CalculateCorruptionCounters(spell_id)`.
- Add `quest::CalculateCounters(spell_id)`.
- Add `quest::CalculateCurseCounters(spell_id)`.
- Add `quest::CalculateDiseaseCounters(spell_id)`.
- Add `quest::CalculatePoisonCounters(spell_id)`.
- Add `quest::GetSpellEffectDescriptionNumber(spell_id)`.
- Add `quest::GetSpellEffectIndex(spell_id, effect_id)`.
- Add `quest::GetSpellFuriousBash(spell_id)`.
- Add `quest::GetSpellMinimumLevel(spell_id)`.
- Add `quest::GetSpellNimbusEffect(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneReduction(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneReduction(spell_id)`.
- Add `quest::GetSpellProcLimitTimer(spell_id)`.
- Add `quest::GetSpellResistType(spell_id)`.
- Add `quest::GetSpellResurrectionSicknessCheck(spell_id_one, spell_id_two)`.
- Add `quest::GetSpellTargetType(spell_id)`.
- Add `quest::GetSpellTriggerSpellID(spell_id)`.
- Add `quest::GetSpellViralMaximumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralMinimumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralSpreadRange(spell_id)`.
- Add `quest::IsAEDurationSpell(spell_id)`.
- Add `quest::IsAENukeSpell(spell_id)`.
- Add `quest::IsAERainNukeSpell(spell_id)`.
- Add `quest::IsAllianceSpell(spell_id)`.
- Add `quest::IsBardOnlyStackEffect(effect_id)`.
- Add `quest::IsBardSong(spell_id)`.
- Add `quest::IsBlankSpellEffect(spell_id, effect_index)`.
- Add `quest::IsBlindSpell(spell_id)`.
- Add `quest::IsBuffSpell(spell_id)`.
- Add `quest::IsCastNotStandingSpell(spell_id)`.
- Add `quest::IsCastOnFadeDurationSpell(spell_id)`.
- Add `quest::IsCastRestrictedSpell(spell_id)`.
- Add `quest::IsCastTimeReductionSpell(spell_id)`.
- Add `quest::IsCastWhileInvisibleSpell(spell_id)`.
- Add `quest::IsCharmSpell(spell_id)`.
- Add `quest::IsCombatSkill(spell_id)`.
- Add `quest::IsCompleteHealDurationSpell(spell_id)`.
- Add `quest::IsCompleteHealSpell(spell_id)`.
- Add `quest::IsCureSpell(spell_id)`.
- Add `quest::IsDamageSpell(spell_id)`.
- Add `quest::IsDeathSaveSpell(spell_id)`.
- Add `quest::IsDebuffSpell(spell_id)`.
- Add `quest::IsDetrimentalSpell(spell_id)`.
- Add `quest::IsDiscipline(spell_id)`.
- Add `quest::IsDisciplineBuff(spell_id)`.
- Add `quest::IsDiseaseCounterSpell(spell_id)`.
- Add `quest::IsDistanceModifierSpell(spell_id)`.
- Add `quest::IsEffectIgnoredInStacking(effect_id)`.
- Add `quest::IsFastHealSpell(spell_id)`.
- Add `quest::IsFearSpell(spell_id)`.
- Add `quest::IsFocusLimit(effect_id)`.
- Add `quest::IsFullDeathSaveSpell(spell_id)`.
- Add `quest::IsGateSpell(spell_id)`.
- Add `quest::IsImprovedDamageSpell(spell_id)`.
- Add `quest::IsImprovedHealingSpell(spell_id)`.
- Add `quest::IsIncreaseDurationSpell(spell_id)`.
- Add `quest::IsIncreaseRangeSpell(spell_id)`.
- Add `quest::IsInstrumentModifierAppliedToSpellEffect(spell_id, effect_id)`.
- Add `quest::IsInvisibleSpell(spell_id)`.
- Add `quest::IsInvulnerabilitySpell(spell_id)`.
- Add `quest::IsLDoNObjectSpell(spell_id)`.
- Add `quest::IsLifetapSpell(spell_id)`.
- Add `quest::IsMagicRuneSpell(spell_id)`.
- Add `quest::IsManaCostReductionSpell(spell_id)`.
- Add `quest::IsManaTapSpell(spell_id)`.
- Add `quest::IsMesmerizeSpell(spell_id)`.
- Add `quest::IsNoDetrimentalSpellAggroSpell(spell_id)`.
- Add `quest::IsPBAENukeSpell(spell_id)`.
- Add `quest::IsPartialDeathSaveSpell(spell_id)`.
- Add `quest::IsPartialResistableSpell(spell_id)`.
- Add `quest::IsPercentalHealSpell(spell_id)`.
- Add `quest::IsPersistDeathSpell(spell_id)`.
- Add `quest::IsPetSpell(spell_id)`.
- Add `quest::IsPoisonCounterSpell(spell_id)`.
- Add `quest::IsPulsingBardSong(spell_id)`.
- Add `quest::IsPureNukeSpell(spell_id)`.
- Add `quest::IsRegularGroupHealSpell(spell_id)`.
- Add `quest::IsRegularSingleTargetHealSpell(spell_id)`.
- Add `quest::IsResistDebuffSpell(spell_id)`.
- Add `quest::IsResistableSpell(spell_id)`.
- Add `quest::IsRestAllowedSpell(spell_id)`.
- Add `quest::IsResurrectionEffects(spell_id)`.
- Add `quest::IsRuneSpell(spell_id)`.
- Add `quest::IsRunning(spell_id)`.
- Add `quest::IsSacrificeSpell(spell_id)`.
- Add `quest::IsSelfConversionSpell(spell_id)`.
- Add `quest::IsShadowStepSpell(spell_id)`.
- Add `quest::IsShortDurationBuff(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id, zone_type)`.
- Add `quest::IsStackableDOT(spell_id)`.
- Add `quest::IsStunSpell(spell_id)`.
- Add `quest::IsSuccorSpell(spell_id)`.
- Add `quest::IsSummonItemSpell(spell_id)`.
- Add `quest::IsSummonPCSpell(spell_id)`.
- Add `quest::IsSummonPetSpell(spell_id)`.
- Add `quest::IsSummonSkeletonSpell(spell_id)`.
- Add `quest::IsSummonSpell(spell_id)`.
- Add `quest::IsSuspendableSpell(spell_id)`.
- Add `quest::IsTargetRequiredForSpell(spell_id)`.
- Add `quest::IsTargetableAESpell(spell_id)`.
- Add `quest::IsTeleportSpell(spell_id)`.
- Add `quest::IsTranslocateSpell(spell_id)`.
- Add `quest::IsValidSpell(spell_id)`.
- Add `quest::IsVeryFastHealSpell(spell_id)`.
- Add `quest::IsVirusSpell(spell_id)`.

- Add `eq.calculate_corruption_counters(spell_id)`.
- Add `eq.calculate_counters(spell_id)`.
- Add `eq.calculate_curse_counters(spell_id)`.
- Add `eq.calculate_disease_counters(spell_id)`.
- Add `eq.calculate_poison_counters(spell_id)`.
- Add `eq.get_spell_effect_description_number(spell_id)`.
- Add `eq.get_spell_effect_index(spell_id, effect_id)`.
- Add `eq.get_spell_furious_bash(spell_id)`.
- Add `eq.get_spell_level(spell_id, class_id)`.
- Add `eq.get_spell_minimum_level(spell_id)`.
- Add `eq.get_spell_nimbus_effect(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_reduction(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_reduction(spell_id)`.
- Add `eq.get_spell_proc_limit_timer(spell_id)`.
- Add `eq.get_spell_resist_type(spell_id)`.
- Add `eq.get_spell_resurrection_sickness_check(spell_id_one, spell_id_two)`.
- Add `eq.get_spell_target_type(spell_id)`.
- Add `eq.get_spell_trigger_spell_id(spell_id)`.
- Add `eq.get_spell_viral_maximum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_minimum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_spread_range(spell_id)`.
- Add `eq.is_ae_duration_spell(spell_id)`.
- Add `eq.is_ae_nuke_spell(spell_id)`.
- Add `eq.is_ae_rain_nuke_spell(spell_id)`.
- Add `eq.is_alliance_spell(spell_id)`.
- Add `eq.is_bard_only_stack_effect(spell_id)`.
- Add `eq.is_bard_song(spell_id)`.
- Add `eq.is_beneficial_spell(spell_id)`.
- Add `eq.is_blank_spell_effect(spell_id)`.
- Add `eq.is_blind_spell(spell_id)`.
- Add `eq.is_buff_spell(spell_id)`.
- Add `eq.is_cast_not_standing_spell(spell_id)`.
- Add `eq.is_cast_on_fade_duration_spell(spell_id)`.
- Add `eq.is_cast_restricted_spell(spell_id)`.
- Add `eq.is_cast_time_reduction_spell(spell_id)`.
- Add `eq.is_cast_while_invisible_spell(spell_id)`.
- Add `eq.is_charm_spell(spell_id)`.
- Add `eq.is_combat_skill(spell_id)`.
- Add `eq.is_complete_heal_duration_spell(spell_id)`.
- Add `eq.is_complete_heal_spell(spell_id)`.
- Add `eq.is_cure_spell(spell_id)`.
- Add `eq.is_damage_spell(spell_id)`.
- Add `eq.is_death_save_spell(spell_id)`.
- Add `eq.is_debuff_spell(spell_id)`.
- Add `eq.is_detrimental_spell(spell_id)`.
- Add `eq.is_discipline(spell_id)`.
- Add `eq.is_discipline_buff(spell_id)`.
- Add `eq.is_disease_counter_spell(spell_id)`.
- Add `eq.is_distance_modifier_spell(spell_id)`.
- Add `eq.is_effect_ignored_in_stacking(effect_id)`.
- Add `eq.is_effect_in_spell(spell_id, effect_id)`.
- Add `eq.is_fast_heal_spell(spell_id)`.
- Add `eq.is_fear_spell(spell_id)`.
- Add `eq.is_focus_limit(effect_id)`.
- Add `eq.is_full_death_save_spell(spell_id)`.
- Add `eq.is_gate_spell(spell_id)`.
- Add `eq.is_group_complete_heal_spell(spell_id)`.
- Add `eq.is_group_heal_over_time_spell(spell_id)`.
- Add `eq.is_group_only_spell(spell_id)`.
- Add `eq.is_group_spell(spell_id)`.
- Add `eq.is_harmony_spell(spell_id)`.
- Add `eq.is_haste_spell(spell_id)`.
- Add `eq.is_heal_over_time_spell(spell_id)`.
- Add `eq.is_health_spell(spell_id)`.
- Add `eq.is_illusion_spell(spell_id)`.
- Add `eq.is_improved_damage_spell(spell_id)`.
- Add `eq.is_improved_healing_spell(spell_id)`.
- Add `eq.is_increase_duration_spell(spell_id)`.
- Add `eq.is_increase_range_spell(spell_id)`.
- Add `eq.is_instrument_modifier_applied_to_spell_effect(spell_id, effect_id)`.
- Add `eq.is_invisible_spell(spell_id)`.
- Add `eq.is_invulnerability_spell(spell_id)`.
- Add `eq.is_ldon_object_spell(spell_id)`.
- Add `eq.is_lifetap_spell(spell_id)`.
- Add `eq.is_magic_rune_spell(spell_id)`.
- Add `eq.is_mana_cost_reduction_spell(spell_id)`.
- Add `eq.is_mana_tap_spell(spell_id)`.
- Add `eq.is_mesmerize_spell(spell_id)`.
- Add `eq.is_no_detrimental_spell_aggro_spell(spell_id)`.
- Add `eq.is_partial_death_save_spell(spell_id)`.
- Add `eq.is_partial_resistable_spell(spell_id)`.
- Add `eq.is_pbae_nuke_spell(spell_id)`.
- Add `eq.is_percental_heal_spell(spell_id)`.
- Add `eq.is_persist_death_spell(spell_id)`.
- Add `eq.is_pet_spell(spell_id)`.
- Add `eq.is_poison_counter_spell(spell_id)`.
- Add `eq.is_pulsing_bard_song(spell_id)`.
- Add `eq.is_pure_nuke_spell(spell_id)`.
- Add `eq.is_regular_group_heal_spell(spell_id)`.
- Add `eq.is_regular_single_target_heal_spell(spell_id)`.
- Add `eq.is_resist_debuff_spell(spell_id)`.
- Add `eq.is_resistable_spell(spell_id)`.
- Add `eq.is_rest_allowed_spell(spell_id)`.
- Add `eq.is_resurrection_effects(spell_id)`.
- Add `eq.is_rune_spell(spell_id)`.
- Add `eq.is_sacrifice_spell(spell_id)`.
- Add `eq.is_self_conversion_spell(spell_id)`.
- Add `eq.is_shadow_step_spell(spell_id)`.
- Add `eq.is_short_duration_buff(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id, zone_type)`.
- Add `eq.is_stackable_dot(spell_id)`.
- Add `eq.is_stun_spell(spell_id)`.
- Add `eq.is_succor_spell(spell_id)`.
- Add `eq.is_summon_item_spell(spell_id)`.
- Add `eq.is_summon_pc_spell(spell_id)`.
- Add `eq.is_summon_pet_spell(spell_id)`.
- Add `eq.is_summon_skeleton_spell(spell_id)`.
- Add `eq.is_summon_spell(spell_id)`.
- Add `eq.is_suspendable_spell(spell_id)`.
- Add `eq.is_target_required_for_spell(spell_id)`.
- Add `eq.is_targetable_ae_spell(spell_id)`.
- Add `eq.is_teleport_spell(spell_id)`.
- Add `eq.is_tgb_compatible_spell(spell_id)`.
- Add `eq.is_translocate_spell(spell_id)`.
- Add `eq.is_valid_spell(spell_id)`.
- Add `eq.is_very_fast_heal_spell(spell_id)`.
- Add `eq.is_virus_spell(spell_id)`.

- A lot of cleanup in the logic and naming of these methods was done.
- Missing GM restricted spells like Guide spells and GM Health buffs were added as defines.
- Good effect values were added as defines.
- Resurrection effects non-stacking value was added as a define.
- Max fast heal casting time and max very fast heal casting time were added as defines.
- `SE_Display` was uncommented so we could use it instead of the magic number `425`.
- `IsEvacSpell(spell_id)` was removed as it was unnecessary since `IsSuccorSpell(spell_id)` checks for `SE_Succor` as well.
- `GetMorphTrigger(spell_id)` was removed as it was unused.
- `GroupOnlySpell(spell_id)` was removed as it was unnecessary since `IsGroupOnlySpell(spell_id)` exists.
- `CanUseSpell(spell_id)` was removed as it was unnecessary since `GetSpellLevel(spell_id, class_id)` exists.
- `BeneficialSpell(spell_id)` was removed as it was unnecessary since `IsBeneficialSpell(spell_id)` exists.

* Update spell_effects.cpp

* Update spdat.cpp
2023-06-12 20:27:22 -04:00
Alex King c5c575b028 [Quest API] Add GetEXPForLevel() to Perl/Lua (#3403)
# Perl
- Add `$client->GetEXPForLevel(check_level)`.

# Lua
- Add `client:GetEXPForLevel(check_level)`.

# Notes
- This allows operators to see the required experience for a level based on the client provided, this takes race/class modifiers into account as well if enabled.
2023-06-12 19:18:39 -05:00
Alex King 152e99444c [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h (#3392)
* [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.cpp
2023-06-12 19:18:17 -05:00
Alex King 795df5c597 [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h (#3390)
* [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.h
2023-06-12 19:17:53 -05:00
Alex King 18eff726d0 [Commands] Assign #opcode to a #reload alias (#3401)
* [Commands] Assign #opcode to a #reload alias

# Notes
- Can use `#reload opcodes

* Add ServerOP_ReloadOpcodes
2023-06-12 18:42:39 -04:00
Alex King f06a37a009 [Cleanup] Add GMFind_Struct to packet structures (#3402)
* [Cleanup] Add GMFind_Struct to packet structures

# Notes
- X and Y were swapped in GMSummon_Struct so it displayed XYZ incorrectly in /find, adding its own struct fixes this.

* Update eq_packet_structs.h

* Update eq_packet_structs.h
2023-06-12 18:35:04 -04:00
Paul Coene ae53efc52c [Targeting] /tar <bad target> should not untarget existing target (#3383)
* [Targeting] /tar <bad target> should not untarget existing target

* Forgot string Id file.

* removed unneeded this->
2023-06-12 16:40:09 -05:00
Alex King 548eb65e1d [Cleanup] Remove InteractiveChat() and TakenAction() from zone/npc.h (#3382)
# Notes
- These are unimplemented and unused.
2023-06-12 15:14:34 -05:00
Alex King fede8760d4 [Cleanup] Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h (#3384)
# Notes
- This is unused.
2023-06-12 15:13:03 -05:00
Alex King 6faa202b57 [Cleanup] Remove pDBAsyncWorkID from zone/entity.h (#3385)
# Notes
- This is unused.
2023-06-12 15:12:47 -05:00
Alex King c406710623 [Cleanup] Remove GetClient(ip, port) from zone/entity.h (#3386)
# Notes
- This is unused.
2023-06-12 15:12:22 -05:00
Alex King 662c4012db [Cleanup] Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h (#3387)
# Notes
- These are unused.
2023-06-12 15:12:00 -05:00
Alex King 849e7b910d [Cleanup] Remove SendAATimer() from zone/entity.h (#3388)
# Notes
- This is unused.
2023-06-12 15:11:32 -05:00
Alex King 8e33755f02 [Cleanup] Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h (#3389)
# Notes
- These are unused.
2023-06-12 15:11:17 -05:00
Alex King dfaa929778 [Cleanup] Remove GateAllClients() from zone/entity.cpp and zone/entity.h (#3391)
# Notes
- This is unused.
2023-06-12 15:10:36 -05:00
Alex King 306b06745f [Cleanup] Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h (#3393)
# Notes
- This is unused.
2023-06-12 15:05:39 -05:00
Alex King 108fc82ee0 [Cleanup] Remove Evade() from zone/entity.cpp and zone/entity.h (#3394)
# Notes
- This is unused.
2023-06-12 15:05:23 -05:00
Alex King 577f61b082 [Cleanup] Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h (#3395)
# Notes
- This is unused.
2023-06-12 15:05:09 -05:00
Alex King a01cf0718d [Cleanup] Remove struct DynamicZoneSafeReturn from zone/entity.h (#3396)
# Notes
- This is unused.
2023-06-12 15:04:54 -05:00
Alex King 90412ba61b [Cleanup] Remove struct TradeEntity from zone/common.h (#3397)
# Notes
- This is unused.
2023-06-12 15:04:38 -05:00
Alex King 5cbc380c62 [Cleanup] Remove CHECK_LOS_STEP from zone/common.h (#3398)
# Notes
- This is unused.
2023-06-12 15:04:25 -05:00
Alex King 6c289a7c71 [Cleanup] Remove _BECOMENPCPET() and _NPCPET() from zone/common.h (#3399)
# Notes
- These are unused.
2023-06-12 15:04:09 -05:00
Alex King 57335b188f [Cleanup] Remove SPECIALIZE_MANA_REDUCE from zone/common.h (#3400)
# Notes
- This is unused.
2023-06-12 15:03:55 -05:00
Alex King 056e429100 [Cleanup] Remove NPC::AddCash() from npc.cpp/npc.h (#3380)
# Notes
- This is unused.
2023-06-09 11:50:52 -04:00
Paul Coene f548aeddb2 [Logging] Fixed statements that logged incorrect data (#3381) 2023-06-07 08:26:04 -04:00
Paul Coene 4ff9faa4e6 [Illusions] RandomizeFeatures and SetGender were killing db texture (#3376)
* [Illusions] RandomizeFeatures and SetGender were killing db texture

* Found actual source of the problem.
2023-06-06 08:30:41 -04:00
Alex King 17fc350d46 [Quest API] Add SendChannelMessage() to Perl/Lua (#3378)
* [Quest API] Add SendChannelMessage() to Perl/Lua

# Perl
- Add `quest::send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Lua
- Add `eq.send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Notes
- This allows operators to send channel messages from scripts like a broadcast or tell.

* Update zoneserver.cpp

* Update lua_general.cpp

* Update questmgr.h
2023-06-03 19:06:40 -05:00
Chris Miles b18bc66b42 [Release] 22.12.0 (#3377) 2023-05-30 00:10:44 -05:00
Alex King 324bfd448e [Commands] Add entity variable command (#3345)
* [Commands] Add entity variable commands

# Commands
- Add `#clearentityvariables` to clear all entity variables from yourself or your target.
- Add `#deleteentityvariable [Variable Name]` to delete an entity variable from yourself or your target.
- Add `#setentityvariable [Variable Name] [Variable Value]` to set an entity variable for yourself or your target.
- Add `#viewentityvariables [Search Criteria]` to view your or your target's entity variables.

# Notes
- `#setentityvariable` can use multi-word names/values by using double quotes like `#setentityvariable "Test Variable" "Test Value"`.
- `#viewentityvariable` does not require a search criteria, not using one shows all entity variables on yourself or your target.

* Update viewentityvariables.cpp

* Unnecessary parameter.

* Consolidate commands.

* Update entityvariable.cpp

* Update command.cpp

* Proper arguments.
2023-05-25 19:49:09 -04:00
Alex King 75560ee830 [Performance] Character tribute is now bulk saved (#3340)
* [Performance] Character tribute is now bulk saved

This pull request combines individual `character_tribute` queries during `Save()` into one.

This pull request also adds a primary key of `id` to `character_tribute` and renames the pre-existing `id` column to `character_id`, this allows us to use repositories for this table.

* Update zonedb.cpp

* Update zonedb.cpp
2023-05-25 19:21:18 -04:00
Alex King 50db7637aa [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua (#3363)
* [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua

# Perl
- Add `EVENT_MEMORIZE_SPELL`.
- Add `EVENT_UNMEMORIZE_SPELL`.
- Add `EVENT_SCRIBE_SPELL`.
- Add `EVENT_UNSCRIBE_SPELL`.

# Lua
- Add `event_memorize_spell`.
- Add `event_unmemorize_spell`.
- Add `event_scribe_spell`.
- Add `event_unscribe_spell`.

# Notes
- Allows operators to perform events on memorization, unmemorization, scribe, or unscribe.
- Cleaned up target description messages for `#unscribespell`.

* Update client.cpp
2023-05-25 18:18:14 -05:00
Alex King 67fdc75df3 [Commands] Cleanup #setanim (#3350)
# Notes
- Make use of constants instead of hard-coded strings.
2023-05-25 18:04:09 -05:00
Chris Miles 9993022418 [Pets] Fix saving inconsistencies with pets (#3375) 2023-05-25 11:33:34 -04:00
Alex King bd95ed44fd [Cleanup] Remove GetMaxRank() from aa_ability.cpp/aa_ability.h (#3347)
# Notes
- This is unused.
2023-05-24 22:44:53 -05:00
Alex King 65fd323eab [Cleanup] Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h (#3344)
# Notes
- These are unused.
2023-05-24 22:42:20 -05:00
Aeadoin 290c58741e [Bug Fix] Fix issue with Group Pointers/Member roles (#3374)
* [Bug Fix] Fix issue with Group Corruption

* cleanup

* Fix for Group Roles

* Fix for Group Roles
2023-05-24 22:40:59 -05:00
Alex King 39d0772a01 [Cleanup] Remove IsRaid() from raids.h (#3361)
# Notes
- This is unused.
2023-05-24 22:40:32 -05:00
Alex King 622fe50479 [Cleanup] Remove numMembers from raids.h (#3362)
# Notes
- This is unused.
2023-05-24 22:40:20 -05:00
Alex King f41a219309 [Cleanup] Remove CalcPetHp from spdat.h (#3364)
# Notes
- This is unused.
2023-05-24 22:37:04 -05:00
Alex King 23bc3c7fd6 [Cleanup] Remove Z_AGGRO from spdat.h (#3365)
# Notes
- This is unused.
2023-05-24 22:36:52 -05:00
Alex King 3144ac1a28 [Cleanup] Cleanup #setskill and #setskillall Commands (#3367)
# Notes
- No need to cap at 400 for max skill.
- When setting skill/skills, if we go over cap, set to cap.
2023-05-24 22:36:38 -05:00
Alex King a5106420e8 [Commands] Add #findcurrency Command (#3368)
* [Commands] Add #findcurrency Command

# Notes
- Allows you to find alternate currencies by item ID or name.
- Has a saylink for summoning a stack of the currency if the GM can use the `#summonitem` command.

* Update findcurrency.cpp

* Update findcurrency.cpp
2023-05-24 22:30:06 -05:00
Alex King 5a42c4f667 [Quest API] Add zone data methods to Perl/Lua (#3342)
# Perl
- Add `quest::GetZoneSafeX(zone_id)`.
- Add `quest::GetZoneSafeX(zone_id, version)`.
- Add `quest::GetZoneSafeY(zone_id)`.
- Add `quest::GetZoneSafeY(zone_id, version)`.
- Add `quest::GetZoneSafeZ(zone_id)`.
- Add `quest::GetZoneSafeZ(zone_id, version)`.
- Add `quest::GetZoneSafeHeading(zone_id)`.
- Add `quest::GetZoneSafeHeading(zone_id, version)`.
- Add `quest::GetZoneMinimumLevel(zone_id)`.
- Add `quest::GetZoneMinimumLevel(zone_id, version)`.
- Add `quest::GetZoneMaximumLevel(zone_id)`.
- Add `quest::GetZoneMaximumLevel(zone_id, version)`.
- Add `quest::GetZoneMinimumStatus(zone_id)`.
- Add `quest::GetZoneMinimumStatus(zone_id, version)`.
- Add `quest::GetZoneTimeZone(zone_id)`.
- Add `quest::GetZoneTimeZone(zone_id, version)`.
- Add `quest::GetZoneMaximumPlayers(zone_id)`.
- Add `quest::GetZoneMaximumPlayers(zone_id, version)`.
- Add `quest::GetZoneRuleSet(zone_id)`.
- Add `quest::GetZoneRuleSet(zone_id, version)`.
- Add `quest::GetZoneNote(zone_id)`.
- Add `quest::GetZoneNote(zone_id, version)`.
- Add `quest::GetZoneUnderworld(zone_id)`.
- Add `quest::GetZoneUnderworld(zone_id, version)`.
- Add `quest::GetZoneMinimumClip(zone_id)`.
- Add `quest::GetZoneMinimumClip(zone_id, version)`.
- Add `quest::GetZoneMaximumClip(zone_id)`.
- Add `quest::GetZoneMaximumClip(zone_id, version)`.
- Add `quest::GetZoneFogMinimumClip(zone_id)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogMaximumClip(zone_id)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogRed(zone_id)`.
- Add `quest::GetZoneFogRed(zone_id, slot)`.
- Add `quest::GetZoneFogRed(zone_id, slot, version)`.
- Add `quest::GetZoneFogGreen(zone_id)`.
- Add `quest::GetZoneFogGreen(zone_id, slot)`.
- Add `quest::GetZoneFogGreen(zone_id, slot, version)`.
- Add `quest::GetZoneFogBlue(zone_id)`.
- Add `quest::GetZoneFogBlue(zone_id, slot)`.
- Add `quest::GetZoneFogBlue(zone_id, slot, version)`.
- Add `quest::GetZoneSky(zone_id)`.
- Add `quest::GetZoneSky(zone_id, version)`.
- Add `quest::GetZoneZType(zone_id)`.
- Add `quest::GetZoneZType(zone_id, version)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id, version)`.
- Add `quest::GetZoneWalkSpeed(zone_id)`.
- Add `quest::GetZoneWalkSpeed(zone_id, version)`.
- Add `quest::GetZoneTimeType(zone_id)`.
- Add `quest::GetZoneTimeType(zone_id, version)`.
- Add `quest::GetZoneFogDensity(zone_id)`.
- Add `quest::GetZoneFogDensity(zone_id, version)`.
- Add `quest::GetZoneFlagNeeded(zone_id)`.
- Add `quest::GetZoneFlagNeeded(zone_id, version)`.
- Add `quest::GetZoneCanBind(zone_id)`.
- Add `quest::GetZoneCanBind(zone_id, version)`.
- Add `quest::GetZoneCanCombat(zone_id)`.
- Add `quest::GetZoneCanCombat(zone_id, version)`.
- Add `quest::GetZoneCanLevitate(zone_id)`.
- Add `quest::GetZoneCanLevitate(zone_id, version)`.
- Add `quest::GetZoneCastOutdoor(zone_id)`.
- Add `quest::GetZoneCastOutdoor(zone_id, version)`.
- Add `quest::GetZoneHotzone(zone_id)`.
- Add `quest::GetZoneHotzone(zone_id, version)`.
- Add `quest::GetZoneInstanceType(zone_id)`.
- Add `quest::GetZoneInstanceType(zone_id, version)`.
- Add `quest::GetZoneShutdownDelay(zone_id)`.
- Add `quest::GetZoneShutdownDelay(zone_id, version)`.
- Add `quest::GetZonePEQZone(zone_id)`.
- Add `quest::GetZonePEQZone(zone_id, version)`.
- Add `quest::GetZoneExpansion(zone_id)`.
- Add `quest::GetZoneExpansion(zone_id, version)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id, version)`.
- Add `quest::GetZoneSuspendBuffs(zone_id)`.
- Add `quest::GetZoneSuspendBuffs(zone_id, version)`.
- Add `quest::GetZoneRainChance(zone_id)`.
- Add `quest::GetZoneRainChance(zone_id, slot)`.
- Add `quest::GetZoneRainChance(zone_id, slot, version)`.
- Add `quest::GetZoneRainDuration(zone_id)`.
- Add `quest::GetZoneRainDuration(zone_id, slot)`.
- Add `quest::GetZoneRainDuration(zone_id, slot, version)`.
- Add `quest::GetZoneSnowChance(zone_id)`.
- Add `quest::GetZoneSnowChance(zone_id, slot)`.
- Add `quest::GetZoneSnowChance(zone_id, slot, version)`.
- Add `quest::GetZoneSnowDuration(zone_id)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot, version)`.
- Add `quest::GetZoneGravity(zone_id)`.
- Add `quest::GetZoneGravity(zone_id, version)`.
- Add `quest::GetZoneType(zone_id)`.
- Add `quest::GetZoneType(zone_id, version)`.
- Add `quest::GetZoneSkyLock(zone_id)`.
- Add `quest::GetZoneSkyLock(zone_id, version)`.
- Add `quest::GetZoneFastRegenHP(zone_id)`.
- Add `quest::GetZoneFastRegenHP(zone_id, version)`.
- Add `quest::GetZoneFastRegenMana(zone_id)`.
- Add `quest::GetZoneFastRegenMana(zone_id, version)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id, version)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id, version)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id, version)`.
- Add `quest::GetZoneMinimumExpansion(zone_id)`.
- Add `quest::GetZoneMinimumExpansion(zone_id, version)`.
- Add `quest::GetZoneMaximumExpansion(zone_id)`.
- Add `quest::GetZoneMaximumExpansion(zone_id, version)`.
- Add `quest::GetZoneContentFlags(zone_id)`.
- Add `quest::GetZoneContentFlags(zone_id, version)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id, version)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id, version)`.
- Add `quest::GetZoneLavaDamage(zone_id)`.
- Add `quest::GetZoneLavaDamage(zone_id, version)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id, version)`.

# Lua
- Add `eq.get_zone_safe_x(zone_id)`.
- Add `eq.get_zone_safe_x(zone_id, version)`.
- Add `eq.get_zone_safe_y(zone_id)`.
- Add `eq.get_zone_safe_y(zone_id, version)`.
- Add `eq.get_zone_safe_z(zone_id)`.
- Add `eq.get_zone_safe_z(zone_id, version)`.
- Add `eq.get_zone_safe_heading(zone_id)`.
- Add `eq.get_zone_safe_heading(zone_id, version)`.
- Add `eq.get_zone_minimum_level(zone_id)`.
- Add `eq.get_zone_minimum_level(zone_id, version)`.
- Add `eq.get_zone_maximum_level(zone_id)`.
- Add `eq.get_zone_maximum_level(zone_id, version)`.
- Add `eq.get_zone_minimum_status(zone_id)`.
- Add `eq.get_zone_minimum_status(zone_id, version)`.
- Add `eq.get_zone_time_zone(zone_id)`.
- Add `eq.get_zone_time_zone(zone_id, version)`.
- Add `eq.get_zone_maximum_players(zone_id)`.
- Add `eq.get_zone_maximum_players(zone_id, version)`.
- Add `eq.get_zone_rule_set(zone_id)`.
- Add `eq.get_zone_rule_set(zone_id, version)`.
- Add `eq.get_zone_note(zone_id)`.
- Add `eq.get_zone_note(zone_id, version)`.
- Add `eq.get_zone_underworld(zone_id)`.
- Add `eq.get_zone_underworld(zone_id, version)`.
- Add `eq.get_zone_minimum_clip(zone_id)`.
- Add `eq.get_zone_minimum_clip(zone_id, version)`.
- Add `eq.get_zone_maximum_clip(zone_id)`.
- Add `eq.get_zone_maximum_clip(zone_id, version)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_red(zone_id)`.
- Add `eq.get_zone_fog_red(zone_id, slot)`.
- Add `eq.get_zone_fog_red(zone_id, slot, version)`.
- Add `eq.get_zone_fog_green(zone_id)`.
- Add `eq.get_zone_fog_green(zone_id, slot)`.
- Add `eq.get_zone_fog_green(zone_id, slot, version)`.
- Add `eq.get_zone_fog_blue(zone_id)`.
- Add `eq.get_zone_fog_blue(zone_id, slot)`.
- Add `eq.get_zone_fog_blue(zone_id, slot, version)`.
- Add `eq.get_zone_sky(zone_id)`.
- Add `eq.get_zone_sky(zone_id, version)`.
- Add `eq.get_zone_ztype(zone_id)`.
- Add `eq.get_zone_ztype(zone_id, version)`.
- Add `eq.get_zone_experience_multiplier(zone_id)`.
- Add `eq.get_zone_experience_multiplier(zone_id, version)`.
- Add `eq.get_zone_walk_speed(zone_id)`.
- Add `eq.get_zone_walk_speed(zone_id, version)`.
- Add `eq.get_zone_time_type(zone_id)`.
- Add `eq.get_zone_time_type(zone_id, version)`.
- Add `eq.get_zone_fog_density(zone_id)`.
- Add `eq.get_zone_fog_density(zone_id, version)`.
- Add `eq.get_zone_flag_needed(zone_id)`.
- Add `eq.get_zone_flag_needed(zone_id, version)`.
- Add `eq.get_zone_can_bind(zone_id)`.
- Add `eq.get_zone_can_bind(zone_id, version)`.
- Add `eq.get_zone_can_combat(zone_id)`.
- Add `eq.get_zone_can_combat(zone_id, version)`.
- Add `eq.get_zone_can_levitate(zone_id)`.
- Add `eq.get_zone_can_levitate(zone_id, version)`.
- Add `eq.get_zone_cast_outdoor(zone_id)`.
- Add `eq.get_zone_cast_outdoor(zone_id, version)`.
- Add `eq.get_zone_hotzone(zone_id)`.
- Add `eq.get_zone_hotzone(zone_id, version)`.
- Add `eq.get_zone_instance_type(zone_id)`.
- Add `eq.get_zone_instance_type(zone_id, version)`.
- Add `eq.get_zone_shutdown_delay(zone_id)`.
- Add `eq.get_zone_shutdown_delay(zone_id, version)`.
- Add `eq.get_zone_peqzone(zone_id)`.
- Add `eq.get_zone_peqzone(zone_id, version)`.
- Add `eq.get_zone_expansion(zone_id)`.
- Add `eq.get_zone_expansion(zone_id, version)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id, version)`.
- Add `eq.get_zone_suspend_buffs(zone_id)`.
- Add `eq.get_zone_suspend_buffs(zone_id, version)`.
- Add `eq.get_zone_rain_chance(zone_id)`.
- Add `eq.get_zone_rain_chance(zone_id, slot)`.
- Add `eq.get_zone_rain_chance(zone_id, slot, version)`.
- Add `eq.get_zone_rain_duration(zone_id)`.
- Add `eq.get_zone_rain_duration(zone_id, slot)`.
- Add `eq.get_zone_rain_duration(zone_id, slot, version)`.
- Add `eq.get_zone_snow_chance(zone_id)`.
- Add `eq.get_zone_snow_chance(zone_id, slot)`.
- Add `eq.get_zone_snow_chance(zone_id, slot, version)`.
- Add `eq.get_zone_snow_duration(zone_id)`.
- Add `eq.get_zone_snow_duration(zone_id, slot)`.
- Add `eq.get_zone_snow_duration(zone_id, slot, version)`.
- Add `eq.get_zone_gravity(zone_id)`.
- Add `eq.get_zone_gravity(zone_id, version)`.
- Add `eq.get_zone_type(zone_id)`.
- Add `eq.get_zone_type(zone_id, version)`.
- Add `eq.get_zone_sky_lock(zone_id)`.
- Add `eq.get_zone_sky_lock(zone_id, version)`.
- Add `eq.get_zone_fast_regen_hp(zone_id)`.
- Add `eq.get_zone_fast_regen_hp(zone_id, version)`.
- Add `eq.get_zone_fast_regen_mana(zone_id)`.
- Add `eq.get_zone_fast_regen_mana(zone_id, version)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id, version)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id, version)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id, version)`.
- Add `eq.get_zone_minimum_expansion(zone_id)`.
- Add `eq.get_zone_minimum_expansion(zone_id, version)`.
- Add `eq.get_zone_maximum_expansion(zone_id)`.
- Add `eq.get_zone_maximum_expansion(zone_id, version)`.
- Add `eq.get_zone_content_flags(zone_id)`.
- Add `eq.get_zone_content_flags(zone_id, version)`.
- Add `eq.get_zone_content_flags_disabled(zone_id)`.
- Add `eq.get_zone_content_flags_disabled(zone_id, version)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id, version)`.
- Add `eq.get_zone_lava_damage(zone_id)`.
- Add `eq.get_zone_lava_damage(zone_id, version)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id, version)`.

# Notes
- These methods add support for reading every value that the `zone` table contains, allowing operators to get any information about a specific zone and version they could need.
2023-05-24 17:59:18 -04:00
Alex King a3107cc54d [Bug Fix] Fix duplicate messages in #npcedit (#3372)
# Notes
- `#npcedit special_attacks` and `#npcedit special_abilities` send duplicate messages since the `d` variable wasn't being set and a message was being sent instead, meaning a message was sent inside the condition as well as a blank message at the bottom of the command.
2023-05-21 18:56:51 -04:00
Alex King f0152cef66 [Rules] Add World:MaximumQuestErrors Rule (#3349)
* [Rules] Add World:MaximumQuestErrors Rule

# Notes
- Allows operators to display more than 30 errors with #questerrors if they want.

* Update quest_interface.h
2023-05-21 18:48:30 -04:00
Alex King 21755a9f9e [Bug Fix] Fix typos in #zheader (#3370)
# Notes
- Argument 2 and 3 were being used when it should have been arguments 1 and 2.
2023-05-21 18:48:22 -04:00
Alex King b329515a07 [Quest API] Cleanup The Darkened Sea Quest Methods Names (#3369)
# Notes
- These were spelled incorrectly.
2023-05-21 18:48:15 -04:00
Alex King ff4b117cfa [Cleanup] Fix #spawn command NPCs having 0 health (#3371)
# Notes
- NPCs when spawned with this command have 0 health by default, requiring operators to manually edit their health if they're using this NPC as an NPC in their hub.
2023-05-21 18:48:08 -04:00
Paul Coene e305ba852b [Bug Fix] NPC Armor Upgrade to a slot not handled correctly (#3366)
* [NPC Armor - Bug] NPC upgardes in armor not correct

* Revert "[NPC Armor - Bug] NPC upgardes in armor not correct"

This reverts commit d5a68654a7.

* [NPC item bonuses] Upgrades not processed correctly

* Update loottables.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:28:01 -04:00
RekkasGit b8c91cf4f9 [Bug Fix] Mob scaling issue with min dmg set to zero while max dmg is not (#3351)
* fix for mob scaling issue with min dmg set to zero while max dmg is not.

* Cleanup

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:11:11 -04:00
Alex King cd82bd8472 [Cleanup] Remove DumpMerchantList() from zone.cpp/zone.h (#3343)
# Notes
- This is unused.
2023-05-17 09:02:14 -04:00
Alex King 20bed20f47 [Cleanup] Delete message.h (#3348)
# Notes
- This is unsued.
2023-05-17 09:00:38 -04:00
Alex King c93054421f [Cleanup] Remove CountNPC() and QueueManaged() from entity.cpp/entity.h (#3346)
# Notes
- These are unused.
2023-05-17 08:58:50 -04:00
Alex King b7a1fc6644 [Cleanup] Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h (#3352)
# Notes
- This is unused.
2023-05-17 08:58:27 -04:00
Alex King 6bfb8fca2e [Cleanup] Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h (#3353)
# Notes
- This is unused.
2023-05-17 08:58:13 -04:00
Alex King 9d6a7ad743 [Cleanup] Remove SetGraveyard() from zone.cpp/zone.h (#3354)
# Notes
- This is unused.
2023-05-17 08:58:02 -04:00
Alex King 076b88be9a [Cleanup] Remove TypeToSkill() from tradeskills.cpp/object.h (#3355)
# Notes
- This is unused.
2023-05-17 08:57:51 -04:00
Alex King 84a779c4df [Cleanup] Remove SetTradeCash() from trading.cpp/common.h (#3356)
# Notes
- This is unused.
2023-05-17 08:57:09 -04:00
Alex King 3fb479e612 [Cleanup] Remove TraderUpdate() from trading.cpp/client.h (#3357)
# Notes
- This is unused.
2023-05-17 08:56:42 -04:00
Alex King c1f4ee0e65 [Cleanup] Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h (#3358)
# Notes
- These are unused.
2023-05-17 08:56:09 -04:00
RekkasGit 32f7dc3d1b [Quest API] Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua (#3359)
* Add HateListClosestClient available for scripting.

* Add other methods.

* Use pre-existing constants.

* Typos

* Update mob.h

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 21:23:19 -04:00
RekkasGit fa55fd1664 [Bug Fix] Fix Heroic INT/WIS Bonuses (#3341)
* fix for heroic int/wis for hybrids

* Update classes.cpp

* Update classes.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 10:52:53 -04:00
Chris Miles c44c0d4efa [Performance] Character buffs now save in bulk (#3336)
* [Performance] Character buffs now save in bulk

* Only insert if we have buffs to insert

* Swap for .empty()
2023-05-09 13:28:34 -05:00
Chris Miles 50c63b95db [Performance] Character pet bulk saving (#3337)
* [Performance] Character pet bulk saving

* Update zonedb.cpp
2023-05-09 13:27:17 -05:00
Chris Miles 612029de6e [Performance] Character bind is now bulk saved (#3338)
* [Performance] Character bind is now bulk saved

* Fix bind heading
2023-05-09 13:22:57 -05:00
Chris Miles dbc6346fe8 [Performance] Mail key is now cached during player load (#3339)
* [Performance] Mail key is now cached during player load

* More refactoring
2023-05-09 13:22:43 -05:00
nytmyr 93a4153a4b [Rules] ResurrectionEffectBlock to prevent/allow/move buffs. (#3288)
* [Rules] ResurrectionEffectsBlock to prevent/allow/move buffs.

This removes the rule ResurrectionEffectsBlock (Bool) and creates ResurrectionEffectsBlock (Int)

Default = 2

Setting to 0 = Functions as it did before any blocking changes, Focus of Spirit and Strength buffs can overwrite Resurrection Effects.

Setting to 1 = Blocks all buffs that could overwrite Resurrection Effects.

Setting to 2 = Allows all buffs that would overwrite Resurrection Effects to land, however they will be moved to a new buff slot if one is available to allow both the beneficial buff to land and detrimental effects of Resurrection Effects to stay in effect until the duration is expired.

* Update logging

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-05-08 08:32:21 -05:00
Akkadius 434f270f68 Revert "[Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)"
This reverts commit 8c23eee42a.
2023-05-07 23:33:43 -05:00
Alex King 5ba33b88bd [Cleanup] Set GetAugmentType() to int again (#3335)
# Notes
- Augment type can be `-1` for all augment types.
2023-05-07 21:40:45 -04:00
Alex King ce1de9997b [Quest API] Add GetPet() to Perl (#3309)
# Perl
- Add `$mob->GetPet()`.

# Notes
- This exists in Lua, but not Perl.
2023-05-07 19:13:26 -05:00
Chris Miles 8814ab26cd [Hotfix] Fix mob item bonus calc (#3334) 2023-05-07 18:23:22 -05:00
Alex King 8c23eee42a [Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)
# Notes
- Before this, quests/plugins would be cached in an old state, so you'd have to either enter the zone and `#reload quest` or `#reload world` to get them to update.
2023-05-07 14:41:57 -04:00
Alex King 5475615448 [Bug Fix] #augmentitem bypasses augment restrictions (#3332)
* [Bug Fix] #augmentitem bypasses augment restrictions

# Notes
- `Object::HandleAugmentation` did not properly check for `augrestrict` values. This allowed augment restrictions to be bypassed with `#augmentitem` or anything else that uses this method.
- `Client::SummonItem` already properly checked these, so I just broke it out into a `Client::IsAugmentRestricted()` method.

* Update item_instance.h
2023-05-07 11:40:04 -04:00
Chris Miles 4a5559022f [Memory Leak] Fix large memory leak introduced in CalcItemBonuses (#3331) 2023-05-07 09:47:03 -04:00
Paul Coene 5be2041085 [Messages] Remove duplicate heal message for healing yourself (#3329) 2023-05-03 16:50:54 -04:00
Jasdac 9f4d60ec36 [Feature] Intoxication setter/getter for source, getter for Perl/Lua (#3330)
* Add setter and getter methods for intoxication
Add GetIntoxication functions for perl and Lua

* Remove trailing tab

* Use clamp instead of min/max
2023-05-03 16:19:53 -04:00
Chris Miles c64a2aec94 [Release] 22.11.0 (#3328)
* [Release] 22.11.0

* Update version.h
2023-04-29 20:37:04 -05:00
Alex King 0e582eda82 [Quest API] Add HasSpellEffect() to Perl/Lua (#3319)
* [Quest API] Add HasSpellEffect() to Perl/Lua

# Perl
- Add `$mob->HasSpellEffect(effect_id)`.

# Lua
- Add `mob:HasSpellEffect(effect_id)`.

# Notes
- Allows operators to see if a Mob has an effect ID from any of their buffs.

* Update mob.cpp
2023-04-29 20:09:00 -05:00
Alex King 7eff6ada87 [Cleanup] Remove unused code in zone/pets.cpp (#3310)
# Notes
- This code is unused.
2023-04-29 20:00:37 -05:00
Alex King 291997d35b [Cleanup] Remove pDontCastBefore_casting_spell from zone/npc.h (#3311)
# Notes
- This is unused.
2023-04-29 20:00:20 -05:00
Alex King ac4572bf79 [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h (#3312)
* [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h

# Notes
- Remove `CheckAccess()` in `zone/client.cpp`.
- Remove `CheckAccess()` in `zone/client.h`.
- Remove `CheckQuests()` in `zone/client.h`.
- Remove `MakeCorpse()` in `zone/client.h`.
- Remove `HPTick()` in `zone/client.h`.
- These methods are unused.

* Update client.h
2023-04-29 20:00:08 -05:00
Alex King f0a9578b6a [Cleanup] Remove GetClassHPFactor() from zone/merc.h (#3314)
# Notes
- This is unused.
2023-04-29 19:59:50 -05:00
Alex King baa824d8fb [Cleanup] Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h (#3313)
# Notes
- This is unused.
2023-04-29 19:59:19 -05:00
Alex King b19d3ac8a2 [Cleanup] Remove unused methods in zone/bot.cpp and zone/bot.h (#3315)
# Notes
- Remove `DoFinishedSpellAETarget()`.
- Remove `SendBotArcheryWearChange()`.
- These are unused.
2023-04-29 19:59:05 -05:00
Alex King 6a393bf0c3 [Quest API] Add GetDefaultRaceSize() overloads to Perl/Lua (#3320)
# Perl
- Add `$mob->GetDefaultRaceSize(race_id)`.
- Add `$mob->GetDefaultRaceSize(race_id, gender_id)`.

# Lua
- Add `mob:GetDefaultRaceSize(race_id)`.
- Add `mob:GetDefaultRaceSize(race_id, gender_id)`.

# Notes
- This allows you to get a default size for a race and gender that isn't the current mob's race and gender.
2023-04-29 19:53:49 -05:00
Alex King 09a5551de1 [Cleanup] quest::setallskill() had always true condition. (#3301)
# Notes
- Remove unnecessary double check of `initiator`.
- Cleanup logic to use `EQ::skills::GetSkillTypeMap()`.
2023-04-29 19:52:30 -05:00
Alex King 6e2e035d66 [Cleanup] Remove unused variable in common/crash.cpp (#3308)
# Notes
- This variable is unused.
2023-04-29 19:51:41 -05:00
Alex King ac5922bb32 [Cleanup] Use default ctor/dtor in oriented_bounding_box.h (#3307)
# Notes
- Use default ctor/dtor instead of empty ones.
2023-04-29 19:51:21 -05:00
Chris Miles ecf2a369cc [Discord] Add Discord webhook callback processing to world (#3322) 2023-04-29 20:49:06 -04:00
Chris Miles 95b306599f [Maps] Update download with faster releases link (#3321) 2023-04-29 19:39:24 -05:00
Chris Miles 497d20512a [Crash] Fix UCS crash that occurs during log reloading (#3324) 2023-04-29 19:39:13 -05:00
Aeadoin db916e946e [Bug Fix] Fix issue with spawning Mercs (#3327) 2023-04-29 18:45:35 -04:00
Alex King 958549b407 [Bug Fix] Possible issues with SummonItem in Client::QuestReward() methods (#3325)
# Notes
- These methods were ignoring the sixth augment slot and could cause item to be summoned attuned being `EQ::invslot::slotCursor` is a non-zero value.
2023-04-26 21:28:24 -04:00
Paul Coene 71ebf1b2d4 [Messages] Remove duplicate you have lost a level message (#3323) 2023-04-25 17:42:31 -04:00
Paul Coene e19b8d3056 [Bug Fix] Fix issue with NPCs no longer using some armor. (#3318)
* [BugFix/NPCs] Fix issue with NPCs no longer using some armor.

* Removed redundant memory clear
2023-04-24 17:05:29 -04:00
Alex King 8b1d64a043 [Cleanup] quest::createBot() unnecessary check against nullptr (#3302)
# Notes
- We initialize this variable, so it can never be a nullptr.
2023-04-23 15:08:50 -04:00
Alex King 576f99f292 [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp (#3306)
* [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp

# Notes
- Add `initiator` check to `quest::permaclass()`.
- Add `initiator` check to `quest::permarace()`.
- Add `initiator` check to `quest::permagender()`.
- Add `initiator` check to `quest::scribespells()`.
- Add `initiator` check to `quest::traindiscs()`.
- Add `initiator` check to `quest::unscribespells()`.
- Add `initiator` check to `quest::untraindiscs()`.
- Cleanup `initiator` check in `quest::pvp()`.
- Cleanup `initiator` check in `quest::movepc()`.
- Cleanup `initiator` check in `quest::gmmove()`.
- Cleanup `initiator` check in `quest::movegrp()`.
- Add `owner` check to `quest::doanim()`.
- Cleanup `initiator` check in `quest::addskill()`.
- Cleanup `initiator` check in `quest::setlanguage()`.
- Cleanup `initiator` check in `quest::setskill()`.

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp
2023-04-23 15:08:32 -04:00
Alex King e3761cf2a3 [Cleanup] Add check for owner in quest::resumetimer() (#3305)
# Notes
- We didn't check for owner before doing `owner->GetName()`.
2023-04-23 15:07:49 -04:00
Alex King ad1764b464 [Cleanup] Add cehck for owner in quest::pausetimer() (#3304)
# Notes
- We didn't check for `owner` before doing `owner->GetName()`.
2023-04-23 15:07:09 -04:00
Alex King 1c9ea57a4e [Cleanup] Fix possible nullptr in quest::addloot() (#3303)
# Notes
- We didn't check for `owner` before calling `owner->IsNPC()`.
2023-04-23 15:06:53 -04:00
Alex King 03c158b674 [Crash] Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() (#3317)
# Notes
- We could possibly not have a `zone` here, causing a crash.
- http://spire.akkadius.com/dev/release/22.9.1?id=3051
- http://spire.akkadius.com/dev/release/22.9.1?id=3052
- http://spire.akkadius.com/dev/release/22.9.1?id=3073
- http://spire.akkadius.com/dev/release/22.9.1?id=3102
- http://spire.akkadius.com/dev/release/22.9.1?id=3103
- http://spire.akkadius.com/dev/release/22.9.1?id=3104
- http://spire.akkadius.com/dev/release/22.9.1?id=3107
- http://spire.akkadius.com/dev/release/22.9.1?id=3108
- http://spire.akkadius.com/dev/release/22.9.1?id=3109
- http://spire.akkadius.com/dev/release/22.9.1?id=3110
- http://spire.akkadius.com/dev/release/22.9.1?id=3111
- http://spire.akkadius.com/dev/release/22.9.1?id=3112
- http://spire.akkadius.com/dev/release/22.9.1?id=3113
- http://spire.akkadius.com/dev/release/22.9.1?id=3114
2023-04-23 15:05:47 -04:00
Aeadoin 39b5374e92 [Crash] Fix possible dereference of nullptr in Client::CalcHPRegen (#3316) 2023-04-23 14:27:43 -04:00
Aeadoin 2d3ddcb574 [Release] 22.10.0 (#3300) 2023-04-22 10:17:20 -04:00
Aeadoin ed09281f66 [Bug Fix] Camping was causing player to leave raid, causing unexpected behavior (#3299) 2023-04-22 10:03:40 -04:00
Paul Coene 8e51bf8b19 Fix crash when Removing empty password protected channel. (#3298) 2023-04-22 08:49:34 -04:00
Alex King 844efa7e20 [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp (#3297)
* [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp

# Notes
- These breaks were inside conditions, meaning the case wasn't always broken.

* Update spell_effects.cpp
2023-04-22 08:49:13 -04:00
Alex King fa3a5c7a72 [Feature] Make ornamentations work with any augment type (#3281)
* [Feature] Make ornamentations work with any augment type

# Notes
- On Live there are augments that are not type 20/21 and are ornamentations.
- We also only allow a singular augment type to be ornamentation augment types, this will allow you to use any augment type as an ornamentation if it has a proper Hero's Forge model or a non-IT63/non-IT64 idfile.

* Update ruletypes.h

* Update client_packet.cpp

* Update item_instance.cpp

* Cleanup.
2023-04-16 10:26:19 -04:00
Aeadoin 93db35658a [Crash] Add additional raid integrity checks on Bot Spawn. (#3295)
* simple cleanup before changes

* can't be in a raid yet

* change to sizeof

* change to use sizeof
2023-04-16 10:06:19 -04:00
Alex King d45a57056a [Cleanup] Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h (#3283)
* [Cleanup] Remove getd(), geti(), InUse(), lasterr(), and VarExists() in embperl.cpp/embperl.h

# Notes
- These are unused.

* Update embperl.h

* Update embperl.cpp
2023-04-15 13:20:18 -04:00
Alex King ff40dbc710 [Cleanup] Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() (#3275)
* [Cleanup] Utilize SetPetPower() in zone/pets.cpp

# Notes
- This wasn't used before.

* Utilize other methods.

* Update special_attacks.cpp
2023-04-15 13:20:04 -04:00
Aeadoin 7523c972fa [Crash] Fix crash with uninitialized item instance, and Bot timeout (#3296) 2023-04-15 13:12:48 -04:00
Alex King 4320c1429e [Cleanup] Remove _GetMovementSpeed() from mob.h (#3276)
# Notes
- This is unused.
2023-04-14 19:42:48 -04:00
Alex King dc8bfddd7a [Cleanup] Remove IsFullHP from mob.cpp/mob.h (#3277)
# Notes
- This is unused.
2023-04-14 19:42:39 -04:00
Alex King a8cdfb07e6 [Cleanup] Remove pendinggroup from mob.h (#3278)
# Notes
- This is unused.
2023-04-14 19:42:27 -04:00
Alex King 011de2692e [Cleanup] Remove IsMeleeDmg() from skills.cpp/skills.h (#3279)
# Notes
- This is unused.
2023-04-14 19:42:14 -04:00
Alex King 0cc76ab489 [Cleanup] Remove position_same_update_count from client.cpp/client.h (#3280)
# Notes
- This is unused.
2023-04-14 19:42:01 -04:00
Alex King c5c9985e0d [Cleanup] Remove ExportVarComplex() from embparser.cpp/embparser.h (#3282)
# Notes
- This is unused.
2023-04-14 19:41:23 -04:00
Alex King a7e95d7818 [Cleanup] Delete embxs.cpp/embxs.h (#3284)
* [Cleanup] Delete embxs.cpp/embxs.h

# Notes
- These files and the one method in them are unused.

* Update embperl.cpp
2023-04-14 19:40:51 -04:00
Alex King 933d856b5b [Cleanup] Remove GetQGlobal() from qglobals.cpp/qglobals.h (#3285)
# Notes
- This is unused.
2023-04-14 19:40:35 -04:00
Alex King 285cc3af29 [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h (#3286)
* [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h

# Notes
- This is unused.

* Update questmgr.h
2023-04-14 19:40:21 -04:00
Alex King de8ae7afa6 [Cleanup] Cleanup zone/zoning.cpp (#3289)
# Notes
- Duplicate outcome cases in `Client::Handle_OP_ZoneChange`.
- Use `.length()` over `strlen` in array defintition.
- Remove unnecessary `else if` in `Client::ZonePC`
2023-04-14 19:40:01 -04:00
Alex King 1b272cba50 [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h (#3290)
* [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h

# Notes
- Utilize default dtor.
- Remove unused ctor.

* Update zone_event_scheduler.cpp
2023-04-14 19:39:25 -04:00
Alex King e35e38b039 [Cleanup] Remove unused variables and use reference in task_manager.cpp (#3291)
# Notes
- Remove unused `query` and `item` variable.
- Use a reference for task data instead of calling `cts->m_completed_tasks[task_index]` over and over.
2023-04-14 19:39:07 -04:00
Alex King 9215ba7a8a [Cleanup] Remove always true statements in task_client_state.cpp (#3292)
# Notes
- `!tasks_enabled.empty()` is always true.
- `tasks_disabled.size()` is always true.
2023-04-14 19:38:35 -04:00
Alex King 3f4334985b [Cleanup] Remove unnecessary condition and cleanup variable name in tasks.cpp (#3293)
# Notes
- `task_state` is verified by `safe_delete`.
- `size` is the name of a member variable, we should just use `sizeof(uint32_t)` instead.
2023-04-14 19:38:28 -04:00
Alex King 21002c2e8a [Quest API] Fix LDoN Methods in Perl/Lua (#3287)
# Perl
- Add `quest::removeldonloss(theme_id)`.
- Add `quest::removeldonwin(theme_id)`.

# Lua
- Fix `eq.remove_ldon_win(theme_id)` as it was using `quest_manager.addldonwin(theme_id)` instead of `quest_manager.removeldonwin(theme_id)`.
2023-04-10 16:16:54 -04:00
Alex King 445f967ed6 [Quest API] Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua (#3274)
# Perl
- Add `$bot->ApplySpellRaid(spell_id)`.
- Add `$bot->ApplySpellRaid(spell_id, duration)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `$bot->SetSpellDuration(spell_id)`.
- Add `$bot->SetSpellDuration(spell_id, duration)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Lua
- Add `bot:ApplySpellRaid(spell_id)`.
- Add `bot:ApplySpellRaid(spell_id, duration)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `bot:SetSpellDuration(spell_id)`.
- Add `bot:SetSpellDuration(spell_id, duration)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Notes
- These methods weren't added initially as we did not support bots in raid groups until recently.
2023-04-09 12:00:12 -04:00
Alex King 57a15d473f [Quest API] Add GetBuffSpellIDs() to Perl/Lua (#3273)
# Perl
- Add `$mob->GetBuffSpellIDs()`.

# Lua
- Add `$mob->GetBuffSpellIDs()`.

# Notes
- These methods allow operators to get a list of a mob's buff IDs without having to loop through their buffs themselves.
2023-04-09 10:58:35 -04:00
Trent df92c578d2 [Rules] Optional summoning when already in melee range (#3204)
* Add summon melee range rule

* Fix compilation

* Remove redundant range check for HateSummon
2023-04-08 18:04:17 -04:00
Aeadoin 3af43a8e8d [Hotfix] Resolve loading of inventory (#3272) 2023-04-08 17:45:06 -04:00
Aeadoin 647bcce30b [Crash] Resolve crash due to uninitialized pointer. (#3271) 2023-04-08 17:21:53 -04:00
Alex King 25b527156c [Cleanup] Fix possible nullptr inst in GetSharedBank() (#3190)
* [Cleanup] Fix possible nullptr inst in GetSharedBank()

# Notes
- We weren't continuing if we had a `nullptr`.

* Update shareddb.cpp

* Fix.
2023-04-08 09:42:10 -04:00
Aeadoin b3ab7deb80 [Bots] Cleanup GetBotTables() (#3270) 2023-04-06 17:43:57 -05:00
Alex King 4a9cb07132 [Cleanup] Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() (#3233)
# Notes
- Bash, Kick, and Taunt have the same reuse time, no reason to set it to the same value.
2023-04-05 19:17:15 -04:00
Alex King 8f1b62d166 [Cleanup] Remove always true/false conditions from bot.cpp (#3237)
* [Cleanup] Remove always true/false conditions from bot.cpp

# Notes
- Some of these conditions were always true or false based on previous conditions.

* Update bot.cpp
2023-04-05 19:05:49 -04:00
Alex King 7e9994b5d4 [Cleanup] Fix ornamentation augment icons in inspect requests (#3264)
* [Cleanup] Fix ornamentation augment icons in inspect requests

# Notes
- We were not setting `aug_item` to the ornamentation augment when we found one.

* Update client.cpp
2023-04-05 19:04:32 -04:00
Chris Miles f2f8fae58b [Telnet] Telnet encoding fix (#3269) 2023-04-05 12:16:25 -04:00
Alex King 3a1e88f9ed [Cleanup] Remove unused SetConfigFile in common/eqemu_config.h (#3208)
# Notes
- This is unused.
2023-04-05 12:15:10 -04:00
Alex King 4e101aa6d6 [Cleanup] Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h (#3210)
# Notes
- This is better than using an empty dtor.
2023-04-05 12:15:02 -04:00
Alex King ef411ee154 [Cleanup] Use default ctor instead of an empty ctor. (#3206)
# Notes
- Use `= default;` instead of an empty ctor.
- https://pvs-studio.com/en/docs/warnings/v832/
2023-04-05 12:14:22 -04:00
Alex King 93b3f97f24 [Cleanup] Cleanup discord.cpp and discord_manager.cpp (#3205)
# Notes
- Unused variables in `discord.cpp`.
- Use `.clear()` instead of setting to `""` in `discord_manager.cpp`.
2023-04-05 12:14:14 -04:00
Alex King c1d4cb90b9 [Cleanup] Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h (#3209)
# Notes
- More performant to pass by value than by reference.
2023-04-05 12:14:01 -04:00
Alex King e939c82717 [Cleanup] Convert equipable_slot_list to std::vector from std::list in bot_command.cpp (#3253)
# Notes
- No need to use a `std::list` here.
2023-04-05 11:35:04 -04:00
Alex King 7d03479f41 [Cleanup] Use constant reference and check for empty string properly in dbcore.cpp (#3203)
# Notes
- Passing by constant reference is more performant.
- Checking for empty string with `!= '\0'` is more performant.
- https://pvs-studio.com/en/docs/warnings/v805/
- https://pvs-studio.com/en/docs/warnings/v813/
2023-04-05 11:27:50 -04:00
Alex King ff440e16b6 [Cleanup] Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() (#3201)
# Notes
- Use these methods to increase performance.
2023-04-05 11:27:12 -04:00
Alex King c6bb0f6495 [Cleanup] Move variable definition to more relevant scope in DatabaseDumpService::Dump() (#3200)
# Notes
- This was unused except for in this one spot, move to scope of condition where it's used.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:26:21 -04:00
Alex King d142bc552a [Cleanuo] Only define row if we have results in Database::GetCharacterID() (#3199)
# Notes
- This is more performant and we don't unnecessarily define a variable we can't use.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:25:28 -04:00
Alex King 7dc57c3b05 [Cleanup] Utilize .empty() instead of checking for an empty string in Database::ReserveName() (#3198)
# Notes
- This is more performant.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:54 -04:00
Alex King ea9b09cf1f [Cleanup] Remove unused variable in Database::CopyCharacter() (#3197)
# Notes
- This variable was created but never used.
- https://pvs-studio.com/en/docs/warnings/v808/
2023-04-05 11:24:27 -04:00
Alex King 968278d8f8 [Cleanup] Use .clear() instead of setting string to empty in eqemu_command_handler.cpp (#3195)
# Notes
- `x = ""` has less performance than `x.clear()`.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:12 -04:00
Alex King aa910864c8 [Cleanup] Remove unused macros in common/types.h (#3194)
# Notes
- These are unused.
2023-04-05 11:23:37 -04:00
Alex King 1499f3338e [Cleanup] Remove always true condition in Strings::Commify() (#3193)
# Notes
- `i < 0` was always true.
2023-04-05 11:23:24 -04:00
Alex King fef2f9fc61 [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member (#3192)
* [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member

# Notes
- This variable was named `m_db_shared_task` which is the same as `SharedTask:;m_db_shared_task`.

* Single letter receiver of complex type.
2023-04-05 11:22:42 -04:00
Alex King 8afbc585da [Cleanup] Remove bool return from GetSharedPlatinum() (#3191)
# Notes
- This was returning `false` and implicitly converting it to an integer.
2023-04-05 11:22:23 -04:00
Alex King 457ce85746 [Cleanup] Cleanup always true/false statements in shareddb.cpp (#3189)
# Notes
- `parent_index < EQ::invslot::SLOT_BEGIN` was always `false`.
- `item->LoreGroup != -1` was always `true`.
2023-04-05 11:21:43 -04:00
Alex King 49c093dc62 [Cleanup] Remove always true statement in say_link.cpp (#3188)
# Notes
- This is always true since we check `!saylinks.empty()` prior to this.
2023-04-05 11:20:52 -04:00
Alex King beccd557a8 [Cleanup] Cleanup item_instance.cpp always true statements and reassigning of same values (#3187)
# Notes
- Some things were always true.
- Some values were reassigned to the value they already were.
2023-04-05 11:20:36 -04:00
Alex King e11610b9fa [Cleanup] Remove unnecessary check for IsStackable() in DeleteItem() (#3186)
# Notes
- We check the opposites therefore we don't need either.
- https://pvs-studio.com/en/docs/warnings/v728/
2023-04-05 11:20:13 -04:00
Alex King 3e652b98bc [Cleanup] Cleanup macros in features.h (#3185)
# Notes
- These needed to either be wrapped in parentheses or simplified to their values.
- https://pvs-studio.com/en/docs/warnings/v1003/
2023-04-05 11:18:22 -04:00
Alex King d43af28de4 [Cleanup] Multiple cases with same outcome in GetDiscordPayloadFromEvent() (#3184)
# Notes
- All 4 of these use `FormatWithNodata`.
2023-04-05 11:17:52 -04:00
Alex King f5106b6af6 [Cleanup] Remove unused code in eq_packet.cpp/eq_packet.h (#3183)
# Notes
- These are unused.
2023-04-05 11:17:29 -04:00
Alex King 3386d13d2d [Cleanup] results variable is assigned but never used in SaveCharacterCreate() (#3180)
# Notes
- This was unnecessary since `QueryDatabase()` runs regardless.
2023-04-05 11:17:10 -04:00
Alex King d1b7c675f9 [Cleanup] Validate for nullptrs in bot.cpp (#3232)
* [Cleanup] Validate for nullptrs in bot.cpp

# Notes
- Validate for nullptrs in these spots in bot.cpp before using the variable.

* Update bot.cpp
2023-04-05 11:15:46 -04:00
Alex King a40e1cf893 [Cleanup] Add missing breaks and returns in bonuses.cpp (#3231)
# Notes
- Many spots were missing a `break;` or a `return` for their value.
2023-04-05 11:15:22 -04:00
Alex King c81ab00764 [Cleanup] Set bonuses to use spell ID instead of boolean (#3230)
# Notes
- Spell bonuses `Illusion` is the spell ID, not a boolean.
2023-04-05 11:14:55 -04:00
Alex King 025ef5e1d6 [Cleanup] Move unreachable code in ApplySpellsBonuses() (#3229)
# Notes
- This code was unreachable since it was inside the switch and should have been checked on its own in the condition where we verify we are using AISpellEffects.
2023-04-05 11:14:28 -04:00
Alex King 1f29a40e6d [Cleanup] Remove extraneous check for NegateAttacks in SE_NegateAttacks (#3228)
# Notes
- We checked both, we only need to check one.
2023-04-05 11:12:02 -04:00
Alex King 66cadd599b [Cleanup] Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() (#3227)
# Notes
- Extra parentheses.
2023-04-05 11:11:41 -04:00
Alex King aa0345c1f1 [Cleanup] Cleanup duplicate conditions in negate bonuses in bonuses.cpp (#3226)
# Notes
- Lots of duplicate conditions.
2023-04-05 11:11:22 -04:00
Alex King 73b11c5036 [Cleanup] SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp (#3223)
# Notes
- These were the same code duplicated.
2023-04-05 11:05:59 -04:00
Alex King efbeb2dbb7 [Cleanup] SE_AttackSpeed3 effect_value is always less than 0 (#3222)
# Notes
- This was always false.
2023-04-05 11:05:44 -04:00
Alex King 8c97c20727 [Cleanup] Fix skill_used being used as boolean in Mob::CommonDamage() (#3220)
# Notes
- This is unnecessary as we always have a skill value.
2023-04-05 11:03:28 -04:00
Alex King f2d07e5c69 [Cleanup] Remove unnecessary break in while loop in Mob::AddToHateList() (#3219)
# Notes
- This is unnecessary and breaks the loop for no reason.
2023-04-05 10:31:57 -04:00
Alex King 64d5b54e65 [Cleanup] Fix filter condition in attack.cpp (#3218)
# Notes
- This condition was causing them to be used as `booleans` versus being checked individually.
2023-04-05 10:31:34 -04:00
Alex King 89b3a04eb3 [Cleanup] Identical conditions right beside each other in aa.cpp (#3213)
# Notes
- These conditions were identical and could be consolidated.
2023-04-05 10:30:27 -04:00
Alex King 1bafe0b6b3 [Cleanup] other is always defined in these cases in attack.cpp (#3217)
# Notes
- `other` is always defined since we check it prior to checking here.
2023-04-05 10:30:13 -04:00
Alex King 82762c3f5a [Cleanup] Use variable for character instead of a loop (#3268)
# Notes
- Store character in a variable instead of looping a list of 1 entry.
2023-04-05 10:29:16 -04:00
Alex King 2742eca119 [Cleanup] Remove unnecessary conditions in Client::SendFactionMessage() (#3267)
# Notes
- `faction_value < this_faction_max` and `faction_value > this_faction_min` are always true if they get to that point in the code.
2023-04-05 10:27:15 -04:00
Alex King 8fc7f3a732 [Cleanup] Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() (#3266)
# Notes
- `value == 0` is unnecessary as it can only be 0 if we fail the `value > 0` check.
2023-04-05 10:27:01 -04:00
Alex King 39ce0178f9 [Cleanup] Remove unnecessary conditions in Client::Consume() (#3265)
# Notes
- We check `increase < 0` prior to this, so this can't ever happen.
2023-04-05 10:26:32 -04:00
Alex King 3d2f560436 [Cleanup] Fix GetLastName() length check in Client::SendWindow() (#3263)
# Notes
- `target->GetLastName()` was always true, we need to make sure the target has a last name.
2023-04-05 10:23:54 -04:00
Alex King a0768d2d28 [Cleanup] Remove unnecessary conditions in Client::FilteredMessageCheck() (#3262)
# Notes
- We check `FilterHide` prior to the secondary conditions, so it can never show up.
2023-04-05 10:23:33 -04:00
Alex King 9009a7aa23 [Cleanup] Remove extra assignment of current_endurance in Client ctor (#3261)
# Notes
- We already assign `current_endurance` to `0`, no need to do it again.
2023-04-05 10:23:20 -04:00
Alex King 67b03b4e31 [Cleanup] Combine similar cases in Client::InitInnates() (#3260)
# Notes
- These cases were the same, consolidating them is better.
2023-04-05 10:23:05 -04:00
Alex King b08975aefb [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() (#3259)
* [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines()

# Notes
- Use `.empty()` instead of using a variable storing size in condition.

* Update client.cpp
2023-04-05 10:22:36 -04:00
Alex King ea3a7cae0b [Cleanup] Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() (#3258)
* [Cleanup] Remove unreachable code in Client::SendMercPersonalInfo()

# Notes
- This cannot be reached due to prior returns.

* Update client.cpp

* Update client.cpp
2023-04-05 10:14:07 -04:00
Alex King 81314a3315 [Cleanup] Fix check for !this in Client::SendHPUpdateMarquee() (#3257)
# Notes
- `!this` isn't valid, as `this` can never be nullptr.
2023-04-05 10:13:24 -04:00
Alex King d33cfad567 [Cleanup] Fix always false conditions in Client::IncStats() (#3256)
# Notes
- Value can never be less than `0` as it's unsigned.
2023-04-05 10:12:32 -04:00
Alex King c1698a5bdd [Cleanup] Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() (#3255)
# Notes
- Fix possible overflows by casting properly.
2023-04-05 10:10:33 -04:00
Alex King 2a094e8792 [Cleanup] Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp (#3254)
# Notes
- Calling multiple times is less performant than using a variable.
2023-04-05 10:09:19 -04:00
Alex King 4a0725e278 [Cleanup] Cleanup string -> char* -> string conversions in bot_command.cpp (#3252)
# Notes
- We were converting back and forth between types unnecessarily.
2023-04-05 09:59:43 -04:00
Alex King 218ffbb2c5 [Cleanup] Delete unused strings in bot_command.cpp (#3251)
# Notes
- These are unused.
2023-04-05 09:59:24 -04:00
Chris Miles 3e30e78158 [Backups] Fix database dump error reporting (#3175)
* [Backups] Fix database dump error reporting

* Update database_dump_service.cpp
2023-04-04 00:14:23 -05:00
Aeadoin ff2af0c49e [Release] 22.9.1 (#3250) 2023-04-03 17:49:39 -04:00
Alex King cd5697bc81 [Cleanup] Multiple cases same outcome and set skip variable to same value (#3216)
# Notes
- `skip` is set to `attacker` before it's set to `attacker` again.
- Multiple spots in `Mob::AttackAnimation` use the same animations.
2023-04-03 17:24:27 -04:00
Alex King b1571cd062 [Cleanup] Wake The Dead argument was named the same as a member variable in Mob (#3214)
# Notes
- Member variable is also named `target`.
2023-04-03 17:23:48 -04:00
Alex King 3e5d0a0601 [Cleanup] Unconditional return in for loop in GetRaidByCharID() (#3179)
# Notes
- This is improper and should just check if we have no result, return `0`, otherwise return `row[0]` of the row we queried.
2023-04-03 17:23:32 -04:00
Alex King 6a80a061dd [Cleanup] Multiple cases with same outcome in GetGMSayColorFromCategory() (#3182)
# Notes
- Both cases have the same return.
- https://pvs-studio.com/en/docs/warnings/v1037/
2023-04-03 17:20:43 -04:00
Alex King 509fd0615e [Cleanup] Remove unused query variable in Database::DeleteInstance() (#3202)
# Notes
- Variable was defined but never used.
2023-04-03 17:18:40 -04:00
Alex King da5e672a28 [Cleanup] Remove unnecessary group validation in Bot::Death() (#3235)
# Note
- We already break if there is no group above, revalidation is unnecessary.
2023-04-03 17:15:09 -04:00
Alex King 7090382074 [Cleanup] Remove unnecessary skill_to_use check in Bot::DoClassAttacks() (#3236)
# Notes
- `skill_to_use` will never be `-1` as it passes through the switch and checks class.
2023-04-03 17:11:56 -04:00
Alex King 26eabcd7a4 [Cleanup] Explicitly cast to float for more precision in Bot::GenerateBastHitPoints() (#3238)
# Notes
- Not casting explicitly we lost precision.
2023-04-03 17:05:48 -04:00
Alex King 60091015d3 [Cleanup] Remove unnecessary >= 0 checks for procs in botspellsai.cpp (#3242)
# Notes
- These are always `>= 0` since they're `uint16`.
2023-04-03 17:05:03 -04:00
Alex King 470392021b [Cleanup] Remove unnecessary setting of spell_type_index in Bot::GetChanceToCastBySpellType() (#3243)
# Notes
- The default is already `SPELL_TYPE_COUNT`, no need to set it again.
2023-04-03 17:04:51 -04:00
Alex King 90984c3215 [Cleanup] Remove unnecessary spell_list validation check in botspellsai.cpp (#3244)
# Notes
- We check if valid above, no need to do it again.
2023-04-03 17:03:56 -04:00
Alex King da2296d416 [Cleanup] Remove unnecessary hpr checks in Bot::BotCastHeal() (#3245)
# Notes
- These checks are unnecessary as we know it doesn't pass previous checks.
2023-04-03 17:03:36 -04:00
Alex King c9221f239c [Cleanup] Remove unnecessary botCaster check in Bot::GetDebuffBotSpell() (#3246)
# Notes
- We already check if `botCaster` is invalid above, no need to do so again.
2023-04-03 17:02:48 -04:00
Alex King f4edc69a87 [Cleanup] Cleanup unnecessary string -> char* -> string conversions in eqemu_config.cpp (#3207)
# Notes
- These conversions are unnecessary since we can just use the string itself.
2023-04-03 17:01:44 -04:00
Alex King 7d04608c4d [Cleanup] summon_count > MAX_SWARM_PETS is always false in aa.cpp (#3212)
# Notes
- This was always false.
2023-04-03 17:00:08 -04:00
Alex King 32be049d96 [Cleanup] Remove extraneous loottable_id setting in WakeTheDead in aa.cpp (#3215)
# Notes
- We already set `made_npc->loottable_id` to `0` above.
2023-04-03 16:59:06 -04:00
Alex King 26fd52fb06 [Cleanup] Fix SEResist array settings duplicate code (#3225)
# Notes
- These conditions did the same thing, combining them is simpler.
2023-04-03 16:53:48 -04:00
Alex King 5dd849ac75 [Cleanup] Fix typo where itembonuses should have been used instead of spellbonuses (#3221)
# Notes
- `itembonuses` was the proper name here, not `spellbonuses`.
2023-04-03 16:51:22 -04:00
Alex King f484fe4176 [Cleanup] gid is assigned 2 values simultaneously in bot.cpp (#3234)
# Notes
- Unnecessarily assigning the value twice simultaneously.
2023-04-03 16:47:46 -04:00
Alex King 3d20c0d6aa [Cleanup] Change level to bot_level in Bot::DoClassAttacks() to not overlap member variable (#3239)
# Notes
- Member variable is named `level`, change variable to `bot_level` so we don't cause issues.
2023-04-03 16:47:31 -04:00
Alex King 0297045cc5 [Cleanup] Move cases in Bot::AICastSpell() (#3247)
# Notes
- These all returned `false`, no need to be separate.
2023-04-03 16:46:31 -04:00
Alex King cb90d00832 [Cleanup] Cleanup variable names in Bot::AddSpellToBotList() (#3248)
# Notes
- `max_hp` was named after a member variable.
2023-04-03 16:45:36 -04:00
Aeadoin f752b57a55 [Cleanup] Cleanup uses of insert/push_back when a temp object is used. (#3170) 2023-04-03 16:45:01 -04:00
Alex King 2bb15271c5 [Cleanup] Fix possible dereferencing of invalid iterator in constants (#3181)
# Notes
- Possible dereferencing of invalid iterator based on logic: https://pvs-studio.com/en/docs/warnings/v783/
2023-04-03 16:42:45 -04:00
Alex King 6976e27501 [Cleanup] Use a constant reference for content_flags in SetContentFlags() (#3196)
# Notes
- This is more performant.
- https://pvs-studio.com/en/docs/warnings/v813/
- https://pvs-studio.com/en/docs/warnings/v820/
2023-04-03 16:38:20 -04:00
Alex King c9f27d6f90 [Cleanup] Remove possible dereferenced nullptrs in bot.cpp (#3241)
# Notes
- Possible dereferenced nullptrs based on logic.
2023-04-03 16:30:46 -04:00
Alex King cb129efcad [Cleanup] Fix loop and code duplication for SE_ProcOnKillShot (#3224)
* [Cleanup] Fix loop for SE_ProcOnKillShot

# Notes
- We were doing `e = 3` instead of doing `e += 3`.

* Update bonuses.cpp
2023-04-03 16:28:15 -04:00
Aeadoin d653989b03 [Bug Fix] Fix issue with Bot Raid invites not working. (#3249)
* [Bug Fix] Fix issue with Bot Raid invites not always working.

* ordering
2023-04-03 16:28:05 -04:00
Alex King ea9b373180 [Cleanup] Further bot.cpp nullptr checks (#3240)
# Notes
- `nullptr` validation
2023-04-03 16:25:00 -04:00
Aeadoin a4e006fbfb [Bug Fix] Correct Forward Declaration compilation warning (#3176)
* [Bug Fix] Correct Forward Declaration compilation warning

* no need for include
2023-04-02 12:19:43 -04:00
Aeadoin 1ffdd4cb34 [Performance] Change to use Pass by reference where valid. (#3163)
* [Performance] Change to use Pass by reference where valid.

* typo
2023-04-01 22:55:40 -04:00
Aeadoin 7f7ba2e6c2 [Cleanup] Remove unused Includes under zone files (#3162) 2023-04-01 22:55:28 -04:00
Aeadoin 090086f50c [Release] 22.9.0 (#3174) 2023-04-01 14:27:52 -04:00
Alex King 407b003f7d [Cleanup] Add client pointer validation to Zone::GetClosestZonePoint() (#3173)
# Notes
- We were not validating pointer here, could cause issues.
2023-04-01 14:22:52 -04:00
Alex King b6d315d803 [Cleanup] Remove unnecessary validation check in Zone::ClearBlockedSpells() (#3172)
# Notes
- This is unnecessary, since `safe_delete_array` checks for validity.
2023-04-01 13:59:03 -04:00
Aeadoin 6927177291 [Fix] Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. (#3171) 2023-04-01 13:31:13 -04:00
Aeadoin 31ede355a8 [Cleanup] Cleanup excessive type casting: string -> char * -> string (#3169)
* [Cleanup] Cleanup excessive type casting: string -> char * -> string

* [Cleanup] Cleanup excessive type casting: string -> char * -> string
2023-04-01 12:45:16 -04:00
Aeadoin 0df84e1ee6 [Crash] Fix out of bound arrays, other potential crashes (#3166) 2023-04-01 12:44:41 -04:00
Aeadoin 0d509a7f3a [Crash] Add Checks for valid pointers or fix existing. (#3164) 2023-04-01 12:44:00 -04:00
Aeadoin 4c2271ff69 [Fix] Prevent VerifyGroup from setting OOZ membername to Null character. (#3168) 2023-04-01 12:40:55 -04:00
Aeadoin ca2072e7bf [Bots] Remove Bot Groups Functionality (#3165)
* [Bots] Remove Bot Groups Functionality

* in-class initializers for member variables.
2023-03-31 21:37:52 -04:00
Alex King e1eb1ff738 [Quest API] Add missing Luabind definitions to lua_general.cpp (#3167)
# Notes
- These definitions were missing somehow.
2023-03-31 21:05:01 -04:00
Aeadoin 25f5898bae [Release] 22.8.2 (#3161) 2023-03-30 09:22:58 -04:00
Aeadoin 934ff3dadf [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat (#3158)
* [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat

* fix ordering of raid/group checks
2023-03-30 08:31:57 -04:00
Aeadoin e4ff76dceb [Bug Fix] Fix for OOZ Group updates when removing/inviting Bots (#3159)
* [Bug Fix] Fix for Cross Zone Group updates with Bots when disbanding/joining groups.

* check for nullptr
2023-03-30 08:31:50 -04:00
Alex King 6960a1a682 [Bug Fix] Fix issues with Lua tables not starting at index 1 (#3160)
* [Bug Fix] Fix issues with Lua tables not starting at index 1

# Notes
- This would cause the first item in the table to be inaccessible since Lua tables start at index `1` instead of index `0`.
- All other spots using Lua tables have their indexes starting at `1`.

* Update lua_general.cpp
2023-03-30 06:02:53 -04:00
Aeadoin d4174ca236 [Fix] Fix strcpy-param-overlap (#3157) 2023-03-29 08:33:06 -04:00
Aeadoin 7854130a93 [Bug Fix] Check Rule "Bots Enabled" to prevent bot database calls on connect (#3154)
* [Bug Fix] Check for Rule "Bots Enabled" to prevent bot database calls if not enabled.

* formatting

* check if LoadBotsList failed, or is bots_list empty
2023-03-28 22:44:47 -04:00
Alex King e9c63c7d94 [Rules] Remove Guild Bank Zone ID Rule (#3156)
# notes
- This rule is useless as guild bank zone ID is hard-coded into the client.
2023-03-28 21:58:58 -04:00
Aeadoin 27e0665aae [Bug Fix] Fix bot_raid_members.sql for MYSQL. (#3155) 2023-03-28 15:25:16 -04:00
Alex King ea2f431fce [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp (#3153)
* [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp

# Notes
- We were only sending `EVENT_DISCONNECT` on GM instant camps or linkdeads.

* Update client_process.cpp
2023-03-27 21:45:02 -04:00
Aeadoin 8bdcf7cb94 [Crash] Add Checks for out of bounds & dereferencing nullptrs (#3151)
* [Crash] Add Checks for out of bounds/nullptr dereferences

* formatting

* formatting

* formatting

* Update bot.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2023-03-27 21:43:46 -04:00
Aeadoin 87cb74b851 [Release] 22.8.1 (#3152) 2023-03-27 17:55:48 -04:00
Alex King 26c267db1b [Cleanup] "equipped" not "equiped", "dual" not "duel". (#3149)
* [Cleanup] "equipped" not "equiped", "dual" not "duel".

# Notes
- These are spelled incorrectly.

* Update spdat.h

* Formatting further.

* Update api_service.cpp
2023-03-27 17:55:37 -04:00
Aeadoin 99f8e6cef5 [Bug Fix] Fix for NPCs having spells interrupted. (#3150) 2023-03-27 16:57:08 -04:00
622 changed files with 21339 additions and 59462 deletions
+535
View File
@@ -1,3 +1,538 @@
## [22.16.0] - 06/27/2023
### Code
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
* Delete common/worldconn.cpp ([#3436](https://github.com/EQEmu/Server/pull/3436)) @Kinglykrab 2023-06-24
* Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h ([#3449](https://github.com/EQEmu/Server/pull/3449)) @Kinglykrab 2023-06-24
* Remove GetACAvoid() from zone/merc.h ([#3447](https://github.com/EQEmu/Server/pull/3447)) @Kinglykrab 2023-06-25
* Remove GetACMit() from zone/merc.h ([#3446](https://github.com/EQEmu/Server/pull/3446)) @Kinglykrab 2023-06-24
* Remove _ClearWaypints() from zone/npc.h ([#3445](https://github.com/EQEmu/Server/pull/3445)) @Kinglykrab 2023-06-24
* Remove acmod() from zone/merc.h ([#3448](https://github.com/EQEmu/Server/pull/3448)) @Kinglykrab 2023-06-24
* Remove command_packetprofile from zone/command.h ([#3432](https://github.com/EQEmu/Server/pull/3432)) @Kinglykrab 2023-06-24
* Remove command_showpetspell in zone/command.h ([#3430](https://github.com/EQEmu/Server/pull/3430)) @Kinglykrab 2023-06-24
* Remove command_unlock from zone/command.h ([#3431](https://github.com/EQEmu/Server/pull/3431)) @Kinglykrab 2023-06-24
### Commands
* Add #finddeity Command ([#3435](https://github.com/EQEmu/Server/pull/3435)) @Kinglykrab 2023-06-26
* Add #findlanguage Command ([#3434](https://github.com/EQEmu/Server/pull/3434)) @Kinglykrab 2023-06-25
* Add #showspells Command ([#3429](https://github.com/EQEmu/Server/pull/3429)) @Kinglykrab 2023-06-24
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
* Cleanup #showbuffs Command ([#3439](https://github.com/EQEmu/Server/pull/3439)) @Kinglykrab 2023-06-26
* Cleanup #shownpcgloballoot and #showzonegloballoot Commands ([#3440](https://github.com/EQEmu/Server/pull/3440)) @Kinglykrab 2023-06-24
* Cleanup #viewcurrencies Command ([#3441](https://github.com/EQEmu/Server/pull/3441)) @Kinglykrab 2023-06-25
* Consolidate #findX commands to a singular #find Command ([#3452](https://github.com/EQEmu/Server/pull/3452)) @Kinglykrab 2023-06-28
* Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop ([#3433](https://github.com/EQEmu/Server/pull/3433)) @Kinglykrab 2023-06-24
* Delete #showbonusstats Command ([#3437](https://github.com/EQEmu/Server/pull/3437)) @Kinglykrab 2023-06-24
* Delete #spellinfo Command ([#3438](https://github.com/EQEmu/Server/pull/3438)) @Kinglykrab 2023-06-24
### Database
* Fix database version checking edge case issue ([#3428](https://github.com/EQEmu/Server/pull/3428)) @Akkadius 2023-06-22
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
### Fixes
* Fix NPC Item Stat Bonuses ([#3444](https://github.com/EQEmu/Server/pull/3444)) @Kinglykrab 2023-06-26
* Fix error in 023_01_21_bots_raid_members.sql ([#3453](https://github.com/EQEmu/Server/pull/3453)) @mibastian 2023-06-28
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
* Merchant Open Flag set only for regular Merchants ([#3454](https://github.com/EQEmu/Server/pull/3454)) @Kinglykrab 2023-06-27
### Readme
* Update new location of database updates ([#3424](https://github.com/EQEmu/Server/pull/3424)) @joligario 2023-06-19
### Rules
* Add ClientPetsUserOwnerNameInLastName rule ([#3442](https://github.com/EQEmu/Server/pull/3442)) @Kinglykrab 2023-06-25
## [22.15.3] - 06/19/2023
### Fixes
* Fix improper condition in Water LOS checks ([#3426](https://github.com/EQEmu/Server/pull/3426)) @Kinglykrab 2023-06-19
## [22.15.2] - 06/19/2023
### Database
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
## [22.15.1] - 06/19/2023
### Schema
* Add `chatchannel_reserved_names` table to `database_schema.h`
## [22.15.0] - 06/19/2023
### Code
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
### Commands
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
### Database
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
### Fixes
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
## [22.14.1] - 06/18/2023
### Backups
* Move world database:dump to use MySQL credentials file ([#3410](https://github.com/EQEmu/Server/pull/3410)) @Akkadius 2023-06-17
### Binaries
* Add support for static linking (portable) binaries ([#3417](https://github.com/EQEmu/Server/pull/3417)) @Akkadius 2023-06-18
### CI
* Build static linux binaries ([#3419](https://github.com/EQEmu/Server/pull/3419)) @Akkadius 2023-06-18
### CLI
* Add `bots:enable` and `bots:disable` commands ([#3415](https://github.com/EQEmu/Server/pull/3415)) @Akkadius 2023-06-17
* Add `mercs:enable` and `mercs:disable` commands ([#3416](https://github.com/EQEmu/Server/pull/3416)) @Akkadius 2023-06-18
* Console menu validation fixes ([#3413](https://github.com/EQEmu/Server/pull/3413)) @Akkadius 2023-06-17
### Database
* Add query multi statement execution support ([#3414](https://github.com/EQEmu/Server/pull/3414)) @Akkadius 2023-06-17
### Feature
* Add Water Line of Sight Checks ([#3408](https://github.com/EQEmu/Server/pull/3408)) @nytmyr 2023-06-17
### Logging
* Logging improvements, console silencing, terminal coloring ([#3412](https://github.com/EQEmu/Server/pull/3412)) @Akkadius 2023-06-17
### Quest API
* Add convert_money_to_string() to Perl/Lua ([#3418](https://github.com/EQEmu/Server/pull/3418)) @Kinglykrab 2023-06-18
### Strings
* Add more test cases for string utils ([#3411](https://github.com/EQEmu/Server/pull/3411)) @Akkadius 2023-06-17
### Targeting
* Fix bug when using /tar on invalid target ([#3407](https://github.com/EQEmu/Server/pull/3407)) @noudess 2023-06-17
### Telnet
* Add cross zone/world wide cast and move functionality to Telnet ([#3409](https://github.com/EQEmu/Server/pull/3409)) @Kinglykrab 2023-06-17
## [22.13.1] - 06/13/2023
### Targeting
* Revert #3383 ([#3405](https://github.com/EQEmu/Server/pull/3405)) @noudess 2023-06-13
## [22.13.0] - 06/12/2023
### Code
* Add GMFind_Struct to packet structures ([#3402](https://github.com/EQEmu/Server/pull/3402)) @Kinglykrab 2023-06-12
* Remove CHECK_LOS_STEP from zone/common.h ([#3398](https://github.com/EQEmu/Server/pull/3398)) @Kinglykrab 2023-06-12
* Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h ([#3384](https://github.com/EQEmu/Server/pull/3384)) @Kinglykrab 2023-06-12
* Remove CountTempPets() from zone/entity.cpp and zone/entity.h ([#3390](https://github.com/EQEmu/Server/pull/3390)) @Kinglykrab 2023-06-12
* Remove Evade() from zone/entity.cpp and zone/entity.h ([#3394](https://github.com/EQEmu/Server/pull/3394)) @Kinglykrab 2023-06-12
* Remove GateAllClients() from zone/entity.cpp and zone/entity.h ([#3391](https://github.com/EQEmu/Server/pull/3391)) @Kinglykrab 2023-06-12
* Remove GetClient(ip, port) from zone/entity.h ([#3386](https://github.com/EQEmu/Server/pull/3386)) @Kinglykrab 2023-06-12
* Remove GetClientCount() from zone/entity.cpp and zone/entity.h ([#3392](https://github.com/EQEmu/Server/pull/3392)) @Kinglykrab 2023-06-12
* Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h ([#3387](https://github.com/EQEmu/Server/pull/3387)) @Kinglykrab 2023-06-12
* Remove InteractiveChat() and TakenAction() from zone/npc.h ([#3382](https://github.com/EQEmu/Server/pull/3382)) @Kinglykrab 2023-06-12
* Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h ([#3393](https://github.com/EQEmu/Server/pull/3393)) @Kinglykrab 2023-06-12
* Remove NPC::AddCash() from npc.cpp/npc.h ([#3380](https://github.com/EQEmu/Server/pull/3380)) @Kinglykrab 2023-06-09
* Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h ([#3389](https://github.com/EQEmu/Server/pull/3389)) @Kinglykrab 2023-06-12
* Remove SPECIALIZE_MANA_REDUCE from zone/common.h ([#3400](https://github.com/EQEmu/Server/pull/3400)) @Kinglykrab 2023-06-12
* Remove SendAATimer() from zone/entity.h ([#3388](https://github.com/EQEmu/Server/pull/3388)) @Kinglykrab 2023-06-12
* Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h ([#3395](https://github.com/EQEmu/Server/pull/3395)) @Kinglykrab 2023-06-12
* Remove _BECOMENPCPET() and _NPCPET() from zone/common.h ([#3399](https://github.com/EQEmu/Server/pull/3399)) @Kinglykrab 2023-06-12
* Remove pDBAsyncWorkID from zone/entity.h ([#3385](https://github.com/EQEmu/Server/pull/3385)) @Kinglykrab 2023-06-12
* Remove struct DynamicZoneSafeReturn from zone/entity.h ([#3396](https://github.com/EQEmu/Server/pull/3396)) @Kinglykrab 2023-06-12
* Remove struct TradeEntity from zone/common.h ([#3397](https://github.com/EQEmu/Server/pull/3397)) @Kinglykrab 2023-06-12
### Commands
* Assign #opcode to a #reload alias ([#3401](https://github.com/EQEmu/Server/pull/3401)) @Kinglykrab 2023-06-12
### Illusions
* RandomizeFeatures and SetGender were killing db texture ([#3376](https://github.com/EQEmu/Server/pull/3376)) @noudess 2023-06-06
### Logging
* Fixed statements that logged incorrect data ([#3381](https://github.com/EQEmu/Server/pull/3381)) @noudess 2023-06-07
### Quest API
* Add GetEXPForLevel() to Perl/Lua ([#3403](https://github.com/EQEmu/Server/pull/3403)) @Kinglykrab 2023-06-12
* Add SendChannelMessage() to Perl/Lua ([#3378](https://github.com/EQEmu/Server/pull/3378)) @Kinglykrab 2023-06-04
* Add several spell methods to Perl/Lua ([#3379](https://github.com/EQEmu/Server/pull/3379)) @Kinglykrab 2023-06-12
### Targeting
* /tar <bad target> should not untarget existing target ([#3383](https://github.com/EQEmu/Server/pull/3383)) @noudess 2023-06-12
## [22.12.0] - 05/29/2023
### Code
* Cleanup #setskill and #setskillall Commands ([#3367](https://github.com/EQEmu/Server/pull/3367)) @Kinglykrab 2023-05-25
* Delete message.h ([#3348](https://github.com/EQEmu/Server/pull/3348)) @Kinglykrab 2023-05-17
* Fix #spawn command NPCs having 0 health ([#3371](https://github.com/EQEmu/Server/pull/3371)) @Kinglykrab 2023-05-21
* Remove CalcPetHp from spdat.h ([#3364](https://github.com/EQEmu/Server/pull/3364)) @Kinglykrab 2023-05-25
* Remove CountNPC() and QueueManaged() from entity.cpp/entity.h ([#3346](https://github.com/EQEmu/Server/pull/3346)) @Kinglykrab 2023-05-17
* Remove DumpMerchantList() from zone.cpp/zone.h ([#3343](https://github.com/EQEmu/Server/pull/3343)) @Kinglykrab 2023-05-17
* Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h ([#3358](https://github.com/EQEmu/Server/pull/3358)) @Kinglykrab 2023-05-17
* Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h ([#3353](https://github.com/EQEmu/Server/pull/3353)) @Kinglykrab 2023-05-17
* Remove GetMaxRank() from aa_ability.cpp/aa_ability.h ([#3347](https://github.com/EQEmu/Server/pull/3347)) @Kinglykrab 2023-05-25
* Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h ([#3352](https://github.com/EQEmu/Server/pull/3352)) @Kinglykrab 2023-05-17
* Remove IsRaid() from raids.h ([#3361](https://github.com/EQEmu/Server/pull/3361)) @Kinglykrab 2023-05-25
* Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h ([#3344](https://github.com/EQEmu/Server/pull/3344)) @Kinglykrab 2023-05-25
* Remove SetGraveyard() from zone.cpp/zone.h ([#3354](https://github.com/EQEmu/Server/pull/3354)) @Kinglykrab 2023-05-17
* Remove SetTradeCash() from trading.cpp/common.h ([#3356](https://github.com/EQEmu/Server/pull/3356)) @Kinglykrab 2023-05-17
* Remove TraderUpdate() from trading.cpp/client.h ([#3357](https://github.com/EQEmu/Server/pull/3357)) @Kinglykrab 2023-05-17
* Remove TypeToSkill() from tradeskills.cpp/object.h ([#3355](https://github.com/EQEmu/Server/pull/3355)) @Kinglykrab 2023-05-17
* Remove Z_AGGRO from spdat.h ([#3365](https://github.com/EQEmu/Server/pull/3365)) @Kinglykrab 2023-05-25
* Remove numMembers from raids.h ([#3362](https://github.com/EQEmu/Server/pull/3362)) @Kinglykrab 2023-05-25
* Set GetAugmentType() to int again ([#3335](https://github.com/EQEmu/Server/pull/3335)) @Kinglykrab 2023-05-08
### Commands
* Add #findcurrency Command ([#3368](https://github.com/EQEmu/Server/pull/3368)) @Kinglykrab 2023-05-25
* Add entity variable command ([#3345](https://github.com/EQEmu/Server/pull/3345)) @Kinglykrab 2023-05-25
* Cleanup #setanim ([#3350](https://github.com/EQEmu/Server/pull/3350)) @Kinglykrab 2023-05-25
### Feature
* Intoxication setter/getter for source, getter for Perl/Lua ([#3330](https://github.com/EQEmu/Server/pull/3330)) @JasXSL 2023-05-03
### Fixes
* #augmentitem bypasses augment restrictions ([#3332](https://github.com/EQEmu/Server/pull/3332)) @Kinglykrab 2023-05-07
* Fix Heroic INT/WIS Bonuses ([#3341](https://github.com/EQEmu/Server/pull/3341)) @RekkasGit 2023-05-15
* Fix duplicate messages in #npcedit ([#3372](https://github.com/EQEmu/Server/pull/3372)) @Kinglykrab 2023-05-21
* Fix issue with Group Pointers/Member roles ([#3374](https://github.com/EQEmu/Server/pull/3374)) @Aeadoin 2023-05-25
* Fix mob item bonus calc ([#3334](https://github.com/EQEmu/Server/pull/3334)) @Akkadius 2023-05-07
* Fix typos in #zheader ([#3370](https://github.com/EQEmu/Server/pull/3370)) @Kinglykrab 2023-05-21
* Mob scaling issue with min dmg set to zero while max dmg is not ([#3351](https://github.com/EQEmu/Server/pull/3351)) @RekkasGit 2023-05-20
* NPC Armor Upgrade to a slot not handled correctly ([#3366](https://github.com/EQEmu/Server/pull/3366)) @noudess 2023-05-20
* ReloadQuests() on Zone::Init() to avoid cached global quests/plugins ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Kinglykrab 2023-05-07
* Revert " ReloadQuests() on Zone::Init() to avoid cached global quests/plugins " ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Akkadius 2023-05-08
### Memory Leak
* Fix large memory leak introduced in CalcItemBonuses ([#3331](https://github.com/EQEmu/Server/pull/3331)) @Akkadius 2023-05-07
### Messages
* Remove duplicate heal message for healing yourself ([#3329](https://github.com/EQEmu/Server/pull/3329)) @noudess 2023-05-03
### Performance
* Character bind is now bulk saved ([#3338](https://github.com/EQEmu/Server/pull/3338)) @Akkadius 2023-05-09
* Character buffs now save in bulk ([#3336](https://github.com/EQEmu/Server/pull/3336)) @Akkadius 2023-05-09
* Character pet bulk saving ([#3337](https://github.com/EQEmu/Server/pull/3337)) @Akkadius 2023-05-09
* Character tribute is now bulk saved ([#3340](https://github.com/EQEmu/Server/pull/3340)) @Kinglykrab 2023-05-25
* Mail key is now cached during player load ([#3339](https://github.com/EQEmu/Server/pull/3339)) @Akkadius 2023-05-09
### Pets
* Fix saving inconsistencies with pets ([#3375](https://github.com/EQEmu/Server/pull/3375)) @Akkadius 2023-05-25
### Quest API
* Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua ([#3359](https://github.com/EQEmu/Server/pull/3359)) @RekkasGit 2023-05-16
* Add GetPet() to Perl ([#3309](https://github.com/EQEmu/Server/pull/3309)) @Kinglykrab 2023-05-08
* Add Memorize and Scribe Spell Events to Perl/Lua ([#3363](https://github.com/EQEmu/Server/pull/3363)) @Kinglykrab 2023-05-25
* Add zone data methods to Perl/Lua ([#3342](https://github.com/EQEmu/Server/pull/3342)) @Kinglykrab 2023-05-24
* Cleanup The Darkened Sea Quest Methods Names ([#3369](https://github.com/EQEmu/Server/pull/3369)) @Kinglykrab 2023-05-21
### Rules
* Add World:MaximumQuestErrors Rule ([#3349](https://github.com/EQEmu/Server/pull/3349)) @Kinglykrab 2023-05-21
* ResurrectionEffectBlock to prevent/allow/move buffs. ([#3288](https://github.com/EQEmu/Server/pull/3288)) @nytmyr 2023-05-08
## [22.11.0] - 04/29/2023
### Code
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
### Crash
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
### Discord
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
### Fixes
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
### Maps
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
### Messages
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
### Quest API
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
## [22.10.0] - 04/22/2023
### Backups
* Fix database dump error reporting ([#3175](https://github.com/EQEmu/Server/pull/3175)) @Akkadius 2023-04-04
### Bots
* Cleanup GetBotTables() ([#3270](https://github.com/EQEmu/Server/pull/3270)) @Aeadoin 2023-04-06
### Cleanuo
* Only define row if we have results in Database::GetCharacterID() ([#3199](https://github.com/EQEmu/Server/pull/3199)) @Kinglykrab 2023-04-05
### Code
* Add missing breaks and returns in bonuses.cpp ([#3231](https://github.com/EQEmu/Server/pull/3231)) @Kinglykrab 2023-04-05
* Breaks in wrong spot in cases in spell_effects.cpp ([#3297](https://github.com/EQEmu/Server/pull/3297)) @Kinglykrab 2023-04-22
* Cleanup always true/false statements in shareddb.cpp ([#3189](https://github.com/EQEmu/Server/pull/3189)) @Kinglykrab 2023-04-05
* Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h ([#3209](https://github.com/EQEmu/Server/pull/3209)) @Kinglykrab 2023-04-05
* Cleanup discord.cpp and discord_manager.cpp ([#3205](https://github.com/EQEmu/Server/pull/3205)) @Kinglykrab 2023-04-05
* Cleanup duplicate conditions in negate bonuses in bonuses.cpp ([#3226](https://github.com/EQEmu/Server/pull/3226)) @Kinglykrab 2023-04-05
* Cleanup item_instance.cpp always true statements and reassigning of same values ([#3187](https://github.com/EQEmu/Server/pull/3187)) @Kinglykrab 2023-04-05
* Cleanup macros in features.h ([#3185](https://github.com/EQEmu/Server/pull/3185)) @Kinglykrab 2023-04-05
* Cleanup string -> char* -> string conversions in bot_command.cpp ([#3252](https://github.com/EQEmu/Server/pull/3252)) @Kinglykrab 2023-04-05
* Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() ([#3266](https://github.com/EQEmu/Server/pull/3266)) @Kinglykrab 2023-04-05
* Cleanup zone/zoning.cpp ([#3289](https://github.com/EQEmu/Server/pull/3289)) @Kinglykrab 2023-04-14
* Combine similar cases in Client::InitInnates() ([#3260](https://github.com/EQEmu/Server/pull/3260)) @Kinglykrab 2023-04-05
* Convert equipable_slot_list to std::vector from std::list in bot_command.cpp ([#3253](https://github.com/EQEmu/Server/pull/3253)) @Kinglykrab 2023-04-05
* Delete embxs.cpp/embxs.h ([#3284](https://github.com/EQEmu/Server/pull/3284)) @Kinglykrab 2023-04-14
* Delete unused strings in bot_command.cpp ([#3251](https://github.com/EQEmu/Server/pull/3251)) @Kinglykrab 2023-04-05
* Fix GetLastName() length check in Client::SendWindow() ([#3263](https://github.com/EQEmu/Server/pull/3263)) @Kinglykrab 2023-04-05
* Fix always false conditions in Client::IncStats() ([#3256](https://github.com/EQEmu/Server/pull/3256)) @Kinglykrab 2023-04-05
* Fix check for !this in Client::SendHPUpdateMarquee() ([#3257](https://github.com/EQEmu/Server/pull/3257)) @Kinglykrab 2023-04-05
* Fix filter condition in attack.cpp ([#3218](https://github.com/EQEmu/Server/pull/3218)) @Kinglykrab 2023-04-05
* Fix ornamentation augment icons in inspect requests ([#3264](https://github.com/EQEmu/Server/pull/3264)) @Kinglykrab 2023-04-05
* Fix possible nullptr inst in GetSharedBank() ([#3190](https://github.com/EQEmu/Server/pull/3190)) @Kinglykrab 2023-04-08
* Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() ([#3255](https://github.com/EQEmu/Server/pull/3255)) @Kinglykrab 2023-04-05
* Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member ([#3192](https://github.com/EQEmu/Server/pull/3192)) @Kinglykrab 2023-04-05
* Fix skill_used being used as boolean in Mob::CommonDamage() ([#3220](https://github.com/EQEmu/Server/pull/3220)) @Kinglykrab 2023-04-05
* Identical conditions right beside each other in aa.cpp ([#3213](https://github.com/EQEmu/Server/pull/3213)) @Kinglykrab 2023-04-05
* Move unreachable code in ApplySpellsBonuses() ([#3229](https://github.com/EQEmu/Server/pull/3229)) @Kinglykrab 2023-04-05
* Move variable definition to more relevant scope in DatabaseDumpService::Dump() ([#3200](https://github.com/EQEmu/Server/pull/3200)) @Kinglykrab 2023-04-05
* Multiple cases with same outcome in GetDiscordPayloadFromEvent() ([#3184](https://github.com/EQEmu/Server/pull/3184)) @Kinglykrab 2023-04-05
* Remove ExportVarComplex() from embparser.cpp/embparser.h ([#3282](https://github.com/EQEmu/Server/pull/3282)) @Kinglykrab 2023-04-14
* Remove GetQGlobal() from qglobals.cpp/qglobals.h ([#3285](https://github.com/EQEmu/Server/pull/3285)) @Kinglykrab 2023-04-14
* Remove IsFullHP from mob.cpp/mob.h ([#3277](https://github.com/EQEmu/Server/pull/3277)) @Kinglykrab 2023-04-14
* Remove IsMeleeDmg() from skills.cpp/skills.h ([#3279](https://github.com/EQEmu/Server/pull/3279)) @Kinglykrab 2023-04-14
* Remove _GetMovementSpeed() from mob.h ([#3276](https://github.com/EQEmu/Server/pull/3276)) @Kinglykrab 2023-04-14
* Remove always true condition in Strings::Commify() ([#3193](https://github.com/EQEmu/Server/pull/3193)) @Kinglykrab 2023-04-05
* Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() ([#3258](https://github.com/EQEmu/Server/pull/3258)) @Kinglykrab 2023-04-05
* Remove always true statement in say_link.cpp ([#3188](https://github.com/EQEmu/Server/pull/3188)) @Kinglykrab 2023-04-05
* Remove always true statements in task_client_state.cpp ([#3292](https://github.com/EQEmu/Server/pull/3292)) @Kinglykrab 2023-04-14
* Remove always true/false conditions from bot.cpp ([#3237](https://github.com/EQEmu/Server/pull/3237)) @Kinglykrab 2023-04-05
* Remove bool return from GetSharedPlatinum() ([#3191](https://github.com/EQEmu/Server/pull/3191)) @Kinglykrab 2023-04-05
* Remove extra assignment of current_endurance in Client ctor ([#3261](https://github.com/EQEmu/Server/pull/3261)) @Kinglykrab 2023-04-05
* Remove extraneous check for NegateAttacks in SE_NegateAttacks ([#3228](https://github.com/EQEmu/Server/pull/3228)) @Kinglykrab 2023-04-05
* Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() ([#3227](https://github.com/EQEmu/Server/pull/3227)) @Kinglykrab 2023-04-05
* Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h ([#3283](https://github.com/EQEmu/Server/pull/3283)) @Kinglykrab 2023-04-15
* Remove item_timers from questmgr.cpp/questmgr.h ([#3286](https://github.com/EQEmu/Server/pull/3286)) @Kinglykrab 2023-04-14
* Remove pendinggroup from mob.h ([#3278](https://github.com/EQEmu/Server/pull/3278)) @Kinglykrab 2023-04-14
* Remove position_same_update_count from client.cpp/client.h ([#3280](https://github.com/EQEmu/Server/pull/3280)) @Kinglykrab 2023-04-14
* Remove unnecessary break in while loop in Mob::AddToHateList() ([#3219](https://github.com/EQEmu/Server/pull/3219)) @Kinglykrab 2023-04-05
* Remove unnecessary check for IsStackable() in DeleteItem() ([#3186](https://github.com/EQEmu/Server/pull/3186)) @Kinglykrab 2023-04-05
* Remove unnecessary condition and cleanup variable name in tasks.cpp ([#3293](https://github.com/EQEmu/Server/pull/3293)) @Kinglykrab 2023-04-14
* Remove unnecessary conditions in Client::Consume() ([#3265](https://github.com/EQEmu/Server/pull/3265)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::FilteredMessageCheck() ([#3262](https://github.com/EQEmu/Server/pull/3262)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::SendFactionMessage() ([#3267](https://github.com/EQEmu/Server/pull/3267)) @Kinglykrab 2023-04-05
* Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() ([#3233](https://github.com/EQEmu/Server/pull/3233)) @Kinglykrab 2023-04-05
* Remove unused SetConfigFile in common/eqemu_config.h ([#3208](https://github.com/EQEmu/Server/pull/3208)) @Kinglykrab 2023-04-05
* Remove unused code in eq_packet.cpp/eq_packet.h ([#3183](https://github.com/EQEmu/Server/pull/3183)) @Kinglykrab 2023-04-05
* Remove unused ctor and use default dtor in xtargetautohaters.h ([#3290](https://github.com/EQEmu/Server/pull/3290)) @Kinglykrab 2023-04-14
* Remove unused macros in common/types.h ([#3194](https://github.com/EQEmu/Server/pull/3194)) @Kinglykrab 2023-04-05
* Remove unused variable in Database::CopyCharacter() ([#3197](https://github.com/EQEmu/Server/pull/3197)) @Kinglykrab 2023-04-05
* Remove unused variables and use reference in task_manager.cpp ([#3291](https://github.com/EQEmu/Server/pull/3291)) @Kinglykrab 2023-04-14
* SE_AttackSpeed3 effect_value is always less than 0 ([#3222](https://github.com/EQEmu/Server/pull/3222)) @Kinglykrab 2023-04-05
* SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp ([#3223](https://github.com/EQEmu/Server/pull/3223)) @Kinglykrab 2023-04-05
* Set bonuses to use spell ID instead of boolean ([#3230](https://github.com/EQEmu/Server/pull/3230)) @Kinglykrab 2023-04-05
* Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() ([#3201](https://github.com/EQEmu/Server/pull/3201)) @Kinglykrab 2023-04-05
* Use .clear() instead of setting string to empty in eqemu_command_handler.cpp ([#3195](https://github.com/EQEmu/Server/pull/3195)) @Kinglykrab 2023-04-05
* Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() ([#3259](https://github.com/EQEmu/Server/pull/3259)) @Kinglykrab 2023-04-05
* Use constant reference and check for empty string properly in dbcore.cpp ([#3203](https://github.com/EQEmu/Server/pull/3203)) @Kinglykrab 2023-04-05
* Use default ctor instead of an empty ctor. ([#3206](https://github.com/EQEmu/Server/pull/3206)) @Kinglykrab 2023-04-05
* Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h ([#3210](https://github.com/EQEmu/Server/pull/3210)) @Kinglykrab 2023-04-05
* Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp ([#3254](https://github.com/EQEmu/Server/pull/3254)) @Kinglykrab 2023-04-05
* Use variable for character instead of a loop ([#3268](https://github.com/EQEmu/Server/pull/3268)) @Kinglykrab 2023-04-05
* Utilize .empty() instead of checking for an empty string in Database::ReserveName() ([#3198](https://github.com/EQEmu/Server/pull/3198)) @Kinglykrab 2023-04-05
* Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() ([#3275](https://github.com/EQEmu/Server/pull/3275)) @Kinglykrab 2023-04-15
* Validate for nullptrs in bot.cpp ([#3232](https://github.com/EQEmu/Server/pull/3232)) @Kinglykrab 2023-04-05
* other is always defined in these cases in attack.cpp ([#3217](https://github.com/EQEmu/Server/pull/3217)) @Kinglykrab 2023-04-05
* results variable is assigned but never used in SaveCharacterCreate() ([#3180](https://github.com/EQEmu/Server/pull/3180)) @Kinglykrab 2023-04-05
### Crash
* Add additional raid integrity checks on Bot Spawn. ([#3295](https://github.com/EQEmu/Server/pull/3295)) @Aeadoin 2023-04-16
* Fix crash with uninitialized item instance, and Bot timeout ([#3296](https://github.com/EQEmu/Server/pull/3296)) @Aeadoin 2023-04-15
* Resolve crash due to uninitialized pointer. ([#3271](https://github.com/EQEmu/Server/pull/3271)) @Aeadoin 2023-04-08
### Feature
* Make ornamentations work with any augment type ([#3281](https://github.com/EQEmu/Server/pull/3281)) @Kinglykrab 2023-04-16
### Fixes
* Camping was causing player to leave raid, causing unexpected behavior ([#3299](https://github.com/EQEmu/Server/pull/3299)) @Aeadoin 2023-04-22
* Resolve loading of inventory ([#3272](https://github.com/EQEmu/Server/pull/3272)) @Aeadoin 2023-04-08
### Quest API
* Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua ([#3274](https://github.com/EQEmu/Server/pull/3274)) @Kinglykrab 2023-04-09
* Add GetBuffSpellIDs() to Perl/Lua ([#3273](https://github.com/EQEmu/Server/pull/3273)) @Kinglykrab 2023-04-09
* Fix LDoN Methods in Perl/Lua ([#3287](https://github.com/EQEmu/Server/pull/3287)) @Kinglykrab 2023-04-10
### Rules
* Optional summoning when already in melee range ([#3204](https://github.com/EQEmu/Server/pull/3204)) @trentdm 2023-04-08
### Telnet
* Telnet encoding fix ([#3269](https://github.com/EQEmu/Server/pull/3269)) @Akkadius 2023-04-05
## [22.9.1] - 04/03/2023
### Code
* Add client pointer validation to Zone::GetClosestZonePoint() ([#3173](https://github.com/EQEmu/Server/pull/3173)) @Kinglykrab 2023-04-01
* Change level to bot_level in Bot::DoClassAttacks() to not overlap member variable ([#3239](https://github.com/EQEmu/Server/pull/3239)) @Kinglykrab 2023-04-03
* Cleanup unnecessary string -> char* -> string conversions in eqemu_config.cpp ([#3207](https://github.com/EQEmu/Server/pull/3207)) @Kinglykrab 2023-04-03
* Cleanup uses of insert/push_back when a temp object is used. ([#3170](https://github.com/EQEmu/Server/pull/3170)) @Aeadoin 2023-04-03
* Cleanup variable names in Bot::AddSpellToBotList() ([#3248](https://github.com/EQEmu/Server/pull/3248)) @Kinglykrab 2023-04-03
* Explicitly cast to float for more precision in Bot::GenerateBastHitPoints() ([#3238](https://github.com/EQEmu/Server/pull/3238)) @Kinglykrab 2023-04-03
* Fix SEResist array settings duplicate code ([#3225](https://github.com/EQEmu/Server/pull/3225)) @Kinglykrab 2023-04-03
* Fix loop and code duplication for SE_ProcOnKillShot ([#3224](https://github.com/EQEmu/Server/pull/3224)) @Kinglykrab 2023-04-03
* Fix possible dereferencing of invalid iterator in constants ([#3181](https://github.com/EQEmu/Server/pull/3181)) @Kinglykrab 2023-04-03
* Fix typo where itembonuses should have been used instead of spellbonuses ([#3221](https://github.com/EQEmu/Server/pull/3221)) @Kinglykrab 2023-04-03
* Further bot.cpp nullptr checks ([#3240](https://github.com/EQEmu/Server/pull/3240)) @Kinglykrab 2023-04-03
* Move cases in Bot::AICastSpell() ([#3247](https://github.com/EQEmu/Server/pull/3247)) @Kinglykrab 2023-04-03
* Multiple cases same outcome and set skip variable to same value ([#3216](https://github.com/EQEmu/Server/pull/3216)) @Kinglykrab 2023-04-03
* Multiple cases with same outcome in GetGMSayColorFromCategory() ([#3182](https://github.com/EQEmu/Server/pull/3182)) @Kinglykrab 2023-04-03
* Remove extraneous loottable_id setting in WakeTheDead in aa.cpp ([#3215](https://github.com/EQEmu/Server/pull/3215)) @Kinglykrab 2023-04-03
* Remove possible dereferenced nullptrs in bot.cpp ([#3241](https://github.com/EQEmu/Server/pull/3241)) @Kinglykrab 2023-04-03
* Remove unnecessary >= 0 checks for procs in botspellsai.cpp ([#3242](https://github.com/EQEmu/Server/pull/3242)) @Kinglykrab 2023-04-03
* Remove unnecessary botCaster check in Bot::GetDebuffBotSpell() ([#3246](https://github.com/EQEmu/Server/pull/3246)) @Kinglykrab 2023-04-03
* Remove unnecessary group validation in Bot::Death() ([#3235](https://github.com/EQEmu/Server/pull/3235)) @Kinglykrab 2023-04-03
* Remove unnecessary hpr checks in Bot::BotCastHeal() ([#3245](https://github.com/EQEmu/Server/pull/3245)) @Kinglykrab 2023-04-03
* Remove unnecessary setting of spell_type_index in Bot::GetChanceToCastBySpellType() ([#3243](https://github.com/EQEmu/Server/pull/3243)) @Kinglykrab 2023-04-03
* Remove unnecessary skill_to_use check in Bot::DoClassAttacks() ([#3236](https://github.com/EQEmu/Server/pull/3236)) @Kinglykrab 2023-04-03
* Remove unnecessary spell_list validation check in botspellsai.cpp ([#3244](https://github.com/EQEmu/Server/pull/3244)) @Kinglykrab 2023-04-03
* Remove unnecessary validation check in Zone::ClearBlockedSpells() ([#3172](https://github.com/EQEmu/Server/pull/3172)) @Kinglykrab 2023-04-01
* Remove unused Includes under zone files ([#3162](https://github.com/EQEmu/Server/pull/3162)) @Aeadoin 2023-04-02
* Remove unused query variable in Database::DeleteInstance() ([#3202](https://github.com/EQEmu/Server/pull/3202)) @Kinglykrab 2023-04-03
* Unconditional return in for loop in GetRaidByCharID() ([#3179](https://github.com/EQEmu/Server/pull/3179)) @Kinglykrab 2023-04-03
* Use a constant reference for content_flags in SetContentFlags() ([#3196](https://github.com/EQEmu/Server/pull/3196)) @Kinglykrab 2023-04-03
* Wake The Dead argument was named the same as a member variable in Mob ([#3214](https://github.com/EQEmu/Server/pull/3214)) @Kinglykrab 2023-04-03
* gid is assigned 2 values simultaneously in bot.cpp ([#3234](https://github.com/EQEmu/Server/pull/3234)) @Kinglykrab 2023-04-03
* summon_count > MAX_SWARM_PETS is always false in aa.cpp ([#3212](https://github.com/EQEmu/Server/pull/3212)) @Kinglykrab 2023-04-03
### Fixes
* Correct Forward Declaration compilation warning ([#3176](https://github.com/EQEmu/Server/pull/3176)) @Aeadoin 2023-04-02
* Fix issue with Bot Raid invites not working. ([#3249](https://github.com/EQEmu/Server/pull/3249)) @Aeadoin 2023-04-03
### Performance
* Change to use Pass by reference where valid. ([#3163](https://github.com/EQEmu/Server/pull/3163)) @Aeadoin 2023-04-02
## [22.9.0] - 04/01/2023
### Bots
* Remove Bot Groups Functionality ([#3165](https://github.com/EQEmu/Server/pull/3165)) @Aeadoin 2023-04-01
### Code
* Cleanup excessive type casting: string -> char * -> string ([#3169](https://github.com/EQEmu/Server/pull/3169)) @Aeadoin 2023-04-01
### Crash
* Add Checks for valid pointers or fix existing. ([#3164](https://github.com/EQEmu/Server/pull/3164)) @Aeadoin 2023-04-01
* Fix out of bound arrays, other potential crashes ([#3166](https://github.com/EQEmu/Server/pull/3166)) @Aeadoin 2023-04-01
### Fixes
* Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. ([#3171](https://github.com/EQEmu/Server/pull/3171)) @Aeadoin 2023-04-01
* Prevent VerifyGroup from setting OOZ membername to Null character. ([#3168](https://github.com/EQEmu/Server/pull/3168)) @Aeadoin 2023-04-01
### Quest API
* Add missing Luabind definitions to lua_general.cpp ([#3167](https://github.com/EQEmu/Server/pull/3167)) @Kinglykrab 2023-04-01
## [22.8.2] - 03/30/2023
### Code
* "equipped" not "equiped", "dual" not "duel". ([#3149](https://github.com/EQEmu/Server/pull/3149)) @Kinglykrab 2023-03-27
### Crash
* Add Checks for out of bounds & dereferencing nullptrs ([#3151](https://github.com/EQEmu/Server/pull/3151)) @Aeadoin 2023-03-28
### Fixes
* Check Rule "Bots Enabled" to prevent bot database calls on connect ([#3154](https://github.com/EQEmu/Server/pull/3154)) @Aeadoin 2023-03-29
* Correct logic checks for Bot rule AllowOwnerOptionAltCombat ([#3158](https://github.com/EQEmu/Server/pull/3158)) @Aeadoin 2023-03-30
* Fix an issue with EVENT_DISCONNECT not firing on regular /camp ([#3153](https://github.com/EQEmu/Server/pull/3153)) @Kinglykrab 2023-03-28
* Fix bot_raid_members.sql for MYSQL. ([#3155](https://github.com/EQEmu/Server/pull/3155)) @Aeadoin 2023-03-28
* Fix for OOZ Group updates when removing/inviting Bots ([#3159](https://github.com/EQEmu/Server/pull/3159)) @Aeadoin 2023-03-30
* Fix issues with Lua tables not starting at index 1 ([#3160](https://github.com/EQEmu/Server/pull/3160)) @Kinglykrab 2023-03-30
* Fix strcpy-param-overlap ([#3157](https://github.com/EQEmu/Server/pull/3157)) @Aeadoin 2023-03-29
### Rules
* Remove Guild Bank Zone ID Rule ([#3156](https://github.com/EQEmu/Server/pull/3156)) @Kinglykrab 2023-03-29
## [22.8.1] - 03/27/2023
### Fixes
* Fix for NPCs having spells interrupted. ([#3150](https://github.com/EQEmu/Server/pull/3150)) @Aeadoin 2023-03-27
## [22.8.0] - 03/25/2023
### Code
+13
View File
@@ -16,6 +16,15 @@ SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
IF (EQEMU_BUILD_STATIC)
SET(BUILD_SHARED_LIBS OFF)
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
MESSAGE(STATUS "Building with static linking")
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
ENDIF(EQEMU_BUILD_STATIC)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
@@ -307,6 +316,10 @@ ELSE()
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF()
IF (EQEMU_BUILD_STATIC)
SET(ZLIB_LIBRARY_LIBS libz.a)
ENDIF(EQEMU_BUILD_STATIC)
MESSAGE(STATUS "")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Usage *")
+6 -1
View File
@@ -15,6 +15,9 @@ SET(common_sources
database.cpp
database_conversions.cpp
database_instances.cpp
database/database_update_manifest.cpp
database/database_update_manifest_bots.cpp
database/database_update.cpp
dbcore.cpp
deity.cpp
dynamic_zone_base.cpp
@@ -506,6 +509,7 @@ SET(common_headers
data_verification.h
database.h
database_schema.h
database/database_update.h
dbcore.h
deity.h
discord/discord.h
@@ -666,7 +670,8 @@ SET(common_headers
StackWalker/StackWalker.h
util/memory_stream.h
util/directory.h
util/uuid.h)
util/uuid.h
)
SOURCE_GROUP(Event FILES
event/event_loop.h
+29
View File
@@ -630,6 +630,20 @@ bool IsINTCasterClass(uint8 class_id)
}
}
bool IsHeroicINTCasterClass(uint8 class_id)
{
switch (class_id) {
case NECROMANCER:
case WIZARD:
case MAGICIAN:
case ENCHANTER:
case SHADOWKNIGHT:
return true;
default:
return false;
}
}
bool IsWISCasterClass(uint8 class_id)
{
switch (class_id) {
@@ -642,6 +656,21 @@ bool IsWISCasterClass(uint8 class_id)
}
}
bool IsHeroicWISCasterClass(uint8 class_id)
{
switch (class_id) {
case CLERIC:
case DRUID:
case SHAMAN:
case PALADIN:
case BEASTLORD:
case RANGER:
return true;
default:
return false;
}
}
bool IsPlateClass(uint8 class_id)
{
switch (class_id) {
+2 -1
View File
@@ -140,7 +140,8 @@ bool IsHybridClass(uint8 class_id);
bool IsCasterClass(uint8 class_id);
bool IsINTCasterClass(uint8 class_id);
bool IsWISCasterClass(uint8 class_id);
bool IsHeroicINTCasterClass(uint8 class_id);
bool IsHeroicWISCasterClass(uint8 class_id);
bool IsPlateClass(uint8 class_id);
bool IsChainClass(uint8 class_id);
bool IsLeatherClass(uint8 class_id);
+2 -2
View File
@@ -77,7 +77,7 @@ namespace EQEmuCommand {
index++;
}
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
std::string arguments_string;
for (auto &arg : arguments) {
arguments_string += " " + arg;
@@ -160,7 +160,7 @@ namespace EQEmuCommand {
*/
std::string command_section;
for (auto &it: in_function_map) {
description = "";
description.clear();
(it.second)(argc, argv, cmd, description);
+1 -1
View File
@@ -120,7 +120,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
/**
* @param content_flags
*/
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
{
WorldContentService::content_flags = content_flags;
}
+1 -1
View File
@@ -167,7 +167,7 @@ public:
std::vector<std::string> GetContentFlagsDisabled();
bool IsContentFlagEnabled(const std::string& content_flag);
bool IsContentFlagDisabled(const std::string& content_flag);
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
void SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags);
void ReloadContentFlags();
WorldContentService * SetExpansionContext();
+1 -4
View File
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info
auto os = EQ::GetOS();
@@ -125,7 +122,7 @@ public:
StackWalker::OnOutput(szText);
}
const std::vector<std::string>& const GetLines() { return _lines; }
const std::vector<std::string>& GetLines() { return _lines; }
private:
std::vector<std::string> _lines;
};
+199 -128
View File
@@ -353,7 +353,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
if (!results.Success() || !results.ErrorMessage().empty()){ return false; }
// Put character into the default guild if rule is being used.
int guild_id = RuleI(Character, DefaultGuild);
@@ -363,7 +363,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
if (character_id > -1) {
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){
if (!results.Success() || !results.ErrorMessage().empty()){
LogInfo("Could not put character [{}] into default Guild", name);
}
}
@@ -449,7 +449,8 @@ bool Database::DeleteCharacter(char *character_name)
return true;
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp)
{
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -634,101 +635,102 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
"%u," // guild_auto_consent
"%u" // RestTimer
")",
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
Strings::Escape(pp->last_name).c_str(), // " last_name, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
Strings::Escape(pp->title).c_str(), // " title, "
Strings::Escape(pp->suffix).c_str(), // " suffix, "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
);
auto results = QueryDatabase(query);
QueryDatabase(query);
/* Save Bind Points */
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
query = StringFormat(
"REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
@@ -739,57 +741,73 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
character_id, pp->binds[2].zone_id, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2,
character_id, pp->binds[3].zone_id, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3,
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
); results = QueryDatabase(query);
);
QueryDatabase(query);
/* HoTT Ability */
if(RuleB(Character, GrantHoTTOnCreate))
{
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
results = QueryDatabase(query);
}
/* HoTT Ability */
if (RuleB(Character, GrantHoTTOnCreate)) {
query = StringFormat(
"INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)",
character_id,
14,
1
);
QueryDatabase(query);
}
/* Save Skills */
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++){
if (pp->skills[i] > 0){
if (firstquery != 1){
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++) {
if (pp->skills[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->skills[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
/* Save Language */
firstquery = 0;
for (int i = 0; i < MAX_PP_LANGUAGE; i++){
if (pp->languages[i] > 0){
if (firstquery != 1){
for (int i = 0; i < MAX_PP_LANGUAGE; i++) {
if (pp->languages[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->languages[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
return true;
}
uint32 Database::GetCharacterID(const char *name) {
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
const auto query = fmt::format(
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
Strings::Escape(name)
);
auto results = QueryDatabase(query);
auto row = results.begin();
if (results.RowCount() == 1)
{
return Strings::ToUnsignedInt(row[0]);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return 0;
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
/*
@@ -999,7 +1017,7 @@ bool Database::GetVariable(std::string varname, std::string &varvalue)
return false;
}
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
bool Database::SetVariable(const std::string& varname, const std::string &varvalue)
{
std::string escaped_name = Strings::Escape(varname);
std::string escaped_value = Strings::Escape(varvalue);
@@ -2043,10 +2061,12 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) {
character_id
);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
return Strings::ToUnsignedInt(row[0]);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return 0;
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
int Database::CountInvSnapshots() {
@@ -2272,7 +2292,6 @@ bool Database::CopyCharacter(
new_rows.emplace_back(new_values);
}
std::string insert_values;
std::vector<std::string> insert_rows;
for (auto &r: new_rows) {
@@ -2328,7 +2347,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
);
if (!DoesTableExist(table_name)) {
LogMySQLQuery("Table [{}] does not exist. Downloading from Github and installing...", table_name);
LogMySQLQuery("Table [{}] does not exist. Downloading and installing...", table_name);
// http get request
httplib::Client cli(
@@ -2336,7 +2355,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
"{}://{}",
request_uri.get_scheme(),
request_uri.get_host()
).c_str()
)
);
cli.set_connection_timeout(0, 60000000); // 60 sec
@@ -2345,7 +2364,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
int sourced_queries = 0;
if (auto res = cli.Get(request_uri.get_path().c_str())) {
if (auto res = cli.Get(request_uri.get_path())) {
if (res->status == 200) {
for (auto &s: Strings::Split(res->body, ';')) {
if (!Strings::Trim(s).empty()) {
@@ -2389,3 +2408,55 @@ uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
return !zones.empty() ? zones[0].min_status : 0;
}
void Database::SourceSqlFromUrl(std::string url)
{
try {
uri request_uri(url);
LogHTTPDetail(
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
url,
request_uri.get_path(),
request_uri.get_host(),
request_uri.get_query(),
request_uri.get_scheme(),
request_uri.get_port()
);
LogInfo("Downloading and installing from [{}]", url);
// http get request
httplib::Client cli(
fmt::format(
"{}://{}",
request_uri.get_scheme(),
request_uri.get_host()
)
);
cli.set_connection_timeout(0, 60000000); // 60 sec
cli.set_read_timeout(60, 0); // 60 seconds
cli.set_write_timeout(60, 0); // 60 seconds
if (auto res = cli.Get(request_uri.get_path())) {
if (res->status == 200) {
auto results = QueryDatabaseMulti(res->body);
if (!results.ErrorMessage().empty()) {
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
return;
}
}
if (res->status == 404) {
LogError("Error retrieving URL [{}]", url);
}
}
else {
LogError("Error retrieving URL [{}]", url);
}
}
catch (std::invalid_argument iae) {
LogError("URI parser error [{}]", iae.what());
}
}
+2 -2
View File
@@ -235,7 +235,7 @@ public:
/* Database Variables */
bool GetVariable(std::string varname, std::string &varvalue);
bool SetVariable(const std::string varname, const std::string &varvalue);
bool SetVariable(const std::string& varname, const std::string &varvalue);
bool LoadVariables();
/* General Queries */
@@ -263,7 +263,7 @@ public:
void ClearInvSnapshots(bool from_now = false);
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
void SourceSqlFromUrl(std::string url);
private:
+92 -23
View File
@@ -28,6 +28,7 @@
#include "../database_schema.h"
#include "../file.h"
#include "../process/process.h"
#include "../termcolor/rang.hpp"
#include <ctime>
@@ -36,6 +37,7 @@
#else
#include <sys/time.h>
#include <thread>
#endif
@@ -91,6 +93,8 @@ std::string DatabaseDumpService::GetMySQLVersion()
return Strings::Trim(version_output);
}
const std::string CREDENTIALS_FILE = "login.my.cnf";
/**
* @return
*/
@@ -99,21 +103,15 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
auto config = EQEmuConfig::get();
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
return fmt::format(
"mysqldump -u {} -p{} -h {} --port={} {}",
config->ContentDbUsername,
config->ContentDbPassword,
config->ContentDbHost,
config->ContentDbPort,
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->ContentDbName
);
};
return fmt::format(
"mysqldump -u {} -p{} -h {} --port={} {}",
config->DatabaseUsername,
config->DatabasePassword,
config->DatabaseHost,
config->DatabasePort,
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->DatabaseDB
);
}
@@ -145,7 +143,7 @@ std::string DatabaseDumpService::GetQueryServTables()
std::string DatabaseDumpService::GetSystemTablesList()
{
auto system_tables = DatabaseSchema::GetServerTables();
auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables();
system_tables.insert(
@@ -199,7 +197,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
return GetSetDumpPath() + GetDumpFileName();
}
void DatabaseDumpService::Dump()
void DatabaseDumpService::DatabaseDump()
{
if (!IsMySQLInstalled()) {
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
@@ -293,14 +291,6 @@ void DatabaseDumpService::Dump()
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
}
std::string execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
File::Makedir(GetSetDumpPath());
}
@@ -308,30 +298,60 @@ void DatabaseDumpService::Dump()
if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
for (auto &table : tables) {
for (auto &table: tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
}
if (tables_to_dump.empty()) {
std::cerr << "No tables were specified" << std::endl;
}
return;
}
else {
const auto execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
BuildCredentialsFile();
std::string execution_result = Process::execute(execute_command);
if (!execution_result.empty() && IsDumpOutputToConsole()) {
std::cout << execution_result;
}
}
LogSys.LoadLogSettingsDefaults();
if (!pipe_file.empty()) {
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
auto r = File::GetContents(file);
if (!r.error.empty()) {
LogError("{}", r.error);
}
for (auto &line: Strings::Split(r.contents, "\n")) {
if (Strings::Contains(line, "mysqldump:")) {
LogError("{}", line);
LogError("Database dump failed. Correct the error before continuing or trying again");
LogError("This is to prevent data loss on behalf of the server operator");
RemoveSqlBackup();
std::exit(1);
}
}
}
if (!tables_to_dump.empty()) {
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
}
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
if (HasCompressionBinary()) {
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
if (IsTarAvailable()) {
Process::execute(
@@ -343,6 +363,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else if (Is7ZipAvailable()) {
Process::execute(
@@ -353,6 +374,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else {
LogInfo("Compression requested, but no available compression binary was found");
@@ -363,6 +385,8 @@ void DatabaseDumpService::Dump()
}
}
RemoveCredentialsFile();
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
// LogDebug("[{}] dump-path", GetSetDumpPath());
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
@@ -535,3 +559,48 @@ void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
{
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
}
void DatabaseDumpService::RemoveSqlBackup()
{
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
if (File::Exists(file)) {
std::filesystem::remove(file);
}
RemoveCredentialsFile();
}
void DatabaseDumpService::BuildCredentialsFile()
{
auto config = EQEmuConfig::get();
std::ofstream out(CREDENTIALS_FILE);
if (out.is_open()) {
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
out << "[mysqldump]" << std::endl;
out << "user=" << config->ContentDbUsername << std::endl;
out << "password=" << config->ContentDbPassword << std::endl;
out << "host=" << config->ContentDbHost << std::endl;
out << "port=" << config->ContentDbPort << std::endl;
out << "default-character-set=utf8" << std::endl;
}
else {
out << "[mysqldump]" << std::endl;
out << "user=" << config->DatabaseUsername << std::endl;
out << "password=" << config->DatabasePassword << std::endl;
out << "host=" << config->DatabaseHost << std::endl;
out << "port=" << config->DatabasePort << std::endl;
out << "default-character-set=utf8" << std::endl;
}
out.close();
}
else {
LogError("Failed to open credentials file for writing");
}
}
void DatabaseDumpService::RemoveCredentialsFile()
{
if (File::Exists(CREDENTIALS_FILE)) {
std::filesystem::remove(CREDENTIALS_FILE);
}
}
+4 -1
View File
@@ -24,7 +24,7 @@
class DatabaseDumpService {
public:
void Dump();
void DatabaseDump();
bool IsDumpAllTables() const;
void SetDumpAllTables(bool dump_all_tables);
bool IsDumpWithNoData() const;
@@ -92,6 +92,9 @@ private:
std::string GetDumpFileNameWithPath();
std::string GetSetDumpPath();
std::string GetQueryServTables();
void RemoveSqlBackup();
void BuildCredentialsFile();
void RemoveCredentialsFile();
};
+300
View File
@@ -0,0 +1,300 @@
#include <filesystem>
#include "database_update.h"
#include "../eqemu_logsys.h"
#include "../database.h"
#include "../strings.h"
#include "../rulesys.h"
#include "../http/httplib.h"
#include "database_update_manifest.cpp"
#include "database_update_manifest_bots.cpp"
#include "database_dump_service.h"
constexpr int BREAK_LENGTH = 70;
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
{
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
if (!results.Success() || !results.RowCount()) {
LogError("Failed to read from [db_version] table!");
return DatabaseVersion{};
}
auto r = results.begin();
return DatabaseVersion{
.server_database_version = Strings::ToInt(r[0]),
.bots_database_version = Strings::ToInt(r[1]),
};
}
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
{
return DatabaseVersion{
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
};
}
// the amount of versions we look-back to ensure we have all migrations
// we may not want to force these, but just warn about the look-backs
constexpr int LOOK_BACK_AMOUNT = 10;
// this check will take action
void DatabaseUpdate::CheckDbUpdates()
{
InjectBotsVersionColumn();
auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions();
if (CheckVersionsUpToDate(v, b)) {
return;
}
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
LogInfo(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.server_database_version,
v.server_database_version
);
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
}
if (b.bots_database_version > 0) {
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
LogInfo(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.bots_database_version,
v.bots_database_version
);
m_database->QueryDatabase(
fmt::format(
"UPDATE `db_version` SET `bots_version` = {}",
b.bots_database_version
)
);
}
}
}
std::string DatabaseUpdate::GetQueryResult(std::string query)
{
auto results = m_database->QueryDatabase(query);
std::vector<std::string> result_lines = {};
for (auto row = results.begin(); row != results.end(); ++row) {
std::vector<std::string> cols;
int field_count = results.ColumnCount();
cols.reserve(field_count);
for (int i = 0; i < field_count; ++i) {
if (row[i] != nullptr) {
cols.emplace_back(row[i]);
}
}
result_lines.emplace_back(Strings::Join(cols, " "));
}
return Strings::Join(result_lines, "\n");
}
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
{
std::string r = Strings::Trim(query_result);
if (e.condition == "contains") {
return Strings::Contains(r, e.match);
}
else if (e.condition == "match") {
return r == e.match;
}
else if (e.condition == "missing") {
return !Strings::Contains(r, e.match);
}
else if (e.condition == "empty") {
return r.empty();
}
else if (e.condition == "not_empty") {
return !r.empty();
}
return false;
}
// return true if we ran updates
bool DatabaseUpdate::UpdateManifest(
std::vector<ManifestEntry> entries,
int version_low,
int version_high
)
{
std::vector<int> missing_migrations = {};
if (version_low != version_high) {
LogSys.DisableMySQLErrorLogs();
for (int version = version_low + 1; version <= version_high; ++version) {
for (auto &e: entries) {
if (e.version == version) {
bool has_migration = true;
std::string r = GetQueryResult(e.check);
if (ShouldRunMigration(e, r)) {
has_migration = false;
missing_migrations.emplace_back(e.version);
}
std::string prefix = fmt::format(
"[{}]",
has_migration ? "ok" : "missing"
);
LogInfo(
"[{}] {:>10} | [{}]",
e.version,
prefix,
e.description
);
}
}
}
LogSys.EnableMySQLErrorLogs();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
if (!missing_migrations.empty()) {
LogInfo("Automatically backing up database before applying updates");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
auto s = DatabaseDumpService();
s.SetDumpAllTables(true);
s.SetDumpWithCompression(true);
s.DatabaseDump();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
}
if (!missing_migrations.empty()) {
LogInfo("Running database migrations. Please wait...");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
}
for (auto &m: missing_migrations) {
for (auto &e: entries) {
if (e.version == m) {
bool errored_migration = false;
auto r = m_database->QueryDatabaseMulti(e.sql);
// ignore empty query result "errors"
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
errored_migration = true;
LogInfo("Required database update failed. This could be a problem");
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
// user input
std::string input;
bool gave_input = false;
time_t start_time = time(nullptr);
time_t wait_time_seconds = 60;
// spawn a concurrent thread that waits for input from std::cin
std::thread t1(
[&]() {
std::cin >> input;
gave_input = true;
}
);
t1.detach();
// check the inputReceived flag once every 50ms for 10 seconds
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// prompt for user skip
if (Strings::Trim(input) == "y") {
errored_migration = false;
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
}
}
LogInfo(
"[{}] [{}] [{}]",
e.version,
e.description,
(errored_migration ? "error" : "ok")
);
if (errored_migration) {
LogError("Fatal | Database migration [{}] failed to run", e.description);
LogError("Fatal | Shutting down");
std::exit(1);
}
}
}
}
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
return true;
}
return false;
}
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
{
m_database = db;
return this;
}
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
{
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfo(
"{:>8} | database [{}] binary [{}] {}",
"Server",
v.server_database_version,
b.server_database_version,
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
);
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
LogInfo(
"{:>8} | database [{}] binary [{}] {}",
"Bots",
v.bots_database_version,
b.bots_database_version,
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
);
}
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
// server database version is required
bool server_up_to_date = v.server_database_version == b.server_database_version;
// bots database version is optional, if not enabled then it is always up-to-date
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
return server_up_to_date && bots_up_to_date;
}
// checks to see if there are pending updates
// used by zone to prevent launch or boot loop until updates are applied
bool DatabaseUpdate::HasPendingUpdates()
{
auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions();
return !CheckVersionsUpToDate(v, b);
}
void DatabaseUpdate::InjectBotsVersionColumn()
{
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
if (r.RowCount() == 0) {
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef EQEMU_DATABASE_UPDATE_H
#define EQEMU_DATABASE_UPDATE_H
#include "../database.h"
struct ManifestEntry {
int version{}; // database version of the migration
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
std::string check{}; // query that checks against the condition
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
std::string sql{}; // the SQL DDL that gets ran when the condition is true
};
struct DatabaseVersion {
int server_database_version;
int bots_database_version;
};
class DatabaseUpdate {
public:
DatabaseVersion GetDatabaseVersions();
DatabaseVersion GetBinaryDatabaseVersions();
void CheckDbUpdates();
std::string GetQueryResult(std::string query);
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
DatabaseUpdate *SetDatabase(Database *db);
bool HasPendingUpdates();
private:
Database *m_database;
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
void InjectBotsVersionColumn();
};
#endif //EQEMU_DATABASE_UPDATE_H
File diff suppressed because one or more lines are too long
@@ -0,0 +1,84 @@
#include "database_update.h"
std::vector<ManifestEntry> bot_manifest_entries = {
ManifestEntry{
.version = 9035,
.description = "2022_12_04_bot_archery.sql",
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `bot_data`
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
)",
},
ManifestEntry{
.version = 9036,
.description = "2023_01_19_drop_bot_views.sql",
.check = "SHOW TABLES LIKE 'vw_groups'",
.condition = "not_empty",
.match = "",
.sql = R"(
DROP VIEW vw_bot_groups;
DROP VIEW vw_bot_character_mobs;
DROP VIEW vw_groups;
DROP VIEW vw_guild_members;
DROP TABLE bot_guild_members;
)",
},
ManifestEntry{
.version = 9037,
.description = "2023_01_22_add_name_index.sql",
.check = "show index from bot_data WHERE key_name = 'name`",
.condition = "",
.match = "empty",
.sql = R"(
create index `name` on bot_data(`name`);
)",
},
ManifestEntry{
.version = 9038,
.description = "2023_02_16_add_caster_range.sql",
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
.condition = "",
.match = "empty",
.sql = R"(
ALTER TABLE `bot_data`
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
)",
},
ManifestEntry{
.version = 9039,
.description = "2023_03_31_remove_bot_groups.sql",
.check = "SHOW TABLES LIKE 'bot_groups'",
.condition = "",
.match = "not_empty",
.sql = R"(
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `bot_groups`;
DROP TABLE IF EXISTS `bot_group_members`;
SET FOREIGN_KEY_CHECKS = 1;
)",
},
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
// .version = 9228,
// .description = "some_new_migration.sql",
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
// .condition = "empty",
// .match = "",
// .sql = R"(
//
//)"
};
// see struct definitions for what each field does
// struct ManifestEntry {
// int version{}; // database version of the migration
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
// std::string check{}; // query that checks against the condition
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
// };
File diff suppressed because it is too large Load Diff
-2
View File
@@ -429,8 +429,6 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
void Database::DeleteInstance(uint16 instance_id)
{
std::string query;
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
+2 -4
View File
@@ -68,7 +68,7 @@ namespace DatabaseSchema {
{"character_spells", "id"},
{"character_task_timers", "character_id"},
{"character_tasks", "charid"},
{"character_tribute", "id"},
{"character_tribute", "character_id"},
{"completed_tasks", "charid"},
{"data_buckets", "id"},
{"faction_values", "char_id"},
@@ -256,6 +256,7 @@ namespace DatabaseSchema {
{
return {
"chatchannels",
"chatchannel_reserved_names",
"command_settings",
"content_flags",
"db_str",
@@ -392,9 +393,6 @@ namespace DatabaseSchema {
"bot_command_settings",
"bot_create_combinations",
"bot_data",
"bot_group_members",
"bot_groups",
"bot_guild_members",
"bot_heal_rotation_members",
"bot_heal_rotation_targets",
"bot_heal_rotations",
+131 -3
View File
@@ -13,6 +13,7 @@
#include <iostream>
#include <mysqld_error.h>
#include <string.h>
#include "strings.h"
#ifdef _WINDOWS
#define snprintf _snprintf
@@ -74,13 +75,13 @@ void DBcore::ping()
m_mutex->unlock();
}
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnFailureOnce)
{
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
return r;
}
bool DBcore::DoesTableExist(std::string table_name)
bool DBcore::DoesTableExist(const std::string& table_name)
{
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
@@ -136,7 +137,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
/**
* Error logging
*/
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
}
@@ -305,3 +306,130 @@ void DBcore::SetMutex(Mutex *mutex)
DBcore::m_mutex = mutex;
}
// executes multiple statements in one query
// do not use this in application logic
// this was built and maintained for database migrations only
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
{
SetMultiStatementsOn();
BenchTimer timer;
timer.reset();
LockMutex lock(m_mutex);
// Reconnect if we are not connected before hand.
if (pStatus != Connected) {
Open();
}
auto r = MySQLRequestResult{};
int status = mysql_real_query(mysql, query.c_str(), query.length());
// process single result
if (status != 0) {
unsigned int error_number = mysql_errno(mysql);
if (error_number == CR_SERVER_GONE_ERROR) {
pStatus = Error;
}
// error logging
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
std::string error_raw = fmt::format("{}", mysql_error(mysql));
std::string mysql_err = Strings::Trim(error_raw);
std::string clean_query = Strings::Replace(query, "\n", "");
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
MYSQL_RES *res = mysql_store_result(mysql);
uint32 row_count = 0;
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
if (res) {
mysql_free_result(res);
}
return r;
}
}
int index = 0;
// there could be a query with a semicolon in the actual data, this is best effort for
// logging / display purposes
// rare that we see this when this is only used in DDL statements
auto pieces = Strings::Split(query, ";");
// process each statement result
do {
uint32 row_count = 0;
MYSQL_RES *res = mysql_store_result(mysql);
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
if (pieces.size() >= index) {
auto piece = pieces[index];
LogMySQLQuery(
"{} -- ({} row{} affected) ({}s)",
piece,
r.RowsAffected(),
r.RowsAffected() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
}
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
if ((status = mysql_next_result(mysql)) > 0) {
if (mysql_errno(mysql) > 0) {
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
}
mysql_free_result(res);
// error logging
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
// we handle errors elsewhere
return r;
}
if (res) {
mysql_free_result(res);
}
index++;
} while (status == 0);
SetMultiStatementsOff();
return r;
}
+16 -3
View File
@@ -24,7 +24,8 @@ public:
~DBcore();
eStatus GetStatus() { return pStatus; }
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
void TransactionBegin();
void TransactionCommit();
void TransactionRollback();
@@ -35,7 +36,7 @@ public:
const std::string &GetOriginHost() const;
void SetOriginHost(const std::string &origin_host);
bool DoesTableExist(std::string table_name);
bool DoesTableExist(const std::string& table_name);
void SetMySQL(const DBcore &o)
{
@@ -77,8 +78,20 @@ private:
uint32 pPort;
bool pSSL;
// allows multiple queries to be executed within the same query
// do not use this under normal operation
// we use this during database migrations only currently
void SetMultiStatementsOn()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
}
// disables multiple statements to be executed in one query
void SetMultiStatementsOff()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
}
};
#endif
+69 -119
View File
@@ -11,7 +11,7 @@
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -19,131 +19,81 @@
#include "deity.h"
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
{
switch (deity_type) {
case DeityBertoxxulous:
return bit_DeityBertoxxulous;
case DeityBrellSirilis:
return bit_DeityBrellSirilis;
case DeityCazicThule:
return bit_DeityCazicThule;
case DeityErollisiMarr:
return bit_DeityErollisiMarr;
case DeityBristlebane:
return bit_DeityBristlebane;
case DeityInnoruuk:
return bit_DeityInnoruuk;
case DeityKarana:
return bit_DeityKarana;
case DeityMithanielMarr:
return bit_DeityMithanielMarr;
case DeityPrexus:
return bit_DeityPrexus;
case DeityQuellious:
return bit_DeityQuellious;
case DeityRallosZek:
return bit_DeityRallosZek;
case DeityRodcetNife:
return bit_DeityRodcetNife;
case DeitySolusekRo:
return bit_DeitySolusekRo;
case DeityTheTribunal:
return bit_DeityTheTribunal;
case DeityTunare:
return bit_DeityTunare;
case DeityVeeshan:
return bit_DeityVeeshan;
case DeityAgnostic_LB:
case DeityAgnostic:
return bit_DeityAgnostic;
default:
return bit_DeityAll;
};
case DeityBertoxxulous:
return bit_DeityBertoxxulous;
case DeityBrellSirilis:
return bit_DeityBrellSirilis;
case DeityCazicThule:
return bit_DeityCazicThule;
case DeityErollisiMarr:
return bit_DeityErollisiMarr;
case DeityBristlebane:
return bit_DeityBristlebane;
case DeityInnoruuk:
return bit_DeityInnoruuk;
case DeityKarana:
return bit_DeityKarana;
case DeityMithanielMarr:
return bit_DeityMithanielMarr;
case DeityPrexus:
return bit_DeityPrexus;
case DeityQuellious:
return bit_DeityQuellious;
case DeityRallosZek:
return bit_DeityRallosZek;
case DeityRodcetNife:
return bit_DeityRodcetNife;
case DeitySolusekRo:
return bit_DeitySolusekRo;
case DeityTheTribunal:
return bit_DeityTheTribunal;
case DeityTunare:
return bit_DeityTunare;
case DeityVeeshan:
return bit_DeityVeeshan;
case DeityAgnostic_LB:
case DeityAgnostic:
return bit_DeityAgnostic;
default:
return bit_DeityAll;
}
}
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
{
switch (deity_type_bit) {
case bit_DeityAgnostic:
return DeityAgnostic;
case bit_DeityBertoxxulous:
return DeityBertoxxulous;
case bit_DeityBrellSirilis:
return DeityBrellSirilis;
case bit_DeityCazicThule:
return DeityCazicThule;
case bit_DeityErollisiMarr:
return DeityErollisiMarr;
case bit_DeityBristlebane:
return DeityBristlebane;
case bit_DeityInnoruuk:
return DeityInnoruuk;
case bit_DeityKarana:
return DeityKarana;
case bit_DeityMithanielMarr:
return DeityMithanielMarr;
case bit_DeityPrexus:
return DeityPrexus;
case bit_DeityQuellious:
return DeityQuellious;
case bit_DeityRallosZek:
return DeityRallosZek;
case bit_DeityRodcetNife:
return DeityRodcetNife;
case bit_DeitySolusekRo:
return DeitySolusekRo;
case bit_DeityTheTribunal:
return DeityTheTribunal;
case bit_DeityTunare:
return DeityTunare;
case bit_DeityVeeshan:
return DeityVeeshan;
default:
return DeityUnknown;
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
{ DeityAgnostic, "Agnostic" },
{ DeityAgnostic_LB, "Agnostic" },
{ DeityBertoxxulous, "Bertoxxulous" },
{ DeityBrellSirilis, "Brell Serilis" },
{ DeityBristlebane, "Bristlebane" },
{ DeityCazicThule, "Cazic-Thule" },
{ DeityErollisiMarr, "Erollisi Marr" },
{ DeityInnoruuk, "Innoruuk" },
{ DeityKarana, "Karana" },
{ DeityMithanielMarr, "Mithaniel Marr" },
{ DeityPrexus, "Prexus" },
{ DeityQuellious, "Quellious" },
{ DeityRallosZek, "Rallos Zek" },
{ DeityRodcetNife, "Rodcet Nife" },
{ DeitySolusekRo, "Solusek Ro" },
{ DeityTheTribunal, "The Tribunal" },
{ DeityTunare, "Tunare" },
{ DeityVeeshan, "Veeshan" }
};
return deity_map;
}
const char* EQ::deity::DeityName(DeityType deity_type)
std::string EQ::deity::GetDeityName(DeityType deity_type)
{
switch (deity_type) {
case DeityBertoxxulous:
return "Bertoxxulous";
case DeityBrellSirilis:
return "Brell Serilis";
case DeityCazicThule:
return "Cazic-Thule";
case DeityErollisiMarr:
return "Erollisi Marr";
case DeityBristlebane:
return "Bristlebane";
case DeityInnoruuk:
return "Innoruuk";
case DeityKarana:
return "Karana";
case DeityMithanielMarr:
return "Mithaniel Marr";
case DeityPrexus:
return "Prexus";
case DeityQuellious:
return "Quellious";
case DeityRallosZek:
return "Rallos Zek";
case DeityRodcetNife:
return "Rodcet Nife";
case DeitySolusekRo:
return "Solusek Ro";
case DeityTheTribunal:
return "The Tribunal";
case DeityTunare:
return "Tunare";
case DeityVeeshan:
return "Veeshan";
case DeityAgnostic_LB:
case DeityAgnostic:
return "Agnostic";
default:
return "Unknown";
};
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
return EQ::deity::GetDeityMap().find(deity_type)->second;
}
return std::string();
}
+22 -21
View File
@@ -21,6 +21,8 @@
#define COMMON_DEITY_H
#include "types.h"
#include <map>
#include <string>
namespace EQ
@@ -49,30 +51,29 @@ namespace EQ
};
enum DeityTypeBit : uint32 {
bit_DeityNone = 0x00000000,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
bit_DeityCazicThule = 0x00000008,
bit_DeityErollisiMarr = 0x00000010,
bit_DeityBristlebane = 0x00000020,
bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
bit_DeityCazicThule = 0x00000008,
bit_DeityErollisiMarr = 0x00000010,
bit_DeityBristlebane = 0x00000020,
bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityMithanielMarr = 0x00000100,
bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = 0xFFFFFFFF
bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = UINT32_MAX
};
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
extern const char* DeityName(DeityType deity_type);
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
extern std::string GetDeityName(DeityType deity_type);
extern const std::map<DeityType, std::string>& GetDeityMap();
} /*deity*/
-6
View File
@@ -27,9 +27,6 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
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"}
};
// payload
Json::Value p;
@@ -96,9 +93,6 @@ void Discord::SendPlayerEventMessage(
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()) {
+2 -2
View File
@@ -37,7 +37,7 @@ void DiscordManager::ProcessMessageQueue()
message,
webhook.webhook_url
);
message = "";
message.clear();
}
message += m;
@@ -51,7 +51,7 @@ void DiscordManager::ProcessMessageQueue()
webhook.webhook_url
);
}
message = "";
message.clear();
}
}
// final flush
+34 -33
View File
@@ -197,11 +197,11 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
std::string EQ::constants::GetLanguageName(int language_id)
{
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return EQ::constants::GetLanguageMap().find(language_id)->second;
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return std::string();
}
return std::string();
return EQ::constants::GetLanguageMap().find(language_id)->second;
}
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
@@ -220,11 +220,11 @@ const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
{
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return std::string();
}
return std::string();
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
}
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
@@ -243,11 +243,11 @@ const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
{
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
if (!EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
return std::string();
}
return std::string();
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
}
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
@@ -365,11 +365,11 @@ const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
{
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
if (!EQ::ValueWithin(faction_consider_level, ConsiderLevel::Ally, ConsiderLevel::Scowls)) {
return std::string();;
}
return std::string();
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
@@ -386,11 +386,11 @@ const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
{
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
if (!EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
return std::string();
}
return std::string();
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
@@ -407,11 +407,11 @@ const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
{
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
if (!EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
return std::string();
}
return std::string();
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
@@ -429,11 +429,11 @@ const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
{
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
if (!EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
return std::string();
}
return std::string();
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
}
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
@@ -507,11 +507,12 @@ const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
std::string EQ::constants::GetObjectTypeName(int object_type)
{
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return std::string();
}
return std::string();
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
@@ -527,11 +528,11 @@ const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
{
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
if (!EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return std::string();
}
return std::string();
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
@@ -553,11 +554,11 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
{
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
if (!EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
return std::string();
}
return std::string();
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
@@ -573,9 +574,9 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
{
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
if (!EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
return std::string();
}
return std::string();
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
}
+7
View File
@@ -1045,4 +1045,11 @@ enum ResurrectionActions
Accept
};
enum ScribeSpellActions
{
Scribe,
Memorize,
Unmemorize
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+1 -1
View File
@@ -129,7 +129,7 @@ namespace EQ
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
InventoryTypeSize_Struct InventoryTypeSize,
const InventoryTypeSize_Struct& InventoryTypeSize,
uint64 EquipmentBitmask,
uint64 GeneralBitmask,
uint64 CursorBitmask,
+1 -138
View File
@@ -236,26 +236,6 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
bool result=false;
@@ -287,74 +267,6 @@ bool result=false;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
} else {
uint16 comp_crc=CRC16(buffer,length-2,Key);
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
#ifdef EQN_DEBUG
if (packet_crc && comp_crc != packet_crc) {
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
}
#endif
valid = (!packet_crc || comp_crc == packet_crc);
}
return valid;
}
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
uint32 newlen=0;
@@ -403,55 +315,6 @@ uint32 flag_offset=1,newlength;
return newlength;
}
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
buffer+=2;
size-=2;
int i;
for (i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = (*(int*)&buffer[i]);
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
int i;
buffer+=2;
size-=2;
for ( i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = pt;
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
return(new EQApplicationPacket(*this));
}
@@ -515,4 +378,4 @@ std::string DumpPacketToString(const EQApplicationPacket* app){
std::ostringstream out;
out << DumpPacketHexToString(app->pBuffer, app->size);
return out.str();
}
}
-3
View File
@@ -80,11 +80,8 @@ public:
protected:
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
uint16 GetRawOpcode() const { return(opcode); }
+11
View File
@@ -1793,6 +1793,17 @@ struct GMSummon_Struct {
/*104*/ uint32 unknown2; // E0 E0 56 00
};
struct GMFind_Struct {
char charname[64];
char gmname[64];
uint32 success;
uint32 zoneID;
float x;
float y;
float z;
uint32 unknown2;
};
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
/* 0*/ char charname[64];
+2 -2
View File
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
}
}
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
auto p = new Patch;
p->signature = sig;
p->name = name;
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
}
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
m_streams.push_back(Record(eqs));
m_streams.emplace_back(Record(eqs));
eqs = nullptr;
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
~EQStreamIdentifier();
//registration interface.
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
//main processing interface
void Process();
-3
View File
@@ -23,9 +23,6 @@
EQDB EQDB::s_EQDB;
EQDB::EQDB() {
}
unsigned int EQDB::field_count() {
return mysql_field_count(mysql_ref);
}
+1 -1
View File
@@ -27,7 +27,7 @@
//this is the main object exported to perl.
class EQDB {
EQDB();
EQDB() = default;
public:
static EQDB *Singleton() { return(&s_EQDB); }
+24 -18
View File
@@ -34,13 +34,13 @@ void EQEmuConfig::parse_config()
LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString());
SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString());
LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
@@ -63,7 +63,7 @@ void EQEmuConfig::parse_config()
auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
@@ -85,16 +85,22 @@ void EQEmuConfig::parse_config()
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
auto_database_updates = false;
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
auto_database_updates = true;
}
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString());
TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString());
WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
@@ -109,9 +115,9 @@ void EQEmuConfig::parse_config()
* UCS
*/
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
/**
* Database
@@ -119,7 +125,7 @@ void EQEmuConfig::parse_config()
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
/**
@@ -128,14 +134,14 @@ void EQEmuConfig::parse_config()
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString().c_str());
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
/**
* QS
*/
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString());
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
@@ -143,9 +149,9 @@ void EQEmuConfig::parse_config()
/**
* Zones
*/
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
/**
* Files
@@ -175,10 +181,10 @@ void EQEmuConfig::parse_config()
/**
* Launcher
*/
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
#ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
#else
+2 -6
View File
@@ -120,6 +120,8 @@ class EQEmuConfig
uint16 ZonePortHigh;
uint8 DefaultStatus;
bool auto_database_updates;
// uint16 DynamicCount;
// map<string,uint16> StaticZones;
@@ -147,12 +149,6 @@ class EQEmuConfig
return (_config);
}
// Allow the use to set the conf file to be used.
static void SetConfigFile(std::string file)
{
EQEmuConfig::ConfigFile = file;
}
// Load the config
static bool LoadConfig(const std::string& path = "")
{
+92 -24
View File
@@ -104,9 +104,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* RFC 5424
*/
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
/**
* Set Category enabled status on defaults
@@ -187,9 +187,10 @@ void EQEmuLogSys::ProcessLogWrite(
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Crash:
case Logs::Error:
case Logs::MySQLError:
case Logs::QuestErrors:
case Logs::Error:
return Chat::Red;
case Logs::MySQLQuery:
case Logs::Debug:
@@ -199,8 +200,6 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
case Logs::Commands:
case Logs::Mercenaries:
return Chat::Magenta;
case Logs::Crash:
return Chat::Red;
default:
return Chat::Yellow;
}
@@ -220,7 +219,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
int line
)
{
bool is_error = (
bool is_error = (
log_category == Logs::LogCategory::Error ||
log_category == Logs::LogCategory::MySQLError ||
log_category == Logs::LogCategory::Crash ||
@@ -262,7 +261,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
}
if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--");
auto s = Strings::Split(message, "--");
if (s.size() > 1) {
std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]);
@@ -298,19 +297,76 @@ void EQEmuLogSys::ProcessConsoleMessage(
}
}
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::fgB::gray
<< "] "
;
// color matching in []
// ex: [<red>variable] would produce [variable] with red inside brackets
std::map<std::string, rang::fgB> colors = {
{"<black>", rang::fgB::black},
{"<green>", rang::fgB::green},
{"<yellow>", rang::fgB::yellow},
{"<blue>", rang::fgB::blue},
{"<magenta>", rang::fgB::magenta},
{"<cyan>", rang::fgB::cyan},
{"<gray>", rang::fgB::gray},
{"<red>", rang::fgB::red},
};
bool match_color = false;
for (auto &c: colors) {
if (Strings::Contains(e, c.first)) {
e = Strings::Replace(e, c.first, "");
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
}
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
// string match to colors
std::map<std::string, rang::fgB> matches = {
{"missing", rang::fgB::red},
{"error", rang::fgB::red},
{"ok", rang::fgB::green},
};
for (auto &c: matches) {
if (Strings::Contains(e, c.first)) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
}
}
// if we don't match a color in either the string matching or
// the color tag matching, we default to yellow inside brackets
// if uppercase, does not get colored
if (!match_color) {
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
}
}
}
else {
@@ -524,6 +580,8 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
*/
void EQEmuLogSys::SilenceConsoleLogging()
{
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = 0;
log_settings[log_index].is_category_enabled = 0;
@@ -537,10 +595,7 @@ void EQEmuLogSys::SilenceConsoleLogging()
*/
void EQEmuLogSys::EnableConsoleLogging()
{
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = Logs::General;
log_settings[log_index].is_category_enabled = 1;
}
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
}
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
@@ -742,3 +797,16 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
return this;
}
void EQEmuLogSys::DisableMySQLErrorLogs()
{
log_settings[Logs::MySQLError].log_to_file = 0;
log_settings[Logs::MySQLError].log_to_console = 0;
log_settings[Logs::MySQLError].log_to_gmsay = 0;
}
void EQEmuLogSys::EnableMySQLErrorLogs()
{
log_settings[Logs::MySQLError].log_to_file = 1;
log_settings[Logs::MySQLError].log_to_console = 1;
log_settings[Logs::MySQLError].log_to_gmsay = 1;
}
+6
View File
@@ -324,6 +324,9 @@ public:
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
// temporary bucket to re-load after silencing
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
struct LogEnabled {
bool log_to_file_enabled;
bool log_to_console_enabled;
@@ -374,6 +377,9 @@ public:
[[nodiscard]] const std::string &GetLogPath() const;
EQEmuLogSys * SetLogPath(const std::string &log_path);
void DisableMySQLErrorLogs();
void EnableMySQLErrorLogs();
private:
// reference to database
+1 -5
View File
@@ -58,10 +58,6 @@ EQTime::EQTime()
SetCurrentEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
{
}
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
//This function was written by the ShowEQ Project.
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
@@ -203,4 +199,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
//Constructor/destructor
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
EQTime();
~EQTime();
~EQTime() = default;
//Get functions
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
+1 -1
View File
@@ -38,7 +38,7 @@ namespace EQ
_running = true;
for (size_t i = 0; i < threads; ++i) {
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
}
}
+4 -10
View File
@@ -333,7 +333,10 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
break;
}
case PlayerEvent::FISH_FAILURE: {
case PlayerEvent::FISH_FAILURE:
case PlayerEvent::FORAGE_FAILURE:
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
@@ -348,10 +351,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
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;
@@ -550,11 +549,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
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;
+3 -3
View File
@@ -218,14 +218,14 @@ enum { //some random constants
#define HARD_LEVEL_CAP 127
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
#define USE_NPC_RANGE2 200*200 //arbitrary right now
#define USE_NPC_RANGE2 40000 //arbitrary right now
// Squared range for rampage 75.0 * 75.0 for now
#define NPC_RAMPAGE_RANGE2 5625.0f
//the formula for experience for killing a mob.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
#define EXP_FORMULA (level * level * 75 * 35 / 10)
#define HIGHEST_AA_VALUE 35
@@ -295,7 +295,7 @@ Developer configuration
#define COMMON_PROFILE
#define PROFILE_DUMP_TIME 3*60
#define PROFILE_DUMP_TIME 180
#endif //EQPROFILE
+24
View File
@@ -37,6 +37,7 @@
#include <fmt/format.h>
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
@@ -80,3 +81,26 @@ std::string File::GetCwd()
{
return fs::current_path().string();
}
FileContentsResult File::GetContents(const std::string &file_name)
{
std::string error;
std::ifstream f;
f.open(file_name);
std::string line;
std::string lines;
if (f.is_open()) {
while (f) {
std::getline(f, line);
lines += line + "\n";
}
}
else {
error = fmt::format("Couldn't open file [{}]", file_name);
}
return FileContentsResult{
.contents = lines,
.error = error,
};
}
+6
View File
@@ -25,10 +25,16 @@
namespace fs = std::filesystem;
struct FileContentsResult {
std::string contents;
std::string error;
};
class File {
public:
static bool Exists(const std::string &name);
static void Makedir(const std::string& directory_name);
static FileContentsResult GetContents(const std::string &file_name);
static std::string FindEqemuConfigPath();
static std::string GetCwd();
};
+4 -4
View File
@@ -6690,7 +6690,7 @@ static WSInit wsinit_;
if (params.empty()) { return Get(path, headers); }
std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, progress);
return Get(path_with_query, headers, progress);
}
inline Result ClientImpl::Get(const std::string &path, const Params &params,
@@ -6710,7 +6710,7 @@ static WSInit wsinit_;
}
std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, response_handler,
return Get(path_with_query, headers, response_handler,
content_receiver, progress);
}
@@ -6807,7 +6807,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body = detail::serialize_multipart_formdata(
items, detail::make_multipart_data_boundary(), content_type);
return Post(path, headers, body, content_type.c_str());
return Post(path, headers, body, content_type);
}
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
@@ -6820,7 +6820,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body =
detail::serialize_multipart_formdata(items, boundary, content_type);
return Post(path, headers, body, content_type.c_str());
return Post(path, headers, body, content_type);
}
inline Result ClientImpl::Put(const std::string &path) {
+8 -7
View File
@@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem(
fail_state = swapRaceClass;
return false;
}
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
fail_state = swapDeity;
return false;
}
@@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem(
fail_state = swapRaceClass;
return false;
}
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
fail_state = swapDeity;
return false;
}
@@ -412,11 +412,12 @@ bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
// If there are no charges left on the item,
if (item_to_delete->GetCharges() <= 0) {
// If the item is stackable (e.g arrows), or
// the item is not stackable, and is not a charged item, or is expendable, delete it
if (item_to_delete->IsStackable() ||
(!item_to_delete->IsStackable() &&
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
) {
// the item is not a charged item, or is expendable, delete it
if (
item_to_delete->IsStackable() ||
item_to_delete->GetItem()->MaxCharges == 0 ||
item_to_delete->IsExpendable()
) {
// Item can now be destroyed
InventoryProfile::MarkDirty(item_to_delete);
return true;
+164 -159
View File
@@ -355,181 +355,186 @@ namespace EQ
struct ItemData {
// Non packet based fields
uint8 MinStatus;
uint8 MinStatus {};
// Packet based fields
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
char Name[64]; // Name
char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30]; // Visible model
uint32 ID; // Unique ID (also PK for DB)
int32 Weight; // Item weight * 10
uint8 NoRent; // No Rent: 0=norent, 255=not norent
uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots; // Bitfield for which slots this item can be used in
uint32 Price; // Item cost (?)
uint32 Icon; // Icon Number
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag;
bool ArtifactFlag;
bool SummonedFlag;
uint8 FVNoDrop; // Firiona Vie nodrop flag
uint32 Favor; // Individual favor
uint32 GuildFavor; // Guild favor
uint32 PointType;
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
char Name[64] {}; // Name
char Lore[80] {}; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30] {}; // Visible model
uint32 ID {}; // Unique ID (also PK for DB)
int32 Weight {}; // Item weight * 10
uint8 NoRent{} ; // No Rent: 0=norent, 255=not norent
uint8 NoDrop {}; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size {}; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots {}; // Bitfield for which slots this item can be used in
uint32 Price {}; // Item cost (?)
uint32 Icon {}; // Icon Number
int32 LoreGroup {}; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag {}; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag {};
bool ArtifactFlag {};
bool SummonedFlag {};
uint8 FVNoDrop {}; // Firiona Vie nodrop flag
uint32 Favor {}; // Individual favor
uint32 GuildFavor {}; // Guild favor
uint32 PointType {};
//uint32 Unk117;
//uint32 Unk118;
//uint32 Unk121;
//uint32 Unk124;
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR; // 0->100
uint8 BagType {}; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots {}; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize {}; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR {}; // 0->100
bool BenefitFlag;
bool Tradeskills; // Is this a tradeskill item?
int8 CR; // Save vs Cold
int8 DR; // Save vs Disease
int8 PR; // Save vs Poison
int8 MR; // Save vs Magic
int8 FR; // Save vs Fire
int8 AStr; // Strength
int8 ASta; // Stamina
int8 AAgi; // Agility
int8 ADex; // Dexterity
int8 ACha; // Charisma
int8 AInt; // Intelligence
int8 AWis; // Wisdom
int32 HP; // HP
int32 Mana; // Mana
int32 AC; // AC
uint32 Deity; // Bitmask of Deities that can equip this item
bool BenefitFlag {};
bool Tradeskills {}; // Is this a tradeskill item?
int8 CR {}; // Save vs Cold
int8 DR {}; // Save vs Disease
int8 PR {}; // Save vs Poison
int8 MR {}; // Save vs Magic
int8 FR {}; // Save vs Fire
int8 AStr {}; // Strength
int8 ASta {}; // Stamina
int8 AAgi {}; // Agility
int8 ADex {}; // Dexterity
int8 ACha {}; // Charisma
int8 AInt {}; // Intelligence
int8 AWis {}; // Wisdom
int32 HP {}; // HP
int32 Mana {}; // Mana
int32 AC {}; // AC
uint32 Deity {}; // Bitmask of Deities that can equip this item
//uint32 Unk033
int32 SkillModValue; // % Mod to skill specified in SkillModType
int32 SkillModMax; // Max skill point modification
uint32 SkillModType; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace; // Bane Damage Race
int32 BaneDmgAmt; // Bane Damage Body Amount
uint32 BaneDmgBody; // Bane Damage Body
bool Magic; // True=Magic Item, False=not
int32 CastTime_;
uint8 ReqLevel; // Required Level to use item
uint32 BardType; // Bard Skill Type
int32 BardValue; // Bard Skill Amount
int8 Light; // Light
uint8 Delay; // Delay * 10
uint8 RecLevel; // Recommended level to use item
uint8 RecSkill; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt; // Elemental Damage
uint8 Range; // Range of item
uint32 Damage; // Delay between item usage (in 0.1 sec increments)
uint32 Color; // RR GG BB 00 <-- as it appears in pc
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
uint32 Races; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054;
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType; // Item Type/Skill (itemClass* from above)
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material; // Item material type
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
float SellRate; // Sell rate
//uint32 Unk059;
int32 SkillModValue {}; // % Mod to skill specified in SkillModType
int32 SkillModMax {}; // Max skill point modification
uint32 SkillModType {}; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace {}; // Bane Damage Race
int32 BaneDmgAmt {}; // Bane Damage Body Amount
uint32 BaneDmgBody {}; // Bane Damage Body
bool Magic {}; // True=Magic Item, False=not
int32 CastTime_ {};
uint8 ReqLevel {}; // Required Level to use item
uint32 BardType {}; // Bard Skill Type
int32 BardValue {}; // Bard Skill Amount
int8 Light {}; // Light
uint8 Delay {}; // Delay * 10
uint8 RecLevel {}; // Recommended level to use item
uint8 RecSkill {}; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType {}; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt {}; // Elemental Damage
uint8 Range {}; // Range of item
uint32 Damage {}; // Delay between item usage (in 0.1 sec increments)
uint32 Color {}; // RR GG BB 00 <-- as it appears in pc
uint32 Classes {}; // Bitfield of classes that can equip item (1 << class#)
uint32 Races {}; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054 {};
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material {}; // Item material type
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
float SellRate {}; // Sell rate
//uint32 Unk059 {};
union {
uint32 Fulfilment; // Food fulfilment (How long it lasts)
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
};
uint32 EliteMaterial;
int32 ProcRate;
int8 CombatEffects; // PoP: Combat Effects +
int8 Shielding; // PoP: Shielding %
int8 StunResist; // PoP: Stun Resist %
int8 StrikeThrough; // PoP: Strike Through %
int32 ExtraDmgSkill;
int32 ExtraDmgAmt;
int8 SpellShield; // PoP: Spell Shield %
int8 Avoidance; // PoP: Avoidance +
int8 Accuracy; // PoP: Accuracy +
uint32 CharmFileID;
int32 FactionMod1; // Faction Mod 1
int32 FactionMod2; // Faction Mod 2
int32 FactionMod3; // Faction Mod 3
int32 FactionMod4; // Faction Mod 4
int32 FactionAmt1; // Faction Amt 1
int32 FactionAmt2; // Faction Amt 2
int32 FactionAmt3; // Faction Amt 3
int32 FactionAmt4; // Faction Amt 4
char CharmFile[32]; // ?
uint32 AugType;
uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
uint32 BaneDmgRaceAmt;
uint32 AugRestrict;
int32 Endur;
int32 DotShielding;
int32 Attack;
int32 Regen;
int32 ManaRegen;
int32 EnduranceRegen;
int32 Haste;
int32 DamageShield;
uint32 RecastDelay;
int RecastType;
uint32 AugDistiller;
bool Attuneable;
bool NoPet;
bool PotionBelt;
bool Stackable;
bool NoTransfer;
bool QuestItemFlag;
int16 StackSize;
uint8 PotionBeltSlots;
item::ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
uint32 EliteMaterial {};
int32 ProcRate {};
int8 CombatEffects {}; // PoP: Combat Effects +
int8 Shielding {}; // PoP: Shielding %
int8 StunResist {}; // PoP: Stun Resist %
int8 StrikeThrough {}; // PoP: Strike Through %
int32 ExtraDmgSkill {};
int32 ExtraDmgAmt {};
int8 SpellShield {}; // PoP: Spell Shield %
int8 Avoidance {}; // PoP: Avoidance +
int8 Accuracy {}; // PoP: Accuracy +
uint32 CharmFileID {};
int32 FactionMod1 {}; // Faction Mod 1
int32 FactionMod2 {}; // Faction Mod 2
int32 FactionMod3 {}; // Faction Mod 3
int32 FactionMod4 {}; // Faction Mod 4
int32 FactionAmt1 {}; // Faction Amt 1
int32 FactionAmt2 {}; // Faction Amt 2
int32 FactionAmt3 {}; // Faction Amt 3
int32 FactionAmt4 {}; // Faction Amt 4
char CharmFile[32] {}; // ?
uint32 AugType {};
uint8 AugSlotType[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme {};
uint32 LDoNPrice {};
uint32 LDoNSold {};
uint32 BaneDmgRaceAmt {};
uint32 AugRestrict {};
int32 Endur {};
int32 DotShielding {};
int32 Attack {};
int32 Regen {};
int32 ManaRegen {};
int32 EnduranceRegen {};
int32 Haste {};
int32 DamageShield {};
uint32 RecastDelay {};
int RecastType {};
uint32 AugDistiller {};
bool Attuneable {};
bool NoPet {};
bool PotionBelt {};
bool Stackable {};
bool NoTransfer {};
bool QuestItemFlag {};
int16 StackSize {};
uint8 PotionBeltSlots {};
item::ItemEffect_Struct Click {};
item::ItemEffect_Struct Proc {};
item::ItemEffect_Struct Worn {};
item::ItemEffect_Struct Focus {};
item::ItemEffect_Struct Scroll {};
item::ItemEffect_Struct Bard {};
uint8 Book; // 0=Not book, 1=Book
uint32 BookType;
char Filename[33]; // Filename for book data
uint8 Book {}; // 0=Not book, 1=Book
uint32 BookType {};
char Filename[33] {}; // Filename for book data
// Begin SoF Fields
int32 SVCorruption;
uint32 Purity;
uint8 EvolvingItem;
uint32 EvolvingID;
uint8 EvolvingLevel;
uint8 EvolvingMax;
uint32 BackstabDmg;
uint32 DSMitigation;
int32 HeroicStr;
int32 HeroicInt;
int32 HeroicWis;
int32 HeroicAgi;
int32 HeroicDex;
int32 HeroicSta;
int32 HeroicCha;
int32 HeroicMR;
int32 HeroicFR;
int32 HeroicCR;
int32 HeroicDR;
int32 HeroicPR;
int32 HeroicSVCorrup;
int32 HealAmt;
int32 SpellDmg;
uint32 LDoNSellBackRate;
uint32 ScriptFileID;
uint16 ExpendableArrow;
uint32 Clairvoyance;
char ClickName[65];
char ProcName[65];
char WornName[65];
char FocusName[65];
char ScrollName[65];
int32 SVCorruption {};
uint32 Purity {};
uint8 EvolvingItem {};
uint32 EvolvingID {};
uint8 EvolvingLevel {};
uint8 EvolvingMax {};
uint32 BackstabDmg {};
uint32 DSMitigation {};
int32 HeroicStr {};
int32 HeroicInt {};
int32 HeroicWis {};
int32 HeroicAgi {};
int32 HeroicDex {};
int32 HeroicSta {};
int32 HeroicCha {};
int32 HeroicMR {};
int32 HeroicFR {};
int32 HeroicCR {};
int32 HeroicDR {};
int32 HeroicPR {};
int32 HeroicSVCorrup {};
int32 HealAmt {};
int32 SpellDmg {};
uint32 LDoNSellBackRate {};
uint32 ScriptFileID {};
uint16 ExpendableArrow {};
uint32 Clairvoyance {};
char ClickName[65] {};
char ProcName[65] {};
char WornName[65] {};
char FocusName[65] {};
char ScrollName[65] {};
//BardName
bool IsEquipable(uint16 Race, uint16 Class) const;
+159 -164
View File
@@ -17,6 +17,7 @@
*/
#include "inventory_profile.h"
#include "../common/data_verification.h"
//#include "classes.h"
//#include "global_define.h"
//#include "item_instance.h"
@@ -57,108 +58,62 @@ static inline int32 GetNextItemInstSerialNumber() {
// class EQ::ItemInstance
//
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new ItemData(*item);
} else {
m_item = nullptr;
}
m_charges = charges;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
if (item) {
m_item = new ItemData(*item);
}
m_charges = charges;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
m_item = db->GetItem(item_id);
if (m_item) {
m_item = new ItemData(*m_item);
}
else {
m_item = nullptr;
}
m_charges = charges;
m_price = 0;
m_merchantslot = 0;
m_attuned=false;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
} else {
m_color = 0;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
m_use_type = use_type;
m_item = nullptr;
m_charges = 0;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
m_color = 0;
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_use_type = use_type;
}
// Make a copy of an EQ::ItemInstance object
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
{
m_use_type=copy.m_use_type;
if(copy.m_item)
m_item = new ItemData(*copy.m_item);
else
m_item = nullptr;
m_use_type = copy.m_use_type;
if (copy.m_item) {
m_item = new ItemData(*copy.m_item);
} else {
m_item = nullptr;
}
m_charges = copy.m_charges;
m_price = copy.m_price;
m_color = copy.m_color;
m_merchantslot = copy.m_merchantslot;
m_currentslot = copy.m_currentslot;
m_attuned = copy.m_attuned;
m_merchantcount = copy.m_merchantcount;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
m_merchantslot=copy.m_merchantslot;
m_currentslot=copy.m_currentslot;
m_attuned=copy.m_attuned;
m_merchantcount=copy.m_merchantcount;
// Copy container contents
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
ItemInstance* inst_old = it->second;
@@ -168,37 +123,42 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
inst_new = inst_old->Clone();
}
if (inst_new != nullptr) {
if (inst_new) {
m_contents[it->first] = inst_new;
}
}
std::map<std::string, std::string>::const_iterator iter;
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
m_custom_data[iter->first] = iter->second;
}
m_SerialNumber = copy.m_SerialNumber;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_SerialNumber = copy.m_SerialNumber;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_evolveLvl = copy.m_evolveLvl;
m_activated = copy.m_activated;
if (copy.m_scaledItem)
if (copy.m_scaledItem) {
m_scaledItem = new ItemData(*copy.m_scaledItem);
else
} else {
m_scaledItem = nullptr;
}
if(copy.m_evolveInfo)
if (copy.m_evolveInfo) {
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
else
} else {
m_evolveInfo = nullptr;
}
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_ornament_hero_model = copy.m_ornament_hero_model;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
}
// Clean up container contents
@@ -216,11 +176,13 @@ bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
// Check usage type
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
if (m_use_type == ItemInstWorldContainer && item_class == item::ItemClassBag) {
return true;
}
if (!m_item)
if (!m_item) {
return false;
}
return (m_item->ItemClass == item_class);
}
@@ -243,21 +205,20 @@ bool EQ::ItemInstance::IsClassBook() const
// Is item stackable?
bool EQ::ItemInstance::IsStackable() const
{
if (!m_item)
return false;
return m_item->Stackable;
return (m_item && m_item->Stackable);
}
bool EQ::ItemInstance::IsCharged() const
{
if (!m_item)
if (!m_item) {
return false;
}
if (m_item->MaxCharges > 1)
if (m_item->MaxCharges > 1) {
return true;
else
} else {
return false;
}
}
// Can item be equipped?
@@ -306,26 +267,30 @@ bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
bool EQ::ItemInstance::IsAugmentable() const
{
if (!m_item)
if (!m_item) {
return false;
}
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (m_item->AugSlotType[index] != 0)
if (m_item->AugSlotType[index] != 0) {
return true;
}
}
return false;
}
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
int index = invslot::EQUIPMENT_BEGIN;
for (; index <= invslot::EQUIPMENT_END; ++index) {
if (m_item->Slots & (1 << index)) {
if (aug_wear_slots & (1 << index))
if (aug_wear_slots & (1 << index)) {
break;
}
}
}
@@ -394,9 +359,10 @@ EQ::ItemInstance* EQ::ItemInstance::GetItem(uint8 index) const
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
{
ItemInstance *item = GetItem(slot);
if (item)
const auto item = GetItem(slot);
if (item) {
return item->GetID();
}
return 0;
}
@@ -520,14 +486,21 @@ uint8 EQ::ItemInstance::FirstOpenSlot() const
uint8 EQ::ItemInstance::GetTotalItemCount() const
{
if (!m_item)
if (!m_item) {
return 0;
}
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
if (!m_item->IsClassBag()) {
return item_count;
}
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } }
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) {
if (GetItem(index)) {
++item_count;
}
}
return item_count;
}
@@ -555,78 +528,99 @@ EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
return nullptr;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugtype) const
bool EQ::ItemInstance::IsOrnamentationAugment(EQ::ItemInstance* augment) const
{
if (!m_item || !m_item->IsClassCommon()) { return nullptr; }
if (ornamentationAugtype == 0) { return nullptr; }
if (!m_item || !m_item->IsClassCommon() || !augment) {
return false;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
{
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
{
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
if (
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
)
{
continue;
}
return GetAugment(i);
const auto augment_item = augment->GetItem();
if (!augment_item) {
return false;
}
const std::string& idfile = augment_item->IDFile;
if (
EQ::ValueWithin(
augment->GetAugmentType(),
OrnamentationAugmentTypes::StandardOrnamentation,
OrnamentationAugmentTypes::SpecialOrnamentation
) ||
(
idfile != "IT63" &&
idfile != "IT64"
) ||
augment_item->HerosForgeModel
) {
return true;
}
return false;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
{
if (!m_item || !m_item->IsClassCommon()) {
return nullptr;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
const auto augment = GetAugment(i);
if (augment && IsOrnamentationAugment(augment)) {
return augment;
}
}
return nullptr;
}
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
{
// Not a Hero Forge item.
if (m_ornament_hero_model == 0 || material_slot < 0)
if (m_ornament_hero_model == 0 || material_slot < 0) {
return 0;
}
// Item is using an explicit Hero Forge ID
if (m_ornament_hero_model >= 1000)
if (m_ornament_hero_model >= 1000) {
return m_ornament_hero_model;
}
// Item is using a shorthand ID
return (m_ornament_hero_model * 100) + material_slot;
}
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
if (!m_item || !m_item->IsClassCommon())
bool EQ::ItemInstance::UpdateOrnamentationInfo()
{
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
bool ornamentSet = false;
const auto augment = GetOrnamentationAugment();
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const ItemData* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
SetOrnamentIcon(ornamentItem->Icon);
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
if (strlen(ornamentItem->IDFile) > 2)
{
SetOrnamentationIDFile(Strings::ToUnsignedInt(&ornamentItem->IDFile[2]));
}
else
{
if (augment) {
const auto augment_item = GetOrnamentationAugment()->GetItem();
if (augment_item) {
SetOrnamentIcon(augment_item->Icon);
SetOrnamentHeroModel(augment_item->HerosForgeModel);
if (strlen(augment_item->IDFile) > 2) {
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2]));
} else {
SetOrnamentationIDFile(0);
}
ornamentSet = true;
return true;
}
}
else
{
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
}
return ornamentSet;
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
return false;
}
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
@@ -940,8 +934,9 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
// if there's no actual item, don't do anything
if (!m_item)
if (!m_item) {
return;
}
// initialize scaling items
if (m_item->CharmFileID != 0) {
@@ -950,7 +945,7 @@ void EQ::ItemInstance::Initialize(SharedDatabase *db) {
}
// initialize evolving items
else if ((db) && m_item->LoreGroup >= 1000 && m_item->LoreGroup != -1) {
else if (db && m_item->LoreGroup >= 1000) {
// not complete yet
}
}
+35 -29
View File
@@ -51,6 +51,11 @@ typedef enum {
byFlagNotSet //apply action if the flag is NOT set
} byFlagSetting;
enum OrnamentationAugmentTypes {
StandardOrnamentation = 20,
SpecialOrnamentation = 21
};
class SharedDatabase;
// ########################################
@@ -103,7 +108,8 @@ namespace EQ
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augment_type) const;
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
@@ -136,7 +142,8 @@ namespace EQ
bool IsAugmented();
bool ContainsAugmentByID(uint32 item_id);
int CountAugmentByID(uint32 item_id);
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool IsOrnamentationAugment(EQ::ItemInstance* augment) const;
ItemInstance* GetOrnamentationAugment() const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
@@ -304,34 +311,33 @@ namespace EQ
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
uint32 m_merchantslot;
int16 m_currentslot;
bool m_attuned;
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_exp;
int8 m_evolveLvl;
bool m_activated;
ItemData* m_scaledItem;
::EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_new_id_file;
uint32 m_ornament_hero_model;
uint32 m_recast_timestamp;
int m_task_delivered_count = 0;
ItemInstTypes m_use_type {ItemInstNormal}; // Usage type for item
const ItemData* m_item {nullptr}; // Ptr to item data
int16 m_charges {0}; // # of charges for chargeable items
uint32 m_price {0}; // Bazaar /trader price
uint32 m_color {0};
uint32 m_merchantslot {0};
int16 m_currentslot {0};
bool m_attuned {false};
int32 m_merchantcount {1}; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber {0}; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp {0};
int8 m_evolveLvl {0};
bool m_activated {false};
ItemData* m_scaledItem {nullptr};
::EvolveInfo* m_evolveInfo {nullptr};
bool m_scaling {false};
uint32 m_ornamenticon {0};
uint32 m_ornamentidfile {0};
uint32 m_new_id_file {0};
uint32 m_ornament_hero_model {0};
uint32 m_recast_timestamp {0};
int m_task_delivered_count {0};
//
// Items inside of this item (augs or contents);
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data;
std::map<std::string, ::Timer> m_timers;
// Items inside of this item (augs or contents) {};
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data {};
std::map<std::string, ::Timer> m_timers {};
};
}
+1 -1
View File
@@ -151,7 +151,7 @@ static char *temp=nullptr;
return false;
}
ptr++;
uint32 id = Strings::ToUnsignedInt(field[id_pos].c_str());
uint32 id = Strings::ToUnsignedInt(field[id_pos]);
items[id]=field;
for(i=0;i<10;i++) {
+21
View File
@@ -51,6 +51,7 @@ void MySQLRequestResult::ZeroOut()
m_RowCount = 0;
m_RowsAffected = 0;
m_LastInsertedID = 0;
m_error_message = "";
}
MySQLRequestResult::~MySQLRequestResult()
@@ -137,3 +138,23 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
other.ZeroOut();
return *this;
}
uint32 MySQLRequestResult::GetErrorNumber() const
{
return m_ErrorNumber;
}
void MySQLRequestResult::SetErrorNumber(uint32 m_error_number)
{
m_ErrorNumber = m_error_number;
}
const std::string &MySQLRequestResult::GetErrorMessage() const
{
return m_error_message;
}
void MySQLRequestResult::SetErrorMessage(const std::string &m_error_message)
{
MySQLRequestResult::m_error_message = m_error_message;
}
+15 -3
View File
@@ -33,30 +33,42 @@ private:
uint32 m_LastInsertedID;
uint32 m_ErrorNumber;
std::string m_error_message;
public:
MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected = 0, uint32 rowCount = 0, uint32 columnCount = 0, uint32 lastInsertedID = 0, uint32 errorNumber = 0, char *errorBuffer = nullptr);
MySQLRequestResult();
MySQLRequestResult();
MySQLRequestResult(MySQLRequestResult&& moveItem);
~MySQLRequestResult();
MySQLRequestResult& operator=(MySQLRequestResult&& other);
bool Success() const { return m_Success;}
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
std::string ErrorMessage() const {
if (!m_error_message.empty()) {
return m_error_message;
}
return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");
}
uint32 ErrorNumber() const {return m_ErrorNumber;}
uint32 RowsAffected() const {return m_RowsAffected;}
uint32 RowCount() const {return m_RowCount;}
uint32 ColumnCount() const {return m_ColumnCount;}
uint32 LastInsertedID() const {return m_LastInsertedID;}
// default to 0 index since we mostly use it that way anyways.
uint32 LengthOfColumn(int columnIndex = 0);
uint32 LengthOfColumn(int columnIndex = 0);
const std::string FieldName(int columnIndex);
MySQLRequestRow& begin() { return m_CurrentRow; }
MySQLRequestRow& end() { return m_OneBeyondRow; }
uint32 GetErrorNumber() const;
void SetErrorNumber(uint32 m_error_number);
const std::string &GetErrorMessage() const;
void SetErrorMessage(const std::string &m_error_message);
private:
void FreeInternals();
void ZeroOut();
+1 -1
View File
@@ -7,7 +7,7 @@ EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
m_server = std::make_unique<EQ::Net::TCPServer>();
m_server->Listen(addr, port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
ConsoleServerConnection *c = new ConsoleServerConnection(this, connection);
m_connections.insert(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
m_connections.emplace(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
});
}
+6 -6
View File
@@ -97,7 +97,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
m_on_new_connection(connection);
}
m_connections.insert(std::make_pair(std::make_pair(addr, port), connection));
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
}
void EQ::Net::DaybreakConnectionManager::Process()
@@ -234,7 +234,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
if (m_on_new_connection) {
m_on_new_connection(connection);
}
m_connections.insert(std::make_pair(std::make_pair(endpoint, port), connection));
m_connections.emplace(std::make_pair(std::make_pair(endpoint, port), connection));
connection->ProcessPacket(p);
}
else if (data[1] != OP_OutOfSession) {
@@ -527,7 +527,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
DynamicPacket *out = new DynamicPacket();
out->PutPacket(0, p);
s->packet_queue.insert(std::make_pair(seq, out));
s->packet_queue.emplace(std::make_pair(seq, out));
}
}
@@ -1427,7 +1427,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(first_packet);
@@ -1459,7 +1459,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(packet);
@@ -1483,7 +1483,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(packet);
+1 -1
View File
@@ -22,7 +22,7 @@ void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
m_streams.insert(std::make_pair(connection, stream));
m_streams.emplace(std::make_pair(connection, stream));
if (m_on_new_connection) {
m_on_new_connection(stream);
}
+1 -1
View File
@@ -45,7 +45,7 @@ void EQ::Net::ServertalkClient::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
@@ -41,7 +41,7 @@ void EQ::Net::ServertalkLegacyClient::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkLegacyClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkLegacyClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
+3 -3
View File
@@ -19,12 +19,12 @@ void EQ::Net::ServertalkServer::Listen(const ServertalkServerOptions& opts)
void EQ::Net::ServertalkServer::OnConnectionIdentified(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
{
m_on_ident.insert(std::make_pair(type, cb));
m_on_ident.emplace(std::make_pair(type, cb));
}
void EQ::Net::ServertalkServer::OnConnectionRemoved(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
{
m_on_disc.insert(std::make_pair(type, cb));
m_on_disc.emplace(std::make_pair(type, cb));
}
void EQ::Net::ServertalkServer::ConnectionDisconnected(ServertalkServerConnection *conn)
@@ -75,7 +75,7 @@ void EQ::Net::ServertalkServer::ConnectionIdentified(ServertalkServerConnection
else {
std::vector<std::shared_ptr<EQ::Net::ServertalkServerConnection>> vec;
vec.push_back(*iter);
m_ident_connections.insert(std::make_pair(conn->GetIdentifier(), vec));
m_ident_connections.emplace(std::make_pair(conn->GetIdentifier(), vec));
}
m_unident_connections.erase(iter);
+1 -1
View File
@@ -100,7 +100,7 @@ void EQ::Net::ServertalkServerConnection::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkServerConnection::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkServerConnection::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
+1 -1
View File
@@ -142,7 +142,7 @@ void EQ::Net::TCPConnection::Write(const char *data, size_t count)
WriteBaton *baton = new WriteBaton;
baton->connection = this;
baton->buffer = new char[count];;
baton->buffer = new char[count];
uv_write_t *write_req = new uv_write_t;
memset(write_req, 0, sizeof(uv_write_t));
-1
View File
@@ -5218,7 +5218,6 @@ namespace RoF
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
-1
View File
@@ -5477,7 +5477,6 @@ namespace RoF2
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
+9 -9
View File
@@ -3851,17 +3851,17 @@ namespace UF
ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
}
//ORNAMENT IDFILE / ICON -
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQ::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ornaIcon = aug_weap->Icon;
uint16 ornament_icon = 0;
const auto augment = inst->GetOrnamentationAugment();
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
if (augment) {
const auto augment_item = augment->GetItem();
ornament_icon = augment_item->Icon;
ob.write(augment_item->IDFile, strlen(augment_item->IDFile));
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon();
ornament_icon = inst->GetOrnamentationIcon();
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
ob.write(tmp, strlen(tmp));
@@ -3870,7 +3870,7 @@ namespace UF
UF::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = ornaIcon;
hdrf.ornamentIcon = ornament_icon;
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown061 = 0; //possibly ornament / special ornament
hdrf.isCopied = 0; //Flag for item to be 'Copied'
+5 -5
View File
@@ -64,7 +64,7 @@ void ProcLauncher::Process() {
if(GetExitCodeProcess(cur->second->proc_info.hProcess, &res)) {
//got exit code, see if its still running...
if(res == STILL_ACTIVE) {
cur++;
++cur;
continue;
}
//else, it died, handle properly
@@ -76,7 +76,7 @@ void ProcLauncher::Process() {
//if we get here, the current process died.
tmp = cur;
tmp++;
++tmp;
ProcessTerminated(cur);
cur = tmp;
}
@@ -174,7 +174,7 @@ ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
std::vector<std::string>::iterator cur, end;
cur = it->args.begin();
end = it->args.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
args += " ";
args += *cur;
}
@@ -306,7 +306,7 @@ void ProcLauncher::TerminateAll(bool final) {
std::map<ProcRef, Spec *>::iterator cur, end;
cur = m_running.begin();
end = m_running.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
Terminate(cur->first, true);
}
} else {
@@ -317,7 +317,7 @@ void ProcLauncher::TerminateAll(bool final) {
std::map<ProcRef, Spec *>::iterator cur, end;
cur = running.begin();
end = running.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
Terminate(cur->first, true);
safe_delete(cur->second);
}
+2 -1
View File
@@ -4,7 +4,8 @@
std::string Process::execute(const std::string &cmd)
{
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
std::string command = fmt::format("{} 2>&1", cmd);
std::shared_ptr<FILE> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) { return "ERROR"; }
char buffer[128];
std::string result;
+1 -1
View File
@@ -258,7 +258,7 @@ bool EQ::ProfanityManager::clear_database_entries(DBcore *db) {
return true;
}
bool EQ::ProfanityManager::check_for_existing_entry(std::string profanity) {
bool EQ::ProfanityManager::check_for_existing_entry(const std::string& profanity) {
if (profanity.empty()) {
return false;
}
+1 -1
View File
@@ -53,7 +53,7 @@ namespace EQ
private:
static bool load_database_entries(DBcore *db);
static bool clear_database_entries(DBcore *db);
static bool check_for_existing_entry(std::string profanity);
static bool check_for_existing_entry(const std::string& profanity);
};
@@ -0,0 +1,354 @@
/**
* 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_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCharacterTributeRepository {
public:
struct CharacterTribute {
int32_t id;
uint32_t character_id;
uint8_t tier;
uint32_t tribute;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
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("character_tribute");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CharacterTribute NewEntity()
{
CharacterTribute e{};
e.id = 0;
e.character_id = 0;
e.tier = 0;
e.tribute = 0;
return e;
}
static CharacterTribute GetCharacterTribute(
const std::vector<CharacterTribute> &character_tributes,
int character_tribute_id
)
{
for (auto &character_tribute : character_tributes) {
if (character_tribute.id == character_tribute_id) {
return character_tribute;
}
}
return NewEntity();
}
static CharacterTribute FindOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
character_tribute_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
character_tribute_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CharacterTribute &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.character_id));
v.push_back(columns[2] + " = " + std::to_string(e.tier));
v.push_back(columns[3] + " = " + std::to_string(e.tribute));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CharacterTribute InsertOne(
Database& db,
CharacterTribute e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
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<CharacterTribute> &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.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
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<CharacterTribute> All(Database& db)
{
std::vector<CharacterTribute> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CharacterTribute> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CharacterTribute> 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) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], 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_CHARACTER_TRIBUTE_REPOSITORY_H
@@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseItemsRepository {
public:
struct Items {
@@ -122,7 +123,7 @@ public:
int32_t pr;
int32_t procrate;
int32_t races;
int32_t range;
int32_t range_;
int32_t reclevel;
int32_t recskill;
int32_t reqlevel;
@@ -417,7 +418,7 @@ public:
"pr",
"procrate",
"races",
"range",
"`range`",
"reclevel",
"recskill",
"reqlevel",
@@ -708,7 +709,7 @@ public:
"pr",
"procrate",
"races",
"range",
"`range`",
"reclevel",
"recskill",
"reqlevel",
@@ -1033,7 +1034,7 @@ public:
e.pr = 0;
e.procrate = 0;
e.races = 0;
e.range = 0;
e.range_ = 0;
e.reclevel = 0;
e.recskill = 0;
e.reqlevel = 0;
@@ -1240,8 +1241,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
items_id
)
);
@@ -1353,7 +1355,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -1671,7 +1673,7 @@ public:
v.push_back(columns[100] + " = " + std::to_string(e.pr));
v.push_back(columns[101] + " = " + std::to_string(e.procrate));
v.push_back(columns[102] + " = " + std::to_string(e.races));
v.push_back(columns[103] + " = " + std::to_string(e.range));
v.push_back(columns[103] + " = " + std::to_string(e.range_));
v.push_back(columns[104] + " = " + std::to_string(e.reclevel));
v.push_back(columns[105] + " = " + std::to_string(e.recskill));
v.push_back(columns[106] + " = " + std::to_string(e.reqlevel));
@@ -1977,7 +1979,7 @@ public:
v.push_back(std::to_string(e.pr));
v.push_back(std::to_string(e.procrate));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.range));
v.push_back(std::to_string(e.range_));
v.push_back(std::to_string(e.reclevel));
v.push_back(std::to_string(e.recskill));
v.push_back(std::to_string(e.reqlevel));
@@ -2291,7 +2293,7 @@ public:
v.push_back(std::to_string(e.pr));
v.push_back(std::to_string(e.procrate));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.range));
v.push_back(std::to_string(e.range_));
v.push_back(std::to_string(e.reclevel));
v.push_back(std::to_string(e.recskill));
v.push_back(std::to_string(e.reqlevel));
@@ -2609,7 +2611,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -2918,7 +2920,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -0,0 +1,50 @@
#ifndef EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_character_tribute_repository.h"
class CharacterTributeRepository: public BaseCharacterTributeRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* CharacterTributeRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* CharacterTributeRepository::GetWhereNeverExpires()
* CharacterTributeRepository::GetWhereXAndY()
* CharacterTributeRepository::DeleteWhereXAndY()
*
* 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
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
+28
View File
@@ -44,7 +44,35 @@ public:
*/
// Custom extended repository methods here
static std::vector<int32> GetItemIDsBySearchCriteria(
Database& db,
std::string search_string,
int query_limit = 0
)
{
auto query = fmt::format(
"SELECT `id` FROM {} WHERE LOWER(`name`) LIKE '%%{}%%' ORDER BY id ASC",
TableName(),
search_string
);
if (query_limit >= 1) {
query += fmt::format(" LIMIT {}", query_limit);
}
std::vector<int32> item_id_list;
auto results = db.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return item_id_list;
}
for (auto row : results) {
item_id_list.emplace_back(Strings::ToInt(row[0]));
}
return item_id_list;
}
};
#endif //EQEMU_ITEMS_REPOSITORY_H
+3 -3
View File
@@ -141,11 +141,11 @@ bool RuleManager::SetRule(const std::string &rule_name, const std::string &rule_
switch (type) {
case IntRule:
m_RuleIntValues[index] = Strings::ToInt(rule_value.c_str());
m_RuleIntValues[index] = Strings::ToInt(rule_value);
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
break;
case RealRule:
m_RuleRealValues[index] = Strings::ToFloat(rule_value.c_str());
m_RuleRealValues[index] = Strings::ToFloat(rule_value);
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
break;
case BoolRule:
@@ -369,7 +369,7 @@ void RuleManager::_SaveRule(Database *db, RuleType type, uint16 index) {
break;
}
const auto rule_notes = _GetRuleNotes(type, index);
const auto& rule_notes = _GetRuleNotes(type, index);
const auto& l = RuleValuesRepository::GetWhere(
*db,
+6 -3
View File
@@ -136,7 +136,6 @@ RULE_BOOL(Character, EnableFoodRequirement, true, "If disabled, food is no longe
RULE_INT(Character, BaseInstrumentSoftCap, 36, "Softcap for instrument mods, 36 commonly referred to as 3.6 as well")
RULE_BOOL(Character, UseSpellFileSongCap, true, "When they removed the AA that increased the cap they removed the above and just use the spell field")
RULE_INT(Character, BaseRunSpeedCap, 158, "Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225")
RULE_INT(Character, OrnamentationAugmentType, 20, "Ornamentation Augment Type")
RULE_REAL(Character, EnvironmentDamageMulipliter, 1, "Multiplier for environmental damage like fall damage.")
RULE_BOOL(Character, UnmemSpellsOnDeath, true, "Setting whether at death all memorized Spells are forgotten")
RULE_REAL(Character, TradeskillUpAlchemy, 2.0, "Alchemy skillup rate adjustment. Lower is faster")
@@ -257,6 +256,7 @@ RULE_BOOL(Pets, UnTargetableSwarmPet, false, "Setting whether swarm pets should
RULE_REAL(Pets, PetPowerLevelCap, 10, "Maximum number of levels a player pet can go up with pet power")
RULE_BOOL(Pets, CanTakeNoDrop, false, "Setting whether anyone can give no-drop items to pets")
RULE_BOOL(Pets, LivelikeBreakCharmOnInvis, true, "Default: true will break charm on any type of invis (hide/ivu/iva/etc) false will only break if the pet can not see you (ex. you have an undead pet and cast IVU")
RULE_BOOL(Pets, ClientPetsUseOwnerNameInLastName, true, "Disable this to keep client pet's last names from being owner_name's pet")
RULE_CATEGORY_END()
RULE_CATEGORY(GM)
@@ -274,7 +274,6 @@ RULE_BOOL(World, EnableTutorialButton, true, "Setting whether the Tutorial butto
RULE_BOOL(World, EnableReturnHomeButton, true, "Setting whether the Return Home button should be active")
RULE_INT(World, MaxLevelForTutorial, 10, "The highest level with which you can enter the tutorial")
RULE_INT(World, TutorialZoneID, 189, "Zone ID of the tutorial")
RULE_INT(World, GuildBankZoneID, 345, "Zone ID of the guild bank")
RULE_INT(World, MinOfflineTimeToReturnHome, 21600, "Minimum offline time to activate the Return Home button. 21600 seconds is 6 Hours")
RULE_INT(World, MaxClientsPerIP, -1, "Maximum number of clients allowed to connect per IP address if account status is < AddMaxClientsStatus. Default value: -1 (feature disabled)")
RULE_INT(World, ExemptMaxClientsStatus, -1, "Exempt accounts from the MaxClientsPerIP and AddMaxClientsStatus rules, if their status is >= this value. Default value: -1 (feature disabled)")
@@ -299,6 +298,7 @@ RULE_BOOL(World, StartZoneSameAsBindOnCreation, true, "Should the start zone alw
RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for characters that are online at login")
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
RULE_INT(World, MaximumQuestErrors, 30, "Changes the maximum number of quest errors that can be displayed in #questerrors, default is 30")
RULE_CATEGORY_END()
RULE_CATEGORY(Zone)
@@ -446,7 +446,8 @@ 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, 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, ResurrectionEffectsBlock, true, "If enabled, resurrection effects cannot be overwritten.")
RULE_INT(Spells, ResurrectionEffectBlock, 2, "0 = allow overwrites/rule disabled. If set to 1 = Block all buffs that would overwrite Resurrection Effects. If set to 2 = Will not overwrite Resurrection Effects, instead moves new buff to an empty slot if available. Default is 2.")
RULE_BOOL(Spells, WaterMatchRequiredForLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for spells LoS to pass.")
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
@@ -519,6 +520,8 @@ RULE_BOOL(Combat, HeadshotOnlyHumanoids, true, "Enable or disable Headshot only
RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shielding Ability (/shield), true by default.")
RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)
+8 -10
View File
@@ -294,7 +294,7 @@ void EQ::SayLinkEngine::generate_text()
m_LinkText = "null";
}
std::string EQ::SayLinkEngine::GenerateQuestSaylink(std::string saylink_text, bool silent, std::string link_name)
std::string EQ::SayLinkEngine::GenerateQuestSaylink(const std::string& saylink_text, bool silent, const std::string& link_name)
{
uint32 saylink_id = 0;
@@ -403,16 +403,14 @@ SaylinkRepository::Saylink EQ::SayLinkEngine::GetOrSaveSaylink(std::string sayli
}
// if not found in database - save
if (saylinks.empty()) {
auto new_saylink = SaylinkRepository::NewEntity();
new_saylink.phrase = saylink_text;
auto new_saylink = SaylinkRepository::NewEntity();
new_saylink.phrase = saylink_text;
// persist to database
auto link = SaylinkRepository::InsertOne(database, new_saylink);
if (link.id > 0) {
g_cached_saylinks.emplace_back(link);
return link;
}
// persist to database
auto link = SaylinkRepository::InsertOne(database, new_saylink);
if (link.id > 0) {
g_cached_saylinks.emplace_back(link);
return link;
}
return {};
+1 -1
View File
@@ -101,7 +101,7 @@ namespace EQ
const std::string& LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
const std::string& LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
static std::string GenerateQuestSaylink(std::string saylink_text, bool silent, std::string link_name);
static std::string GenerateQuestSaylink(const std::string& saylink_text, bool silent, const std::string& link_name);
void Reset();
+13 -12
View File
@@ -235,18 +235,19 @@
#define ServerOP_ReloadMerchants 0x4109
#define ServerOP_ReloadNPCEmotes 0x4110
#define ServerOP_ReloadObjects 0x4111
#define ServerOP_ReloadPerlExportSettings 0x4112
#define ServerOP_ReloadRules 0x4113
#define ServerOP_ReloadStaticZoneData 0x4114
#define ServerOP_ReloadTasks 0x4115
#define ServerOP_ReloadTitles 0x4116
#define ServerOP_ReloadTraps 0x4117
#define ServerOP_ReloadVariables 0x4118
#define ServerOP_ReloadVeteranRewards 0x4119
#define ServerOP_ReloadWorld 0x4120
#define ServerOP_ReloadZonePoints 0x4121
#define ServerOP_ReloadDzTemplates 0x4122
#define ServerOP_ReloadZoneData 0x4123
#define ServerOP_ReloadOpcodes 0x4112
#define ServerOP_ReloadPerlExportSettings 0x4113
#define ServerOP_ReloadRules 0x4114
#define ServerOP_ReloadStaticZoneData 0x4115
#define ServerOP_ReloadTasks 0x4116
#define ServerOP_ReloadTitles 0x4117
#define ServerOP_ReloadTraps 0x4118
#define ServerOP_ReloadVariables 0x4119
#define ServerOP_ReloadVeteranRewards 0x4120
#define ServerOP_ReloadWorld 0x4121
#define ServerOP_ReloadZonePoints 0x4122
#define ServerOP_ReloadDzTemplates 0x4123
#define ServerOP_ReloadZoneData 0x4124
#define ServerOP_CZDialogueWindow 0x4500
#define ServerOP_CZLDoNUpdate 0x4501
+2 -2
View File
@@ -47,9 +47,9 @@ const SharedTasksRepository::SharedTasks &SharedTask::GetDbSharedTask() const
return m_db_shared_task;
}
void SharedTask::SetDbSharedTask(const SharedTasksRepository::SharedTasks &m_db_shared_task)
void SharedTask::SetDbSharedTask(const SharedTasksRepository::SharedTasks &t)
{
SharedTask::m_db_shared_task = m_db_shared_task;
SharedTask::m_db_shared_task = t;
}
SharedTaskRequest SharedTask::GetRequestCharacters(Database &db, uint32_t requested_character_id)
+1 -1
View File
@@ -216,7 +216,7 @@ public:
// active record of database shared task
const SharedTasksRepository::SharedTasks &GetDbSharedTask() const;
void SetDbSharedTask(const SharedTasksRepository::SharedTasks &m_db_shared_task);
void SetDbSharedTask(const SharedTasksRepository::SharedTasks &t);
std::vector<SharedTaskActivityStateEntry> m_shared_task_activity_state;
std::vector<SharedTaskMember> m_members;
+92 -69
View File
@@ -133,55 +133,54 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
{
char MailKeyString[17];
char mail_key[17];
if (RuleB(Chat, EnableMailKeyIPVerification) == true)
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
else
sprintf(MailKeyString, "%08X", MailKey);
if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
}
else {
sprintf(mail_key, "%08X", MailKey);
}
const std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
MailKeyString, CharID);
const auto results = QueryDatabase(query);
if (!results.Success())
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, MailKeyString, results.ErrorMessage().c_str());
const std::string query = StringFormat(
"UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
mail_key, CharID
);
const auto results = QueryDatabase(query);
if (!results.Success()) {
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
}
}
std::string SharedDatabase::GetMailKey(int CharID, bool key_only)
SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
{
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", CharID);
auto results = QueryDatabase(query);
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
Log(Logs::Detail, Logs::MySQLError, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str());
return std::string();
return MailKeys{};
}
if (!results.RowCount()) {
Log(Logs::General, Logs::ClientLogin, "Error: Mailkey for character id [%i] does not exist or could not be found", CharID);
return std::string();
Log(Logs::General,
Logs::ClientLogin,
"Error: Mailkey for character id [%i] does not exist or could not be found",
character_id
);
return MailKeys{};
}
auto& row = results.begin();
auto &row = results.begin();
if (row != results.end()) {
std::string mail_key = row[0];
if (mail_key.length() > 8 && key_only) {
return mail_key.substr(8);
}
else {
return mail_key;
}
return MailKeys{
.mail_key = mail_key.substr(8),
.mail_key_full = mail_key
};
}
else {
Log(Logs::General, Logs::MySQLError, "Internal MySQL error in SharedDatabase::GetMailKey(int, bool)");
return std::string();
}
return MailKeys{};
}
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQ::ItemInstance*>::const_iterator &start, std::list<EQ::ItemInstance*>::const_iterator &end)
@@ -425,17 +424,13 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
{
const std::string query = StringFormat("SELECT sharedplat FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
if (results.RowCount() != 1)
return 0;
auto& row = results.begin();
const auto query = fmt::format("SELECT sharedplat FROM account WHERE id = {}", account_id);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return 0;
}
auto row = results.begin();
return Strings::ToInt(row[0]);
}
@@ -499,25 +494,32 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
{
std::string query;
if (is_charid)
query = StringFormat("SELECT sb.slotid, sb.itemid, sb.charges, "
"sb.augslot1, sb.augslot2, sb.augslot3, "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
"FROM sharedbank sb INNER JOIN character_data ch "
"ON ch.account_id=sb.acctid WHERE ch.id = %i ORDER BY sb.slotid",
id);
else
query = StringFormat("SELECT slotid, itemid, charges, "
"augslot1, augslot2, augslot3, "
"augslot4, augslot5, augslot6, custom_data "
"FROM sharedbank WHERE acctid=%i ORDER BY slotid",
id);
if (is_charid) {
query = fmt::format(
"SELECT sb.slotid, sb.itemid, sb.charges, "
"sb.augslot1, sb.augslot2, sb.augslot3, "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
"FROM sharedbank sb INNER JOIN character_data ch "
"ON ch.account_id = sb.acctid WHERE ch.id = {} ORDER BY sb.slotid",
id
);
} else {
query = fmt::format(
"SELECT slotid, itemid, charges, "
"augslot1, augslot2, augslot3, "
"augslot4, augslot5, augslot6, custom_data "
"FROM sharedbank WHERE acctid = {} ORDER BY slotid",
id
);
}
auto results = QueryDatabase(query);
// If we have no results we still need to return true
if (!results.Success()) {
return false;
}
for (auto& row = results.begin(); row != results.end(); ++row) {
for (auto row : results) {
int16 slot_id = static_cast<int16>(Strings::ToInt(row[0]));
uint32 item_id = Strings::ToUnsignedInt(row[1]);
const int16 charges = static_cast<int16>(Strings::ToInt(row[2]));
@@ -533,16 +535,26 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
const EQ::ItemData *item = GetItem(item_id);
if (!item) {
LogError("Warning: [{}] [{}] has an invalid item_id [{}] in inventory slot [{}]",
((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id);
LogError(
"Warning: [{}] [{}] has an invalid item_id [{}] in inventory slot [{}]",
is_charid ? "charid" : "acctid",
id,
item_id,
slot_id
);
continue;
}
auto inst = CreateBaseItem(item, charges);
if (!inst) {
continue;
}
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
if (inst && item->IsClassCommon()) {
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
if (aug[i])
if (aug[i]) {
inst->PutAugment(this, i, aug[i]);
}
}
}
@@ -556,14 +568,21 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id != INVALID_INDEX)
if (put_slot_id != INVALID_INDEX) {
continue;
}
LogError("Warning: Invalid slot_id for item in shared bank inventory: [{}]=[{}], item_id=[{}], slot_id=[{}]",
((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id);
LogError(
"Warning: Invalid slot_id for item in shared bank inventory: [{}]=[{}], item_id=[{}], slot_id=[{}]",
is_charid ? "charid" : "acctid",
id,
item_id,
slot_id
);
if (is_charid)
if (is_charid) {
SaveInventory(id, nullptr, slot_id);
}
}
return true;
@@ -619,7 +638,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
}
else if (slot_id <= EQ::invbag::BANK_BAGS_END && slot_id >= EQ::invbag::BANK_BAGS_BEGIN) { // Titanium check
const auto parent_index = ((slot_id - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT);
if (parent_index < EQ::invslot::SLOT_BEGIN || parent_index >= bank_size) {
if (parent_index >= bank_size) {
cv_conflict = true;
continue;
}
@@ -1564,24 +1583,28 @@ EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
// set it to 1 charge so that it is usable on creation
if (charges == 0 && item->MaxCharges == -1)
if (charges == 0 && item->MaxCharges == -1) {
charges = 1;
}
// Stackable items need a minimum charge of 1 to remain moveable.
if(charges <= 0 && item->Stackable)
if (charges <= 0 && item->Stackable) {
charges = 1;
}
inst = new EQ::ItemInstance(item, charges);
if (inst == nullptr) {
if (!inst) {
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateBaseItem()");
LogError("Item Data = ID: {}, Name: {}, Charges: {}", item->ID, item->Name, charges);
return nullptr;
}
if(item->CharmFileID != 0 || (item->LoreGroup >= 1000 && item->LoreGroup != -1)) {
if (item->CharmFileID != 0 || item->LoreGroup >= 1000) {
inst->Initialize(this);
}
}
return inst;
}
+5 -1
View File
@@ -81,7 +81,11 @@ public:
bool SetGMInvul(uint32 account_id, bool gminvul);
bool SetGMFlymode(uint32 account_id, uint8 flymode);
void SetMailKey(int CharID, int IPAddress, int MailKey);
std::string GetMailKey(int CharID, bool key_only = false);
struct MailKeys {
std::string mail_key;
std::string mail_key_full;
};
MailKeys GetMailKey(int character_id);
bool SaveCursor(
uint32 char_id,
std::list<EQ::ItemInstance *>::const_iterator &start,
-27
View File
@@ -148,33 +148,6 @@ int32 EQ::skills::GetBaseDamage(SkillType skill)
}
}
bool EQ::skills::IsMeleeDmg(SkillType skill)
{
switch (skill) {
case Skill1HBlunt:
case Skill1HSlashing:
case Skill2HBlunt:
case Skill2HSlashing:
case SkillBackstab:
case SkillBash:
case SkillDragonPunch:
case SkillEagleStrike:
case SkillFlyingKick:
case SkillHandtoHand:
case SkillKick:
case Skill1HPiercing:
case SkillRiposte:
case SkillRoundKick:
case SkillThrowing:
case SkillTigerClaw:
case SkillFrenzy:
case Skill2HPiercing:
return true;
default:
return false;
}
}
const std::map<EQ::skills::SkillType, std::string>& EQ::skills::GetSkillTypeMap()
{
static const std::map<SkillType, std::string> skill_type_map = {
-1
View File
@@ -168,7 +168,6 @@ namespace EQ
bool IsBardInstrumentSkill(SkillType skill);
bool IsCastingSkill(SkillType skill);
int32 GetBaseDamage(SkillType skill);
bool IsMeleeDmg(SkillType skill);
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
extern const std::vector<SkillType>& GetExtraDamageSkills();
+1177 -700
View File
File diff suppressed because it is too large Load Diff
+103 -62
View File
@@ -171,6 +171,37 @@
#define SPELL_ILLUSION_MALE 1732
#define SPELL_UNSUMMON_SELF 892
#define SPELL_ANCIENT_LIFEBANE 2115
#define SPELL_GMHP25K 6817
#define SPELL_GMHP50K 6818
#define SPELL_GMHP100K 6819
#define SPELL_GMHP225K 6820
#define SPELL_GMHP475K 6821
#define SPELL_GMHP925K 6822
#define SPELL_GMHP2M 6823
#define SPELL_GMHP3M 6824
#define SPELL_GMHP5M 39851
#define SPELL_GUIDE_ACTING_ONE 778
#define SPELL_GUIDE_ALLIANCE_ONE 810
#define SPELL_GUIDE_CANCEL_MAGIC_ONE 811
#define SPELL_GUIDE_JOURNEY_ONE 813
#define SPELL_GUIDE_VISION_ONE 814
#define SPELL_GUIDE_HEALTH_ONE 815
#define SPELL_GUIDE_INVULNERABILITY_ONE 816
#define SPELL_GUIDE_BOLT_ONE 817
#define SPELL_GUIDE_MEMORY_BLUR_ONE 818
#define SPELL_GUIDE_ACTING_TWO 1209
#define SPELL_GUIDE_CANCEL_MAGIC_TWO 1211
#define SPELL_GUIDE_JOURNEY_TWO 1212
#define SPELL_GUIDE_VISION_TWO 1213
#define SPELL_GUIDE_HEALTH_TWO 1214
#define SPELL_GUIDE_INVULNERABILITY_TWO 1215
#define SPELL_GUIDE_BOLT_TWO 1216
#define SPELL_GUIDE_MEMORY_BLUR_TWO 1217
#define SPELL_GUIDE_ALLIANCE_TWO 1219
#define SPELL_GUIDE_EVACUATION 3921
#define SPELL_GUIDE_LEVITATION 39852
#define SPELL_GUIDE_SPELL_HASTE 39853
#define SPELL_GUIDE_HASTE 39854
//spellgroup ids
#define SPELLGROUP_FRENZIED_BURNOUT 2754
@@ -201,8 +232,22 @@
#define INSTRUMENT_LUTE 13011
#define INSTRUMENT_HORN 13012
//option types for the rule Spells:ResurrectionEffectBlock
#define RES_EFFECTS_CANNOT_STACK -1
#define NO_RES_EFFECTS_BLOCK 0
#define RES_EFFECTS_BLOCK 1
#define RES_EFFECTS_BLOCK_WITH_BUFFS 2
#define MOVE_NEW_SLOT 2
const int Z_AGGRO=10;
#define PARTIAL_DEATH_SAVE 1
#define FULL_DEATH_SAVE 2
#define MAX_FAST_HEAL_CASTING_TIME 2000
#define MAX_VERY_FAST_HEAL_CASTING_TIME 1000
#define DETRIMENTAL_EFFECT 0
#define BENEFICIAL_EFFECT 1
#define BENEFICIAL_EFFECT_GROUP_ONLY 2
const uint32 MobAISpellRange=100; // max range of buffs
@@ -504,7 +549,7 @@ enum SpellRestriction
HAS_NO_ILLUSIONS_OF_GRANDEUR_BUFF = 12519, //
IS_HP_ABOVE_50_PCT = 16010, //
IS_HP_UNDER_50_PCT = 16031, //
IS_OFF_HAND_EQUIPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
IS_OFF_HAND_EQUIPPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
HAS_NO_PACT_OF_FATE_RECOURSE_BUFF = 29556, // This spell will not work while Pact of Fate Recourse is active. | caster restriction |
HAS_NO_SHROUD_OF_PRAYER_BUFF = 32339, // Your target cannot receive another Quiet Prayer this soon.
IS_MANA_BELOW_20_PCT = 38311, // This ability requires you to be at or below 20% of your maximum mana.
@@ -1160,7 +1205,7 @@ typedef enum {
#define SE_LimitUseMin 422 // implemented, @Ff Minium amount of numhits for a spell to be focused, base: numhit amt
#define SE_LimitUseType 423 // implemented, @Ff Focus will only affect if has this numhits type, base: numhit type
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
#define SE_SkillProcAttempt 427 // implemented - chance to proc when using a skill(ie taunt)
#define SE_LimitToSkill 428 // implemented, @Procs, limits what combat skills will effect a skill proc, base: skill value, limit: none, max: none
@@ -1211,7 +1256,7 @@ typedef enum {
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Duel Wield is equiped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Dual Wield is equipped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
@@ -1443,7 +1488,7 @@ extern int32 SPDAT_RECORDS;
bool IsTargetableAESpell(uint16 spell_id);
bool IsSacrificeSpell(uint16 spell_id);
bool IsLifetapSpell(uint16 spell_id);
bool IsMezSpell(uint16 spell_id);
bool IsMesmerizeSpell(uint16 spell_id);
bool IsStunSpell(uint16 spell_id);
bool IsSlowSpell(uint16 spell_id);
bool IsHasteSpell(uint16 spell_id);
@@ -1452,22 +1497,23 @@ bool IsPercentalHealSpell(uint16 spell_id);
bool IsGroupOnlySpell(uint16 spell_id);
bool IsBeneficialSpell(uint16 spell_id);
bool IsDetrimentalSpell(uint16 spell_id);
bool IsInvisSpell(uint16 spell_id);
bool IsInvisibleSpell(uint16 spell_id);
bool IsInvulnerabilitySpell(uint16 spell_id);
bool IsCHDurationSpell(uint16 spell_id);
bool IsCompleteHealDurationSpell(uint16 spell_id);
bool IsPoisonCounterSpell(uint16 spell_id);
bool IsDiseaseCounterSpell(uint16 spell_id);
bool IsSummonItemSpell(uint16 spell_id);
bool IsSummonSkeletonSpell(uint16 spell_id);
bool IsSummonPetSpell(uint16 spell_id);
bool IsSummonPCSpell(uint16 spell_id);
bool IsPetSpell(uint16 spell_id);
bool IsCharmSpell(uint16 spell_id);
bool IsBlindSpell(uint16 spell_id);
bool IsEffectHitpointsSpell(uint16 spell_id);
bool IsReduceCastTimeSpell(uint16 spell_id);
bool IsHealthSpell(uint16 spell_id);
bool IsCastTimeReductionSpell(uint16 spell_id);
bool IsIncreaseDurationSpell(uint16 spell_id);
bool IsReduceManaSpell(uint16 spell_id);
bool IsExtRangeSpell(uint16 spell_id);
bool IsManaCostReductionSpell(uint16 spell_id);
bool IsIncreaseRangeSpell(uint16 spell_id);
bool IsImprovedHealingSpell(uint16 spell_id);
bool IsImprovedDamageSpell(uint16 spell_id);
bool IsAEDurationSpell(uint16 spell_id);
@@ -1475,26 +1521,22 @@ bool IsPureNukeSpell(uint16 spell_id);
bool IsAENukeSpell(uint16 spell_id);
bool IsPBAENukeSpell(uint16 spell_id);
bool IsAERainNukeSpell(uint16 spell_id);
bool IsPartialCapableSpell(uint16 spell_id);
bool IsPartialResistableSpell(uint16 spell_id);
bool IsResistableSpell(uint16 spell_id);
bool IsGroupSpell(uint16 spell_id);
bool IsTGBCompatibleSpell(uint16 spell_id);
bool IsBardSong(uint16 spell_id);
bool IsEffectInSpell(uint16 spellid, int effect);
uint16 GetTriggerSpellID(uint16 spell_id, uint32 effect);
bool IsBlankSpellEffect(uint16 spellid, int effect_index);
bool IsValidSpell(uint32 spellid);
bool IsSummonSpell(uint16 spellid);
bool IsEvacSpell(uint16 spellid);
bool IsDamageSpell(uint16 spellid);
bool IsFearSpell(uint16 spellid);
bool IsCureSpell(uint16 spellid);
bool BeneficialSpell(uint16 spell_id);
bool GroupOnlySpell(uint16 spell_id);
int GetSpellEffectIndex(uint16 spell_id, int effect);
int CanUseSpell(uint16 spellid, int classa, int level);
int GetMinLevel(uint16 spell_id);
int GetSpellLevel(uint16 spell_id, int classa);
bool IsEffectInSpell(uint16 spell_id, int effect_id);
uint16 GetSpellTriggerSpellID(uint16 spell_id, int effect_id);
bool IsBlankSpellEffect(uint16 spell_id, int effect_index);
bool IsValidSpell(uint32 spell_id);
bool IsSummonSpell(uint16 spell_id);
bool IsDamageSpell(uint16 spell_id);
bool IsFearSpell(uint16 spell_id);
bool IsCureSpell(uint16 spell_id);
int GetSpellEffectIndex(uint16 spell_id, int effect_id);
uint8 GetSpellMinimumLevel(uint16 spell_id);
uint8 GetSpellLevel(uint16 spell_id, uint8 class_id);
int CalcBuffDuration_formula(int level, int formula, int duration);
int32 CalculatePoisonCounters(uint16 spell_id);
int32 CalculateDiseaseCounters(uint16 spell_id);
@@ -1505,10 +1547,11 @@ bool IsDisciplineBuff(uint16 spell_id);
bool IsDiscipline(uint16 spell_id);
bool IsCombatSkill(uint16 spell_id);
bool IsResurrectionEffects(uint16 spell_id);
int8 GetSpellResurrectionSicknessCheck(uint16 spell_id_one, uint16 spell_id_two);
bool IsRuneSpell(uint16 spell_id);
bool IsMagicRuneSpell(uint16 spell_id);
bool IsManaTapSpell(uint16 spell_id);
bool IsAllianceSpellLine(uint16 spell_id);
bool IsAllianceSpell(uint16 spell_id);
bool IsDeathSaveSpell(uint16 spell_id);
bool IsFullDeathSaveSpell(uint16 spell_id);
bool IsPartialDeathSaveSpell(uint16 spell_id);
@@ -1517,10 +1560,10 @@ bool IsSuccorSpell(uint16 spell_id);
bool IsTeleportSpell(uint16 spell_id);
bool IsTranslocateSpell(uint16 spell_id);
bool IsGateSpell(uint16 spell_id);
bool IsPlayerIllusionSpell(uint16 spell_id); // seveian 2008-09-23
bool IsIllusionSpell(uint16 spell_id);
bool IsLDoNObjectSpell(uint16 spell_id);
int32 GetSpellResistType(uint16 spell_id);
int32 GetSpellTargetType(uint16 spell_id);
int GetSpellResistType(uint16 spell_id);
int GetSpellTargetType(uint16 spell_id);
bool IsHealOverTimeSpell(uint16 spell_id);
bool IsCompleteHealSpell(uint16 spell_id);
bool IsFastHealSpell(uint16 spell_id);
@@ -1535,38 +1578,36 @@ bool IsSelfConversionSpell(uint16 spell_id);
bool IsBuffSpell(uint16 spell_id);
bool IsPersistDeathSpell(uint16 spell_id);
bool IsSuspendableSpell(uint16 spell_id);
uint32 GetMorphTrigger(uint32 spell_id);
bool IsCastonFadeDurationSpell(uint16 spell_id);
bool IsPowerDistModSpell(uint16 spell_id);
uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
uint32 GetPartialMagicRuneAmount(uint32 spell_id);
bool NoDetrimentalSpellAggro(uint16 spell_id);
bool IsStackableDot(uint16 spell_id);
bool IsBardOnlyStackEffect(int effect);
bool IsCastWhileInvis(uint16 spell_id);
bool IsEffectIgnoredInStacking(int spa);
bool IsFocusLimit(int spa);
bool SpellRequiresTarget(int target_type);
bool IsVirusSpell(int32 spell_id);
int GetViralMinSpreadTime(int32 spell_id);
int GetViralMaxSpreadTime(int32 spell_id);
int GetViralSpreadRange(int32 spell_id);
bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect);
bool IsPulsingBardSong(int32 spell_id);
uint32 GetProcLimitTimer(int32 spell_id, int proc_type);
bool IgnoreCastingRestriction(int32 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75);
int GetSpellEffectDescNum(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
bool DetrimentalSpellAllowsRest(uint16 spell_id);
uint32 GetNimbusEffect(uint16 spell_id);
int32 GetFuriousBash(uint16 spell_id);
bool IsCastOnFadeDurationSpell(uint16 spell_id);
bool IsDistanceModifierSpell(uint16 spell_id);
int GetSpellPartialMeleeRuneReduction(uint16 spell_id);
int GetSpellPartialMagicRuneReduction(uint16 spell_id);
int GetSpellPartialMeleeRuneAmount(uint16 spell_id);
int GetSpellPartialMagicRuneAmount(uint16 spell_id);
bool IsNoDetrimentalSpellAggroSpell(uint16 spell_id);
bool IsStackableDOT(uint16 spell_id);
bool IsBardOnlyStackEffect(int effect_id);
bool IsCastWhileInvisibleSpell(uint16 spell_id);
bool IsEffectIgnoredInStacking(int effect_id);
bool IsFocusLimit(int effect_id);
bool IsTargetRequiredForSpell(uint16 spell_id);
bool IsVirusSpell(uint16 spell_id);
int GetSpellViralMinimumSpreadTime(uint16 spell_id);
int GetSpellViralMaximumSpreadTime(uint16 spell_id);
int GetSpellViralSpreadRange(uint16 spell_id);
bool IsInstrumentModifierAppliedToSpellEffect(uint16 spell_id, int effect_id);
bool IsPulsingBardSong(uint16 spell_id);
int GetSpellProcLimitTimer(uint16 spell_id, int proc_type);
bool IsCastNotStandingSpell(uint16 spell_id);
int GetSpellEffectDescriptionNumber(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int damage_shield_type = 0);
bool IsRestAllowedSpell(uint16 spell_id);
int GetSpellNimbusEffect(uint16 spell_id);
int GetSpellFuriousBash(uint16 spell_id);
bool IsShortDurationBuff(uint16 spell_id);
bool IsSpellUsableThisZoneType(uint16 spell_id, uint8 zone_type);
bool IsSpellUsableInThisZoneType(uint16 spell_id, uint8 zone_type);
const char *GetSpellName(uint16 spell_id);
int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot = 0);
bool CastRestrictedSpell(int spellid);
int GetSpellStatValue(uint16 spell_id, const char* stat_identifier, uint8 slot = 0);
bool IsCastRestrictedSpell(uint16 spell_id);
#endif
+3 -3
View File
@@ -658,11 +658,11 @@ typedef pdb_symbol current;
size_t next = 0;
size_t delimiter_size = sizeof(kBackwardPathDelimiter) - 1;
while ((next = s.find(kBackwardPathDelimiter, last)) != std::string::npos) {
out.push_back(s.substr(last, next - last));
out.emplace_back(s.substr(last, next - last));
last = next + delimiter_size;
}
if (last <= s.length()) {
out.push_back(s.substr(last));
out.emplace_back(s.substr(last));
}
return out;
}
@@ -3760,7 +3760,7 @@ private:
continue;
started = true;
}
lines.push_back(make_pair(line_idx, line));
lines.emplace_back(make_pair(line_idx, line));
}
lines.erase(
+5 -7
View File
@@ -76,7 +76,7 @@ std::vector<std::string> Strings::Split(const std::string& s, const std::string&
res.push_back(token);
}
res.push_back(s.substr(pos_start));
res.emplace_back(s.substr(pos_start));
return res;
}
@@ -287,15 +287,12 @@ std::string Strings::Commify(const std::string &number)
for (i = string_length - 3; i >= 0; i -= 3) {
if (i > 0) {
temp_string = "," + number.substr(static_cast<unsigned long>(i), 3) + temp_string;
}
else {
} else {
temp_string = number.substr(static_cast<unsigned long>(i), 3) + temp_string;
}
}
if (i < 0) {
temp_string = number.substr(0, static_cast<unsigned long>(3 + i)) + temp_string;
}
temp_string = number.substr(0, static_cast<unsigned long>(3 + i)) + temp_string;
return temp_string;
}
@@ -373,7 +370,8 @@ std::string Strings::NumberToWords(unsigned long long int n)
return res;
}
std::string Strings::Money(uint32 platinum, uint32 gold, uint32 silver, uint32 copper)
std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 copper)
{
std::string money_string = "Unknown";
if (copper && silver && gold && platinum) { // CSGP
+3 -3
View File
@@ -114,7 +114,7 @@ public:
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 Money(uint32 platinum, uint32 gold = 0, uint32 silver = 0, uint32 copper = 0);
static std::string Money(uint64 platinum, uint64 gold = 0, uint64 silver = 0, uint64 copper = 0);
static std::string NumberToWords(unsigned long long int n);
static std::string Repeat(std::string s, int n);
static std::string Replace(std::string subject, const std::string &search, const std::string &replace);
@@ -219,7 +219,7 @@ std::vector<std::string> join_pair(
std::vector<std::string> output;
for (const std::pair<T1, T2> &src_iter: src) {
output.push_back(
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}",
@@ -253,7 +253,7 @@ std::vector<std::string> join_tuple(
for (const std::tuple<T1, T2, T3, T4> &src_iter: src) {
output.push_back(
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
+2
View File
@@ -220,6 +220,8 @@ inline bool isMsysPty(int fd) noexcept
#endif
inline bool g_is_forced_tty = std::getenv("IS_TTY");
inline bool isTerminal(const std::streambuf *osbuf) noexcept
{
if (g_is_forced_tty) {
-3
View File
@@ -57,9 +57,6 @@ typedef const char Const_char; //for perl XS
#define safe_delete(d) if(d) { delete d; d=nullptr; }
#define safe_delete_array(d) if(d) { delete[] d; d=nullptr; }
#define L32(i) ((uint32) i)
#define H32(i) ((uint32) (i >> 32))
#define L16(i) ((uint16) i)
#ifndef WIN32
// More WIN32 compatability
+3 -3
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.8.0-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.16.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
@@ -42,9 +42,9 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9227
#define CURRENT_BINARY_DATABASE_VERSION 9228
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
#endif
-87
View File
@@ -1,87 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/global_define.h"
#include "../common/eqemu_logsys.h"
#include <iomanip>
#include "worldconn.h"
#include "eqemu_config.h"
#include "md5.h"
#include "servertalk.h"
WorldConnection::WorldConnection(EmuTCPConnection::ePacketMode mode, const char *password)
: m_password(password)
{
tcpc.SetPacketMode(mode);
pTryReconnect = true;
pConnected = false;
}
WorldConnection::~WorldConnection() {
}
bool WorldConnection::SendPacket(ServerPacket* pack) {
if (!Connected())
return false;
return tcpc.SendPacket(pack);
}
void WorldConnection::OnConnected() {
const EQEmuConfig *Config=EQEmuConfig::get();
LogNetcode("[WORLD] Connected to World: [{}]:[{}]", Config->WorldIP.c_str(), Config->WorldTCPPort);
auto pack = new ServerPacket(ServerOP_ZAAuth, 16);
MD5::Generate((const uchar*) m_password.c_str(), m_password.length(), pack->pBuffer);
SendPacket(pack);
safe_delete(pack);
}
void WorldConnection::Process() {
//persistent connection....
if (!Connected()) {
pConnected = tcpc.Connected();
if (pConnected) {
OnConnected();
}
else
return;
}
}
void WorldConnection::AsyncConnect() {
const EQEmuConfig *Config=EQEmuConfig::get();
tcpc.AsyncConnect(Config->WorldIP.c_str(), Config->WorldTCPPort);
}
bool WorldConnection::Connect() {
const EQEmuConfig *Config=EQEmuConfig::get();
char errbuf[TCPConnection_ErrorBufferSize];
if (tcpc.Connect(Config->WorldIP.c_str(), Config->WorldTCPPort, errbuf)) {
return true;
} else {
LogNetcode("[WORLD] WorldConnection connect: Connecting to the server [{}]:[{}] failed: [{}]", Config->WorldIP.c_str(), Config->WorldTCPPort, errbuf);
}
return false;
}
void WorldConnection::Disconnect() {
tcpc.Disconnect();
}
+1136 -1
View File
File diff suppressed because it is too large Load Diff
+60 -2
View File
@@ -24,6 +24,8 @@
#include "../common/repositories/zone_repository.h"
#include "../common/repositories/base/base_content_flags_repository.h"
#include <glm/vec4.hpp>
class ZoneStore {
public:
ZoneStore();
@@ -35,7 +37,7 @@ public:
ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0);
ZoneRepository::Zone *GetZone(const char *in_zone_name);
ZoneRepository::Zone *GetZone(std::string in_zone_name);
ZoneRepository::Zone *GetZone(const std::string& in_zone_name);
uint32 GetZoneID(const char *in_zone_name);
uint32 GetZoneID(std::string zone_name);
std::string GetZoneName(uint32 zone_id);
@@ -43,6 +45,62 @@ public:
const char *GetZoneName(uint32 zone_id, bool error_unknown = false);
const char *GetZoneLongName(uint32 zone_id, bool error_unknown = false);
ZoneRepository::Zone *GetZoneWithFallback(uint32 zone_id, int version = 0);
glm::vec4 GetZoneSafeCoordinates(uint32 zone_id, int version = 0);
float GetZoneGraveyardID(uint32 zone_id, int version = 0);
uint8 GetZoneMinimumLevel(uint32 zone_id, int version = 0);
uint8 GetZoneMaximumLevel(uint32 zone_id, int version = 0);
uint8 GetZoneMinimumStatus(uint32 zone_id, int version = 0);
int GetZoneTimeZone(uint32 zone_id, int version = 0);
int GetZoneMaximumPlayers(uint32 zone_id, int version = 0);
uint32 GetZoneRuleSet(uint32 zone_id, int version = 0);
const std::string& GetZoneNote(uint32 zone_id, int version = 0);
float GetZoneUnderworld(uint32 zone_id, int version = 0);
float GetZoneMinimumClip(uint32 zone_id, int version = 0);
float GetZoneMaximumClip(uint32 zone_id, int version = 0);
float GetZoneFogMinimumClip(uint32 zone_id, uint8 slot = 0, int version = 0);
float GetZoneFogMaximumClip(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogRed(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogGreen(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneFogBlue(uint32 zone_id, uint8 slot = 0, int version = 0);
uint8 GetZoneSky(uint32 zone_id, int version = 0);
uint8 GetZoneZType(uint32 zone_id, int version = 0);
float GetZoneExperienceMultiplier(uint32 zone_id, int version = 0);
float GetZoneWalkSpeed(uint32 zone_id, int version = 0);
uint8 GetZoneTimeType(uint32 zone_id, int version = 0);
float GetZoneFogDensity(uint32 zone_id, int version = 0);
const std::string& GetZoneFlagNeeded(uint32 zone_id, int version = 0);
int8 GetZoneCanBind(uint32 zone_id, int version = 0);
int8 GetZoneCanCombat(uint32 zone_id, int version = 0);
int8 GetZoneCanLevitate(uint32 zone_id, int version = 0);
int8 GetZoneCastOutdoor(uint32 zone_id, int version = 0);
uint8 GetZoneHotzone(uint32 zone_id, int version = 0);
uint8 GetZoneInstanceType(uint32 zone_id, int version = 0);
uint64 GetZoneShutdownDelay(uint32 zone_id, int version = 0);
int8 GetZonePEQZone(uint32 zone_id, int version = 0);
int8 GetZoneExpansion(uint32 zone_id, int version = 0);
int8 GetZoneBypassExpansionCheck(uint32 zone_id, int version = 0);
uint8 GetZoneSuspendBuffs(uint32 zone_id, int version = 0);
int GetZoneRainChance(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneRainDuration(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneSnowChance(uint32 zone_id, uint8 slot = 0, int version = 0);
int GetZoneSnowDuration(uint32 zone_id, uint8 slot = 0, int version = 0);
float GetZoneGravity(uint32 zone_id, int version = 0);
int GetZoneType(uint32 zone_id, int version = 0);
int8 GetZoneSkyLock(uint32 zone_id, int version = 0);
int GetZoneFastRegenHP(uint32 zone_id, int version = 0);
int GetZoneFastRegenMana(uint32 zone_id, int version = 0);
int GetZoneFastRegenEndurance(uint32 zone_id, int version = 0);
int GetZoneNPCMaximumAggroDistance(uint32 zone_id, int version = 0);
uint32 GetZoneMaximumMovementUpdateRange(uint32 zone_id, int version = 0);
int8 GetZoneMinimumExpansion(uint32 zone_id, int version = 0);
int8 GetZoneMaximumExpansion(uint32 zone_id, int version = 0);
const std::string& GetZoneContentFlags(uint32 zone_id, int version = 0);
const std::string& GetZoneContentFlagsDisabled(uint32 zone_id, int version = 0);
int GetZoneUnderworldTeleportIndex(uint32 zone_id, int version = 0);
int GetZoneLavaDamage(uint32 zone_id, int version = 0);
int GetZoneMinimumLavaDamage(uint32 zone_id, int version = 0);
private:
std::vector<ZoneRepository::Zone> m_zones;
};
@@ -53,7 +111,7 @@ extern ZoneStore zone_store;
* Global helpers
*/
inline uint32 ZoneID(const char *in_zone_name) { return zone_store.GetZoneID(in_zone_name); }
inline uint32 ZoneID(std::string zone_name) { return zone_store.GetZoneID(zone_name); }
inline uint32 ZoneID(const std::string& zone_name) { return zone_store.GetZoneID(zone_name); }
inline const char *ZoneName(uint32 zone_id, bool error_unknown = false)
{
return zone_store.GetZoneName(
+1 -1
View File
@@ -489,7 +489,7 @@ bool Client::VerifyLoginHash(
* @param db_loginserver
*/
void Client::DoSuccessfulLogin(
const std::string in_account_name,
const std::string& in_account_name,
int db_account_id,
const std::string &db_loginserver
)
+1 -1
View File
@@ -175,7 +175,7 @@ public:
const std::string &password_hash
);
void DoSuccessfulLogin(const std::string in_account_name, int db_account_id, const std::string &db_loginserver);
void DoSuccessfulLogin(const std::string& in_account_name, int db_account_id, const std::string &db_loginserver);
void CreateLocalAccount(const std::string &username, const std::string &password);
void CreateEQEmuAccount(const std::string &in_account_name, const std::string &in_account_password, unsigned int loginserver_account_id);
+1 -1
View File
@@ -490,7 +490,7 @@ namespace LoginserverWebserver {
token_data.can_write
);
server.token_manager->loaded_api_tokens.insert(
server.token_manager->loaded_api_tokens.emplace(
std::make_pair(
token_data.token,
token_data
+2 -2
View File
@@ -71,10 +71,10 @@ public:
inline void AutoLinkAccounts(bool b) { auto_link_accounts = b; }
inline bool CanAutoLinkAccounts() const { return auto_link_accounts; }
inline void EQEmuLoginServerAddress(std::string v) { eqemu_loginserver_address = v; }
inline void EQEmuLoginServerAddress(const std::string& v) { eqemu_loginserver_address = v; }
inline std::string GetEQEmuLoginServerAddress() const { return eqemu_loginserver_address; }
inline void DefaultLoginServerName(std::string v) { default_loginserver_name = v; }
inline void DefaultLoginServerName(const std::string& v) { default_loginserver_name = v; }
inline std::string GetDefaultLoginServerName() const { return default_loginserver_name; }
inline void UpdateInsecurePasswords(bool b) { update_insecure_passwords = b; }

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