mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Merge and compile fixes (non-bot, will do bots later)
This commit is contained in:
commit
a53f65d86b
339
GPL.txt
339
GPL.txt
@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; 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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
165
LICENSE
Normal file
165
LICENSE
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
12
LICENSE.md
12
LICENSE.md
@ -1,12 +0,0 @@
|
||||
The server code and utilities are released under GPLv3.
|
||||
|
||||
We also include some small libraries for convienence that may be under different licensing:
|
||||
|
||||
SocketLib - GPL
|
||||
LibXML - ZLib License
|
||||
StackWalker - New BSD License
|
||||
ZLib - ZLib License
|
||||
MySQL - GPL
|
||||
Perl - GPL / ActiveState (under the assumption that this is a free project).
|
||||
CPPUnit - GLP
|
||||
StringUtilities - Apache
|
||||
27
README.md
27
README.md
@ -17,10 +17,7 @@
|
||||
|:---:|:---:|:---:|
|
||||
|**Install Count**|||
|
||||
### > Windows
|
||||
* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows)
|
||||
* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide)
|
||||
|
||||
|
||||
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
|
||||
|
||||
### > Debian/Ubuntu/CentOS/Fedora
|
||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
||||
@ -53,7 +50,23 @@ forum, although pull requests will be much quicker and easier on all parties.
|
||||
- **User Discord Channel**: `#general`
|
||||
- **Developer Discord Channel**: `#eqemucoders`
|
||||
|
||||
Resources
|
||||
---
|
||||
## Resources
|
||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||
- [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki)
|
||||
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
|
||||
|
||||
## Related Repositories
|
||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||
* [Maps](https://github.com/Akkadius/EQEmuMaps)
|
||||
* [Installer Resources](https://github.com/Akkadius/EQEmuInstall)
|
||||
* [Zone Utilities](https://github.com/EQEmu/zone-utilities) - Various utilities and libraries for parsing, rendering and manipulating EQ Zone files.
|
||||
|
||||
## Other License Info
|
||||
|
||||
* The server code and utilities are released under **GPLv3**
|
||||
* We also include some small libraries for convienence that may be under different licensing
|
||||
* SocketLib - GPL LibXML
|
||||
* zlib - zlib license
|
||||
* MariaDB/MySQL - GPL
|
||||
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
|
||||
* CPPUnit - GLP StringUtilities - Apache
|
||||
* LUA - MIT
|
||||
|
||||
@ -1,5 +1,77 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 03/28/2018 ==
|
||||
Kayen: SE_CastOnFadeEffect, SE_CastOnFadeEffectNPC, SE_CastOnFadeEffectAlway triggered spell will now hit
|
||||
the correct targets.
|
||||
|
||||
|
||||
== 03/07/2018 ==
|
||||
Uleat: Added command '#ucs' to force a reconnect to UCS server.
|
||||
- Works in place of client auto-reconnect packet in zones where feature is unsupported
|
||||
- Currently, you will need to manually re-join channels
|
||||
|
||||
== 03/04/2018 ==
|
||||
Uleat: Updated UCS versioning
|
||||
- SoF and higher clients have a new opcode identified (update your *.conf files)
|
||||
- Rework of previous ucs connectivity code
|
||||
- Unrelated: Zone::weatherSend() now takes an optional parameter for singular updates (as in client entering zone)
|
||||
-- prior to this, every client already in-zone received a weather update packet whenever a new client zoned in
|
||||
|
||||
== 02/18/2018 ==
|
||||
Uleat: Bug reporting fix and overhaul.
|
||||
- Fixed bug reporting for SoD+ clients
|
||||
- Added ability to disable bug reporting (set rule 'Bugs:ReportingSystemActive' to 'false')
|
||||
- Implemented a more detailed reporting system (set rule 'Bugs:UseOldReportingMethod' to 'false')
|
||||
-- New system is not currently compatible with script-based monitoring
|
||||
- Soft-removal of defunct 'Petition Bug' system
|
||||
|
||||
== 02/14/2018 ==
|
||||
mackal: Fix Heading -- Quests broken
|
||||
|
||||
Please report any other issues with heading, most things were tested and worked
|
||||
|
||||
You can use eqemu_server.pl to run a conversion to fix your headings in quests.
|
||||
Some may need manual review.
|
||||
|
||||
== 02/10/2018 ==
|
||||
mackal: Add Global Loot system
|
||||
|
||||
This will allow us to implement global loot similarly to how it works on live
|
||||
This system reuses our current loottable tables which the global_loot table references.
|
||||
The limits for the rules to govern if a table should be rolled are min level, max level, rare,
|
||||
raid, race, class, bodytype, and zone
|
||||
|
||||
race, class, bodytype, and zone are a pipe | separated list of IDs.
|
||||
|
||||
== 01/31/2018 ==
|
||||
Uleat: Re-work of Bot::AI_Process(). Overall behavior is much improved.
|
||||
- Removed a 'ton' of unneeded packet updates
|
||||
- Added a 'leash' to the distance a bot can travel
|
||||
- Added a 'main assist' feature to target control (set using group roles)
|
||||
- Added combat 'jitter' movement to complement the existing rogue movement
|
||||
- Attack can now be aborted if target contains no leash owner nor bot hate and leash owner turns off auto-attack
|
||||
- Please report any issues with the bot AI code
|
||||
|
||||
Added a work-around for heal rotations crashing the server - under certain conditions.
|
||||
|
||||
== 01/28/2018 ==
|
||||
Mackal: Spell AI tweaks
|
||||
|
||||
AI spells are treated as "innate" spells (devs use this term, and I think this is what they mean by it)
|
||||
These spells are spammed by the NPC, lots of encounters on live work like this and this will greatly reduce
|
||||
the need to do quest scripting on these types of encounters.
|
||||
|
||||
You can safely run update npc_spells_entries set priority = priority + 1 where priority >= 0; if you want to disable this new behavior
|
||||
|
||||
== 10/08/2017 ==
|
||||
Mackal: Rework regens
|
||||
|
||||
Regen will now match whats reported by modern clients, besides where they lie due to known bugs
|
||||
|
||||
HP and END regens are now based on the BaseData.txt values allowing easy customization
|
||||
Those cases:
|
||||
- The client always applies hunger penalties, it appears they don't exist anymore on live you can turn them on with a rule
|
||||
- The way the client gets buff mana/end regen benefits incorrectly applies the bard mod making these values lie sometimes
|
||||
|
||||
== 9/17/2017 ==
|
||||
Akkadius: Add model/race offset to FixZ calc (KLS)
|
||||
|
||||
@ -24,8 +24,8 @@ struct BaseDataStruct
|
||||
double base_hp;
|
||||
double base_mana;
|
||||
double base_end;
|
||||
double unk1;
|
||||
double unk2;
|
||||
double hp_regen;
|
||||
double end_regen;
|
||||
double hp_factor;
|
||||
double mana_factor;
|
||||
double endurance_factor;
|
||||
|
||||
@ -472,16 +472,6 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertPPDeblob();
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
/* Fetch EQEmu Server script */
|
||||
if (!std::ifstream("eqemu_server.pl")){
|
||||
std::cout << "Pulling down automatic database upgrade script..." << std::endl;
|
||||
#ifdef _WIN32
|
||||
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
|
||||
#else
|
||||
system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
system("perl eqemu_server.pl ran_from_world");
|
||||
|
||||
|
||||
@ -18,3 +18,68 @@
|
||||
*/
|
||||
|
||||
#include "emu_constants.h"
|
||||
|
||||
|
||||
const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
switch (category_id) {
|
||||
case catVideo:
|
||||
return "Video";
|
||||
case catAudio:
|
||||
return "Audio";
|
||||
case catPathing:
|
||||
return "Pathing";
|
||||
case catQuest:
|
||||
return "Quest";
|
||||
case catTradeskills:
|
||||
return "Tradeskills";
|
||||
case catSpellStacking:
|
||||
return "Spell stacking";
|
||||
case catDoorsPortals:
|
||||
return "Doors/Portals";
|
||||
case catItems:
|
||||
return "Items";
|
||||
case catNPC:
|
||||
return "NPC";
|
||||
case catDialogs:
|
||||
return "Dialogs";
|
||||
case catLoNTCG:
|
||||
return "LoN - TCG";
|
||||
case catMercenaries:
|
||||
return "Mercenaries";
|
||||
case catOther:
|
||||
default:
|
||||
return "Other";
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category_name) {
|
||||
if (!category_name)
|
||||
return catOther;
|
||||
|
||||
if (!strcmp(category_name, "Video"))
|
||||
return catVideo;
|
||||
if (!strcmp(category_name, "Audio"))
|
||||
return catAudio;
|
||||
if (!strcmp(category_name, "Pathing"))
|
||||
return catPathing;
|
||||
if (!strcmp(category_name, "Quest"))
|
||||
return catQuest;
|
||||
if (!strcmp(category_name, "Tradeskills"))
|
||||
return catTradeskills;
|
||||
if (!strcmp(category_name, "Spell stacking"))
|
||||
return catSpellStacking;
|
||||
if (!strcmp(category_name, "Doors/Portals"))
|
||||
return catDoorsPortals;
|
||||
if (!strcmp(category_name, "Items"))
|
||||
return catItems;
|
||||
if (!strcmp(category_name, "NPC"))
|
||||
return catNPC;
|
||||
if (!strcmp(category_name, "Dialogs"))
|
||||
return catDialogs;
|
||||
if (!strcmp(category_name, "LoN - TCG"))
|
||||
return catLoNTCG;
|
||||
if (!strcmp(category_name, "Mercenaries"))
|
||||
return catMercenaries;
|
||||
|
||||
return catOther;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include "emu_legacy.h"
|
||||
#include "emu_versions.h"
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace EQEmu
|
||||
@ -114,7 +114,11 @@ namespace EQEmu
|
||||
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
|
||||
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
|
||||
|
||||
const size_t SayLinkOpenerSize = 1;
|
||||
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
|
||||
const size_t SayLinkTextSize = 256; // this may be varied until it breaks something (tested:374) - the others are constant
|
||||
const size_t SayLinkCloserSize = 1;
|
||||
const size_t SayLinkMaximumSize = (SayLinkOpenerSize + SayLinkBodySize + SayLinkTextSize + SayLinkCloserSize);
|
||||
|
||||
const int LongBuffs = RoF2::constants::LongBuffs;
|
||||
const int ShortBuffs = RoF2::constants::ShortBuffs;
|
||||
@ -126,6 +130,37 @@ namespace EQEmu
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace bug {
|
||||
enum CategoryID : uint32 {
|
||||
catOther = 0,
|
||||
catVideo,
|
||||
catAudio,
|
||||
catPathing,
|
||||
catQuest,
|
||||
catTradeskills,
|
||||
catSpellStacking,
|
||||
catDoorsPortals,
|
||||
catItems,
|
||||
catNPC,
|
||||
catDialogs,
|
||||
catLoNTCG,
|
||||
catMercenaries
|
||||
};
|
||||
|
||||
enum OptionalInfoFlag : uint32 {
|
||||
infoNoOptionalInfo = 0x0,
|
||||
infoCanDuplicate = 0x1,
|
||||
infoCrashBug = 0x2,
|
||||
infoTargetInfo = 0x4,
|
||||
infoCharacterFlags = 0x8,
|
||||
infoUnknownValue = 0xFFFFFFF0
|
||||
};
|
||||
|
||||
const char* CategoryIDToCategoryName(CategoryID category_id);
|
||||
CategoryID CategoryNameToCategoryID(const char* category_name);
|
||||
|
||||
} // namespace bug
|
||||
|
||||
enum class CastingSlot : uint32 {
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
|
||||
@ -78,6 +78,8 @@ namespace EQEmu
|
||||
SLOT_CURSOR_BAG_END = 340,
|
||||
SLOT_TRIBUTE_BEGIN = 400,
|
||||
SLOT_TRIBUTE_END = 404,
|
||||
SLOT_GUILD_TRIBUTE_BEGIN = 450,
|
||||
SLOT_GUILD_TRIBUTE_END = 451,
|
||||
SLOT_BANK_BEGIN = 2000,
|
||||
SLOT_BANK_END = 2023,
|
||||
SLOT_BANK_BAGS_BEGIN = 2031,
|
||||
@ -173,8 +175,6 @@ namespace EQEmu
|
||||
|
||||
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ N(OP_AcceptNewTask),
|
||||
N(OP_AckPacket),
|
||||
N(OP_Action),
|
||||
N(OP_Action2),
|
||||
N(OP_AddNimbusEffect),
|
||||
N(OP_AdventureData),
|
||||
N(OP_AdventureDetails),
|
||||
N(OP_AdventureFinish),
|
||||
@ -339,6 +340,7 @@ N(OP_MOTD),
|
||||
N(OP_MoveCoin),
|
||||
N(OP_MoveDoor),
|
||||
N(OP_MoveItem),
|
||||
N(OP_MoveMultipleItems),
|
||||
N(OP_MoveLogDisregard),
|
||||
N(OP_MoveLogRequest),
|
||||
N(OP_MultiLineMsg),
|
||||
@ -391,6 +393,7 @@ N(OP_PVPLeaderBoardReply),
|
||||
N(OP_PVPLeaderBoardRequest),
|
||||
N(OP_PVPStats),
|
||||
N(OP_QueryResponseThing),
|
||||
N(OP_QueryUCSServerStatus),
|
||||
N(OP_RaidInvite),
|
||||
N(OP_RaidJoin),
|
||||
N(OP_RaidUpdate),
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace versions {
|
||||
enum class ClientVersion {
|
||||
enum class ClientVersion : uint32 {
|
||||
Unknown = 0,
|
||||
Client62, // Build: 'Aug 4 2005 15:40:59'
|
||||
Titanium, // Build: 'Oct 31 2005 10:33:37'
|
||||
@ -72,7 +72,7 @@ namespace EQEmu
|
||||
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||
|
||||
|
||||
enum class MobVersion {
|
||||
enum class MobVersion : uint32 {
|
||||
Unknown = 0,
|
||||
Client62,
|
||||
Titanium,
|
||||
@ -121,6 +121,20 @@ namespace EQEmu
|
||||
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
|
||||
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
|
||||
|
||||
|
||||
enum UCSVersion : char {
|
||||
ucsUnknown = '\0',
|
||||
ucsClient62Chat = 'A',
|
||||
ucsClient62Mail = 'a',
|
||||
ucsTitaniumChat = 'B',
|
||||
ucsTitaniumMail = 'b',
|
||||
ucsSoFCombined = 'C',
|
||||
ucsSoDCombined = 'D',
|
||||
ucsUFCombined = 'E',
|
||||
ucsRoFCombined = 'F',
|
||||
ucsRoF2Combined = 'G'
|
||||
};
|
||||
|
||||
} /*versions*/
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
@ -280,7 +280,7 @@ union
|
||||
// horse: 0=brown, 1=white, 2=black, 3=tan
|
||||
};
|
||||
/*0340*/ uint32 spawnId; // Spawn Id
|
||||
/*0344*/ uint8 unknown0344[3];
|
||||
/*0344*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0347*/ uint8 IsMercenary;
|
||||
/*0348*/ EQEmu::TintProfile equipment_tint;
|
||||
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
||||
@ -551,6 +551,7 @@ struct BlockedBuffs_Struct
|
||||
/*86*/ uint16 Flags;
|
||||
};
|
||||
|
||||
// same for adding
|
||||
struct RemoveNimbusEffect_Struct
|
||||
{
|
||||
/*00*/ uint32 spawnid; // Spawn ID
|
||||
@ -854,6 +855,7 @@ static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size r
|
||||
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
|
||||
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 240;
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
@ -993,7 +995,8 @@ struct PlayerProfile_Struct
|
||||
/*4768*/ int32 platinum_shared; // Platinum shared between characters
|
||||
/*4772*/ uint8 unknown4808[24];
|
||||
/*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
|
||||
/*5196*/ uint8 unknown5132[184];
|
||||
/*5196*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
|
||||
/*5296*/ uint8 unknown5132[84];
|
||||
/*5380*/ uint32 pvp2; //
|
||||
/*5384*/ uint32 unknown5420; //
|
||||
/*5388*/ uint32 pvptype; //
|
||||
@ -1250,21 +1253,22 @@ struct Action_Struct
|
||||
{
|
||||
/* 00 */ uint16 target; // id of target
|
||||
/* 02 */ uint16 source; // id of caster
|
||||
/* 04 */ uint16 level; // level of caster
|
||||
/* 06 */ uint16 instrument_mod;
|
||||
/* 08 */ uint32 bard_focus_id;
|
||||
/* 12 */ uint16 unknown16;
|
||||
// some kind of sequence that's the same in both actions
|
||||
// as well as the combat damage, to tie em together?
|
||||
/* 14 */ uint32 sequence;
|
||||
/* 18 */ uint32 unknown18;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
||||
/* 23 */ uint32 unknown23;
|
||||
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/* 10 */ float force;
|
||||
/* 14 */ float hit_heading;
|
||||
/* 18 */ float hit_pitch;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||
/* 27 */ uint16 spell; // spell id being cast
|
||||
/* 29 */ uint8 unknown29;
|
||||
/* 29 */ uint8 spell_level;
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/* 31 */
|
||||
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
// newer clients have some data for setting LaunchSpellData when effect_flag & 4
|
||||
// /* 31 */ uint8 spell_gem;
|
||||
// /* 32 */ uint32 inventory_slot;
|
||||
// /* 36 */ uint32 item_cast_type;
|
||||
};
|
||||
|
||||
// this is what prints the You have been struck. and the regular
|
||||
@ -1274,12 +1278,12 @@ struct CombatDamage_Struct
|
||||
{
|
||||
/* 00 */ uint16 target;
|
||||
/* 02 */ uint16 source;
|
||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
|
||||
/* 05 */ uint16 spellid;
|
||||
/* 07 */ uint32 damage;
|
||||
/* 11 */ float force;
|
||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 19 */ float meleepush_z;
|
||||
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 19 */ float hit_pitch;
|
||||
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||
};
|
||||
|
||||
@ -3320,23 +3324,32 @@ struct GuildMakeLeader{
|
||||
char target[64];
|
||||
};
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ char unknown308[160];
|
||||
/*0468*/ char target_name[64];
|
||||
/*0532*/ uint32 type;
|
||||
/*0536*/ char unknown536[2052];
|
||||
/*2584*/ char bug[2048];
|
||||
/*4632*/ char unknown4632[6];
|
||||
/*4638*/ char system_info[4094];
|
||||
struct BugReport_Struct {
|
||||
/*0000*/ uint32 category_id;
|
||||
/*0004*/ char category_name[64];
|
||||
/*0068*/ char reporter_name[64];
|
||||
/*0132*/ char unused_0132[32];
|
||||
/*0164*/ char ui_path[128];
|
||||
/*0292*/ float pos_x;
|
||||
/*0296*/ float pos_y;
|
||||
/*0300*/ float pos_z;
|
||||
/*0304*/ uint32 heading;
|
||||
/*0308*/ uint32 unused_0308;
|
||||
/*0312*/ uint32 time_played;
|
||||
/*0316*/ char padding_0316[8];
|
||||
/*0324*/ uint32 target_id;
|
||||
/*0328*/ char padding_0328[140];
|
||||
/*0468*/ uint32 unknown_0468; // seems to always be '0'
|
||||
/*0472*/ char target_name[64];
|
||||
/*0536*/ uint32 optional_info_mask;
|
||||
|
||||
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||
/*0540*/ char unused_0540[2052];
|
||||
/*2592*/ char bug_report[2050];
|
||||
/*4642*/ char system_info[4098];
|
||||
/*8740*/
|
||||
};
|
||||
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -3363,20 +3376,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -4764,6 +4778,7 @@ struct BuffIconEntry_Struct
|
||||
uint32 spell_id;
|
||||
int32 tics_remaining;
|
||||
uint32 num_hits;
|
||||
char caster[64];
|
||||
};
|
||||
|
||||
struct BuffIcon_Struct
|
||||
@ -4773,6 +4788,7 @@ struct BuffIcon_Struct
|
||||
uint16 count;
|
||||
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
|
||||
int32 tic_timer;
|
||||
int32 name_lengths; // so ahh we kind of do these packets hacky, this is the total length of all the names to make creating the real packets in the translators easier
|
||||
BuffIconEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
@ -5351,6 +5367,23 @@ struct AuraDestory_Struct {
|
||||
};
|
||||
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char Augment6[5];
|
||||
/*036*/ char IsEvolving[1];
|
||||
/*037*/ char EvolveGroup[4];
|
||||
/*041*/ char EvolveLevel[2];
|
||||
/*043*/ char OrnamentIcon[5];
|
||||
/*048*/ char Hash[8];
|
||||
/*056*/
|
||||
};
|
||||
|
||||
// Restore structure packing to default
|
||||
#pragma pack()
|
||||
|
||||
|
||||
@ -23,351 +23,112 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.xml";
|
||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||
|
||||
void EQEmuConfig::do_world(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
TiXmlElement * sub_ele;;
|
||||
text = ParseTextBlock(ele, "shortname");
|
||||
if (text) {
|
||||
ShortName = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "longname");
|
||||
if (text) {
|
||||
LongName = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "address", true);
|
||||
if (text) {
|
||||
WorldAddress = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "localaddress", true);
|
||||
if (text) {
|
||||
LocalAddress = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "maxclients", true);
|
||||
if (text) {
|
||||
MaxClients = atoi(text);
|
||||
}
|
||||
// Get the <key> element
|
||||
text = ParseTextBlock(ele, "key", true);
|
||||
if (text) {
|
||||
SharedKey = text;
|
||||
}
|
||||
// Get the <loginserver> element
|
||||
sub_ele = ele->FirstChildElement("loginserver");
|
||||
if (sub_ele) {
|
||||
text = ParseTextBlock(sub_ele, "host", true);
|
||||
if (text) {
|
||||
LoginHost = text;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "port", true);
|
||||
if (text) {
|
||||
LoginPort = atoi(text);
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "legacy", true);
|
||||
if (text) {
|
||||
LoginLegacy = atoi(text) > 0 ? true : false;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "account", true);
|
||||
if (text) {
|
||||
LoginAccount = text;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "password", true);
|
||||
if (text) {
|
||||
LoginPassword = text;
|
||||
}
|
||||
void EQEmuConfig::parse_config() {
|
||||
|
||||
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||
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 = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||
LoginLegacy = false;
|
||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true;
|
||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
||||
} else {
|
||||
char str[32];
|
||||
char str[32];
|
||||
loginlist.Clear();
|
||||
do {
|
||||
sprintf(str, "loginserver%i", ++LoginCount);
|
||||
sub_ele = ele->FirstChildElement(str);
|
||||
if (sub_ele) {
|
||||
auto loginconfig = new LoginConfig;
|
||||
text = ParseTextBlock(sub_ele, "host", true);
|
||||
if (text) {
|
||||
loginconfig->LoginHost = text;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "port", true);
|
||||
if (text) {
|
||||
loginconfig->LoginPort = atoi(text);
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "legacy", true);
|
||||
if (text) {
|
||||
loginconfig->LoginLegacy = atoi(text) > 0 ? true : false;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "account", true);
|
||||
if (text) {
|
||||
loginconfig->LoginAccount = text;
|
||||
}
|
||||
text = ParseTextBlock(sub_ele, "password", true);
|
||||
if (text) {
|
||||
loginconfig->LoginPassword = text;
|
||||
}
|
||||
loginlist.Insert(loginconfig);
|
||||
if (!_root["server"]["world"][str].isObject()) {
|
||||
break;
|
||||
}
|
||||
} while (sub_ele);
|
||||
}
|
||||
// Check for locked
|
||||
sub_ele = ele->FirstChildElement("locked");
|
||||
if (sub_ele != nullptr) {
|
||||
Locked = true;
|
||||
}
|
||||
// Get the <tcp> element
|
||||
sub_ele = ele->FirstChildElement("tcp");
|
||||
if (sub_ele != nullptr) {
|
||||
text = sub_ele->Attribute("ip");
|
||||
if (text) {
|
||||
WorldIP = text;
|
||||
}
|
||||
text = sub_ele->Attribute("port");
|
||||
if (text) {
|
||||
WorldTCPPort = atoi(text);
|
||||
}
|
||||
}
|
||||
|
||||
sub_ele = ele->FirstChildElement("telnet");
|
||||
if (sub_ele != nullptr) {
|
||||
text = sub_ele->Attribute("ip");
|
||||
if (text) {
|
||||
TelnetIP = text;
|
||||
}
|
||||
text = sub_ele->Attribute("port");
|
||||
if (text) {
|
||||
TelnetTCPPort = atoi(text);
|
||||
}
|
||||
text = sub_ele->Attribute("enabled");
|
||||
if (text && !strcasecmp(text, "true")) {
|
||||
TelnetEnabled = true;
|
||||
}
|
||||
}
|
||||
auto loginconfig = new LoginConfig;
|
||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||
|
||||
// Get the <http> element
|
||||
sub_ele = ele->FirstChildElement("http");
|
||||
if (sub_ele != nullptr) {
|
||||
// text = sub_ele->Attribute("ip");
|
||||
// if (text)
|
||||
// WorldIP=text;
|
||||
text = sub_ele->Attribute("mimefile");
|
||||
if (text) {
|
||||
WorldHTTPMimeFile = text;
|
||||
}
|
||||
text = sub_ele->Attribute("port");
|
||||
if (text) {
|
||||
WorldHTTPPort = atoi(text);
|
||||
}
|
||||
text = sub_ele->Attribute("enabled");
|
||||
if (text && !strcasecmp(text, "true")) {
|
||||
WorldHTTPEnabled = true;
|
||||
}
|
||||
loginconfig->LoginLegacy = false;
|
||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true;
|
||||
loginlist.Insert(loginconfig);
|
||||
} while (LoginCount < 100);
|
||||
}
|
||||
|
||||
|
||||
//<locked> from xml converts to json as locked: "", so i default to "false".
|
||||
//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;
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||
|
||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||
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 = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPEnabled = false;
|
||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
|
||||
|
||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
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 = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||
|
||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||
|
||||
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
||||
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
||||
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
||||
|
||||
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
||||
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||
|
||||
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
||||
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||
#ifdef WIN32
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||
#else
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "./zone").asString();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_chatserver(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "host", true);
|
||||
if (text) {
|
||||
ChatHost = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "port", true);
|
||||
if (text) {
|
||||
ChatPort = atoi(text);
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_mailserver(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "host", true);
|
||||
if (text) {
|
||||
MailHost = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "port", true);
|
||||
if (text) {
|
||||
MailPort = atoi(text);
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_database(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "host", true);
|
||||
if (text) {
|
||||
DatabaseHost = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "port", true);
|
||||
if (text) {
|
||||
DatabasePort = atoi(text);
|
||||
}
|
||||
text = ParseTextBlock(ele, "username", true);
|
||||
if (text) {
|
||||
DatabaseUsername = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "password", true);
|
||||
if (text) {
|
||||
DatabasePassword = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "db", true);
|
||||
if (text) {
|
||||
DatabaseDB = text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "host", true);
|
||||
if (text) {
|
||||
QSDatabaseHost = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "port", true);
|
||||
if (text) {
|
||||
QSDatabasePort = atoi(text);
|
||||
}
|
||||
text = ParseTextBlock(ele, "username", true);
|
||||
if (text) {
|
||||
QSDatabaseUsername = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "password", true);
|
||||
if (text) {
|
||||
QSDatabasePassword = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "db", true);
|
||||
if (text) {
|
||||
QSDatabaseDB = text;
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_zones(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
TiXmlElement *sub_ele;
|
||||
// TiXmlNode *node,*sub_node;
|
||||
text = ParseTextBlock(ele, "defaultstatus", true);
|
||||
if (text) {
|
||||
DefaultStatus = atoi(text);
|
||||
}
|
||||
// Get the <ports> element
|
||||
sub_ele = ele->FirstChildElement("ports");
|
||||
if (sub_ele != nullptr) {
|
||||
text = sub_ele->Attribute("low");
|
||||
if (text) {
|
||||
ZonePortLow = atoi(text);
|
||||
};
|
||||
text = sub_ele->Attribute("high");
|
||||
if (text) {
|
||||
ZonePortHigh = atoi(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_files(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "spells", true);
|
||||
if (text) {
|
||||
SpellsFile = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "opcodes", true);
|
||||
if (text) {
|
||||
OpCodesFile = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "plugin.pl", true);
|
||||
if (text) {
|
||||
PluginPlFile = text;
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_directories(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
text = ParseTextBlock(ele, "maps", true);
|
||||
if (text) {
|
||||
MapDir = text;
|
||||
if ( MapDir.back() != '/' )
|
||||
MapDir += '/';
|
||||
}
|
||||
text = ParseTextBlock(ele, "quests", true);
|
||||
if (text) {
|
||||
QuestDir = text;
|
||||
if ( QuestDir.back() != '/' )
|
||||
QuestDir += '/';
|
||||
}
|
||||
text = ParseTextBlock(ele, "plugins", true);
|
||||
if (text) {
|
||||
PluginDir = text;
|
||||
if ( PluginDir.back() != '/' )
|
||||
PluginDir += '/';
|
||||
}
|
||||
text = ParseTextBlock(ele, "lua_modules", true);
|
||||
if (text) {
|
||||
LuaModuleDir = text;
|
||||
if ( LuaModuleDir.back() != '/' )
|
||||
LuaModuleDir += '/';
|
||||
}
|
||||
text = ParseTextBlock(ele, "patches", true);
|
||||
if (text) {
|
||||
PatchDir = text;
|
||||
if ( PatchDir.back() != '/' )
|
||||
PatchDir += '/';
|
||||
}
|
||||
text = ParseTextBlock(ele, "shared_memory", true);
|
||||
if (text) {
|
||||
SharedMemDir = text;
|
||||
if ( SharedMemDir.back() != '/' )
|
||||
SharedMemDir += '/';
|
||||
}
|
||||
//Not Fully Implemented yet LogDir
|
||||
text = ParseTextBlock(ele, "logs", true);
|
||||
if (text) {
|
||||
LogDir = text;
|
||||
if ( LogDir.back() != '/' )
|
||||
LogDir += '/';
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuConfig::do_launcher(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
TiXmlElement *sub_ele;
|
||||
text = ParseTextBlock(ele, "logprefix", true);
|
||||
if (text) {
|
||||
LogPrefix = text;
|
||||
}
|
||||
text = ParseTextBlock(ele, "logsuffix", true);
|
||||
if (text) {
|
||||
LogSuffix = text;
|
||||
}
|
||||
// Get the <exe> element
|
||||
text = ParseTextBlock(ele, "exe", true);
|
||||
if (text) {
|
||||
ZoneExe = text;
|
||||
}
|
||||
// Get the <timers> element
|
||||
sub_ele = ele->FirstChildElement("timers");
|
||||
if (sub_ele != nullptr) {
|
||||
text = sub_ele->Attribute("restart");
|
||||
if (text) {
|
||||
RestartWait = atoi(text);
|
||||
}
|
||||
text = sub_ele->Attribute("reterminate");
|
||||
if (text) {
|
||||
TerminateWait = atoi(text);
|
||||
}
|
||||
text = sub_ele->Attribute("initial");
|
||||
if (text) {
|
||||
InitialBootWait = atoi(text);
|
||||
}
|
||||
text = sub_ele->Attribute("interval");
|
||||
if (text) {
|
||||
ZoneBootInterval = atoi(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
||||
{
|
||||
if (var_name == "ShortName") {
|
||||
@ -564,4 +325,3 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
|
||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@ -18,8 +18,9 @@
|
||||
#ifndef __EQEmuConfig_H
|
||||
#define __EQEmuConfig_H
|
||||
|
||||
#include "xml_parser.h"
|
||||
#include "json/json.h"
|
||||
#include "linked_list.h"
|
||||
#include <fstream>
|
||||
|
||||
struct LoginConfig {
|
||||
std::string LoginHost;
|
||||
@ -29,7 +30,7 @@ struct LoginConfig {
|
||||
bool LoginLegacy;
|
||||
};
|
||||
|
||||
class EQEmuConfig : public XMLParser
|
||||
class EQEmuConfig
|
||||
{
|
||||
public:
|
||||
virtual std::string GetByName(const std::string &var_name) const;
|
||||
@ -115,88 +116,14 @@ class EQEmuConfig : public XMLParser
|
||||
protected:
|
||||
|
||||
static EQEmuConfig *_config;
|
||||
|
||||
Json::Value _root;
|
||||
static std::string ConfigFile;
|
||||
|
||||
#define ELEMENT(name) \
|
||||
void do_##name(TiXmlElement *ele);
|
||||
#include "eqemu_config_elements.h"
|
||||
|
||||
void parse_config();
|
||||
|
||||
EQEmuConfig()
|
||||
{
|
||||
// import the needed handler prototypes
|
||||
#define ELEMENT(name) \
|
||||
Handlers[#name]=(ElementHandler)&EQEmuConfig::do_##name;
|
||||
#include "eqemu_config_elements.h"
|
||||
// Set sane defaults
|
||||
// Login server
|
||||
LoginHost = "login.eqemulator.net";
|
||||
LoginPort = 5998;
|
||||
LoginLegacy = false;
|
||||
// World
|
||||
Locked = false;
|
||||
WorldTCPPort = 9000;
|
||||
TelnetTCPPort = 9001;
|
||||
TelnetEnabled = false;
|
||||
WorldHTTPEnabled = false;
|
||||
WorldHTTPPort = 9080;
|
||||
WorldHTTPMimeFile = "mime.types";
|
||||
SharedKey = ""; //blank disables authentication
|
||||
// Mail
|
||||
ChatHost = "eqchat.eqemulator.net";
|
||||
ChatPort = 7778;
|
||||
// Mail
|
||||
MailHost = "eqmail.eqemulator.net";
|
||||
MailPort = 7779;
|
||||
// Mysql
|
||||
DatabaseHost = "localhost";
|
||||
DatabasePort = 3306;
|
||||
DatabaseUsername = "eq";
|
||||
DatabasePassword = "eq";
|
||||
DatabaseDB = "eq";
|
||||
// QueryServ Database
|
||||
QSDatabaseHost = "localhost";
|
||||
QSDatabasePort = 3306;
|
||||
QSDatabaseUsername = "eq";
|
||||
QSDatabasePassword = "eq";
|
||||
QSDatabaseDB = "eq";
|
||||
// Files
|
||||
SpellsFile = "spells_us.txt";
|
||||
OpCodesFile = "opcodes.conf";
|
||||
PluginPlFile = "plugin.pl";
|
||||
// Dirs
|
||||
MapDir = "Maps/";
|
||||
QuestDir = "quests/";
|
||||
PluginDir = "plugins/";
|
||||
LuaModuleDir = "lua_modules/";
|
||||
PatchDir = "./";
|
||||
SharedMemDir = "shared/";
|
||||
LogDir = "logs/";
|
||||
{
|
||||
|
||||
// Launcher
|
||||
LogPrefix = "logs/zone-";
|
||||
LogSuffix = ".log";
|
||||
RestartWait = 10000; //milliseconds
|
||||
TerminateWait = 10000; //milliseconds
|
||||
InitialBootWait = 20000; //milliseconds
|
||||
ZoneBootInterval = 2000; //milliseconds
|
||||
#ifdef WIN32
|
||||
ZoneExe = "zone.exe";
|
||||
#else
|
||||
ZoneExe = "./zone";
|
||||
#endif
|
||||
// Zones
|
||||
ZonePortLow = 7000;
|
||||
ZonePortHigh = 7999;
|
||||
DefaultStatus = 0;
|
||||
// For where zones need to connect to.
|
||||
WorldIP = "127.0.0.1";
|
||||
TelnetIP = "127.0.0.1";
|
||||
// Dynamics to start
|
||||
//DynamicCount=5;
|
||||
MaxClients = -1;
|
||||
LoginCount = 0;
|
||||
}
|
||||
virtual ~EQEmuConfig() {}
|
||||
|
||||
@ -205,9 +132,7 @@ class EQEmuConfig : public XMLParser
|
||||
// Produce a const singleton
|
||||
static const EQEmuConfig *get()
|
||||
{
|
||||
if (_config == nullptr) {
|
||||
LoadConfig();
|
||||
}
|
||||
LoadConfig();
|
||||
return (_config);
|
||||
}
|
||||
|
||||
@ -221,10 +146,28 @@ class EQEmuConfig : public XMLParser
|
||||
static bool LoadConfig()
|
||||
{
|
||||
if (_config != nullptr) {
|
||||
delete _config;
|
||||
return true;
|
||||
}
|
||||
_config = new EQEmuConfig;
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(), "server");
|
||||
|
||||
return parseFile();
|
||||
}
|
||||
|
||||
// Load config file and parse data
|
||||
static bool parseFile() {
|
||||
if (_config == nullptr) {
|
||||
return LoadConfig();
|
||||
}
|
||||
|
||||
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
|
||||
try {
|
||||
fconfig >> _config->_root;
|
||||
_config->parse_config();
|
||||
}
|
||||
catch (std::exception) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dump() const;
|
||||
|
||||
@ -89,6 +89,7 @@ enum LogCategory {
|
||||
HP_Update,
|
||||
FixZ,
|
||||
Food,
|
||||
Traps,
|
||||
MaxCategoryID /* Don't Remove this*/
|
||||
};
|
||||
|
||||
@ -142,7 +143,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||
"Headless Client",
|
||||
"HP Update",
|
||||
"FixZ",
|
||||
"Food"
|
||||
"Food",
|
||||
"Traps"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -219,6 +219,9 @@ enum { //some random constants
|
||||
//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
|
||||
|
||||
// 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
|
||||
@ -276,6 +279,11 @@ enum {
|
||||
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||
|
||||
|
||||
// consumption timers for food/drink here instead of rules because the client
|
||||
// uses these. Times in ms.
|
||||
#define CONSUMPTION_TIMER 46000
|
||||
#define CONSUMPTION_MNK_TIMER 92000
|
||||
|
||||
/*
|
||||
|
||||
Developer configuration
|
||||
|
||||
@ -111,7 +111,8 @@
|
||||
#define GLM_COMPILER_GCC70 0x02000A00
|
||||
#define GLM_COMPILER_GCC71 0x02000B00
|
||||
#define GLM_COMPILER_GCC72 0x02000C00
|
||||
#define GLM_COMPILER_GCC80 0x02000D00
|
||||
#define GLM_COMPILER_GCC73 0x02000D00
|
||||
#define GLM_COMPILER_GCC80 0x02000E00
|
||||
|
||||
// CUDA
|
||||
#define GLM_COMPILER_CUDA 0x10000000
|
||||
@ -283,6 +284,8 @@
|
||||
# define GLM_COMPILER (GLM_COMPILER_GCC71)
|
||||
# elif (__GNUC__ == 7) && (__GNUC_MINOR__ == 2)
|
||||
# define GLM_COMPILER (GLM_COMPILER_GCC72)
|
||||
# elif (__GNUC__ == 7) && (__GNUC_MINOR__ == 3)
|
||||
# define GLM_COMPILER (GLM_COMPILER_GCC73)
|
||||
# elif (__GNUC__ >= 8)
|
||||
# define GLM_COMPILER (GLM_COMPILER_GCC80)
|
||||
# else
|
||||
|
||||
@ -194,32 +194,70 @@ uint32 rnd_hash( time_t t, clock_t c )
|
||||
|
||||
float EQ13toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<2));
|
||||
}
|
||||
|
||||
float NewEQ13toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<6));
|
||||
return static_cast<float>(d) / 64.0f;
|
||||
}
|
||||
|
||||
float EQ19toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<3));
|
||||
return static_cast<float>(d) / 8.0f;
|
||||
}
|
||||
|
||||
int FloatToEQ13(float d)
|
||||
{
|
||||
return int(d*float(1<<2));
|
||||
}
|
||||
|
||||
int NewFloatToEQ13(float d)
|
||||
{
|
||||
return int(d*float(1<<6));
|
||||
return static_cast<int>(d * 64.0f);
|
||||
}
|
||||
|
||||
int FloatToEQ19(float d)
|
||||
{
|
||||
return int(d*float(1<<3));
|
||||
return static_cast<int>(d * 8.0f);
|
||||
}
|
||||
|
||||
float EQ12toFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 4.0f;
|
||||
}
|
||||
|
||||
int FloatToEQ12(float d)
|
||||
{
|
||||
return static_cast<int>((d + 2048.0f) * 4.0f) % 2048;
|
||||
}
|
||||
|
||||
float EQ10toFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 20.0f;
|
||||
}
|
||||
|
||||
int FloatToEQ10(float d)
|
||||
{
|
||||
return static_cast<int>(d * 20.0f);
|
||||
}
|
||||
|
||||
float EQSpeedRunToFloat(int d)
|
||||
{
|
||||
return static_cast<float>(d) / 40.0f;
|
||||
}
|
||||
|
||||
int FloatToEQSpeedRun(float d)
|
||||
{
|
||||
return static_cast<int>(d * 40.0f);
|
||||
}
|
||||
|
||||
float FixHeading(float in)
|
||||
{
|
||||
int i = 0;
|
||||
if (in >= 512.0f) {
|
||||
do {
|
||||
in -= 512.0f;
|
||||
} while (in >= 512.0f && i++ <= 5);
|
||||
}
|
||||
i = 0;
|
||||
if (in < 0.0f) {
|
||||
do {
|
||||
in += 512.0f;
|
||||
} while (in < 0.0f && i++ <= 5);
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -50,13 +50,25 @@ uint32 ResolveIP(const char* hostname, char* errbuf = 0);
|
||||
bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf = 0);
|
||||
void CoutTimestamp(bool ms = true);
|
||||
float EQ13toFloat(int d);
|
||||
float NewEQ13toFloat(int d);
|
||||
float EQ19toFloat(int d);
|
||||
float EQHtoFloat(int d);
|
||||
int FloatToEQ13(float d);
|
||||
int NewFloatToEQ13(float d);
|
||||
int FloatToEQ19(float d);
|
||||
int FloatToEQH(float d);
|
||||
|
||||
float EQ12toFloat(int d);
|
||||
int FloatToEQ12(float d);
|
||||
|
||||
float EQ10toFloat(int d);
|
||||
int FloatToEQ10(float d);
|
||||
|
||||
// this is also a 10 bit float
|
||||
float EQSpeedRunToFloat(int d);
|
||||
int FloatToEQSpeedRun(float d);
|
||||
|
||||
// brings heading back into EQ angles range
|
||||
float FixHeading(float in);
|
||||
|
||||
uint32 SwapBits21and22(uint32 mask);
|
||||
uint32 Catch22(uint32 mask);
|
||||
|
||||
|
||||
@ -165,7 +165,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
||||
{
|
||||
auto iter = m_connections.begin();
|
||||
while (iter != m_connections.end()) {
|
||||
auto connection = iter->second;
|
||||
auto &connection = iter->second;
|
||||
auto status = connection->m_status;
|
||||
|
||||
switch (status)
|
||||
@ -1397,4 +1397,4 @@ EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t exp
|
||||
}
|
||||
|
||||
return SequencePast;
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,11 +57,11 @@ namespace RoF
|
||||
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot);
|
||||
static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
|
||||
// client to server say link converter
|
||||
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink);
|
||||
|
||||
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
|
||||
@ -163,22 +163,23 @@ namespace RoF
|
||||
OUT(level);
|
||||
eq->unknown06 = 0;
|
||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||
eq->bard_focus_id = emu->bard_focus_id;
|
||||
eq->knockback_angle = emu->sequence;
|
||||
eq->unknown22 = 0;
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
eq->damage = 0;
|
||||
eq->unknown31 = 0;
|
||||
OUT(spell);
|
||||
eq->level2 = eq->level;
|
||||
eq->effect_flag = emu->buff_unknown;
|
||||
eq->unknown39 = 14;
|
||||
eq->unknown43 = 0;
|
||||
eq->unknown44 = 17;
|
||||
eq->unknown45 = 0;
|
||||
eq->unknown46 = -1;
|
||||
eq->unknown50 = 0;
|
||||
eq->unknown54 = 0;
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag);
|
||||
eq->spell_gem = 0;
|
||||
eq->slot.Type = INVALID_INDEX;
|
||||
eq->slot.Unknown02 = 0;
|
||||
eq->slot.Slot = INVALID_INDEX;
|
||||
eq->slot.SubIndex = INVALID_INDEX;
|
||||
eq->slot.AugIndex = INVALID_INDEX;
|
||||
eq->slot.Unknown01 = 0;
|
||||
eq->item_cast_type = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -460,7 +461,7 @@ namespace RoF
|
||||
{
|
||||
SETUP_VAR_ENCODE(BuffIcon_Struct);
|
||||
|
||||
uint32 sz = 12 + (17 * emu->count);
|
||||
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
|
||||
__packet->size = sz;
|
||||
__packet->pBuffer = new unsigned char[sz];
|
||||
memset(__packet->pBuffer, 0, sz);
|
||||
@ -476,7 +477,7 @@ namespace RoF
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||
__packet->WriteString("");
|
||||
__packet->WriteString(emu->entries[i].caster);
|
||||
}
|
||||
__packet->WriteUInt8(emu->type); // Unknown
|
||||
|
||||
@ -520,7 +521,7 @@ namespace RoF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
ServerToRoFSayLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
@ -659,8 +660,8 @@ namespace RoF
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(special);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@ -847,7 +848,7 @@ namespace RoF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
ServerToRoFSayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -899,7 +900,7 @@ namespace RoF
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToRoFTextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToRoFSayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -2184,11 +2185,11 @@ namespace RoF
|
||||
outapp->WriteUInt32(emu->skills[r]);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(25); // Unknown count
|
||||
outapp->WriteUInt32(structs::MAX_PP_INNATE_SKILL); // Innate Skills count
|
||||
|
||||
for (uint32 r = 0; r < 25; r++)
|
||||
for (uint32 r = 0; r < structs::MAX_PP_INNATE_SKILL; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(emu->InnateSkills[r]); // Innate Skills (regen, slam, etc)
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_PP_DISCIPLINES); // Discipline count
|
||||
@ -3295,7 +3296,7 @@ namespace RoF
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
ServerToRoFSayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -3369,7 +3370,7 @@ namespace RoF
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToRoFTextLink(new_message, old_message);
|
||||
ServerToRoFSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||
@ -3847,9 +3848,12 @@ namespace RoF
|
||||
OUT(y);
|
||||
OUT(x);
|
||||
OUT(z)
|
||||
OUT(zone_reason);
|
||||
OUT(zone_reason);
|
||||
OUT(success);
|
||||
|
||||
if (eq->success < 0)
|
||||
eq->success -= 1;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
@ -4352,7 +4356,7 @@ namespace RoF
|
||||
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoFToServerTextLink(new_message, old_message);
|
||||
RoFToServerSayLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
@ -4463,7 +4467,7 @@ namespace RoF
|
||||
IN(type);
|
||||
IN(spellid);
|
||||
IN(damage);
|
||||
IN(meleepush_xy);
|
||||
IN(hit_heading);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4486,7 +4490,7 @@ namespace RoF
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
RoFToServerTextLink(new_message, old_message);
|
||||
RoFToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -5913,19 +5917,19 @@ namespace RoF
|
||||
return (rofCorpseSlot - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
rofTextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
rofSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
rofTextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
rofSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -5935,36 +5939,36 @@ namespace RoF
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// Diff: ^
|
||||
|
||||
rofTextLink.push_back('\x12');
|
||||
rofTextLink.append(segments[segment_iter].substr(0, 41));
|
||||
rofSayLink.push_back('\x12');
|
||||
rofSayLink.append(segments[segment_iter].substr(0, 41));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
rofTextLink.push_back(segments[segment_iter][42]);
|
||||
rofSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
rofTextLink.push_back('F');
|
||||
rofSayLink.push_back('F');
|
||||
|
||||
rofTextLink.append(segments[segment_iter].substr(43));
|
||||
rofTextLink.push_back('\x12');
|
||||
rofSayLink.append(segments[segment_iter].substr(43));
|
||||
rofSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
rofTextLink.append(segments[segment_iter]);
|
||||
rofSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink)
|
||||
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rofTextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = rofTextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rofSayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = rofSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rofTextLink, '\x12');
|
||||
auto segments = SplitString(rofSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -5974,14 +5978,14 @@ namespace RoF
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter].substr(0, 41));
|
||||
serverTextLink.push_back('0');
|
||||
serverTextLink.append(segments[segment_iter].substr(41));
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 41));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(41));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,11 +57,11 @@ namespace RoF2
|
||||
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot);
|
||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
|
||||
// client to server say link converter
|
||||
static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink);
|
||||
|
||||
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
|
||||
@ -232,22 +232,23 @@ namespace RoF2
|
||||
OUT(level);
|
||||
eq->unknown06 = 0;
|
||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||
eq->bard_focus_id = emu->bard_focus_id;
|
||||
eq->knockback_angle = emu->sequence;
|
||||
eq->unknown22 = 0;
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
eq->damage = 0;
|
||||
eq->unknown31 = 0;
|
||||
OUT(spell);
|
||||
eq->level2 = eq->level;
|
||||
eq->effect_flag = emu->buff_unknown;
|
||||
eq->unknown39 = 14;
|
||||
eq->unknown43 = 0;
|
||||
eq->unknown44 = 17;
|
||||
eq->unknown45 = 0;
|
||||
eq->unknown46 = -1;
|
||||
eq->unknown50 = 0;
|
||||
eq->unknown54 = 0;
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag);
|
||||
eq->spell_gem = 0;
|
||||
eq->slot.Type = INVALID_INDEX;
|
||||
eq->slot.Unknown02 = 0;
|
||||
eq->slot.Slot = INVALID_INDEX;
|
||||
eq->slot.SubIndex = INVALID_INDEX;
|
||||
eq->slot.AugIndex = INVALID_INDEX;
|
||||
eq->slot.Unknown01 = 0;
|
||||
eq->item_cast_type = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -528,7 +529,7 @@ namespace RoF2
|
||||
{
|
||||
SETUP_VAR_ENCODE(BuffIcon_Struct);
|
||||
|
||||
uint32 sz = 12 + (17 * emu->count);
|
||||
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
|
||||
__packet->size = sz;
|
||||
__packet->pBuffer = new unsigned char[sz];
|
||||
memset(__packet->pBuffer, 0, sz);
|
||||
@ -544,7 +545,7 @@ namespace RoF2
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||
__packet->WriteString("");
|
||||
__packet->WriteString(emu->entries[i].caster);
|
||||
}
|
||||
__packet->WriteUInt8(emu->type); // Unknown
|
||||
|
||||
@ -588,7 +589,7 @@ namespace RoF2
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
ServerToRoF2SayLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
@ -727,8 +728,8 @@ namespace RoF2
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(special);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@ -915,7 +916,7 @@ namespace RoF2
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
ServerToRoF2SayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -967,7 +968,7 @@ namespace RoF2
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToRoF2TextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToRoF2SayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -2261,11 +2262,11 @@ namespace RoF2
|
||||
outapp->WriteUInt32(emu->skills[r]);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(25); // Unknown count
|
||||
outapp->WriteUInt32(structs::MAX_PP_INNATE_SKILL); // Innate Skills count
|
||||
|
||||
for (uint32 r = 0; r < 25; r++)
|
||||
for (uint32 r = 0; r < structs::MAX_PP_INNATE_SKILL; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(emu->InnateSkills[r]); // Innate Skills (regen, slam, etc)
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_PP_DISCIPLINES); // Discipline count
|
||||
@ -3364,7 +3365,7 @@ namespace RoF2
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
ServerToRoF2SayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -3438,7 +3439,7 @@ namespace RoF2
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToRoF2TextLink(new_message, old_message);
|
||||
ServerToRoF2SayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||
@ -3991,9 +3992,12 @@ namespace RoF2
|
||||
OUT(y);
|
||||
OUT(x);
|
||||
OUT(z)
|
||||
OUT(zone_reason);
|
||||
OUT(zone_reason);
|
||||
OUT(success);
|
||||
|
||||
if (eq->success < 0)
|
||||
eq->success -= 1;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
@ -4592,7 +4596,7 @@ namespace RoF2
|
||||
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
RoF2ToServerTextLink(new_message, old_message);
|
||||
RoF2ToServerSayLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
@ -4703,7 +4707,7 @@ namespace RoF2
|
||||
IN(type);
|
||||
IN(spellid);
|
||||
IN(damage);
|
||||
IN(meleepush_xy);
|
||||
IN(hit_heading);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4726,7 +4730,7 @@ namespace RoF2
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
RoF2ToServerTextLink(new_message, old_message);
|
||||
RoF2ToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -6230,19 +6234,19 @@ namespace RoF2
|
||||
return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
rof2TextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
rof2SayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
rof2TextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
rof2SayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -6252,29 +6256,29 @@ namespace RoF2
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
rof2TextLink.push_back('\x12');
|
||||
rof2TextLink.append(segments[segment_iter]);
|
||||
rof2TextLink.push_back('\x12');
|
||||
rof2SayLink.push_back('\x12');
|
||||
rof2SayLink.append(segments[segment_iter]);
|
||||
rof2SayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
rof2TextLink.append(segments[segment_iter]);
|
||||
rof2SayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink)
|
||||
static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rof2TextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = rof2TextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rof2SayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = rof2SayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(rof2TextLink, '\x12');
|
||||
auto segments = SplitString(rof2SayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -6284,12 +6288,12 @@ namespace RoF2
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff:
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ namespace RoF2
|
||||
ItemPacket11 = 111,
|
||||
ItemPacket12 = 112,
|
||||
ItemPacketRecovery = 113,
|
||||
ItemPacket14 = 115
|
||||
ItemPacket14 = 115 // Parcel? adds to merchant window too
|
||||
};
|
||||
|
||||
} /*item*/
|
||||
|
||||
@ -131,6 +131,7 @@ static const uint32 MAX_PP_LANGUAGE = 32; // was 25
|
||||
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
|
||||
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300;
|
||||
static const uint32 MAX_PP_DISCIPLINES = 300; // was 200
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
@ -399,7 +400,7 @@ struct Spawn_Struct_Position
|
||||
|
||||
struct Spawn_Struct_Position
|
||||
{
|
||||
signed padding0000:12;
|
||||
signed angle:12; // pitch of camera?
|
||||
signed y:19;
|
||||
signed padding0001:1;
|
||||
|
||||
@ -415,7 +416,7 @@ struct Spawn_Struct_Position
|
||||
signed z:19;
|
||||
signed padding0020:3;
|
||||
|
||||
signed animation:10; // animation
|
||||
signed animation:10; // SpeedRun
|
||||
signed deltaY:13;
|
||||
signed padding0023:9;
|
||||
};
|
||||
@ -429,7 +430,7 @@ struct Spawn_Struct
|
||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||
/*0064*/ uint32 spawnId;
|
||||
/*0068*/ uint8 level;
|
||||
/*0069*/ float unknown1;
|
||||
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
Spawn_Struct_Bitfields Bitfields;
|
||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||
@ -1155,8 +1156,8 @@ union
|
||||
/*01012*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [300] 3600 bytes - AAs 12 bytes each
|
||||
/*04612*/ uint32 skill_count; // Seen 100
|
||||
/*04616*/ uint32 skills[MAX_PP_SKILL]; // [100] 400 bytes - List of skills
|
||||
/*05016*/ uint32 unknown15_count; // Seen 25
|
||||
/*05020*/ uint32 unknown_rof15[25]; // Most are 255 or 0
|
||||
/*05016*/ uint32 InnateSkills_count; // Seen 25
|
||||
/*05020*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL]; // Most are 255 or 0
|
||||
/*05120*/ uint32 discipline_count; // Seen 200
|
||||
/*05124*/ Disciplines_Struct disciplines; // [200] 800 bytes Known disciplines
|
||||
/*05924*/ uint32 timestamp_count; // Seen 20
|
||||
@ -1461,17 +1462,17 @@ struct Action_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ uint32 bard_focus_id; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint32 spell; // spell id being cast
|
||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*39*/
|
||||
};
|
||||
@ -1483,25 +1484,21 @@ struct ActionAlt_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ uint32 bard_focus_id; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint32 spell; // spell id being cast
|
||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
|
||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
||||
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
|
||||
/*45*/ uint8 unknown45; // New field to Underfoot - Seen 0
|
||||
/*46*/ int32 unknown46; // New field to Underfoot - Seen -1
|
||||
/*50*/ uint32 unknown50; // New field to Underfoot - Seen 0
|
||||
/*54*/ uint16 unknown54; // New field to Underfoot - Seen 0
|
||||
/*39*/ uint8 spell_gem;
|
||||
/*40*/ InventorySlot_Struct slot;
|
||||
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||
/*56*/
|
||||
};
|
||||
|
||||
@ -1516,9 +1513,9 @@ struct CombatDamage_Struct
|
||||
/* 05 */ uint32 spellid;
|
||||
/* 09 */ int32 damage;
|
||||
/* 13 */ float force; // cd cc cc 3d
|
||||
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 21 */ float meleepush_z;
|
||||
/* 25 */ uint8 unknown25; // was [9]
|
||||
/* 17 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 21 */ float hit_pitch;
|
||||
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||
/* 30 */
|
||||
};
|
||||
@ -1826,6 +1823,20 @@ struct MoveItem_Struct
|
||||
/*0028*/
|
||||
};
|
||||
|
||||
struct MultiMoveItemSub_Struct
|
||||
{
|
||||
/*0000*/ InventorySlot_Struct from_slot;
|
||||
/*0012*/ InventorySlot_Struct to_slot;
|
||||
/*0024*/ uint32 number_in_stack;
|
||||
/*0028*/ uint8 unknown[8];
|
||||
};
|
||||
|
||||
struct MultiMoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 count;
|
||||
/*0004*/ MultiMoveItemSub_Struct moves[0];
|
||||
};
|
||||
|
||||
//
|
||||
// from_slot/to_slot
|
||||
// -1 - destroy
|
||||
@ -3590,21 +3601,6 @@ struct GuildSetRank_Struct
|
||||
/*80*/
|
||||
};
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ uint32 type;
|
||||
/*0312*/ char unknown312[2144];
|
||||
/*2456*/ char bug[1024];
|
||||
/*3480*/ char placeholder[2];
|
||||
/*3482*/ char system_info[4098];
|
||||
};
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -3631,20 +3627,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -5088,6 +5085,23 @@ struct CrystalCountUpdate_Struct
|
||||
/*012*/ uint32 CareerEbonCrystals;
|
||||
};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char Augment6[5];
|
||||
/*036*/ char IsEvolving[1];
|
||||
/*037*/ char EvolveGroup[4];
|
||||
/*041*/ char EvolveLevel[2];
|
||||
/*043*/ char OrnamentIcon[5];
|
||||
/*048*/ char Hash[8];
|
||||
/*056*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
}; /*RoF2*/
|
||||
|
||||
@ -131,6 +131,7 @@ static const uint32 MAX_PP_LANGUAGE = 32; // was 25
|
||||
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
|
||||
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300;
|
||||
static const uint32 MAX_PP_DISCIPLINES = 200; // was 100
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
@ -407,7 +408,7 @@ struct Spawn_Struct
|
||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||
/*0064*/ uint32 spawnId;
|
||||
/*0068*/ uint8 level;
|
||||
/*0069*/ float unknown1;
|
||||
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
Spawn_Struct_Bitfields Bitfields;
|
||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||
@ -1096,8 +1097,8 @@ union
|
||||
/*01012*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [300] 3600 bytes - AAs 12 bytes each
|
||||
/*04612*/ uint32 skill_count; // Seen 100
|
||||
/*04616*/ uint32 skills[MAX_PP_SKILL]; // [100] 400 bytes - List of skills
|
||||
/*05016*/ uint32 unknown15_count; // Seen 25
|
||||
/*05020*/ uint32 unknown_rof15[25]; // Most are 255 or 0
|
||||
/*05016*/ uint32 InnateSkills_count; // Seen 25
|
||||
/*05020*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL]; // Most are 255 or 0
|
||||
/*05120*/ uint32 discipline_count; // Seen 200
|
||||
/*05124*/ Disciplines_Struct disciplines; // [200] 800 bytes Known disciplines
|
||||
/*05924*/ uint32 timestamp_count; // Seen 20
|
||||
@ -1449,17 +1450,17 @@ struct Action_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ uint32 bard_focus_id; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint32 spell; // spell id being cast
|
||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*39*/
|
||||
};
|
||||
@ -1471,25 +1472,21 @@ struct ActionAlt_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ uint32 bard_focus_id; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint32 spell; // spell id being cast
|
||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
|
||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
||||
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
|
||||
/*45*/ uint8 unknown45; // New field to Underfoot - Seen 0
|
||||
/*46*/ int32 unknown46; // New field to Underfoot - Seen -1
|
||||
/*50*/ uint32 unknown50; // New field to Underfoot - Seen 0
|
||||
/*54*/ uint16 unknown54; // New field to Underfoot - Seen 0
|
||||
/*39*/ uint8 spell_gem;
|
||||
/*40*/ InventorySlot_Struct slot;
|
||||
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||
/*56*/
|
||||
};
|
||||
|
||||
@ -1504,9 +1501,9 @@ struct CombatDamage_Struct
|
||||
/* 05 */ uint32 spellid;
|
||||
/* 09 */ int32 damage;
|
||||
/* 13 */ float force; // cd cc cc 3d
|
||||
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 21 */ float meleepush_z;
|
||||
/* 25 */ uint8 unknown25; // was [9]
|
||||
/* 17 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 21 */ float hit_pitch;
|
||||
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||
/* 30 */
|
||||
};
|
||||
@ -3544,21 +3541,6 @@ struct GuildSetRank_Struct
|
||||
/*80*/
|
||||
};
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ uint32 type;
|
||||
/*0312*/ char unknown312[2144];
|
||||
/*2456*/ char bug[1024];
|
||||
/*3480*/ char placeholder[2];
|
||||
/*3482*/ char system_info[4098];
|
||||
};
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -3585,20 +3567,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -5019,6 +5002,23 @@ struct MercenaryMerchantRequest_Struct {
|
||||
struct MercenaryMerchantResponse_Struct {
|
||||
/*0000*/ uint32 ResponseType;
|
||||
/*0004*/
|
||||
};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char Augment6[5];
|
||||
/*036*/ char IsEvolving[1];
|
||||
/*037*/ char EvolveGroup[4];
|
||||
/*041*/ char EvolveLevel[1];
|
||||
/*042*/ char OrnamentIcon[5];
|
||||
/*047*/ char Hash[8];
|
||||
/*055*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
@ -53,11 +53,11 @@ namespace SoD
|
||||
static inline uint32 SoDToServerSlot(uint32 sodSlot);
|
||||
static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
|
||||
// client to server say link converter
|
||||
static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink);
|
||||
|
||||
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
|
||||
@ -161,15 +161,14 @@ namespace SoD
|
||||
OUT(source);
|
||||
OUT(level);
|
||||
OUT(instrument_mod);
|
||||
eq->sequence = emu->sequence;
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
//OUT(damage);
|
||||
OUT(spell);
|
||||
eq->level2 = emu->level;
|
||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
||||
//eq->unknown0036 = -1;
|
||||
//eq->unknown0040 = -1;
|
||||
//eq->unknown0044 = -1;
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -346,7 +345,7 @@ namespace SoD
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
ServerToSoDSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
@ -458,8 +457,8 @@ namespace SoD
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(special);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@ -625,7 +624,7 @@ namespace SoD
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
ServerToSoDSayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -677,7 +676,7 @@ namespace SoD
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToSoDTextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToSoDSayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -1605,6 +1604,7 @@ namespace SoD
|
||||
OUT(copper_cursor);
|
||||
|
||||
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
|
||||
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
|
||||
|
||||
// OUT(unknown04760[236]);
|
||||
OUT(toxicity);
|
||||
@ -2155,7 +2155,7 @@ namespace SoD
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
ServerToSoDSayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -2251,7 +2251,7 @@ namespace SoD
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToSoDTextLink(new_message, old_message);
|
||||
ServerToSoDSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||
@ -2932,25 +2932,6 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Bug)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BugStruct);
|
||||
SETUP_DIRECT_DECODE(BugStruct, structs::BugStruct);
|
||||
|
||||
strn0cpy(emu->chartype, eq->chartype, sizeof(emu->chartype));
|
||||
strn0cpy(emu->name, eq->name, sizeof(emu->name));
|
||||
strn0cpy(emu->ui, eq->ui, sizeof(emu->ui));
|
||||
IN(x);
|
||||
IN(y);
|
||||
IN(z);
|
||||
IN(heading);
|
||||
strn0cpy(emu->target_name, eq->target_name, sizeof(emu->target_name));
|
||||
strn0cpy(emu->bug, eq->bug, sizeof(emu->bug));
|
||||
strn0cpy(emu->system_info, eq->system_info, sizeof(emu->system_info));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_CastSpell)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||
@ -2971,7 +2952,7 @@ namespace SoD
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoDToServerTextLink(new_message, old_message);
|
||||
SoDToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -3085,7 +3066,7 @@ namespace SoD
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
SoDToServerTextLink(new_message, old_message);
|
||||
SoDToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -3935,19 +3916,19 @@ namespace SoD
|
||||
return (sodCorpseSlot - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
sodTextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
sodSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
sodTextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
sodSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -3957,37 +3938,37 @@ namespace SoD
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
sodTextLink.push_back('\x12');
|
||||
sodTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
sodTextLink.append(segments[segment_iter].substr(36, 5));
|
||||
sodSayLink.push_back('\x12');
|
||||
sodSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
sodSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
sodTextLink.push_back(segments[segment_iter][42]);
|
||||
sodSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
sodTextLink.push_back('F');
|
||||
sodSayLink.push_back('F');
|
||||
|
||||
sodTextLink.append(segments[segment_iter].substr(43));
|
||||
sodTextLink.push_back('\x12');
|
||||
sodSayLink.append(segments[segment_iter].substr(43));
|
||||
sodSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
sodTextLink.append(segments[segment_iter]);
|
||||
sodSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink)
|
||||
static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sodTextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = sodTextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sodSayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = sodSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sodTextLink, '\x12');
|
||||
auto segments = SplitString(sodSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -3997,16 +3978,16 @@ namespace SoD
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverTextLink.append("00000");
|
||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverTextLink.push_back('0');
|
||||
serverTextLink.append(segments[segment_iter].substr(36));
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(36));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,6 @@ D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
|
||||
@ -292,7 +292,7 @@ struct Spawn_Struct
|
||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||
/*0064*/ uint32 spawnId;
|
||||
/*0068*/ uint8 level;
|
||||
/*0069*/ float unknown1;
|
||||
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
Spawn_Struct_Bitfields Bitfields;
|
||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||
@ -818,6 +818,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
|
||||
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
@ -923,7 +924,8 @@ struct PlayerProfile_Struct
|
||||
/*06488*/ uint32 silver_cursor; // Silver Pieces on cursor
|
||||
/*06492*/ uint32 copper_cursor; // Copper Pieces on cursor
|
||||
/*06496*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
|
||||
/*06896*/ uint8 unknown04760[136];
|
||||
/*06896*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
|
||||
/*06996*/ uint8 unknown04760[36];
|
||||
/*07032*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
|
||||
/*07036*/ uint32 thirst_level; // Drink (ticks till next drink)
|
||||
/*07040*/ uint32 hunger_level; // Food (ticks till next eat)
|
||||
@ -1213,20 +1215,18 @@ struct Action_Struct
|
||||
{
|
||||
/* 00 */ uint16 target; // id of target
|
||||
/* 02 */ uint16 source; // id of caster
|
||||
/* 04 */ uint16 level; // level of caster
|
||||
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
|
||||
/* 08 */ uint32 unknown08;
|
||||
/* 12 */ uint16 unknown16;
|
||||
// some kind of sequence that's the same in both actions
|
||||
// as well as the combat damage, to tie em together?
|
||||
/* 14 */ float sequence; // was uint32
|
||||
/* 18 */ uint32 unknown18;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
||||
/* 23 */ uint32 unknown23;
|
||||
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/* 10 */ float force;
|
||||
/* 14 */ float hit_heading;
|
||||
/* 18 */ float hit_pitch;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||
/* 27 */ uint16 spell; // spell id being cast
|
||||
/* 29 */ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/* 29 */ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
/* 31 */
|
||||
};
|
||||
|
||||
@ -1235,26 +1235,23 @@ struct Action_Struct
|
||||
// has to do with buff blocking??
|
||||
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||
{
|
||||
/*0000*/ uint16 target; // Target ID
|
||||
/*0002*/ uint16 source; // SourceID
|
||||
/*0004*/ uint16 level; // level of caster
|
||||
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
|
||||
/*0008*/ uint32 unknown08;
|
||||
/*0012*/ uint16 unknown16;
|
||||
/*0014*/ uint32 sequence;
|
||||
/*0018*/ uint32 unknown18;
|
||||
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
|
||||
/*0023*/ uint32 damage; // Amount of Damage
|
||||
/*0027*/ uint16 spell; // SpellID
|
||||
/*0029*/ uint8 unknown29;
|
||||
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
|
||||
/*0035*/ uint8 unknown0035; // seen 00
|
||||
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
|
||||
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
|
||||
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
|
||||
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
|
||||
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
|
||||
/*0000*/ uint16 target; // id of target
|
||||
/*0002*/ uint16 source; // id of caster
|
||||
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/*0010*/ float force;
|
||||
/*0014*/ float hit_heading;
|
||||
/*0018*/ float hit_pitch;
|
||||
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*0023*/ uint16 unknown23; // OSX says min_damage
|
||||
/*0025*/ uint16 unknown25; // OSX says tohit
|
||||
/*0027*/ uint16 spell; // spell id being cast
|
||||
/*0029*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
/*0031*/ uint8 spell_slot;
|
||||
/*0032*/ uint32 slot[5];
|
||||
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||
/*0056*/
|
||||
};
|
||||
|
||||
@ -1269,9 +1266,9 @@ struct CombatDamage_Struct
|
||||
/* 05 */ uint16 spellid;
|
||||
/* 07 */ int32 damage;
|
||||
/* 11 */ float force; // cd cc cc 3d
|
||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 19 */ float meleepush_z;
|
||||
/* 23 */ uint8 unknown23; // was [9]
|
||||
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 19 */ float hit_pitch;
|
||||
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||
/* 28 */
|
||||
};
|
||||
@ -3006,24 +3003,6 @@ struct GuildMakeLeader{
|
||||
char target[64];
|
||||
};
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ uint32 type1; //seems to be just a different way of seeing type; seems to be ordered completely differently
|
||||
/*0004*/ char chartype[64];
|
||||
/*0068*/ char name[96];
|
||||
/*0164*/ char ui[128];
|
||||
/*0292*/ float x;
|
||||
/*0296*/ float y;
|
||||
/*0300*/ float z;
|
||||
/*0304*/ float heading;
|
||||
/*0308*/ uint32 unknown304;
|
||||
/*0312*/ char unknown308[160];
|
||||
/*0472*/ char target_name[64];
|
||||
/*0536*/ uint32 type;
|
||||
/*0540*/ char unknown536[2052];
|
||||
/*2588*/ char bug[2048];
|
||||
/*4636*/ char unknown4632[6];
|
||||
/*4642*/ char system_info[4094];
|
||||
};
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -3050,20 +3029,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -4400,6 +4380,22 @@ struct MercenaryAssign_Struct {
|
||||
/*0004*/ uint32 MercUnk01; //
|
||||
/*0008*/ uint32 MercUnk02; //
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char IsEvolving[1];
|
||||
/*032*/ char EvolveGroup[4];
|
||||
/*036*/ char EvolveLevel[1];
|
||||
/*037*/ char OrnamentIcon[5];
|
||||
/*042*/ char Hash[8];
|
||||
/*050*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
@ -53,11 +53,11 @@ namespace SoF
|
||||
static inline uint32 SoFToServerSlot(uint32 sofSlot);
|
||||
static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
|
||||
// client to server say link converter
|
||||
static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink);
|
||||
|
||||
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||
@ -161,15 +161,14 @@ namespace SoF
|
||||
OUT(source);
|
||||
OUT(level);
|
||||
OUT(instrument_mod);
|
||||
eq->sequence = emu->sequence;
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
//OUT(damage);
|
||||
OUT(spell);
|
||||
eq->level2 = emu->level;
|
||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
||||
//eq->unknown0036 = -1;
|
||||
//eq->unknown0040 = -1;
|
||||
//eq->unknown0044 = -1;
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -328,7 +327,7 @@ namespace SoF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
ServerToSoFSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
@ -440,8 +439,8 @@ namespace SoF
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -613,7 +612,7 @@ namespace SoF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
ServerToSoFSayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -665,7 +664,7 @@ namespace SoF
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToSoFTextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToSoFSayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -1276,6 +1275,7 @@ namespace SoF
|
||||
OUT(copper_cursor);
|
||||
|
||||
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
|
||||
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
|
||||
|
||||
// OUT(unknown04760[236]);
|
||||
OUT(toxicity);
|
||||
@ -1813,7 +1813,7 @@ namespace SoF
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
ServerToSoFSayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -1881,7 +1881,7 @@ namespace SoF
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToSoFTextLink(new_message, old_message);
|
||||
ServerToSoFSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||
@ -2384,6 +2384,17 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Bug)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||
|
||||
emu->category_id = EQEmu::bug::CategoryNameToCategoryID(eq->category_name);
|
||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_CastSpell)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||
@ -2403,7 +2414,7 @@ namespace SoF
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
SoFToServerTextLink(new_message, old_message);
|
||||
SoFToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -2517,7 +2528,7 @@ namespace SoF
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
SoFToServerTextLink(new_message, old_message);
|
||||
SoFToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -3304,19 +3315,19 @@ namespace SoF
|
||||
return (sofCorpseSlot - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
sofTextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
sofSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
sofTextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
sofSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -3326,37 +3337,37 @@ namespace SoF
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
sofTextLink.push_back('\x12');
|
||||
sofTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
sofTextLink.append(segments[segment_iter].substr(36, 5));
|
||||
sofSayLink.push_back('\x12');
|
||||
sofSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
sofSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
sofTextLink.push_back(segments[segment_iter][42]);
|
||||
sofSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
sofTextLink.push_back('F');
|
||||
sofSayLink.push_back('F');
|
||||
|
||||
sofTextLink.append(segments[segment_iter].substr(43));
|
||||
sofTextLink.push_back('\x12');
|
||||
sofSayLink.append(segments[segment_iter].substr(43));
|
||||
sofSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
sofTextLink.append(segments[segment_iter]);
|
||||
sofSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink)
|
||||
static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sofTextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = sofTextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sofSayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = sofSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(sofTextLink, '\x12');
|
||||
auto segments = SplitString(sofSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -3366,16 +3377,16 @@ namespace SoF
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverTextLink.append("00000");
|
||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverTextLink.push_back('0');
|
||||
serverTextLink.append(segments[segment_iter].substr(36));
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(36));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +95,7 @@ D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
|
||||
@ -52,6 +52,25 @@ struct EnterWorld_Struct {
|
||||
struct WorldObjectsSent_Struct {
|
||||
};
|
||||
|
||||
// yep, even SoF had a version of the new inventory system, used by OP_MoveMultipleItems
|
||||
struct InventorySlot_Struct
|
||||
{
|
||||
/*000*/ int32 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Trade = 3, World = 4, Limbo = 5
|
||||
/*004*/ int32 Slot;
|
||||
/*008*/ int32 SubIndex;
|
||||
/*012*/ int32 AugIndex;
|
||||
/*016*/ int32 Unknown01;
|
||||
};
|
||||
|
||||
// unsure if they have a version of this, completeness though
|
||||
struct TypelessInventorySlot_Struct
|
||||
{
|
||||
/*000*/ int32 Slot;
|
||||
/*004*/ int32 SubIndex;
|
||||
/*008*/ int32 AugIndex;
|
||||
/*012*/ int32 Unknown01;
|
||||
};
|
||||
|
||||
/* Name Approval Struct */
|
||||
/* Len: */
|
||||
/* Opcode: 0x8B20*/
|
||||
@ -307,7 +326,8 @@ union
|
||||
/*0725*/ uint8 targetable; // 1 = Targetable 0 = Not Targetable (is_npc?)
|
||||
/*0726*/ uint8 unknown0726[4];
|
||||
/*0730*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
/*0731*/ uint8 unknown0731[11];
|
||||
/*0731*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0735*/ uint8 unknown0731[7];
|
||||
/*0742*/ uint8 targetable_with_hotkey;
|
||||
/*0743*/ signed padding00:12; // ***Placeholder
|
||||
signed x:19; // x coord
|
||||
@ -799,6 +819,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
|
||||
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
@ -903,7 +924,8 @@ struct PlayerProfile_Struct //23576 Octets
|
||||
/*06488*/ uint32 silver_cursor; // Silver Pieces on cursor
|
||||
/*06492*/ uint32 copper_cursor; // Copper Pieces on cursor
|
||||
/*06496*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
|
||||
/*06896*/ uint8 unknown04760[136];
|
||||
/*06896*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
|
||||
/*06996*/ uint8 unknown04760[36];
|
||||
/*07032*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
|
||||
/*07036*/ uint32 thirst_level; // Drink (ticks till next drink)
|
||||
/*07040*/ uint32 hunger_level; // Food (ticks till next eat)
|
||||
@ -1193,20 +1215,18 @@ struct Action_Struct
|
||||
{
|
||||
/* 00 */ uint16 target; // id of target
|
||||
/* 02 */ uint16 source; // id of caster
|
||||
/* 04 */ uint16 level; // level of caster
|
||||
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
|
||||
/* 08 */ uint32 unknown08;
|
||||
/* 12 */ uint16 unknown16;
|
||||
// some kind of sequence that's the same in both actions
|
||||
// as well as the combat damage, to tie em together?
|
||||
/* 14 */ float sequence; // was uint32
|
||||
/* 18 */ uint32 unknown18;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
||||
/* 23 */ uint32 unknown23;
|
||||
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/* 10 */ float force;
|
||||
/* 14 */ float hit_heading;
|
||||
/* 18 */ float hit_pitch;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||
/* 27 */ uint16 spell; // spell id being cast
|
||||
/* 29 */ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/* 29 */ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
/* 31 */
|
||||
};
|
||||
|
||||
@ -1215,26 +1235,23 @@ struct Action_Struct
|
||||
// has to do with buff blocking??
|
||||
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||
{
|
||||
/*0000*/ uint16 target; // Target ID
|
||||
/*0002*/ uint16 source; // SourceID
|
||||
/*0004*/ uint16 level; // level of caster
|
||||
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
|
||||
/*0008*/ uint32 unknown08;
|
||||
/*0012*/ uint16 unknown16;
|
||||
/*0014*/ uint32 sequence;
|
||||
/*0018*/ uint32 unknown18;
|
||||
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
|
||||
/*0023*/ uint32 damage; // Amount of Damage
|
||||
/*0027*/ uint16 spell; // SpellID
|
||||
/*0029*/ uint8 unknown29;
|
||||
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
|
||||
/*0035*/ uint8 unknown0035; // seen 00
|
||||
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
|
||||
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
|
||||
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
|
||||
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
|
||||
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
|
||||
/*0000*/ uint16 target; // id of target
|
||||
/*0002*/ uint16 source; // id of caster
|
||||
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/*0010*/ float force;
|
||||
/*0014*/ float hit_heading;
|
||||
/*0018*/ float hit_pitch;
|
||||
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*0023*/ uint16 unknown23; // OSX says min_damage
|
||||
/*0025*/ uint16 unknown25; // OSX says tohit
|
||||
/*0027*/ uint16 spell; // spell id being cast
|
||||
/*0029*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
/*0031*/ uint8 spell_slot;
|
||||
/*0032*/ uint32 slot[5];
|
||||
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||
/*0056*/
|
||||
};
|
||||
|
||||
@ -1249,9 +1266,10 @@ struct CombatDamage_Struct
|
||||
/* 05 */ uint16 spellid;
|
||||
/* 07 */ int32 damage;
|
||||
/* 11 */ float force; // cd cc cc 3d
|
||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 19 */ float meleepush_z;
|
||||
/* 23 */ uint8 unknown23[5]; // was [9] this appears unrelated to the stuff the other clients do here?
|
||||
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 19 */ float hit_pitch;
|
||||
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage, Report function doesn't seem to check this :P
|
||||
/* 28 */
|
||||
};
|
||||
|
||||
@ -1555,6 +1573,19 @@ struct MoveItem_Struct
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MultiMoveItemSub_Struct
|
||||
{
|
||||
/*0000*/ InventorySlot_Struct from_slot;
|
||||
/*0020*/ uint32 number_in_stack; // so the amount we are moving from the source
|
||||
/*0024*/ InventorySlot_Struct to_slot;
|
||||
};
|
||||
|
||||
struct MultiMoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 count;
|
||||
/*0004*/ MultiMoveItemSub_Struct moves[0];
|
||||
};
|
||||
|
||||
//
|
||||
// from_slot/to_slot
|
||||
// -1 - destroy
|
||||
@ -2872,23 +2903,31 @@ struct GuildMakeLeader{
|
||||
char target[64];
|
||||
};
|
||||
|
||||
struct BugReport_Struct {
|
||||
/*0000*/ char category_name[64];
|
||||
/*0064*/ char character_name[64];
|
||||
/*0128*/ char unused_0128[32];
|
||||
/*0160*/ char ui_path[128];
|
||||
/*0288*/ float pos_x;
|
||||
/*0292*/ float pos_y;
|
||||
/*0296*/ float pos_z;
|
||||
/*0300*/ uint32 heading;
|
||||
/*0304*/ uint32 unused_0304;
|
||||
/*0308*/ uint32 time_played;
|
||||
/*0312*/ char padding_0312[8];
|
||||
/*0320*/ uint32 target_id;
|
||||
/*0324*/ char padding_0324[140];
|
||||
/*0464*/ uint32 unknown_0464; // seems to always be '0'
|
||||
/*0468*/ char target_name[64];
|
||||
/*0532*/ uint32 optional_info_mask;
|
||||
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ uint32 type;
|
||||
/*0312*/ char unknown312[2144];
|
||||
/*2456*/ char bug[1024];
|
||||
/*3480*/ char placeholder[2];
|
||||
/*3482*/ char system_info[4098];
|
||||
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||
/*0536*/ char unused_0536[2052];
|
||||
/*2588*/ char bug_report[2050];
|
||||
/*4638*/ char system_info[4098];
|
||||
/*8736*/
|
||||
};
|
||||
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -2915,20 +2954,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -4112,6 +4152,22 @@ struct AltCurrencySellItem_Struct {
|
||||
/*004*/ uint32 slot_id;
|
||||
/*006*/ uint32 charges;
|
||||
/*010*/ uint32 cost;
|
||||
};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char IsEvolving[1];
|
||||
/*032*/ char EvolveGroup[4];
|
||||
/*036*/ char EvolveLevel[1];
|
||||
/*037*/ char OrnamentIcon[5];
|
||||
/*042*/ char Hash[8];
|
||||
/*050*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
@ -52,11 +52,11 @@ namespace Titanium
|
||||
static inline uint32 TitaniumToServerSlot(int16 titaniumSlot);
|
||||
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
|
||||
// client to server say link converter
|
||||
static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink);
|
||||
|
||||
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||
@ -164,11 +164,14 @@ namespace Titanium
|
||||
OUT(source);
|
||||
OUT(level);
|
||||
OUT(instrument_mod);
|
||||
OUT(sequence);
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
//OUT(damage);
|
||||
OUT(spell);
|
||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -290,7 +293,7 @@ namespace Titanium
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
ServerToTitaniumSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
|
||||
@ -358,8 +361,8 @@ namespace Titanium
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -532,7 +535,7 @@ namespace Titanium
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
ServerToTitaniumSayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -574,7 +577,7 @@ namespace Titanium
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToTitaniumTextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToTitaniumSayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -1020,6 +1023,7 @@ namespace Titanium
|
||||
OUT(copper_cursor);
|
||||
|
||||
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
|
||||
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
|
||||
|
||||
// OUT(unknown04760[236]);
|
||||
OUT(toxicity);
|
||||
@ -1401,7 +1405,7 @@ namespace Titanium
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
ServerToTitaniumSayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -1457,7 +1461,7 @@ namespace Titanium
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToTitaniumTextLink(new_message, old_message);
|
||||
ServerToTitaniumSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
|
||||
@ -1788,6 +1792,17 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Bug)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||
|
||||
emu->category_id = EQEmu::bug::CategoryNameToCategoryID(eq->category_name);
|
||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_CastSpell)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||
@ -1807,7 +1822,7 @@ namespace Titanium
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||
std::string new_message;
|
||||
TitaniumToServerTextLink(new_message, old_message);
|
||||
TitaniumToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -1879,7 +1894,7 @@ namespace Titanium
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
TitaniumToServerTextLink(new_message, old_message);
|
||||
TitaniumToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -2473,19 +2488,19 @@ namespace Titanium
|
||||
return titaniumCorpseSlot;
|
||||
}
|
||||
|
||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
titaniumTextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
titaniumSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
titaniumTextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
titaniumSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -2495,37 +2510,37 @@ namespace Titanium
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
titaniumTextLink.push_back('\x12');
|
||||
titaniumTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
titaniumTextLink.append(segments[segment_iter].substr(36, 5));
|
||||
titaniumSayLink.push_back('\x12');
|
||||
titaniumSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
titaniumSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
titaniumTextLink.push_back(segments[segment_iter][42]);
|
||||
titaniumSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
titaniumTextLink.push_back('F');
|
||||
titaniumSayLink.push_back('F');
|
||||
|
||||
titaniumTextLink.append(segments[segment_iter].substr(48));
|
||||
titaniumTextLink.push_back('\x12');
|
||||
titaniumSayLink.append(segments[segment_iter].substr(48));
|
||||
titaniumSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
titaniumTextLink.append(segments[segment_iter]);
|
||||
titaniumSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink)
|
||||
static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (titaniumTextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = titaniumTextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (titaniumSayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = titaniumSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(titaniumTextLink, '\x12');
|
||||
auto segments = SplitString(titaniumSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -2535,18 +2550,18 @@ namespace Titanium
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverTextLink.append("00000");
|
||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverTextLink.push_back('0');
|
||||
serverTextLink.push_back(segments[segment_iter][36]);
|
||||
serverTextLink.append("00000");
|
||||
serverTextLink.append(segments[segment_iter].substr(37));
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.push_back(segments[segment_iter][36]);
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(37));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
|
||||
@ -48,6 +48,23 @@ struct EnterWorld_Struct {
|
||||
/*068*/ uint32 return_home; // 01 on "Return Home", 00 if not
|
||||
};
|
||||
|
||||
// yep, even tit had a version of the new inventory system, used by OP_MoveMultipleItems
|
||||
struct InventorySlot_Struct
|
||||
{
|
||||
/*000*/ int32 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Trade = 3, World = 4, Limbo = 5
|
||||
/*004*/ int32 Slot;
|
||||
/*008*/ int32 SubIndex; // no aug index in Tit
|
||||
/*012*/ int32 Unknown01;
|
||||
};
|
||||
|
||||
// unsure if they have a version of this, completeness though
|
||||
struct TypelessInventorySlot_Struct
|
||||
{
|
||||
/*000*/ int32 Slot;
|
||||
/*004*/ int32 SubIndex; // no aug index in Tit
|
||||
/*008*/ int32 Unknown01;
|
||||
};
|
||||
|
||||
/* Name Approval Struct */
|
||||
/* Len: */
|
||||
/* Opcode: 0x8B20*/
|
||||
@ -310,7 +327,7 @@ union
|
||||
// horse: 0=brown, 1=white, 2=black, 3=tan
|
||||
};
|
||||
/*0340*/ uint32 spawnId; // Spawn Id
|
||||
/*0344*/ uint8 unknown0344[4];
|
||||
/*0344*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0348*/ TintProfile equipment_tint;
|
||||
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
||||
/*0385*/
|
||||
@ -740,6 +757,7 @@ static const uint32 MAX_PP_LANGUAGE = 28;
|
||||
static const uint32 MAX_PP_SPELLBOOK = 400;
|
||||
static const uint32 MAX_PP_MEMSPELL = 9;
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 240;
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
@ -844,7 +862,8 @@ struct PlayerProfile_Struct
|
||||
/*04452*/ uint32 silver_cursor; // Silver Pieces on cursor
|
||||
/*04456*/ uint32 copper_cursor; // Copper Pieces on cursor
|
||||
/*04460*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
|
||||
/*04860*/ uint8 unknown04760[136];
|
||||
/*04860*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
|
||||
/*04960*/ uint8 unknown04760[36];
|
||||
/*04996*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
|
||||
/*05000*/ uint32 thirst_level; // Drink (ticks till next drink)
|
||||
/*05004*/ uint32 hunger_level; // Food (ticks till next eat)
|
||||
@ -1100,20 +1119,18 @@ struct Action_Struct
|
||||
{
|
||||
/* 00 */ uint16 target; // id of target
|
||||
/* 02 */ uint16 source; // id of caster
|
||||
/* 04 */ uint16 level; // level of caster
|
||||
/* 06 */ uint16 instrument_mod;
|
||||
/* 08 */ uint32 unknown08;
|
||||
/* 12 */ uint16 unknown16;
|
||||
// some kind of sequence that's the same in both actions
|
||||
// as well as the combat damage, to tie em together?
|
||||
/* 14 */ uint32 sequence;
|
||||
/* 18 */ uint32 unknown18;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
||||
/* 23 */ uint32 unknown23;
|
||||
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||
/* 10 */ float force;
|
||||
/* 14 */ float hit_heading;
|
||||
/* 18 */ float hit_pitch;
|
||||
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||
/* 27 */ uint16 spell; // spell id being cast
|
||||
/* 29 */ uint8 unknown29;
|
||||
/* 29 */ uint8 spell_level;
|
||||
// this field seems to be some sort of success flag, if it's 4
|
||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
||||
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||
/* 31 */
|
||||
};
|
||||
|
||||
@ -1124,12 +1141,12 @@ struct CombatDamage_Struct
|
||||
{
|
||||
/* 00 */ uint16 target;
|
||||
/* 02 */ uint16 source;
|
||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
|
||||
/* 05 */ uint16 spellid;
|
||||
/* 07 */ uint32 damage;
|
||||
/* 11 */ float force;
|
||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 19 */ float meleepush_z;
|
||||
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 19 */ float hit_pitch;
|
||||
/* 23 */
|
||||
};
|
||||
|
||||
@ -1327,6 +1344,19 @@ struct MoveItem_Struct
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MultiMoveItemSub_Struct
|
||||
{
|
||||
/*0000*/ InventorySlot_Struct from_slot;
|
||||
/*0016*/ uint32 number_in_stack; // so the amount we are moving from the source
|
||||
/*0020*/ InventorySlot_Struct to_slot;
|
||||
};
|
||||
|
||||
struct MultiMoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 count;
|
||||
/*0004*/ MultiMoveItemSub_Struct moves[0];
|
||||
};
|
||||
|
||||
//
|
||||
// from_slot/to_slot
|
||||
// -1 - destroy
|
||||
@ -2539,21 +2569,32 @@ struct GuildMakeLeader{
|
||||
char name[64];
|
||||
char target[64];
|
||||
};
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ uint32 type;
|
||||
/*0312*/ char unknown312[2144];
|
||||
/*2456*/ char bug[1024];
|
||||
/*3480*/ char placeholder[2];
|
||||
/*3482*/ char system_info[4098];
|
||||
|
||||
struct BugReport_Struct {
|
||||
/*0000*/ char category_name[64];
|
||||
/*0064*/ char character_name[64];
|
||||
/*0128*/ char unused_0128[32];
|
||||
/*0160*/ char ui_path[128];
|
||||
/*0288*/ float pos_x;
|
||||
/*0292*/ float pos_y;
|
||||
/*0296*/ float pos_z;
|
||||
/*0300*/ uint32 heading;
|
||||
/*0304*/ uint32 unused_0304;
|
||||
/*0308*/ uint32 time_played;
|
||||
/*0312*/ char padding_0312[8];
|
||||
/*0320*/ uint32 target_id;
|
||||
/*0324*/ char padding_0324[140];
|
||||
/*0464*/ uint32 unknown_0464; // seems to always be '0'
|
||||
/*0468*/ char target_name[64];
|
||||
/*0532*/ uint32 optional_info_mask;
|
||||
|
||||
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||
/*0536*/ char unused_0536[2052];
|
||||
/*2588*/ char bug_report[2050];
|
||||
/*4638*/ char system_info[4098];
|
||||
/*8736*/
|
||||
};
|
||||
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -2580,20 +2621,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -3521,6 +3563,21 @@ struct LFGuild_GuildToggle_Struct
|
||||
// char ScrollName; // '0'
|
||||
//};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char IsEvolving[1];
|
||||
/*032*/ char EvolveGroup[4];
|
||||
/*036*/ char EvolveLevel[1];
|
||||
/*037*/ char Hash[8];
|
||||
/*045*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
}; /*Titanium*/
|
||||
|
||||
@ -53,11 +53,11 @@ namespace UF
|
||||
static inline uint32 UFToServerSlot(uint32 ufSlot);
|
||||
static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot);
|
||||
|
||||
// server to client text link converter
|
||||
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink);
|
||||
// server to client say link converter
|
||||
static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink);
|
||||
|
||||
// client to server text link converter
|
||||
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink);
|
||||
// client to server say link converter
|
||||
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink);
|
||||
|
||||
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
|
||||
@ -161,29 +161,20 @@ namespace UF
|
||||
OUT(source);
|
||||
OUT(level);
|
||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||
eq->knockback_angle = emu->sequence;
|
||||
OUT(force);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(type);
|
||||
OUT(spell);
|
||||
eq->level2 = eq->level;
|
||||
eq->effect_flag = emu->buff_unknown;
|
||||
eq->unknown37 = 0x01;
|
||||
eq->unknown44 = 0xFFFFFFFF;
|
||||
eq->unknown48 = 0xFFFFFFFF;
|
||||
eq->unknown52 = 0xFFFFFFFF;
|
||||
|
||||
/*OUT(target);
|
||||
OUT(source);
|
||||
OUT(level);
|
||||
OUT(instrument_mod);
|
||||
eq->sequence = emu->sequence;
|
||||
OUT(type);
|
||||
//OUT(damage);
|
||||
OUT(spell);
|
||||
eq->level2 = emu->level;
|
||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
||||
//eq->unknown0036 = -1;
|
||||
//eq->unknown0040 = -1;
|
||||
//eq->unknown0044 = -1;*/
|
||||
OUT(spell_level);
|
||||
OUT(effect_flag);
|
||||
eq->spell_gem = 0;
|
||||
eq->slot[0] = -1; // type
|
||||
eq->slot[1] = -1; // slot
|
||||
eq->slot[2] = -1; // sub index
|
||||
eq->slot[3] = -1; // aug index
|
||||
eq->slot[4] = -1; // unknown
|
||||
eq->item_cast_type = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -391,7 +382,7 @@ namespace UF
|
||||
{
|
||||
SETUP_VAR_ENCODE(BuffIcon_Struct);
|
||||
|
||||
uint32 sz = 12 + (17 * emu->count);
|
||||
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
|
||||
__packet->size = sz;
|
||||
__packet->pBuffer = new unsigned char[sz];
|
||||
memset(__packet->pBuffer, 0, sz);
|
||||
@ -407,7 +398,7 @@ namespace UF
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits);
|
||||
__packet->WriteString("");
|
||||
__packet->WriteString(emu->entries[i].caster);
|
||||
}
|
||||
__packet->WriteUInt8(emu->type);
|
||||
|
||||
@ -463,7 +454,7 @@ namespace UF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToUFTextLink(new_message, old_message);
|
||||
ServerToUFSayLink(new_message, old_message);
|
||||
|
||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||
@ -586,8 +577,8 @@ namespace UF
|
||||
OUT(spellid);
|
||||
OUT(damage);
|
||||
OUT(force);
|
||||
OUT(meleepush_xy);
|
||||
OUT(meleepush_z);
|
||||
OUT(hit_heading);
|
||||
OUT(hit_pitch);
|
||||
OUT(special);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@ -762,7 +753,7 @@ namespace UF
|
||||
|
||||
std::string old_message = emu->message;
|
||||
std::string new_message;
|
||||
ServerToUFTextLink(new_message, old_message);
|
||||
ServerToUFSayLink(new_message, old_message);
|
||||
|
||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||
// new_message = new_message.substr(0, 512);
|
||||
@ -814,7 +805,7 @@ namespace UF
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
if (old_message_array[i].length() == 0) { break; }
|
||||
ServerToUFTextLink(new_message_array[i], old_message_array[i]);
|
||||
ServerToUFSayLink(new_message_array[i], old_message_array[i]);
|
||||
new_message_size += new_message_array[i].length() + 1;
|
||||
}
|
||||
|
||||
@ -1850,6 +1841,7 @@ namespace UF
|
||||
OUT(copper_cursor);
|
||||
|
||||
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
|
||||
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
|
||||
|
||||
// OUT(unknown04760[236]);
|
||||
OUT(toxicity);
|
||||
@ -2468,7 +2460,7 @@ namespace UF
|
||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||
std::string new_message;
|
||||
|
||||
ServerToUFTextLink(new_message, old_message);
|
||||
ServerToUFSayLink(new_message, old_message);
|
||||
|
||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||
@ -2538,7 +2530,7 @@ namespace UF
|
||||
|
||||
std::string old_message = InBuffer; // start 'Reward' as string
|
||||
std::string new_message;
|
||||
ServerToUFTextLink(new_message, old_message);
|
||||
ServerToUFSayLink(new_message, old_message);
|
||||
|
||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||
@ -3286,7 +3278,7 @@ namespace UF
|
||||
|
||||
std::string old_message = InBuffer;
|
||||
std::string new_message;
|
||||
UFToServerTextLink(new_message, old_message);
|
||||
UFToServerSayLink(new_message, old_message);
|
||||
|
||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||
@ -3397,7 +3389,7 @@ namespace UF
|
||||
IN(type);
|
||||
IN(spellid);
|
||||
IN(damage);
|
||||
IN(meleepush_xy);
|
||||
IN(hit_heading);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -3420,7 +3412,7 @@ namespace UF
|
||||
|
||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||
std::string new_message;
|
||||
UFToServerTextLink(new_message, old_message);
|
||||
UFToServerSayLink(new_message, old_message);
|
||||
|
||||
__packet->size = sizeof(Emote_Struct);
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
@ -4289,19 +4281,19 @@ namespace UF
|
||||
return (ufCorpseSlot - 1);
|
||||
}
|
||||
|
||||
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink)
|
||||
static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink)
|
||||
{
|
||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
||||
ufTextLink = serverTextLink;
|
||||
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||
ufSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverTextLink, '\x12');
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
||||
ufTextLink.append(segments[segment_iter]);
|
||||
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||
ufSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -4311,37 +4303,37 @@ namespace UF
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
ufTextLink.push_back('\x12');
|
||||
ufTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
ufTextLink.append(segments[segment_iter].substr(36, 5));
|
||||
ufSayLink.push_back('\x12');
|
||||
ufSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
ufSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
ufTextLink.push_back(segments[segment_iter][42]);
|
||||
ufSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
ufTextLink.push_back('F');
|
||||
ufSayLink.push_back('F');
|
||||
|
||||
ufTextLink.append(segments[segment_iter].substr(43));
|
||||
ufTextLink.push_back('\x12');
|
||||
ufSayLink.append(segments[segment_iter].substr(43));
|
||||
ufSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
ufTextLink.append(segments[segment_iter]);
|
||||
ufSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink)
|
||||
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink)
|
||||
{
|
||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (ufTextLink.find('\x12') == std::string::npos)) {
|
||||
serverTextLink = ufTextLink;
|
||||
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (ufSayLink.find('\x12') == std::string::npos)) {
|
||||
serverSayLink = ufSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(ufTextLink, '\x12');
|
||||
auto segments = SplitString(ufSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
@ -4351,16 +4343,16 @@ namespace UF
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
serverTextLink.push_back('\x12');
|
||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverTextLink.append("00000");
|
||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverTextLink.push_back('0');
|
||||
serverTextLink.append(segments[segment_iter].substr(36));
|
||||
serverTextLink.push_back('\x12');
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(36));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverTextLink.append(segments[segment_iter]);
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ struct Spawn_Struct
|
||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||
/*0064*/ uint32 spawnId;
|
||||
/*0068*/ uint8 level;
|
||||
/*0069*/ float unknown1;
|
||||
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
Spawn_Struct_Bitfields Bitfields;
|
||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||
@ -848,6 +848,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
|
||||
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
|
||||
static const uint32 MAX_PP_MEMSPELL = 12; //was 9 now 10 on Underfoot
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
@ -954,7 +955,8 @@ struct PlayerProfile_Struct
|
||||
/*07336*/ uint32 silver_cursor; // Silver Pieces on cursor
|
||||
/*07340*/ uint32 copper_cursor; // Copper Pieces on cursor
|
||||
/*07344*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
|
||||
/*07744*/ uint8 unknown07644[136];
|
||||
/*07744*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
|
||||
/*07844*/ uint8 unknown07644[36];
|
||||
/*07880*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
|
||||
/*07884*/ uint32 thirst_level; // Drink (ticks till next drink)
|
||||
/*07888*/ uint32 hunger_level; // Food (ticks till next eat)
|
||||
@ -1250,19 +1252,19 @@ struct Action_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*10*/ uint16 instrument_focus;
|
||||
/*12*/ uint16 unknown12; // seems to always be set to something and it doesn't change between casts except in special cases like changing instrument mods
|
||||
/*14*/ uint32 unknown14; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint16 spell; // spell id being cast
|
||||
/*35*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*35*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*37*/
|
||||
};
|
||||
|
||||
|
||||
@ -1274,27 +1276,22 @@ struct ActionAlt_Struct
|
||||
{
|
||||
/*00*/ uint16 target; // id of target
|
||||
/*02*/ uint16 source; // id of caster
|
||||
/*04*/ uint16 level; // level of caster - Seen 0
|
||||
/*06*/ uint32 unknown06;
|
||||
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||
/*10*/ float instrument_mod;
|
||||
/*14*/ uint32 unknown14; // seen 0
|
||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
||||
/*22*/ uint32 unknown22;
|
||||
/*26*/ uint8 type;
|
||||
/*27*/ uint32 damage;
|
||||
/*31*/ uint16 unknown31;
|
||||
/*14*/ float force;
|
||||
/*18*/ float hit_heading;
|
||||
/*22*/ float hit_pitch;
|
||||
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||
/*27*/ uint32 damage; // OSX says min_damage
|
||||
/*31*/ uint16 unknown31; // OSX says tohit
|
||||
/*33*/ uint16 spell; // spell id being cast
|
||||
/*35*/ uint8 level2; // level of caster again? Or maybe the castee
|
||||
/*35*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||
/*37*/ uint32 unknown37; // New field to Underfoot - Seen 14
|
||||
/*41*/ uint8 unknown41; // New field to Underfoot - Seen 0
|
||||
/*42*/ uint8 unknown42; // New field to Underfoot - Seen 0
|
||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
||||
/*44*/ uint32 unknown44; // New field to Underfoot - Seen 23
|
||||
/*48*/ uint32 unknown48; // New field to Underfoot - Seen -1
|
||||
/*52*/ uint32 unknown52; // New field to Underfoot - Seen -1
|
||||
/*56*/ uint32 unknown56; // New field to Underfoot - Seen 0
|
||||
/*60*/ uint32 unknown60; // New field to Underfoot - Seen 0
|
||||
/*37*/ uint8 spell_gem;
|
||||
/*38*/ uint8 padding38[2];
|
||||
/*40*/ uint32 slot[5];
|
||||
/*60*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||
/*64*/
|
||||
};
|
||||
|
||||
@ -1309,9 +1306,9 @@ struct CombatDamage_Struct
|
||||
/* 05 */ uint16 spellid;
|
||||
/* 07 */ int32 damage;
|
||||
/* 11 */ float force; // cd cc cc 3d
|
||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
||||
/* 19 */ float meleepush_z;
|
||||
/* 23 */ uint8 unknown23; // was [9]
|
||||
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||
/* 19 */ float hit_pitch;
|
||||
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||
/* 28 */
|
||||
};
|
||||
@ -3058,23 +3055,6 @@ struct GuildMakeLeader{
|
||||
char target[64];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct BugStruct{
|
||||
/*0000*/ char chartype[64];
|
||||
/*0064*/ char name[96];
|
||||
/*0160*/ char ui[128];
|
||||
/*0288*/ float x;
|
||||
/*0292*/ float y;
|
||||
/*0296*/ float z;
|
||||
/*0300*/ float heading;
|
||||
/*0304*/ uint32 unknown304;
|
||||
/*0308*/ uint32 type;
|
||||
/*0312*/ char unknown312[2144];
|
||||
/*2456*/ char bug[1024];
|
||||
/*3480*/ char placeholder[2];
|
||||
/*3482*/ char system_info[4098];
|
||||
};
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@ -3101,20 +3081,21 @@ struct Ground_Spawn{
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
struct PetitionBug_Struct{
|
||||
uint32 petition_number;
|
||||
uint32 unknown4;
|
||||
char accountname[64];
|
||||
uint32 zoneid;
|
||||
char name[64];
|
||||
uint32 level;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 unknown152[3];
|
||||
uint32 time;
|
||||
uint32 unknown168;
|
||||
char text[1028];
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
// uint32 petition_number;
|
||||
// uint32 unknown4;
|
||||
// char accountname[64];
|
||||
// uint32 zoneid;
|
||||
// char name[64];
|
||||
// uint32 level;
|
||||
// uint32 class_;
|
||||
// uint32 race;
|
||||
// uint32 unknown152[3];
|
||||
// uint32 time;
|
||||
// uint32 unknown168;
|
||||
// char text[1028];
|
||||
//};
|
||||
|
||||
struct ApproveZone_Struct {
|
||||
char name[64];
|
||||
@ -4503,6 +4484,22 @@ struct MercenaryAssign_Struct {
|
||||
/*0004*/ uint32 MercUnk01; //
|
||||
/*0008*/ uint32 MercUnk02; //
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct SayLinkBodyFrame_Struct {
|
||||
/*000*/ char ActionID[1];
|
||||
/*001*/ char ItemID[5];
|
||||
/*006*/ char Augment1[5];
|
||||
/*011*/ char Augment2[5];
|
||||
/*016*/ char Augment3[5];
|
||||
/*021*/ char Augment4[5];
|
||||
/*026*/ char Augment5[5];
|
||||
/*031*/ char IsEvolving[1];
|
||||
/*032*/ char EvolveGroup[4];
|
||||
/*036*/ char EvolveLevel[1];
|
||||
/*037*/ char OrnamentIcon[5];
|
||||
/*042*/ char Hash[8];
|
||||
/*050*/
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
116
common/races.cpp
116
common/races.cpp
@ -1488,6 +1488,122 @@ uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit)
|
||||
}
|
||||
}
|
||||
|
||||
float GetRaceGenderDefaultHeight(int race, int gender)
|
||||
{
|
||||
static float male_height[] = {
|
||||
6.0f, 6.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 5.5f, 4.0f, 8.0f, 9.0f, 3.5f, 3.0f, 6.0f, 6.0f,
|
||||
2.0f, 8.5f, 8.0f, 21.0f, 20.0f, 6.0f, 6.0f, 3.5f, 3.0f, 6.0f, 2.0f, 5.0f, 5.0f, 6.0f, 6.0f,
|
||||
6.0f, 7.5f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 5.0f, 6.0f, 6.0f, 7.0f, 4.0f, 4.7f, 6.0f,
|
||||
8.0f, 3.0f, 12.0f, 5.0f, 21.0f, 6.0f, 6.0f, 3.0f, 9.0f, 6.0f, 6.0f, 2.0f, 6.0f, 3.0f, 6.0f,
|
||||
4.0f, 20.0f, 5.0f, 5.0f, 6.0f, 9.0f, 25.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.5f,
|
||||
7.0f, 6.0f, 5.0f, 6.0f, 1.5f, 1.0f, 3.5f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 3.0f, 3.0f,
|
||||
7.0f, 12.0f, 8.0f, 9.0f, 4.0f, 11.5f, 8.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f, 20.0f, 10.0f,
|
||||
6.5f, 6.0f, 17.0f, 1.0f, 4.0f, 6.0f, 8.0f, 5.0f, 1.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f,
|
||||
3.0f, 8.0f, 2.0f, 24.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 3.0f, 7.0f, 9.0f, 6.0f, 11.0f, 2.5f,
|
||||
14.0f, 8.0f, 7.0f, 12.0f, 6.0f, 27.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.0f, 9.0f, 9.0f, 6.0f, 9.0f,
|
||||
3.0f, 3.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 15.0f, 15.0f, 9.0f, 7.0f, 6.0f, 6.0f, 7.0f, 8.0f,
|
||||
3.0f, 3.0f, 6.0f, 7.0f, 13.0f, 6.0f, 6.0f, 9.0f, 5.0f, 7.0f, 9.0f, 6.0f, 6.0f, 8.0f, 6.0f,
|
||||
6.0f, 5.5f, 6.0f, 4.0f, 25.0f, 6.0f, 6.0f, 6.0f, 22.0f, 20.0f, 6.0f, 10.0f, 13.5f, 12.0f, 3.0f,
|
||||
30.0f, 6.0f, 6.0f, 35.0f, 1.5f, 8.0f, 3.0f, 6.0f, 2.0f, 6.0f, 6.0f, 5.0f, 2.0f, 7.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 6.0f, 6.0f, 8.0f, 8.0f, 7.0f, 8.0f, 6.0f, 7.0f, 6.0f, 7.0f,
|
||||
6.0f, 10.0f, 3.0f, 6.0f, 8.0f, 9.0f, 15.0f, 5.0f, 10.0f, 7.0f, 6.0f, 7.0f, 6.0f, 7.0f, 7.0f,
|
||||
12.0f, 6.0f, 4.0f, 6.0f, 5.0f, 3.0f, 30.0f, 30.0f, 15.0f, 20.0f, 6.0f, 10.0f, 6.0f, 14.0f, 14.0f,
|
||||
16.0f, 15.0f, 30.0f, 15.0f, 7.5f, 5.0f, 4.0f, 6.0f, 15.0f, 6.5f, 3.0f, 12.0f, 10.0f, 10.5f, 10.0f,
|
||||
7.5f, 6.0f, 6.0f, 12.5f, 9.0f, 20.0f, 2.0f, 10.0f, 25.0f, 8.0f, 6.0f, 6.0f, 10.0f, 18.0f, 45.0f,
|
||||
13.0f, 15.0f, 8.0f, 30.0f, 25.0f, 25.0f, 10.0f, 13.0f, 5.0f, 3.5f, 15.0f, 35.0f, 11.0f, 15.0f, 50.0f,
|
||||
13.0f, 6.0f, 7.0f, 6.0f, 60.0f, 6.0f, 22.0f, 22.0f, 21.0f, 22.0f, 15.0f, 25.0f, 23.0f, 8.0f, 15.0f,
|
||||
10.0f, 6.0f, 7.0f, 6.0f, 12.0f, 9.5f, 6.0f, 12.0f, 12.0f, 12.0f, 15.0f, 4.0f, 5.0f, 105.0f, 20.0f,
|
||||
5.0f, 10.0f, 10.0f, 10.0f, 20.0f, 13.5f, 8.0f, 10.0f, 3.0f, 5.0f, 9.0f, 6.0f, 6.0f, 6.0f, 10.0f,
|
||||
8.0f, 8.0f, 8.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f, 9.0f, 9.0f, 6.0f, 8.5f, 6.0f, 7.0f,
|
||||
8.0f, 7.0f, 11.0f, 6.0f, 7.0f, 9.0f, 8.0f, 6.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 10.0f,
|
||||
6.0f, 3.0f, 4.0f, 3.0f, 3.0f, 4.0f, 10.0f, 10.0f, 2.0f, 8.0f, 6.0f, 6.0f, 14.0f, 7.0f, 5.0f,
|
||||
9.0f, 7.0f, 7.0f, 10.0f, 10.0f, 12.0f, 9.0f, 7.0f, 12.0f, 13.0f, 16.0f, 6.0f, 9.0f, 6.0f, 6.0f,
|
||||
10.0f, 25.0f, 15.0f, 6.0f, 25.0f, 6.0f, 6.0f, 8.0f, 11.0f, 6.0f, 9.0f, 2.0f, 6.0f, 5.0f, 4.0f,
|
||||
8.5f, 6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 15.0f, 1.0f, 2.0f, 6.0f, 40.0f, 8.0f, 12.0f, 3.0f, 8.0f,
|
||||
99.0f, 9.0f, 100.0f, 100.0f, 10.0f, 6.0f, 27.5f, 20.0f, 6.0f, 6.0f, 5.0f, 6.0f, 8.0f, 5.0f, 3.0f,
|
||||
11.5f, 25.0f, 80.0f, 20.0f, 9.0f, 8.0f, 5.0f, 4.0f, 7.0f, 10.0f, 6.0f, 11.0f, 8.0f, 5.0f, 6.0f,
|
||||
6.0f, 30.0f, 7.0f, 15.0f, 9.0f, 6.0f, 9.0f, 6.0f, 3.0f, 32.5f, 15.0f, 7.5f, 10.0f, 10.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 20.0f, 6.0f, 6.0f, 6.0f, 25.0f, 12.0f, 6.0f, 8.0f, 6.0f,
|
||||
6.0f, 20.0f, 10.0f, 8.0f, 12.0f, 8.0f, 2.0f, 6.0f, 3.0f, 6.0f, 7.0f, 1.5f, 6.0f, 3.0f, 3.0f,
|
||||
3.0f, 3.0f, 2.0f, 3.0f, 3.0f, 6.0f, 6.0f, 6.0f, 4.5f, 7.0f, 6.0f, 7.0f, 6.0f, 22.0f, 8.0f,
|
||||
15.0f, 22.0f, 8.0f, 15.0f, 6.0f, 80.0f, 150.0f, 7.0f, 6.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 35.0f, 20.0f, 9.0f, 6.0f, 6.0f, 6.0f, 20.0f, 20.0f,
|
||||
20.0f, 20.0f, 20.0f, 9.0f, 4.0f, 4.0f, 10.0f, 5.0f, 8.0f, 6.0f, 10.0f, 6.0f, 6.0f, 2.0f, 36.0f,
|
||||
14.0f, 7.0f, 250.0f, 6.0f, 9.0f, 6.0f, 7.0f, 4.0f, 6.0f, 8.0f, 6.0f, 23.0f, 6.0f, 6.0f, 6.0f,
|
||||
70.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 20.0f, 6.0f, 6.0f, 6.0f, 5.0f, 1.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
4.0f, 4.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
|
||||
6.0f, 6.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 7.5f, 6.0f, 6.0f, 4.0f, 6.0f, 3.0f, 6.0f, 6.0f,
|
||||
1.0f, 9.0f, 7.0f, 8.0f, 7.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
|
||||
};
|
||||
|
||||
static float female_height[] = {
|
||||
6.0f, 6.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 5.5f, 4.0f, 8.0f, 9.0f, 3.5f, 3.0f, 6.0f, 6.0f,
|
||||
2.0f, 8.5f, 8.0f, 21.0f, 20.0f, 6.0f, 6.0f, 3.5f, 3.0f, 6.0f, 2.0f, 5.0f, 5.0f, 6.0f, 6.0f,
|
||||
6.0f, 7.5f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 5.0f, 6.0f, 6.0f, 7.0f, 4.0f, 4.7f, 6.0f,
|
||||
8.0f, 3.0f, 12.0f, 5.0f, 21.0f, 6.0f, 6.0f, 3.0f, 9.0f, 6.0f, 6.0f, 2.0f, 6.0f, 3.0f, 6.0f,
|
||||
4.0f, 20.0f, 5.0f, 5.0f, 6.0f, 9.0f, 25.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.5f,
|
||||
7.0f, 6.0f, 5.0f, 6.0f, 1.5f, 1.0f, 3.5f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 3.0f, 3.0f,
|
||||
7.0f, 12.0f, 8.0f, 9.0f, 4.0f, 11.5f, 8.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f, 20.0f, 10.0f,
|
||||
6.5f, 6.0f, 17.0f, 1.0f, 4.0f, 6.0f, 8.0f, 5.0f, 1.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f,
|
||||
3.0f, 8.0f, 2.0f, 24.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 3.0f, 7.0f, 9.0f, 6.0f, 11.0f, 2.5f,
|
||||
14.0f, 8.0f, 7.0f, 12.0f, 6.0f, 27.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.0f, 9.0f, 9.0f, 6.0f, 9.0f,
|
||||
3.0f, 3.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 15.0f, 15.0f, 9.0f, 7.0f, 6.0f, 6.0f, 7.0f, 8.0f,
|
||||
3.0f, 3.0f, 6.0f, 7.0f, 13.0f, 6.0f, 6.0f, 9.0f, 5.0f, 7.0f, 9.0f, 6.0f, 6.0f, 8.0f, 6.0f,
|
||||
6.0f, 5.5f, 6.0f, 4.0f, 25.0f, 6.0f, 6.0f, 6.0f, 22.0f, 20.0f, 6.0f, 10.0f, 13.5f, 12.0f, 3.0f,
|
||||
30.0f, 6.0f, 6.0f, 35.0f, 1.5f, 8.0f, 3.0f, 6.0f, 2.0f, 6.0f, 6.0f, 5.0f, 2.0f, 7.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 6.0f, 6.0f, 8.0f, 8.0f, 7.0f, 8.0f, 6.0f, 7.0f, 6.0f, 7.0f,
|
||||
6.0f, 10.0f, 3.0f, 6.0f, 8.0f, 9.0f, 15.0f, 5.0f, 10.0f, 7.0f, 6.0f, 7.0f, 6.0f, 7.0f, 7.0f,
|
||||
12.0f, 6.0f, 4.0f, 6.0f, 5.0f, 3.0f, 30.0f, 30.0f, 15.0f, 20.0f, 6.0f, 10.0f, 6.0f, 14.0f, 14.0f,
|
||||
16.0f, 15.0f, 30.0f, 15.0f, 7.5f, 5.0f, 4.0f, 6.0f, 15.0f, 6.5f, 3.0f, 12.0f, 10.0f, 10.5f, 10.0f,
|
||||
7.5f, 6.0f, 6.0f, 12.5f, 9.0f, 20.0f, 2.0f, 10.0f, 25.0f, 8.0f, 6.0f, 6.0f, 10.0f, 18.0f, 45.0f,
|
||||
13.0f, 15.0f, 8.0f, 30.0f, 25.0f, 25.0f, 10.0f, 13.0f, 5.0f, 3.5f, 15.0f, 35.0f, 11.0f, 15.0f, 50.0f,
|
||||
13.0f, 6.0f, 7.0f, 6.0f, 60.0f, 6.0f, 22.0f, 22.0f, 21.0f, 22.0f, 15.0f, 25.0f, 23.0f, 8.0f, 15.0f,
|
||||
10.0f, 6.0f, 7.0f, 6.0f, 12.0f, 9.5f, 6.0f, 12.0f, 12.0f, 12.0f, 15.0f, 4.0f, 5.0f, 105.0f, 20.0f,
|
||||
5.0f, 10.0f, 10.0f, 10.0f, 20.0f, 13.5f, 8.0f, 10.0f, 3.0f, 5.0f, 9.0f, 6.0f, 6.0f, 6.0f, 10.0f,
|
||||
8.0f, 8.0f, 8.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f, 9.0f, 9.0f, 6.0f, 8.5f, 6.0f, 7.0f,
|
||||
8.0f, 7.0f, 11.0f, 6.0f, 7.0f, 9.0f, 8.0f, 6.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 10.0f,
|
||||
6.0f, 3.0f, 4.0f, 3.0f, 3.0f, 4.0f, 10.0f, 10.0f, 2.0f, 8.0f, 6.0f, 6.0f, 14.0f, 7.0f, 5.0f,
|
||||
9.0f, 7.0f, 7.0f, 10.0f, 10.0f, 12.0f, 9.0f, 7.0f, 12.0f, 13.0f, 16.0f, 6.0f, 9.0f, 6.0f, 6.0f,
|
||||
10.0f, 25.0f, 15.0f, 6.0f, 25.0f, 6.0f, 6.0f, 8.0f, 11.0f, 6.0f, 9.0f, 2.0f, 6.0f, 5.0f, 4.0f,
|
||||
8.5f, 6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 15.0f, 1.0f, 2.0f, 6.0f, 40.0f, 8.0f, 12.0f, 3.0f, 8.0f,
|
||||
99.0f, 9.0f, 100.0f, 100.0f, 10.0f, 6.0f, 27.5f, 20.0f, 6.0f, 6.0f, 5.0f, 6.0f, 8.0f, 5.0f, 3.0f,
|
||||
11.5f, 25.0f, 80.0f, 20.0f, 9.0f, 8.0f, 5.0f, 4.0f, 7.0f, 10.0f, 6.0f, 11.0f, 8.0f, 5.0f, 6.0f,
|
||||
6.0f, 30.0f, 7.0f, 15.0f, 9.0f, 6.0f, 9.0f, 6.0f, 3.0f, 32.5f, 15.0f, 7.5f, 10.0f, 10.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 20.0f, 6.0f, 6.0f, 6.0f, 25.0f, 12.0f, 6.0f, 8.0f, 6.0f,
|
||||
6.0f, 20.0f, 9.0f, 8.0f, 12.0f, 8.0f, 2.0f, 6.0f, 3.0f, 6.0f, 7.0f, 1.5f, 6.0f, 3.0f, 3.0f,
|
||||
3.0f, 3.0f, 2.0f, 3.0f, 3.0f, 6.0f, 6.0f, 6.0f, 4.5f, 7.0f, 6.0f, 7.0f, 5.7f, 22.0f, 8.0f,
|
||||
15.0f, 22.0f, 8.0f, 15.0f, 6.0f, 80.0f, 150.0f, 7.0f, 6.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 35.0f, 20.0f, 9.0f, 6.0f, 6.0f, 6.0f, 20.0f, 20.0f,
|
||||
20.0f, 20.0f, 20.0f, 9.0f, 4.0f, 4.0f, 10.0f, 5.0f, 8.0f, 6.0f, 10.0f, 5.7f, 6.0f, 2.0f, 36.0f,
|
||||
14.0f, 7.0f, 250.0f, 6.0f, 9.0f, 6.0f, 7.0f, 4.0f, 6.0f, 8.0f, 6.0f, 23.0f, 6.0f, 6.0f, 6.0f,
|
||||
70.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 20.0f, 6.0f, 6.0f, 6.0f, 5.0f, 1.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
4.0f, 4.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
|
||||
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
|
||||
6.0f, 6.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 7.5f, 6.0f, 6.0f, 4.0f, 6.0f, 3.0f, 6.0f, 6.0f,
|
||||
1.0f, 9.0f, 7.0f, 8.0f, 7.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
|
||||
};
|
||||
|
||||
const auto size = sizeof(male_height) / sizeof(male_height[0]);
|
||||
|
||||
if (race > size)
|
||||
return 6.0f;
|
||||
|
||||
if (gender == 1)
|
||||
return female_height[race];
|
||||
|
||||
return male_height[race];
|
||||
}
|
||||
|
||||
// PlayerAppearance prep
|
||||
#define HUMAN_MALE ((HUMAN << 8) | MALE)
|
||||
|
||||
@ -858,6 +858,8 @@ uint32 GetPlayerRaceBit(uint16 race_id);
|
||||
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
||||
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
|
||||
|
||||
float GetRaceGenderDefaultHeight(int race, int gender);
|
||||
|
||||
|
||||
// player race-/gender-based model feature validators
|
||||
namespace PlayerAppearance
|
||||
|
||||
@ -44,6 +44,7 @@ RULE_INT(Character, DeathExpLossMaxLevel, 255) // Any level greater than this wi
|
||||
RULE_INT(Character, DeathItemLossLevel, 10)
|
||||
RULE_INT(Character, DeathExpLossMultiplier, 3) //Adjust how much exp is lost
|
||||
RULE_BOOL(Character, UseDeathExpLossMult, false) //Adjust to use the above multiplier or to use code default.
|
||||
RULE_BOOL(Character, UseOldRaceRezEffects, false) // older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore
|
||||
RULE_INT(Character, CorpseDecayTimeMS, 10800000)
|
||||
RULE_INT(Character, CorpseResTimeMS, 10800000) // time before cant res corpse(3 hours)
|
||||
RULE_BOOL(Character, LeaveCorpses, true)
|
||||
@ -66,11 +67,12 @@ RULE_INT(Character, AutosaveIntervalS, 300) //0=disabled
|
||||
RULE_INT(Character, HPRegenMultiplier, 100)
|
||||
RULE_INT(Character, ManaRegenMultiplier, 100)
|
||||
RULE_INT(Character, EnduranceRegenMultiplier, 100)
|
||||
RULE_BOOL(Character, OldMinMana, false) // this is used for servers that want to follow older skill cap formulas so they can still have some regen w/o mediate
|
||||
RULE_INT(Character, ConsumptionMultiplier, 100) //item's hunger restored = this value * item's food level, 100 = normal, 50 = people eat 2x as fast, 200 = people eat 2x as slow
|
||||
RULE_BOOL(Character, HealOnLevel, false)
|
||||
RULE_BOOL(Character, FeignKillsPet, false)
|
||||
RULE_INT(Character, ItemManaRegenCap, 15)
|
||||
RULE_INT(Character, ItemHealthRegenCap, 35)
|
||||
RULE_INT(Character, ItemHealthRegenCap, 30)
|
||||
RULE_INT(Character, ItemDamageShieldCap, 30)
|
||||
RULE_INT(Character, ItemAccuracyCap, 150)
|
||||
RULE_INT(Character, ItemAvoidanceCap, 100)
|
||||
@ -91,10 +93,12 @@ RULE_INT(Character, HasteCap, 100) // Haste cap for non-v3(overhaste) haste.
|
||||
RULE_INT(Character, SkillUpModifier, 100) //skill ups are at 100%
|
||||
RULE_BOOL(Character, SharedBankPlat, false) //off by default to prevent duping for now
|
||||
RULE_BOOL(Character, BindAnywhere, false)
|
||||
RULE_INT(Character, RestRegenPercent, 0) // Set to >0 to enable rest state bonus HP and mana regen.
|
||||
RULE_BOOL(Character, RestRegenEnabled, true) // Enable OOC Regen
|
||||
RULE_INT(Character, RestRegenHP, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
|
||||
RULE_INT(Character, RestRegenMana, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
|
||||
RULE_INT(Character, RestRegenEnd, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
|
||||
RULE_INT(Character, RestRegenTimeToActivate, 30) // Time in seconds for rest state regen to kick in.
|
||||
RULE_INT(Character, RestRegenRaidTimeToActivate, 300) // Time in seconds for rest state regen to kick in with a raid target.
|
||||
RULE_BOOL(Character, RestRegenEndurance, false) // Whether rest regen will work for endurance or not.
|
||||
RULE_INT(Character, KillsPerGroupLeadershipAA, 250) // Number of dark blues or above per Group Leadership AA
|
||||
RULE_INT(Character, KillsPerRaidLeadershipAA, 250) // Number of dark blues or above per Raid Leadership AA
|
||||
RULE_INT(Character, MaxFearDurationForPlayerCharacter, 4) //4 tics, each tic calculates every 6 seconds.
|
||||
@ -117,7 +121,8 @@ RULE_BOOL(Character, EnableDiscoveredItems, true) // If enabled, it enables EVEN
|
||||
RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Window, for users with UF and later clients.
|
||||
RULE_BOOL(Character, EnableAggroMeter, true) // Enable Aggro Meter, for users with RoF and later clients.
|
||||
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
|
||||
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
|
||||
RULE_INT(Character, FoodLossPerUpdate, 32) // How much food/water you lose per stamina update
|
||||
RULE_BOOL(Character, EnableHungerPenalties, false) // being hungry/thirsty has negative effects -- it does appear normal live servers do not have penalties
|
||||
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.
|
||||
@ -152,6 +157,7 @@ RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Targe
|
||||
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
||||
RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server
|
||||
RULE_BOOL(Character, AllowCrossClassTrainers, false)
|
||||
RULE_BOOL(Character, PetsUseReagents, true) //Pets use reagent on spells
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mercs)
|
||||
@ -187,12 +193,14 @@ RULE_INT(Skills, MaxTrainSpecializations, 50) // Max level a GM trainer will tra
|
||||
RULE_INT(Skills, SwimmingStartValue, 100)
|
||||
RULE_BOOL(Skills, TrainSenseHeading, false)
|
||||
RULE_INT(Skills, SenseHeadingStartValue, 200)
|
||||
RULE_BOOL(Skills, SelfLanguageLearning, true)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Pets)
|
||||
RULE_REAL(Pets, AttackCommandRange, 150)
|
||||
RULE_BOOL(Pets, UnTargetableSwarmPet, false)
|
||||
RULE_REAL(Pets, PetPowerLevelCap, 10) // Max number of levels your pet can go up with pet power
|
||||
RULE_BOOL(Pets, CanTakeNoDrop, false) // Can everyone trade nodrop gear to pets
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(GM)
|
||||
@ -227,6 +235,7 @@ RULE_INT(World, TitaniumStartZoneID, -1) //Sets the Starting Zone for Titanium C
|
||||
RULE_INT(World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS.
|
||||
RULE_BOOL(World, UseClientBasedExpansionSettings, true) // if true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using
|
||||
RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules.
|
||||
RULE_INT(World, PVPMinLevel, 0) // minimum level to pvp
|
||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
||||
@ -269,17 +278,10 @@ RULE_INT(Zone, GlobalLootMultiplier, 1) // Sets Global Loot drop multiplier for
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Map)
|
||||
//enable these to help prevent mob hopping when they are pathing
|
||||
RULE_BOOL(Map, FixPathingZWhenLoading, true) //increases zone boot times a bit to reduce hopping.
|
||||
RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, accomplishes the same thing but does it at each waypoint instead of once at boot time.
|
||||
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
|
||||
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
|
||||
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
|
||||
RULE_BOOL(Map, MobZVisualDebug, false) // Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaLoading, 45) //while loading each waypoint: max change in Z to allow the BestZ code to apply.
|
||||
RULE_INT(Map, FindBestZHeightAdjust, 1) // Adds this to the current Z before seeking the best Z position
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
@ -401,6 +403,7 @@ RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false) // ignore the 5 level spr
|
||||
RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though
|
||||
RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target.
|
||||
RULE_BOOL(Spells, OldRainTargets, false) // use old incorrectly implemented max targets for rains
|
||||
RULE_BOOL(Spells, NPCSpellPush, false) // enable spell push on NPCs
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
@ -503,6 +506,7 @@ RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will tak
|
||||
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
|
||||
RULE_BOOL(Combat, ClassicMasterWu, false) // classic master wu uses a random special, modern doesn't
|
||||
RULE_INT(Combat, LevelToStopDamageCaps, 0) // 1 will effectively disable them, 20 should give basically same results as old incorrect system
|
||||
RULE_BOOL(Combat, ClassicNPCBackstab, false) // true disables npc facestab - npcs get normal attack if not behind
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
@ -669,6 +673,12 @@ RULE_CATEGORY_END()
|
||||
RULE_CATEGORY(AA)
|
||||
RULE_INT(AA, ExpPerPoint, 23976503) //Amount of exp per AA. Is the same as the amount of exp to go from level 51 to level 52.
|
||||
RULE_BOOL(AA, Stacking, true) //Allow AA that belong to the same group to stack on SOF+ clients.
|
||||
RULE_BOOL(AA, NormalizedAAEnabled, false) // TSS+ change to AA that normalizes AA XP to a fixed # of white con kills independent of level.
|
||||
RULE_INT(AA, NormalizedAANumberOfWhiteConPerAA, 25) // The number of white con kills per AA point.
|
||||
RULE_BOOL(AA, ModernAAScalingEnabled, false) // Are we linearly scaling AA XP based on total # of earned AA?
|
||||
RULE_REAL(AA, ModernAAScalingStartPercent, 1000) // 1000% or 10x AA XP at the start of the scaling range
|
||||
RULE_INT(AA, ModernAAScalingAAMinimum, 0) // The minimum number of earned AA before AA XP scaling begins.
|
||||
RULE_INT(AA, ModernAAScalingAALimit, 4000) // The number of earned AA when AA XP scaling ends
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Console)
|
||||
@ -714,6 +724,12 @@ RULE_BOOL(Client, UseLiveFactionMessage, false) // Allows players to see faction
|
||||
RULE_BOOL(Client, UseLiveBlockedMessage, false) // Allows players to see faction adjustments like Live
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Bugs)
|
||||
RULE_BOOL(Bugs, ReportingSystemActive, true) // Activates bug reporting
|
||||
RULE_BOOL(Bugs, UseOldReportingMethod, true) // Forces the use of the old bug reporting system
|
||||
RULE_BOOL(Bugs, DumpTargetEntity, false) // Dumps the target entity, if one is provided
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
#undef RULE_CATEGORY
|
||||
#undef RULE_INT
|
||||
#undef RULE_REAL
|
||||
|
||||
@ -29,10 +29,10 @@
|
||||
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
|
||||
{
|
||||
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
|
||||
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
|
||||
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
|
||||
return false;
|
||||
|
||||
say_link_body_struct.unknown_1 = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
|
||||
say_link_body_struct.action_id = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
|
||||
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
|
||||
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
|
||||
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
|
||||
@ -44,7 +44,7 @@ bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct
|
||||
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
|
||||
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
|
||||
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
|
||||
say_link_body_struct.hash = (int)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
|
||||
say_link_body_struct.hash = (uint32)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -53,7 +53,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
|
||||
{
|
||||
say_link_body = StringFormat(
|
||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||
(0x0F & say_link_body_struct.unknown_1),
|
||||
(0x0F & say_link_body_struct.action_id),
|
||||
(0x000FFFFF & say_link_body_struct.item_id),
|
||||
(0x000FFFFF & say_link_body_struct.augment_1),
|
||||
(0x000FFFFF & say_link_body_struct.augment_2),
|
||||
@ -68,7 +68,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
|
||||
(0xFFFFFFFF & say_link_body_struct.hash)
|
||||
);
|
||||
|
||||
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
|
||||
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -79,7 +79,7 @@ EQEmu::SayLinkEngine::SayLinkEngine()
|
||||
Reset();
|
||||
}
|
||||
|
||||
std::string EQEmu::SayLinkEngine::GenerateLink()
|
||||
const std::string& EQEmu::SayLinkEngine::GenerateLink()
|
||||
{
|
||||
m_Link.clear();
|
||||
m_LinkBody.clear();
|
||||
@ -88,18 +88,26 @@ std::string EQEmu::SayLinkEngine::GenerateLink()
|
||||
generate_body();
|
||||
generate_text();
|
||||
|
||||
if ((m_LinkBody.length() == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) && (m_LinkText.length() > 0)) {
|
||||
if ((m_LinkBody.length() == EQEmu::constants::SayLinkBodySize) && (m_LinkText.length() > 0)) {
|
||||
m_Link.push_back(0x12);
|
||||
m_Link.append(m_LinkBody);
|
||||
m_Link.append(m_LinkText);
|
||||
m_Link.push_back(0x12);
|
||||
}
|
||||
|
||||
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
|
||||
if ((m_Link.length() == 0) || (m_Link.length() > (EQEmu::constants::SayLinkMaximumSize))) {
|
||||
m_Error = true;
|
||||
m_Link = "<LINKER ERROR>";
|
||||
Log(Logs::General, Logs::Error, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
|
||||
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
|
||||
Log(Logs::General, Logs::Error, "SayLinkEngine::GenerateLink() failed to generate a useable say link");
|
||||
Log(Logs::General, Logs::Error, ">> LinkType: %i, Lengths: {link: %u(%u), body: %u(%u), text: %u(%u)}",
|
||||
m_LinkType,
|
||||
m_Link.length(),
|
||||
EQEmu::constants::SayLinkMaximumSize,
|
||||
m_LinkBody.length(),
|
||||
EQEmu::constants::SayLinkBodySize,
|
||||
m_LinkText.length(),
|
||||
EQEmu::constants::SayLinkTextSize
|
||||
);
|
||||
Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str());
|
||||
Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str());
|
||||
}
|
||||
@ -113,20 +121,10 @@ void EQEmu::SayLinkEngine::Reset()
|
||||
m_ItemData = nullptr;
|
||||
m_LootData = nullptr;
|
||||
m_ItemInst = nullptr;
|
||||
m_Proxy_unknown_1 = 0;
|
||||
m_ProxyItemID = 0;
|
||||
m_ProxyAugment1ID = 0;
|
||||
m_ProxyAugment2ID = 0;
|
||||
m_ProxyAugment3ID = 0;
|
||||
m_ProxyAugment4ID = 0;
|
||||
m_ProxyAugment5ID = 0;
|
||||
m_ProxyAugment6ID = 0;
|
||||
m_ProxyIsEvolving = 0;
|
||||
m_ProxyEvolveGroup = 0;
|
||||
m_ProxyEvolveLevel = 0;
|
||||
m_ProxyOrnamentIcon = 0;
|
||||
m_ProxyHash = 0;
|
||||
m_ProxyText = nullptr;
|
||||
|
||||
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
|
||||
memset(&m_LinkProxyStruct, 0, sizeof(SayLinkProxy_Struct));
|
||||
|
||||
m_TaskUse = false;
|
||||
m_Link.clear();
|
||||
m_LinkBody.clear();
|
||||
@ -194,32 +192,32 @@ void EQEmu::SayLinkEngine::generate_body()
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_Proxy_unknown_1)
|
||||
m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1;
|
||||
if (m_ProxyItemID)
|
||||
m_LinkBodyStruct.item_id = m_ProxyItemID;
|
||||
if (m_ProxyAugment1ID)
|
||||
m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID;
|
||||
if (m_ProxyAugment2ID)
|
||||
m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID;
|
||||
if (m_ProxyAugment3ID)
|
||||
m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID;
|
||||
if (m_ProxyAugment4ID)
|
||||
m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID;
|
||||
if (m_ProxyAugment5ID)
|
||||
m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID;
|
||||
if (m_ProxyAugment6ID)
|
||||
m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID;
|
||||
if (m_ProxyIsEvolving)
|
||||
m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving;
|
||||
if (m_ProxyEvolveGroup)
|
||||
m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup;
|
||||
if (m_ProxyEvolveLevel)
|
||||
m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel;
|
||||
if (m_ProxyOrnamentIcon)
|
||||
m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon;
|
||||
if (m_ProxyHash)
|
||||
m_LinkBodyStruct.hash = m_ProxyHash;
|
||||
if (m_LinkProxyStruct.action_id)
|
||||
m_LinkBodyStruct.action_id = m_LinkProxyStruct.action_id;
|
||||
if (m_LinkProxyStruct.item_id)
|
||||
m_LinkBodyStruct.item_id = m_LinkProxyStruct.item_id;
|
||||
if (m_LinkProxyStruct.augment_1)
|
||||
m_LinkBodyStruct.augment_1 = m_LinkProxyStruct.augment_1;
|
||||
if (m_LinkProxyStruct.augment_2)
|
||||
m_LinkBodyStruct.augment_2 = m_LinkProxyStruct.augment_2;
|
||||
if (m_LinkProxyStruct.augment_3)
|
||||
m_LinkBodyStruct.augment_3 = m_LinkProxyStruct.augment_3;
|
||||
if (m_LinkProxyStruct.augment_4)
|
||||
m_LinkBodyStruct.augment_4 = m_LinkProxyStruct.augment_4;
|
||||
if (m_LinkProxyStruct.augment_5)
|
||||
m_LinkBodyStruct.augment_5 = m_LinkProxyStruct.augment_5;
|
||||
if (m_LinkProxyStruct.augment_6)
|
||||
m_LinkBodyStruct.augment_6 = m_LinkProxyStruct.augment_6;
|
||||
if (m_LinkProxyStruct.is_evolving)
|
||||
m_LinkBodyStruct.is_evolving = m_LinkProxyStruct.is_evolving;
|
||||
if (m_LinkProxyStruct.evolve_group)
|
||||
m_LinkBodyStruct.evolve_group = m_LinkProxyStruct.evolve_group;
|
||||
if (m_LinkProxyStruct.evolve_level)
|
||||
m_LinkBodyStruct.evolve_level = m_LinkProxyStruct.evolve_level;
|
||||
if (m_LinkProxyStruct.ornament_icon)
|
||||
m_LinkBodyStruct.ornament_icon = m_LinkProxyStruct.ornament_icon;
|
||||
if (m_LinkProxyStruct.hash)
|
||||
m_LinkBodyStruct.hash = m_LinkProxyStruct.hash;
|
||||
|
||||
|
||||
if (m_TaskUse)
|
||||
@ -227,7 +225,7 @@ void EQEmu::SayLinkEngine::generate_body()
|
||||
|
||||
m_LinkBody = StringFormat(
|
||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||
(0x0F & m_LinkBodyStruct.unknown_1),
|
||||
(0x0F & m_LinkBodyStruct.action_id),
|
||||
(0x000FFFFF & m_LinkBodyStruct.item_id),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_1),
|
||||
(0x000FFFFF & m_LinkBodyStruct.augment_2),
|
||||
@ -245,8 +243,8 @@ void EQEmu::SayLinkEngine::generate_body()
|
||||
|
||||
void EQEmu::SayLinkEngine::generate_text()
|
||||
{
|
||||
if (m_ProxyText != nullptr) {
|
||||
m_LinkText = m_ProxyText;
|
||||
if (m_LinkProxyStruct.text != nullptr) {
|
||||
m_LinkText = m_LinkProxyStruct.text;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ namespace EQEmu
|
||||
} /*saylink*/
|
||||
|
||||
struct SayLinkBody_Struct {
|
||||
uint8 unknown_1; /* %1X */
|
||||
uint8 action_id; /* %1X */
|
||||
uint32 item_id; /* %05X */
|
||||
uint32 augment_1; /* %05X */
|
||||
uint32 augment_2; /* %05X */
|
||||
@ -56,13 +56,18 @@ namespace EQEmu
|
||||
uint32 augment_5; /* %05X */
|
||||
uint32 augment_6; /* %05X */
|
||||
uint8 is_evolving; /* %1X */
|
||||
uint32 evolve_group; /* %05X */
|
||||
uint32 evolve_group; /* %04X */
|
||||
uint8 evolve_level; /* %02X */
|
||||
uint32 ornament_icon; /* %05X */
|
||||
int hash; /* %08X */
|
||||
uint32 hash; /* %08X */
|
||||
};
|
||||
|
||||
struct SayLinkProxy_Struct : SayLinkBody_Struct {
|
||||
const char* text;
|
||||
};
|
||||
|
||||
class SayLinkEngine {
|
||||
// TODO: consider methods for direct 'saylink' assignments
|
||||
public:
|
||||
SayLinkEngine();
|
||||
|
||||
@ -72,29 +77,29 @@ namespace EQEmu
|
||||
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
|
||||
|
||||
// mainly for saylinks..but, not limited to
|
||||
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
|
||||
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; }
|
||||
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; }
|
||||
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; }
|
||||
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; }
|
||||
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; }
|
||||
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; }
|
||||
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; }
|
||||
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; }
|
||||
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; }
|
||||
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; }
|
||||
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; }
|
||||
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; }
|
||||
void SetProxyActionID(uint8 proxy_action_id) { m_LinkProxyStruct.action_id = proxy_action_id; } // should always be '0'
|
||||
void SetProxyItemID(uint32 proxy_item_id) { m_LinkProxyStruct.item_id = proxy_item_id; }
|
||||
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_1 = proxy_augment_id; }
|
||||
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_2 = proxy_augment_id; }
|
||||
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_3 = proxy_augment_id; }
|
||||
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_4 = proxy_augment_id; }
|
||||
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_5 = proxy_augment_id; }
|
||||
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_6 = proxy_augment_id; }
|
||||
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_LinkProxyStruct.is_evolving = proxy_is_evolving; }
|
||||
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_LinkProxyStruct.evolve_group = proxy_evolve_group; }
|
||||
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_LinkProxyStruct.evolve_level = proxy_evolve_level; }
|
||||
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_LinkProxyStruct.ornament_icon = proxy_ornament_icon; }
|
||||
void SetProxyHash(uint32 proxy_hash) { m_LinkProxyStruct.hash = proxy_hash; }
|
||||
|
||||
void SetProxyText(const char* proxy_text) { m_ProxyText = proxy_text; } // overrides standard text use
|
||||
void SetProxyText(const char* proxy_text) { m_LinkProxyStruct.text = proxy_text; } // overrides standard text use
|
||||
void SetTaskUse() { m_TaskUse = true; }
|
||||
|
||||
std::string GenerateLink();
|
||||
const std::string& GenerateLink();
|
||||
bool LinkError() { return m_Error; }
|
||||
|
||||
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
||||
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||
const std::string& Link() { return m_Link; } // contains full string format: '\x12' '<LinkBody>' '<LinkText>' '\x12'
|
||||
const std::string& LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||
const std::string& LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||
|
||||
void Reset();
|
||||
|
||||
@ -106,23 +111,9 @@ namespace EQEmu
|
||||
const ItemData* m_ItemData;
|
||||
const ServerLootItem_Struct* m_LootData;
|
||||
const ItemInstance* m_ItemInst;
|
||||
|
||||
uint8 m_Proxy_unknown_1;
|
||||
uint32 m_ProxyItemID;
|
||||
uint32 m_ProxyAugment1ID;
|
||||
uint32 m_ProxyAugment2ID;
|
||||
uint32 m_ProxyAugment3ID;
|
||||
uint32 m_ProxyAugment4ID;
|
||||
uint32 m_ProxyAugment5ID;
|
||||
uint32 m_ProxyAugment6ID;
|
||||
uint8 m_ProxyIsEvolving;
|
||||
uint32 m_ProxyEvolveGroup;
|
||||
uint8 m_ProxyEvolveLevel;
|
||||
uint32 m_ProxyOrnamentIcon;
|
||||
int m_ProxyHash;
|
||||
const char* m_ProxyText;
|
||||
bool m_TaskUse;
|
||||
SayLinkBody_Struct m_LinkBodyStruct;
|
||||
SayLinkProxy_Struct m_LinkProxyStruct;
|
||||
bool m_TaskUse;
|
||||
std::string m_Link;
|
||||
std::string m_LinkBody;
|
||||
std::string m_LinkText;
|
||||
|
||||
@ -190,6 +190,8 @@
|
||||
#define ServerOP_ReloadLogs 0x4010
|
||||
#define ServerOP_ReloadPerlExportSettings 0x4011
|
||||
#define ServerOP_CZSetEntityVariableByClientName 0x4012
|
||||
#define ServerOP_UCSServerStatusRequest 0x4013
|
||||
#define ServerOP_UCSServerStatusReply 0x4014
|
||||
/* Query Server OP Codes */
|
||||
#define ServerOP_QSPlayerLogTrades 0x5010
|
||||
#define ServerOP_QSPlayerLogHandins 0x5011
|
||||
@ -1278,6 +1280,17 @@ struct ServerRequestTellQueue_Struct {
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct UCSServerStatus_Struct {
|
||||
uint8 available; // non-zero=true, 0=false
|
||||
union {
|
||||
struct {
|
||||
uint16 port;
|
||||
uint16 unused;
|
||||
};
|
||||
uint32 timestamp;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
@ -110,6 +110,41 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
||||
return EntitledTime;
|
||||
}
|
||||
|
||||
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
||||
{
|
||||
char MailKeyString[17];
|
||||
|
||||
if (RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
||||
else
|
||||
sprintf(MailKeyString, "%08X", MailKey);
|
||||
|
||||
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
MailKeyString, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
Log(Logs::General, Logs::Error, "SharedDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
std::string SharedDatabase::GetMailKey(int CharID, bool key_only)
|
||||
{
|
||||
std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", CharID);
|
||||
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();
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
std::string mail_key = row[0];
|
||||
|
||||
if (mail_key.length() > 8 && key_only)
|
||||
return mail_key.substr(8);
|
||||
else
|
||||
return mail_key;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end)
|
||||
{
|
||||
// Delete cursor items
|
||||
@ -1817,8 +1852,8 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
|
||||
bd->base_hp = atof(row[2]);
|
||||
bd->base_mana = atof(row[3]);
|
||||
bd->base_end = atof(row[4]);
|
||||
bd->unk1 = atof(row[5]);
|
||||
bd->unk2 = atof(row[6]);
|
||||
bd->hp_regen = atof(row[5]);
|
||||
bd->end_regen = atof(row[6]);
|
||||
bd->hp_factor = atof(row[7]);
|
||||
bd->mana_factor = atof(row[8]);
|
||||
bd->endurance_factor = atof(row[9]);
|
||||
|
||||
@ -72,6 +72,8 @@ class SharedDatabase : public Database
|
||||
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
|
||||
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
|
||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||
std::string GetMailKey(int CharID, bool key_only = false);
|
||||
|
||||
/*
|
||||
Character InventoryProfile
|
||||
|
||||
@ -73,6 +73,8 @@ enum SpellTypes : uint32
|
||||
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
|
||||
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong | SpellType_PreCombatBuff | SpellType_PreCombatBuffSong),
|
||||
|
||||
SpellTypes_Innate = (SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root),
|
||||
|
||||
SpellType_Any = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
@ -131,6 +133,11 @@ enum SpellAffectIndex {
|
||||
SAI_NPC_Special_80 = 80,
|
||||
SAI_Trap_Lock = 88
|
||||
};
|
||||
|
||||
enum class GlobalGroup {
|
||||
Lich = 46,
|
||||
};
|
||||
|
||||
enum RESISTTYPE
|
||||
{
|
||||
RESIST_NONE = 0,
|
||||
@ -965,7 +972,6 @@ bool IsCastWhileInvis(uint16 spell_id);
|
||||
bool IsEffectIgnoredInStacking(int spa);
|
||||
|
||||
int CalcPetHp(int levelb, int classb, int STA = 75);
|
||||
const char *GetRandPetName();
|
||||
int GetSpellEffectDescNum(uint16 spell_id);
|
||||
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
|
||||
bool DetrimentalSpellAllowsRest(uint16 spell_id);
|
||||
|
||||
@ -30,9 +30,9 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9114
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9122
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
|
||||
#else
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
||||
#endif
|
||||
|
||||
@ -1886,6 +1886,8 @@ FMT_DEFINE_INT_FORMATTERS(unsigned long)
|
||||
FMT_DEFINE_INT_FORMATTERS(LongLong)
|
||||
FMT_DEFINE_INT_FORMATTERS(ULongLong)
|
||||
|
||||
#define CHAR_WIDTH 1
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns a string formatter that pads the formatted argument with the fill
|
||||
|
||||
@ -46,7 +46,7 @@ public:
|
||||
_chat_config=new queryservconfig;
|
||||
_config=_chat_config;
|
||||
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(),"server");
|
||||
return _config->parseFile();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -28,6 +28,10 @@
|
||||
extern Database database;
|
||||
extern uint32 ChatMessagesSent;
|
||||
|
||||
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||
|
||||
ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string inPassword, bool inPermanent, int inMinimumStatus) :
|
||||
DeleteTimer(0) {
|
||||
|
||||
@ -384,6 +388,8 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
|
||||
|
||||
if(!Sender) return;
|
||||
|
||||
std::string cv_messages[EQEmu::versions::ClientVersionCount];
|
||||
|
||||
ChatMessagesSent++;
|
||||
|
||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||
@ -398,7 +404,28 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
|
||||
{
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Sending message to %s from %s",
|
||||
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
|
||||
ChannelClient->SendChannelMessage(Name, Message, Sender);
|
||||
|
||||
if (cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())].length() == 0) {
|
||||
switch (ChannelClient->GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
ServerToClient45SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoF:
|
||||
case EQEmu::versions::ClientVersion::SoD:
|
||||
case EQEmu::versions::ClientVersion::UF:
|
||||
ServerToClient50SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF:
|
||||
ServerToClient55SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF2:
|
||||
default:
|
||||
cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())] = Message;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChannelClient->SendChannelMessage(Name, cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Sender);
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
@ -655,3 +682,118 @@ std::string CapitaliseName(std::string inString) {
|
||||
return NormalisedName;
|
||||
}
|
||||
|
||||
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||
clientSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 56) {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
clientSayLink.push_back('\x12');
|
||||
clientSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
clientSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
clientSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
clientSayLink.push_back('F');
|
||||
|
||||
clientSayLink.append(segments[segment_iter].substr(48));
|
||||
clientSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||
clientSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 56) {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
clientSayLink.push_back('\x12');
|
||||
clientSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
clientSayLink.append(segments[segment_iter].substr(36, 5));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
clientSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
clientSayLink.push_back('F');
|
||||
|
||||
clientSayLink.append(segments[segment_iter].substr(43));
|
||||
clientSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||
clientSayLink = serverSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(serverSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 56) {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// Diff: ^
|
||||
|
||||
clientSayLink.push_back('\x12');
|
||||
clientSayLink.append(segments[segment_iter].substr(0, 41));
|
||||
|
||||
if (segments[segment_iter][41] == '0')
|
||||
clientSayLink.push_back(segments[segment_iter][42]);
|
||||
else
|
||||
clientSayLink.push_back('F');
|
||||
|
||||
clientSayLink.append(segments[segment_iter].substr(43));
|
||||
clientSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
clientSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,6 +513,7 @@ Client::Client(std::shared_ptr<EQStreamInterface> eqs) {
|
||||
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
||||
|
||||
TypeOfConnection = ConnectionTypeUnknown;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||
|
||||
UnderfootOrLater = false;
|
||||
}
|
||||
@ -681,6 +682,7 @@ void Clientlist::Process()
|
||||
it = ClientChatConnections.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@ -2134,34 +2136,62 @@ void Client::SetConnectionType(char c) {
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'S':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF/SoD)");
|
||||
break;
|
||||
}
|
||||
case 'U':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot+)");
|
||||
break;
|
||||
}
|
||||
case 'M':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeMail;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (6.2 or Titanium client)");
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
case EQEmu::versions::ucsTitaniumChat:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeChat;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (6.2 or Titanium client)");
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (Titanium)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsTitaniumMail:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeMail;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (Titanium)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsSoFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::SoF;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsSoDCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::SoD;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoD)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsUFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::UF;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsRoFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::RoF;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsRoF2Combined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::RoF2;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF2)");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeUnknown;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,8 +139,11 @@ public:
|
||||
std::string MailBoxName();
|
||||
int GetMailBoxNumber() { return CurrentMailBox; }
|
||||
int GetMailBoxNumber(std::string CharacterName);
|
||||
|
||||
void SetConnectionType(char c);
|
||||
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
||||
EQEmu::versions::ClientVersion GetClientVersion() { return ClientVersion_; }
|
||||
|
||||
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
||||
void SendNotification(int MailBoxNumber, std::string From, std::string Subject, int MessageID);
|
||||
void ChangeMailBox(int NewMailBox);
|
||||
@ -167,7 +170,9 @@ private:
|
||||
Timer *GlobalChatLimiterTimer; //60 seconds
|
||||
int AttemptedMessages;
|
||||
bool ForceDisconnect;
|
||||
|
||||
ConnectionType TypeOfConnection;
|
||||
EQEmu::versions::ClientVersion ClientVersion_;
|
||||
bool UnderfootOrLater;
|
||||
};
|
||||
|
||||
@ -183,7 +188,6 @@ public:
|
||||
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
||||
|
||||
private:
|
||||
|
||||
EQ::Net::EQStreamManager *chatsf;
|
||||
|
||||
std::list<Client*> ClientChatConnections;
|
||||
|
||||
@ -46,7 +46,7 @@ public:
|
||||
_chat_config=new ucsconfig;
|
||||
_config=_chat_config;
|
||||
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(),"server");
|
||||
return _config->parseFile();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/packet_functions.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "worldserver.h"
|
||||
#include "clientlist.h"
|
||||
#include "ucsconfig.h"
|
||||
@ -41,6 +42,10 @@ extern Database database;
|
||||
|
||||
void ProcessMailTo(Client *c, std::string from, std::string subject, std::string message);
|
||||
|
||||
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||
|
||||
WorldServer::WorldServer()
|
||||
{
|
||||
m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "UCS", Config->SharedKey));
|
||||
@ -94,7 +99,26 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
||||
|
||||
if (Message[0] == ';')
|
||||
{
|
||||
c->SendChannelMessageByNumber(Message.substr(1, std::string::npos));
|
||||
std::string new_message;
|
||||
switch (c->GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoF:
|
||||
case EQEmu::versions::ClientVersion::SoD:
|
||||
case EQEmu::versions::ClientVersion::UF:
|
||||
Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF:
|
||||
Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF2:
|
||||
default:
|
||||
new_message = Message.substr(1, std::string::npos);
|
||||
break;
|
||||
}
|
||||
|
||||
c->SendChannelMessageByNumber(new_message);
|
||||
}
|
||||
else if (Message[0] == '[')
|
||||
{
|
||||
@ -116,3 +140,108 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||
serverSayLink = clientSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(clientSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 45) {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 (Source)
|
||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^ ^^^^^
|
||||
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.push_back(segments[segment_iter][36]);
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(37));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||
serverSayLink = clientSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(clientSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 50) {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^^^^^ ^
|
||||
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||
serverSayLink.append("00000");
|
||||
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(36));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||
serverSayLink = clientSayLink;
|
||||
return;
|
||||
}
|
||||
|
||||
auto segments = SplitString(clientSayLink, '\x12');
|
||||
|
||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||
if (segment_iter & 1) {
|
||||
if (segments[segment_iter].length() <= 55) {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
// TODO: log size mismatch error
|
||||
continue;
|
||||
}
|
||||
|
||||
// Idx: 0 1 6 11 16 21 26 31 36 37 41 42 47 (Source)
|
||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||
// Diff: ^
|
||||
|
||||
serverSayLink.push_back('\x12');
|
||||
serverSayLink.append(segments[segment_iter].substr(0, 41));
|
||||
serverSayLink.push_back('0');
|
||||
serverSayLink.append(segments[segment_iter].substr(41));
|
||||
serverSayLink.push_back('\x12');
|
||||
}
|
||||
else {
|
||||
serverSayLink.append(segments[segment_iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
utils/defaults/eqemu_config.json
Executable file
8
utils/defaults/eqemu_config.json
Executable file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"server": {
|
||||
"world": {
|
||||
"shortname": "setme",
|
||||
"longname": "I Forgot To Edit My Config"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
utils/defaults/eqemu_config.json.full
Executable file
54
utils/defaults/eqemu_config.json.full
Executable file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"server": {
|
||||
"zones": {
|
||||
"defaultstatus": "20",
|
||||
"ports": {
|
||||
"low": "7000",
|
||||
"high": "7100"
|
||||
}
|
||||
},
|
||||
"database": {
|
||||
"password": "eq",
|
||||
"db": "eq",
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "eq"
|
||||
},
|
||||
"world": {
|
||||
"shortname": "setme",
|
||||
"longname": "I Forgot To Edit My Config",
|
||||
"loginserver": {
|
||||
"password": "",
|
||||
"host": "login.eqemulator.net",
|
||||
"port": "5998",
|
||||
"account": ""
|
||||
},
|
||||
"tcp": {
|
||||
"port": "9000",
|
||||
"telnet": "disable",
|
||||
"ip": "127.0.0.1"
|
||||
},
|
||||
"key": "some long random string",
|
||||
"http": {
|
||||
"mimefile": "mime.types",
|
||||
"port": "9080",
|
||||
"enabled": "false"
|
||||
}
|
||||
},
|
||||
"mailserver": {
|
||||
"host": "channels.eqemulator.net",
|
||||
"port": "7778"
|
||||
},
|
||||
"chatserver": {
|
||||
"host": "channels.eqemulator.net",
|
||||
"port": "7778"
|
||||
},
|
||||
"qsdatabase": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "eq",
|
||||
"password": "eq",
|
||||
"db": "eq"
|
||||
}
|
||||
}
|
||||
}
|
||||
355
utils/doc_scripts/perlparse/main.go
Normal file
355
utils/doc_scripts/perlparse/main.go
Normal file
@ -0,0 +1,355 @@
|
||||
//Parses perl scripts
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "../../../zone/embparser_api.cpp"
|
||||
err := readFile(path)
|
||||
if err != nil {
|
||||
log.Panicf("Failed to read file: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type API struct {
|
||||
Function string
|
||||
Arguments []*Argument
|
||||
}
|
||||
|
||||
type Argument struct {
|
||||
Name string
|
||||
Type string
|
||||
API *API
|
||||
}
|
||||
|
||||
func readFile(path string) (err error) {
|
||||
inFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Failed to open file")
|
||||
}
|
||||
defer inFile.Close()
|
||||
scanner := bufio.NewScanner(inFile)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
|
||||
arguments := map[string][]*Argument{}
|
||||
functions := []*API{}
|
||||
reg, err := regexp.Compile(`\]+|\[+|\?+|[...]+`)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Failed to compile regex")
|
||||
return
|
||||
}
|
||||
regType, err := regexp.Compile(`(unsigned long|long|int32|bool|uint[0-9]+|int|auto|float|unsigned int|char[ \*]).+([. a-zA-Z]+=)`)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Failed to compile type regex")
|
||||
return
|
||||
}
|
||||
|
||||
lastArguments := []*Argument{}
|
||||
lastAPI := &API{}
|
||||
lineNum := 0
|
||||
for scanner.Scan() {
|
||||
lineNum++
|
||||
key := ""
|
||||
line := scanner.Text()
|
||||
if len(line) < 1 {
|
||||
continue
|
||||
}
|
||||
if len(lastArguments) > 0 { //existing args to parse
|
||||
for i, argument := range lastArguments {
|
||||
key = fmt.Sprintf("ST(%d)", i)
|
||||
if strings.Contains(line, key) {
|
||||
//We found a definition argument line
|
||||
if argument.Type != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
match := regType.FindStringSubmatch(line)
|
||||
if len(match) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
//key = `int`
|
||||
//function = line[strings.Index(line, key)+len(key):]
|
||||
newType := ""
|
||||
|
||||
switch v := strings.TrimSpace(match[1]); v {
|
||||
case "int":
|
||||
newType = "int"
|
||||
case "int32":
|
||||
newType = "int"
|
||||
case "float":
|
||||
newType = "float"
|
||||
case "unsigned int":
|
||||
newType = "uint"
|
||||
case "uint32":
|
||||
newType = "uint"
|
||||
case "uint8":
|
||||
newType = "uint"
|
||||
case "uint":
|
||||
newType = "uint"
|
||||
case "bool":
|
||||
newType = "bool"
|
||||
case "uint16":
|
||||
newType = "uint"
|
||||
case "long":
|
||||
newType = "long"
|
||||
case "unsigned long":
|
||||
newType = "unsigned long"
|
||||
case "char":
|
||||
newType = "string"
|
||||
case "auto":
|
||||
//Auto is tricky
|
||||
if strings.Contains(line, "glm::vec4") {
|
||||
newType = "float"
|
||||
}
|
||||
|
||||
default:
|
||||
log.Printf(`Unknown type: "%s" on line %d`, v, lineNum)
|
||||
}
|
||||
//log.Println("Found arg type", newType, "on index", i, argument.Name)
|
||||
lastArguments[i].Type = newType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function := ""
|
||||
|
||||
argLine := ""
|
||||
args := []string{}
|
||||
//Find line
|
||||
key = `Perl_croak(aTHX_ "Usage:`
|
||||
if strings.Contains(line, key) {
|
||||
function = line[strings.Index(line, key)+len(key):]
|
||||
}
|
||||
|
||||
for _, argument := range lastArguments {
|
||||
arguments[argument.Name] = append(arguments[argument.Name], argument)
|
||||
}
|
||||
|
||||
lastArguments = []*Argument{}
|
||||
|
||||
//Trim off the endings
|
||||
key = `");`
|
||||
if strings.Contains(function, key) {
|
||||
function = function[0:strings.Index(function, key)]
|
||||
}
|
||||
//Strip out the arguments
|
||||
key = `(`
|
||||
if strings.Contains(function, key) {
|
||||
argLine = function[strings.Index(function, key)+len(key):]
|
||||
function = function[0:strings.Index(function, key)]
|
||||
key = `)`
|
||||
if strings.Contains(argLine, key) {
|
||||
argLine = argLine[:strings.Index(argLine, key)]
|
||||
}
|
||||
key = `=`
|
||||
if strings.Contains(argLine, key) {
|
||||
argLine = argLine[:strings.Index(argLine, key)]
|
||||
}
|
||||
argLine = reg.ReplaceAllString(argLine, "")
|
||||
}
|
||||
key = `,`
|
||||
argLine = strings.TrimSpace(argLine)
|
||||
|
||||
if strings.Contains(argLine, key) {
|
||||
args = strings.Split(argLine, key)
|
||||
}
|
||||
|
||||
if len(function) < 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
newArgs := []string{}
|
||||
for j, _ := range args {
|
||||
args[j] = strings.TrimSpace(args[j])
|
||||
if len(args[j]) == 0 {
|
||||
continue
|
||||
}
|
||||
newArgs = append(newArgs, args[j])
|
||||
}
|
||||
|
||||
lastAPI = &API{
|
||||
Function: function,
|
||||
}
|
||||
|
||||
for _, arg := range newArgs {
|
||||
argType, _ := knownTypes[arg]
|
||||
argument := &Argument{
|
||||
Name: arg,
|
||||
Type: argType,
|
||||
API: lastAPI,
|
||||
}
|
||||
lastArguments = append(lastArguments, argument)
|
||||
}
|
||||
lastAPI.Arguments = lastArguments
|
||||
|
||||
functions = append(functions, lastAPI)
|
||||
}
|
||||
|
||||
foundCount := 0
|
||||
failCount := 0
|
||||
for key, val := range arguments {
|
||||
isMissing := false
|
||||
line := ""
|
||||
line = fmt.Sprintf("%s used by %d functions:", key, len(val))
|
||||
for _, fnc := range val {
|
||||
line += fmt.Sprintf("%s(%s %s), ", fnc.API.Function, fnc.Type, key)
|
||||
if fnc.Type == "" {
|
||||
isMissing = true
|
||||
}
|
||||
}
|
||||
if isMissing {
|
||||
fmt.Println(line)
|
||||
failCount++
|
||||
} else {
|
||||
foundCount++
|
||||
}
|
||||
}
|
||||
log.Println(foundCount, "functions properly identified,", failCount, "have errors")
|
||||
|
||||
line := ""
|
||||
for _, api := range functions {
|
||||
line += fmt.Sprintf("void %s(", strings.TrimSpace(api.Function))
|
||||
for _, argument := range api.Arguments {
|
||||
line += fmt.Sprintf("%s %s, ", argument.Type, argument.Name)
|
||||
}
|
||||
if len(api.Arguments) > 0 {
|
||||
line = line[0 : len(line)-2]
|
||||
}
|
||||
line += ")\n"
|
||||
}
|
||||
fmt.Println(line)
|
||||
return
|
||||
}
|
||||
|
||||
var knownTypes = map[string]string{
|
||||
"activity_id": "uint",
|
||||
"alt_mode": "bool",
|
||||
"anim_num": "int",
|
||||
"best_z": "float",
|
||||
"buttons": "int",
|
||||
"channel_id": "int",
|
||||
"char_id": "int",
|
||||
"charges": "int",
|
||||
"class_id": "int",
|
||||
"client_name": "string",
|
||||
"color": "int",
|
||||
"color_id": "int",
|
||||
"condition_id": "int",
|
||||
"copper": "int",
|
||||
"count": "int",
|
||||
"debug_level": "int",
|
||||
"decay_time": "int",
|
||||
"dest_heading": "float",
|
||||
"dest_x": "float",
|
||||
"dest_y": "float",
|
||||
"dest_z": "float",
|
||||
"distance": "int",
|
||||
"door_id": "int",
|
||||
"doorid": "uint",
|
||||
"duration": "int",
|
||||
"effect_id": "int",
|
||||
"elite_material_id": "int",
|
||||
"enforce_level_requirement": "bool",
|
||||
"explore_id": "uint",
|
||||
"faction_value": "int",
|
||||
"fade_in": "int",
|
||||
"fade_out": "int",
|
||||
"fadeout": "uint",
|
||||
"firstname": "string",
|
||||
"from": "string",
|
||||
"gender_id": "int",
|
||||
"gold": "int",
|
||||
"grid_id": "int",
|
||||
"guild_rank_id": "int",
|
||||
"heading": "float",
|
||||
"hero_forge_model_id": "int",
|
||||
"ignore_quest_update": "bool",
|
||||
"instance_id": "int",
|
||||
"int_unused": "int",
|
||||
"int_value": "int",
|
||||
"is_enabled": "bool",
|
||||
"is_strict": "bool",
|
||||
"item_id": "int",
|
||||
"key": "string",
|
||||
"language_id": "int",
|
||||
"lastname": "string",
|
||||
"leader_name": "string",
|
||||
"level": "int",
|
||||
"link_name": "string",
|
||||
"macro_id": "int",
|
||||
"max_level": "int",
|
||||
"max_x": "float",
|
||||
"max_y": "float",
|
||||
"max_z": "float",
|
||||
"message": "string",
|
||||
"milliseconds": "int",
|
||||
"min_level": "int",
|
||||
"min_x": "float",
|
||||
"min_y": "float",
|
||||
"min_z": "float",
|
||||
"name": "string",
|
||||
"new_hour": "int",
|
||||
"new_min": "int",
|
||||
"node1": "int",
|
||||
"node2": "int",
|
||||
"npc_id": "int",
|
||||
"npc_type_id": "int",
|
||||
"object_type": "int",
|
||||
"options": "int",
|
||||
"platinum": "int",
|
||||
"popup_id": "int",
|
||||
"priority": "int",
|
||||
"quantity": "int",
|
||||
"race_id": "int",
|
||||
"remove_item": "bool",
|
||||
"requested_id": "int",
|
||||
"reset_base": "bool",
|
||||
"saveguard": "bool",
|
||||
"seconds": "int",
|
||||
"send_to_world": "bool",
|
||||
"signal_id": "int",
|
||||
"silent": "bool",
|
||||
"silver": "int",
|
||||
"size": "int",
|
||||
"stat_id": "int",
|
||||
"str_value": "string",
|
||||
"subject": "string",
|
||||
"target_enum": "string",
|
||||
"target_id": "int",
|
||||
"task": "int",
|
||||
"task_id": "uint",
|
||||
"task_id1": "int",
|
||||
"task_id10": "int",
|
||||
"task_id2": "int",
|
||||
"task_set": "int",
|
||||
"taskid": "int",
|
||||
"taskid1": "int",
|
||||
"taskid2": "int",
|
||||
"taskid3": "int",
|
||||
"taskid4": "int",
|
||||
"teleport": "int",
|
||||
"temp": "int",
|
||||
"texture_id": "int",
|
||||
"theme_id": "int",
|
||||
"update_world": "int",
|
||||
"updated_time_till_repop": "uint",
|
||||
"version": "int",
|
||||
"wait_ms": "int",
|
||||
"window_title": "string",
|
||||
"x": "float",
|
||||
"y": "float",
|
||||
"z": "float",
|
||||
"zone_id": "int",
|
||||
"zone_short": "string",
|
||||
`task_id%i`: "int",
|
||||
}
|
||||
@ -165,6 +165,7 @@ OP_GMNameChange=0x3077 # Was 0x4434
|
||||
OP_GMLastName=0x4dd7 # Was 0x3077
|
||||
|
||||
# Misc Opcodes
|
||||
OP_QueryUCSServerStatus=0x6964
|
||||
OP_InspectRequest=0x23f1
|
||||
OP_InspectAnswer=0x5794
|
||||
OP_InspectMessageUpdate=0x3064
|
||||
@ -248,6 +249,7 @@ OP_AutoAttack=0x0d14
|
||||
OP_AutoAttack2=0x3912
|
||||
OP_Consume=0x4692
|
||||
OP_MoveItem=0x62a2
|
||||
OP_MoveMultipleItems=0x55ef
|
||||
OP_DeleteItem=0x3eb5
|
||||
OP_DeleteCharge=0x2d5b
|
||||
OP_ItemPacket=0x5e0e
|
||||
@ -341,6 +343,7 @@ OP_MobUpdate=0x6b5a
|
||||
OP_NPCMoveUpdate=0x5bd9
|
||||
OP_CameraEffect=0x5712
|
||||
OP_SpellEffect=0x72b6
|
||||
OP_AddNimbusEffect=0x2954
|
||||
OP_RemoveNimbusEffect=0x3ba7
|
||||
OP_AltCurrency=0x8fcb
|
||||
OP_AltCurrencyMerchantRequest=0x7e3e
|
||||
|
||||
@ -164,6 +164,7 @@ OP_GMNameChange=0x035f
|
||||
OP_GMLastName=0x46ce
|
||||
|
||||
# Misc Opcodes
|
||||
OP_QueryUCSServerStatus=0x398f
|
||||
OP_InspectRequest=0x57bc
|
||||
OP_InspectAnswer=0x71ac
|
||||
OP_InspectMessageUpdate=0x4d25
|
||||
@ -247,6 +248,7 @@ OP_AutoAttack=0x109d
|
||||
OP_AutoAttack2=0x3526
|
||||
OP_Consume=0x4b70
|
||||
OP_MoveItem=0x32ee
|
||||
OP_MoveMultipleItems=0x5623
|
||||
OP_DeleteItem=0x18ad
|
||||
OP_DeleteCharge=0x01b8
|
||||
OP_ItemPacket=0x368e
|
||||
@ -340,6 +342,7 @@ OP_MobUpdate=0x2c84
|
||||
OP_NPCMoveUpdate=0x5892
|
||||
OP_CameraEffect=0x127f
|
||||
OP_SpellEffect=0x5936
|
||||
OP_AddNimbusEffect=0xc693
|
||||
OP_RemoveNimbusEffect=0x7b1e
|
||||
OP_AltCurrency=0x6b6d
|
||||
OP_AltCurrencyMerchantRequest=0x5409
|
||||
|
||||
@ -165,6 +165,7 @@ OP_GMKill=0x6685 # C
|
||||
OP_GMNameChange=0x565d # C
|
||||
OP_GMLastName=0x3563 # C
|
||||
|
||||
OP_QueryUCSServerStatus=0x4036
|
||||
OP_InspectAnswer=0x4938 # C
|
||||
OP_Action2=0x7e4d # C OP_Damage?
|
||||
OP_BeginCast=0x0d5a # C
|
||||
@ -241,6 +242,7 @@ OP_AutoAttack=0x3d86 # C
|
||||
OP_AutoAttack2=0x4ca1 # C
|
||||
OP_Consume=0x7ce4 # C
|
||||
OP_MoveItem=0x7f56 # C
|
||||
OP_MoveMultipleItems=0x4572
|
||||
OP_DeleteItem=0x36f8 # C
|
||||
OP_DeleteCharge=0x1df9 # C
|
||||
OP_ItemPacket=0x34f8 # C
|
||||
@ -345,6 +347,7 @@ OP_AltCurrencySell=0x7a21
|
||||
OP_AltCurrencySellSelection=0x26d9
|
||||
OP_AltCurrencyReclaim=0x712c
|
||||
OP_ShroudProgress=0x0296
|
||||
OP_AddNimbusEffect=0x6840
|
||||
OP_RemoveNimbusEffect=0x5272 # C
|
||||
OP_Untargetable=0x5ea1 # 0x301d on UF?
|
||||
OP_IncreaseStats=0x71eb
|
||||
|
||||
@ -237,6 +237,7 @@ OP_AutoAttack=0x3427 #Trevius 01/20/09
|
||||
OP_AutoAttack2=0x6017 #Trevius 01/20/09
|
||||
OP_Consume=0x729a #Trevius 02/08/09
|
||||
OP_MoveItem=0x14B3 #Trevius 02/08/09
|
||||
OP_MoveMultipleItems=0x2d3e
|
||||
OP_DeleteItem=0x7DD4 #Xinu 03/08/09 0x41EE 0x018E 0x070C
|
||||
OP_DeleteCharge=0x32e2 #Trevius 03/23/09
|
||||
OP_ItemPacket=0x78Cd #Trevius 02/08/09
|
||||
@ -329,6 +330,7 @@ OP_AltCurrencyPurchase=0x3994
|
||||
OP_AltCurrencySell=0x2ac3
|
||||
OP_AltCurrencySellSelection=0x7d00
|
||||
OP_AltCurrencyReclaim=0x1996
|
||||
OP_AddNimbusEffect=0x45e2
|
||||
OP_RemoveNimbusEffect=0x5872 # C
|
||||
OP_InspectMessageUpdate=0x67e9 # C
|
||||
OP_OpenInventory=0x66c8
|
||||
|
||||
@ -198,6 +198,7 @@ OP_Split=0x4848 # ShowEQ 10/27/05
|
||||
OP_Surname=0x4668 # ShowEQ 10/27/05
|
||||
OP_ClearSurname=0x6cdb
|
||||
OP_MoveItem=0x420f # ShowEQ 10/27/05
|
||||
OP_MoveMultipleItems=0x463b
|
||||
OP_FaceChange=0x0f8e # ShowEQ 10/27/05
|
||||
OP_ItemPacket=0x3397 # ShowEQ 10/27/05
|
||||
OP_ItemLinkResponse=0x667c # ShowEQ 10/27/05
|
||||
|
||||
@ -168,6 +168,7 @@ OP_GMKill=0x799c # C
|
||||
OP_GMNameChange=0x0f48 # C
|
||||
OP_GMLastName=0x7bfb # C
|
||||
|
||||
OP_QueryUCSServerStatus=0x4481
|
||||
OP_InspectAnswer=0x0c2b # C
|
||||
OP_BeginCast=0x0d5a # C
|
||||
OP_ColoredText=0x71bf # C
|
||||
@ -251,6 +252,7 @@ OP_AutoAttack=0x1df9 # C
|
||||
OP_AutoAttack2=0x517b # C
|
||||
OP_Consume=0x24c5 # V
|
||||
OP_MoveItem=0x2641 # C
|
||||
OP_MoveMultipleItems=0x40e8
|
||||
OP_DeleteItem=0x66e0 # C
|
||||
OP_DeleteCharge=0x4ca1 # C
|
||||
OP_ItemPacket=0x7b6e # C
|
||||
@ -346,6 +348,7 @@ OP_MobUpdate=0x4656 # Same as OP_SpawnPositionUpdate
|
||||
OP_NPCMoveUpdate=0x0f3e #
|
||||
OP_CameraEffect=0x6b0e # V
|
||||
OP_SpellEffect=0x57a3 # V
|
||||
OP_AddNimbusEffect=0x6361
|
||||
OP_RemoveNimbusEffect=0x2c77 # C
|
||||
OP_AltCurrency=0x659e
|
||||
OP_AltCurrencyMerchantRequest=0x214C
|
||||
|
||||
252
utils/scripts/database_dumper.pl
Normal file
252
utils/scripts/database_dumper.pl
Normal file
@ -0,0 +1,252 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
############################################################
|
||||
#::: Script: db_dumper.pl
|
||||
#::: Purpose: Utility to easily manage database backups and compress.
|
||||
#::: Export Individual DB Tables...
|
||||
#::: Export specific databases...
|
||||
#::: Built for both Windows and Linux
|
||||
#::: Windows uses WinRar or 7-Zip for compression
|
||||
#::: Linux uses tar for compression
|
||||
#::: Author: Akkadius
|
||||
############################################################
|
||||
|
||||
$localdrive = "C:"; #::: Where Windows and all Install Programs are...
|
||||
$linesep = "---------------------------------------";
|
||||
|
||||
use POSIX qw(strftime);
|
||||
my $date = strftime "%m_%d_%Y", localtime;
|
||||
print "\nTodays Date: " . $date . "\n";
|
||||
|
||||
use Config;
|
||||
print "Operating System is: $Config{osname}\n";
|
||||
if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
||||
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||
|
||||
if(!$ARGV[0]){
|
||||
print "\nERROR! Need arguments\n";
|
||||
print "#::: Help :::#\n";
|
||||
print "######################################################\n";
|
||||
print "Arguments\n";
|
||||
print " loc=\"C:\\File Location\" - File path location to backup...\n";
|
||||
print " database=\"dbname\" - Manually specify databasename, default is database in eqemu_config.xml\n";
|
||||
print " tables=\"table1,table2,table3\" - Manually specify tables, default is to dump all tables from database\n";
|
||||
print " compress - Compress Database with 7-ZIP, will fallback to WinRAR depending on what is installed (Must be installed to default program dir)...\n";
|
||||
print " nolock - Does not lock tables, meant for backuping while the server is running..\n";
|
||||
print " backup_name=\"name\" - Sets database backup prefix name\n";
|
||||
print ' Example: perl DB_Dumper.pl Loc="E:\Backups"' . "\n";
|
||||
print "######################################################\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub read_eqemu_config_json {
|
||||
use JSON;
|
||||
my $json = new JSON();
|
||||
|
||||
my $content;
|
||||
open(my $fh, '<', "eqemu_config.json") or die "Unable to open config: eqemu_config.json - This must be in your EQEmu Server Folder\n"; {
|
||||
local $/;
|
||||
$content = <$fh>;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
$config = $json->decode($content);
|
||||
|
||||
$db = $config->{"server"}{"database"}{"db"};
|
||||
$host = $config->{"server"}{"database"}{"host"};
|
||||
$user = $config->{"server"}{"database"}{"username"};
|
||||
$pass = $config->{"server"}{"database"}{"password"};
|
||||
$long_name = $config->{"server"}{"world"}{"longname"};
|
||||
|
||||
}
|
||||
|
||||
read_eqemu_config_json();
|
||||
|
||||
$Debug = 0;
|
||||
print "[db_dumper.pl] Arguments\n" if $Debug;
|
||||
$n = 0;
|
||||
while($ARGV[$n]){
|
||||
print $n . ': ' . $ARGV[$n] . "\n" if $Debug;
|
||||
if($ARGV[$n]=~/nolock/i){
|
||||
$no_lock = 1;
|
||||
}
|
||||
if($ARGV[$n]=~/compress/i){
|
||||
print "[db_dumper.pl] Compression SET\n";
|
||||
$Compress = 1;
|
||||
}
|
||||
if($ARGV[$n]=~/database=/i){
|
||||
@DB_NAME = split('=', $ARGV[$n]);
|
||||
print "[db_dumper.pl] Database is " . $DB_NAME[1] . "\n";
|
||||
$db = $DB_NAME[1];
|
||||
}
|
||||
if($ARGV[$n]=~/backup_name=/i){
|
||||
@data = split('=', $ARGV[$n]);
|
||||
print "[db_dumper.pl] Backup Name is " . $data[1] . "\n";
|
||||
$backup_name = $data[1];
|
||||
}
|
||||
if($ARGV[$n]=~/loc=/i){
|
||||
@backup_location = split('=', $ARGV[$n]);
|
||||
print "[db_dumper.pl] Backup Directory: " . $backup_location[1] . "\n";
|
||||
}
|
||||
if($ARGV[$n]=~/tables=/i){
|
||||
@Tables = split('=', $ARGV[$n]); @TList = split(',', $Tables[1]);
|
||||
foreach my $tables (@TList){
|
||||
$t_tables .= $tables . " ";
|
||||
$t_tables_l .= $tables . "_";
|
||||
$t_tables_p .= $tables . "\n";
|
||||
}
|
||||
print "[db_dumper.pl] Backing up tables: \n############################\n" . $t_tables_p . "############################\n";
|
||||
}
|
||||
$n++;
|
||||
}
|
||||
|
||||
#::: Check for Backup Directory existence, if doesn't exist then create...
|
||||
if (-d $backup_location[1]) {
|
||||
print "[db_dumper.pl] Directory currently exists... Adding files to it...\n";
|
||||
}
|
||||
elsif($backup_location[1] ne ""){
|
||||
print "[db_dumper.pl] Directory does NOT exist! Creating...\n";
|
||||
mkdir($backup_location[1]) or die 'Failed to create folder, maybe created the folder manually at "' . $backup_location[1]. '" ?';
|
||||
}
|
||||
else{
|
||||
print "[db_dumper.pl] No save location specified... Saving to folder script is running in...\n";
|
||||
}
|
||||
if($backup_location[1] ne ""){
|
||||
if($OS eq "Windows"){ $file_app = "\\"; }
|
||||
if($OS eq "Linux"){ $file_app = "/"; }
|
||||
}
|
||||
else {
|
||||
$file_app = "";
|
||||
}
|
||||
|
||||
if($t_tables ne ""){
|
||||
$tables_f_l = substr($t_tables_l, 0, 20) . '-';
|
||||
if($backup_name){
|
||||
$target_file = $backup_name . '_' . $date . '';
|
||||
}
|
||||
else {
|
||||
$target_file = '' . $tables_f_l . '_' . $date . '';
|
||||
}
|
||||
|
||||
print "[db_dumper.pl] Performing table based backup...\n";
|
||||
#::: Backup Database...
|
||||
print "[db_dumper.pl] Backing up Database " . $db . "... \n";
|
||||
if($no_lock == 1){
|
||||
$added_parameters .= " --skip-lock-tables ";
|
||||
}
|
||||
$cmd = 'mysqldump -u' . $user . ' --host ' . $host . ' ' . $added_parameters . ' --max_allowed_packet=512M --password="' . $pass . '" ' . $db . ' ' . $t_tables . ' > "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql"';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
}
|
||||
else{ #::: Entire DB Backup
|
||||
|
||||
if($backup_name){
|
||||
$target_file = $backup_name . '_' . $db . '_' . $date . '';
|
||||
}
|
||||
else {
|
||||
$target_file = '' . $db . '_' . $date . '';
|
||||
}
|
||||
|
||||
#::: Backup Database...
|
||||
print "[db_dumper.pl] Backing up Database " . $db . "... \n";
|
||||
if($no_lock == 1){
|
||||
$added_parameters .= " --skip-lock-tables ";
|
||||
}
|
||||
$cmd = 'mysqldump -u' . $user . ' --host ' . $host . ' ' . $added_parameters . ' --max_allowed_packet=512M --password="' . $pass . '" ' . $db . ' > "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql"';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
#::: Get File Size
|
||||
$fileloc = '' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql';
|
||||
$filesize = -s $fileloc;
|
||||
if($filesize < 1000){ print "[db_dumper.pl] " . 'Error occurred... exiting...' . "\n"; exit; }
|
||||
print "[db_dumper.pl] Backup DONE... DB Backup File Size '" . $filesize . "' (" . get_filesize_str($fileloc) . ")\n";
|
||||
|
||||
#::: WinRar Get, check compression flag
|
||||
if($Compress == 1){
|
||||
if($OS eq "Windows"){
|
||||
if(-d $localdrive . "\\Program Files\\7-Zip"){
|
||||
print "[db_dumper.pl] ::: You have 7-Zip installed as 64 Bit...\n";
|
||||
$S_ZIP = $localdrive . "\\Program Files\\7-Zip";
|
||||
}
|
||||
elsif(-d $localdrive . "\\Program Files (x86)\\7-Zip"){
|
||||
print "[db_dumper.pl] ::: You have 7-Zip installed as 32 Bit...\n";
|
||||
$S_ZIP = $localdrive . "\\Program Files (x86)\\7-Zip";
|
||||
}
|
||||
elsif(-d $localdrive . "\\Program Files (x86)\\WinRAR"){
|
||||
print "[db_dumper.pl] ::: You have WinRAR installed as 32 Bit...\n";
|
||||
$WinRar = $localdrive . "\\Program Files (x86)\\WinRAR";
|
||||
}
|
||||
elsif(-d $localdrive . "\\Program Files\\WinRAR"){
|
||||
print "[db_dumper.pl] ::: You have WinRAR installed as 64 Bit...\n";
|
||||
$WinRar = $localdrive . "\\Program Files\\WinRAR";
|
||||
}
|
||||
else{
|
||||
print "[db_dumper.pl] No WinRAR installed... Will not compress...\n";
|
||||
}
|
||||
if($S_ZIP ne ""){
|
||||
print "[db_dumper.pl] Compressing Database with 7-ZIP... \n";
|
||||
$cmd = '"' . $S_ZIP . '\\7z" a -t7z -m0=lzma -mx=9 "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.7z" "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
print "[db_dumper.pl] \nDeleting RAW .sql Dump... \n";
|
||||
$cmd = 'del "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
$final_file = $target_file . ".7z";
|
||||
}
|
||||
elsif($WinRar ne ""){
|
||||
print "[db_dumper.pl] Compressing Database with WinRAR... \n";
|
||||
$cmd = '"' . $WinRar . '\\rar" a "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.rar" "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
print "[db_dumper.pl] \nDeleting RAW .sql Dump... \n";
|
||||
$cmd = 'del "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
$final_file = $target_file . ".rar";
|
||||
}
|
||||
}
|
||||
if($OS eq "Linux"){
|
||||
print "[db_dumper.pl] Compressing Database with Tarball... \n";
|
||||
$cmd = 'tar -zcvf "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.tar.gz" "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
print "[db_dumper.pl] \nDeleting RAW .sql Dump... \n";
|
||||
$cmd = 'rm "' . $backup_location[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||
printcmd($cmd);
|
||||
system($cmd);
|
||||
$final_file = $target_file . ".tar.gz";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$final_file = $target_file . ".sql";
|
||||
}
|
||||
|
||||
#::: Get Final File Location for display
|
||||
if($backup_location[1] ne ""){ $final_loc = $backup_location[1] . '' . $file_app . ""; }
|
||||
else{
|
||||
if($OS eq "Windows"){
|
||||
$final_loc = `echo %cd%`;
|
||||
}
|
||||
elsif($OS eq "Linux"){
|
||||
$final_loc = `pwd`;
|
||||
}
|
||||
}
|
||||
|
||||
print "[db_dumper.pl] Final file located: " . $final_loc . "" . $final_file . "\n";
|
||||
|
||||
sub printcmd{
|
||||
print "[db_dumper.pl] Command [" . $_[0] . "]\n";
|
||||
}
|
||||
|
||||
sub get_filesize_str{
|
||||
my $file = shift();
|
||||
my $size = (stat($file))[7] || die "stat($file): $!\n";
|
||||
if ($size > 1099511627776) { return sprintf("%.2f TiB", $size / 1099511627776); }
|
||||
elsif ($size > 1073741824) { return sprintf("%.2f GiB", $size / 1073741824); }
|
||||
elsif ($size > 1048576) { return sprintf("%.2f MiB", $size / 1048576); }
|
||||
elsif ($size > 1024) { return sprintf("%.2f KiB", $size / 1024); }
|
||||
else { return "$size byte" . ($size == 1 ? "" : "s"); }
|
||||
}
|
||||
@ -48,10 +48,18 @@ if(-e "eqemu_server_skip_update.txt"){
|
||||
}
|
||||
|
||||
#::: Check for script self update
|
||||
check_xml_to_json_conversion() if $ARGV[0] eq "convert_xml";
|
||||
do_self_update_check_routine() if !$skip_self_update_check;
|
||||
get_windows_wget();
|
||||
get_perl_version();
|
||||
read_eqemu_config_xml();
|
||||
if(-e "eqemu_config.json") {
|
||||
read_eqemu_config_json();
|
||||
}
|
||||
else {
|
||||
#::: This will need to stay for servers who simply haven't updated yet
|
||||
# This script can still update without the server bins being updated
|
||||
read_eqemu_config_xml();
|
||||
}
|
||||
get_mysql_path();
|
||||
|
||||
#::: Remove old eqemu_update.pl
|
||||
@ -265,7 +273,7 @@ sub new_server {
|
||||
analytics_insertion("new_server::install", $database_name);
|
||||
|
||||
if($OS eq "Linux"){
|
||||
build_linux_source();
|
||||
build_linux_source("login");
|
||||
}
|
||||
|
||||
do_installer_routines();
|
||||
@ -281,6 +289,10 @@ sub new_server {
|
||||
|
||||
show_install_summary_info();
|
||||
|
||||
if($OS eq "Linux") {
|
||||
unlink('/home/eqemu/install_variables.txt');
|
||||
}
|
||||
|
||||
rmtree('updates_staged');
|
||||
|
||||
return;
|
||||
@ -291,6 +303,61 @@ sub new_server {
|
||||
}
|
||||
}
|
||||
|
||||
sub check_xml_to_json_conversion {
|
||||
if(-e "eqemu_config.xml" && !-e "eqemu_config.json") {
|
||||
|
||||
if($OS eq "Windows"){
|
||||
get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/xmltojson/xmltojson-windows-x86.exe", "xmltojson.exe");
|
||||
print "Converting eqemu_config.xml to eqemu_config.json\n";
|
||||
print `xmltojson eqemu_config.xml`;
|
||||
}
|
||||
if($OS eq "Linux"){
|
||||
get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/xmltojson/xmltojson-linux-x86", "xmltojson");
|
||||
print "Converting eqemu_config.xml to eqemu_config.json\n";
|
||||
print `chmod 755 xmltojson`;
|
||||
print `./xmltojson eqemu_config.xml`;
|
||||
}
|
||||
|
||||
#::: Prettify and alpha order the config
|
||||
use JSON;
|
||||
my $json = new JSON();
|
||||
|
||||
my $content;
|
||||
open(my $fh, '<', "eqemu_config.json") or die "cannot open file $filename"; {
|
||||
local $/;
|
||||
$content = <$fh>;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
$result = $json->decode($content);
|
||||
$json->canonical(1);
|
||||
|
||||
print $json->pretty->indent_length(5)->utf8->encode($result),"\n";
|
||||
|
||||
open(my $fh, '>', 'eqemu_config.json');
|
||||
print $fh $json->pretty->indent_length(5)->utf8->encode($result);
|
||||
close $fh;
|
||||
|
||||
mkdir('backups');
|
||||
copy_file("eqemu_config.xml", "backups/eqemu_config.xml");
|
||||
unlink('eqemu_config.xml');
|
||||
unlink('db_dumper.pl');
|
||||
|
||||
print "[Server Maintenance] eqemu_config.xml is now DEPRECATED \n";
|
||||
print "[Server Maintenance] eqemu_config.json is now the new Server config format \n";
|
||||
print " A backup of this old config is located in the backups folder of your server directory\n";
|
||||
print " --- \n";
|
||||
print " You may have some plugins and/or applications that still require reference of this config file\n";
|
||||
print " Please update these plugins/applications to use the new configuration format if needed\n";
|
||||
print " --- \n";
|
||||
print " Thanks for your understanding\n";
|
||||
print " The EQEmulator Team\n\n";
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub build_linux_source {
|
||||
|
||||
$build_options = $_[0];
|
||||
@ -330,10 +397,10 @@ sub build_linux_source {
|
||||
|
||||
print "Generating CMake build files...\n";
|
||||
if($os_flavor eq "fedora_core"){
|
||||
print `cmake $cmake_options -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" ..`;
|
||||
print `cmake $cmake_options -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" ..`;
|
||||
}
|
||||
else {
|
||||
print `cmake $cmake_options -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" ..`;
|
||||
print `cmake $cmake_options -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" ..`;
|
||||
}
|
||||
print "Building EQEmu Server code. This will take a while.";
|
||||
|
||||
@ -352,6 +419,7 @@ sub build_linux_source {
|
||||
print `ln -s -f $source_dir/Server/build/bin/ucs .`;
|
||||
print `ln -s -f $source_dir/Server/build/bin/world .`;
|
||||
print `ln -s -f $source_dir/Server/build/bin/zone .`;
|
||||
print `ln -s -f $source_dir/Server/build/bin/loginserver .`;
|
||||
}
|
||||
|
||||
sub do_installer_routines {
|
||||
@ -362,8 +430,8 @@ sub do_installer_routines {
|
||||
mkdir('updates_staged');
|
||||
mkdir('shared');
|
||||
|
||||
do_install_config_xml();
|
||||
read_eqemu_config_xml();
|
||||
do_install_config_json();
|
||||
read_eqemu_config_json();
|
||||
get_installation_variables();
|
||||
|
||||
$db_name = "peq";
|
||||
@ -579,7 +647,12 @@ sub do_self_update_check_routine {
|
||||
sub get_installation_variables{
|
||||
#::: Fetch installation variables before building the config
|
||||
if($OS eq "Linux"){
|
||||
open (INSTALL_VARS, "../install_variables.txt");
|
||||
if(-e "../install_variables.txt") {
|
||||
open (INSTALL_VARS, "../install_variables.txt");
|
||||
}
|
||||
elsif(-e "install_variables.txt") {
|
||||
open (INSTALL_VARS, "./install_variables.txt");
|
||||
}
|
||||
}
|
||||
if($OS eq "Windows"){
|
||||
open (INSTALL_VARS, "install_variables.txt");
|
||||
@ -593,73 +666,51 @@ sub get_installation_variables{
|
||||
close (INSTALL_VARS);
|
||||
}
|
||||
|
||||
sub do_install_config_xml {
|
||||
sub do_install_config_json {
|
||||
get_installation_variables();
|
||||
|
||||
#::: Fetch XML template
|
||||
get_remote_file($install_repository_request_url . "eqemu_config.xml", "eqemu_config_template.xml");
|
||||
#::: Fetch json template
|
||||
get_remote_file($install_repository_request_url . "eqemu_config.json", "eqemu_config_template.json");
|
||||
|
||||
#::: Open new config file
|
||||
open (NEW_CONFIG, '>', 'eqemu_config.xml');
|
||||
use JSON;
|
||||
my $json = new JSON();
|
||||
|
||||
my $content;
|
||||
open(my $fh, '<', "eqemu_config_template.json") or die "cannot open file $filename"; {
|
||||
local $/;
|
||||
$content = <$fh>;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
$config = $json->decode($content);
|
||||
|
||||
$in_database_tag = 0;
|
||||
$long_name = "Akkas " . $OS . " PEQ Installer (" . generate_random_password(5) . ')';
|
||||
$config->{"server"}{"world"}{"longname"} = $long_name;
|
||||
$config->{"server"}{"world"}{"key"} = generate_random_password(30);
|
||||
|
||||
#::: Iterate through template and replace variables...
|
||||
open (FILE_TEMPLATE, "eqemu_config_template.xml");
|
||||
while (<FILE_TEMPLATE>){
|
||||
chomp;
|
||||
$o = $_;
|
||||
|
||||
#::: Find replace variables
|
||||
|
||||
if($o=~/\<\!--/i){
|
||||
next;
|
||||
}
|
||||
|
||||
if($o=~/database/i && $o=~/\<\//i){
|
||||
$in_database_tag = 0;
|
||||
}
|
||||
if($o=~/database/i){
|
||||
$in_database_tag = 1;
|
||||
}
|
||||
|
||||
if($o=~/key/i){
|
||||
my($replace_key) = $o =~ />(\w+)</;
|
||||
$new_key = generate_random_password(30);
|
||||
$o =~ s/$replace_key/$new_key/g;
|
||||
}
|
||||
if($o=~/\<longname\>/i){
|
||||
my($replace_name) = $o =~ /<longname>(.*)<\/longname>/;
|
||||
$append = '(' . generate_random_password(5) . ')';
|
||||
$o =~ s/$replace_name/Akkas $OS PEQ Installer $append/g;
|
||||
}
|
||||
if($o=~/\<username\>/i && $in_database_tag){
|
||||
my($replace_username) = $o =~ />(\w+)</;
|
||||
$o =~ s/$replace_username/$installation_variables{"mysql_eqemu_user"}/g;
|
||||
}
|
||||
if($o=~/\<password\>/i && $in_database_tag){
|
||||
my($replace_password) = $o =~ />(\w+)</;
|
||||
$o =~ s/$replace_password/$installation_variables{"mysql_eqemu_password"}/g;
|
||||
}
|
||||
if($o=~/\<db\>/i){
|
||||
my($replace_db_name) = $o =~ />(\w+)</;
|
||||
|
||||
#::: There is really no reason why this shouldn't be set
|
||||
if($installation_variables{"mysql_eqemu_db_name"}){
|
||||
$db_name = $installation_variables{"mysql_eqemu_db_name"};
|
||||
}
|
||||
else {
|
||||
$db_name = "peq";
|
||||
}
|
||||
|
||||
$o =~ s/$replace_db_name/$db_name/g;
|
||||
}
|
||||
print NEW_CONFIG $o . "\n";
|
||||
if($installation_variables{"mysql_eqemu_db_name"}){
|
||||
$db_name = $installation_variables{"mysql_eqemu_db_name"};
|
||||
}
|
||||
else {
|
||||
$db_name = "peq";
|
||||
}
|
||||
|
||||
close(FILE_TEMPLATE);
|
||||
close(NEW_CONFIG);
|
||||
unlink("eqemu_config_template.xml");
|
||||
$config->{"server"}{"database"}{"username"} = $installation_variables{"mysql_eqemu_user"};
|
||||
$config->{"server"}{"database"}{"password"} = $installation_variables{"mysql_eqemu_password"};
|
||||
$config->{"server"}{"database"}{"db"} = $db_name;
|
||||
|
||||
$config->{"server"}{"qsdatabase"}{"username"} = $installation_variables{"mysql_eqemu_user"};
|
||||
$config->{"server"}{"qsdatabase"}{"password"} = $installation_variables{"mysql_eqemu_password"};
|
||||
$config->{"server"}{"qsdatabase"}{"db"} = $db_name;
|
||||
|
||||
$json->canonical(1);
|
||||
$json->indent_length(5);
|
||||
|
||||
open(my $fh, '>', 'eqemu_config.json');
|
||||
print $fh $json->pretty->indent_length(5)->utf8->encode($config);
|
||||
close $fh;
|
||||
|
||||
unlink("eqemu_config_template.json");
|
||||
}
|
||||
|
||||
sub fetch_utility_scripts {
|
||||
@ -725,6 +776,13 @@ sub show_menu_prompt {
|
||||
print "Enter a command #> ";
|
||||
$last_menu = trim($input);
|
||||
}
|
||||
elsif($input eq "conversions"){
|
||||
print "\n>>> Conversions Menu\n\n";
|
||||
print " [quest_heading_convert] Converts old heading format in quest scripts to new (live format)\n";
|
||||
print " \n> main - go back to main menu\n";
|
||||
print "Enter a command #> ";
|
||||
$last_menu = trim($input);
|
||||
}
|
||||
elsif($input eq "assets"){
|
||||
print "\n>>> Server Assets Menu\n\n";
|
||||
print " [maps] Download latest maps\n";
|
||||
@ -733,7 +791,7 @@ sub show_menu_prompt {
|
||||
print " [plugins] Download latest plugins\n";
|
||||
print " [lua_modules] Download latest lua_modules\n";
|
||||
print " [utility_scripts] Download utility scripts to run and operate the EQEmu Server\n";
|
||||
if($OS eq "Windows"){
|
||||
if($OS eq "Windows") {
|
||||
print ">>> Windows\n";
|
||||
print " [windows_server_download] Updates server via latest 'stable' code\n";
|
||||
print " [windows_server_latest] Updates server via latest commit 'unstable'\n";
|
||||
@ -766,6 +824,8 @@ sub show_menu_prompt {
|
||||
elsif($input eq "setup_loginserver"){ do_windows_login_server_setup(); $dc = 1; }
|
||||
elsif($input eq "new_server"){ new_server(); $dc = 1; }
|
||||
elsif($input eq "setup_bots"){ setup_bots(); $dc = 1; }
|
||||
elsif($input eq "linux_login_server_setup"){ do_linux_login_server_setup(); $dc = 1; }
|
||||
elsif($input eq "quest_heading_convert"){ quest_heading_convert(); $dc = 1; }
|
||||
elsif($input eq "exit"){
|
||||
exit;
|
||||
}
|
||||
@ -816,6 +876,7 @@ sub print_main_menu {
|
||||
print " [assets] Manage server assets \n";
|
||||
print " [new_server] New folder EQEmu/PEQ install - Assumes MySQL/Perl installed \n";
|
||||
print " [setup_bots] Enables bots on server - builds code and database requirements \n";
|
||||
print " [conversions] Routines used for conversion of scripts/data \n";
|
||||
print "\n";
|
||||
print " exit \n";
|
||||
print "\n";
|
||||
@ -858,13 +919,13 @@ sub check_for_database_dump_script{
|
||||
return;
|
||||
}
|
||||
|
||||
#::: Check for script changes :: db_dumper.pl
|
||||
get_remote_file($eqemu_repository_request_url . "utils/scripts/db_dumper.pl", "updates_staged/db_dumper.pl", 0, 1, 1);
|
||||
#::: Check for script changes :: database_dumper.pl
|
||||
get_remote_file($eqemu_repository_request_url . "utils/scripts/database_dumper.pl", "updates_staged/database_dumper.pl", 0, 1, 1);
|
||||
|
||||
if(-e "updates_staged/db_dumper.pl") {
|
||||
if(-e "updates_staged/database_dumper.pl") {
|
||||
|
||||
my $remote_script_size = -s "updates_staged/db_dumper.pl";
|
||||
my $local_script_size = -s "db_dumper.pl";
|
||||
my $remote_script_size = -s "updates_staged/database_dumper.pl";
|
||||
my $local_script_size = -s "database_dumper.pl";
|
||||
|
||||
if($remote_script_size != $local_script_size){
|
||||
print "[Update] Script has been updated, updating...\n";
|
||||
@ -876,14 +937,14 @@ sub check_for_database_dump_script{
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
if($file=~/db_dumper/i){
|
||||
if($file=~/database_dumper/i){
|
||||
$destination_file = $file;
|
||||
$destination_file =~s/updates_staged\///g;
|
||||
print "[Install] Installing :: " . $destination_file . "\n";
|
||||
unlink($destination_file);
|
||||
copy_file($file, $destination_file);
|
||||
if($OS eq "Linux"){
|
||||
system("chmod 755 db_dumper.pl");
|
||||
system("chmod 755 database_dumper.pl");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -893,7 +954,7 @@ sub check_for_database_dump_script{
|
||||
print "[Update] No script update necessary...\n";
|
||||
}
|
||||
|
||||
unlink("updates_staged/db_dumper.pl");
|
||||
unlink("updates_staged/database_dumper.pl");
|
||||
}
|
||||
|
||||
return;
|
||||
@ -903,7 +964,7 @@ sub check_for_database_dump_script{
|
||||
sub database_dump {
|
||||
check_for_database_dump_script();
|
||||
print "[Database] Performing database backup....\n";
|
||||
print `perl db_dumper.pl database="$db" loc="backups"`;
|
||||
print `perl database_dumper.pl database="$db" loc="backups"`;
|
||||
}
|
||||
|
||||
sub database_dump_player_tables {
|
||||
@ -921,7 +982,7 @@ sub database_dump_player_tables {
|
||||
}
|
||||
$tables = substr($tables, 0, -1);
|
||||
|
||||
print `perl db_dumper.pl database="$db" loc="backups" tables="$tables" backup_name="player_tables_export" nolock`;
|
||||
print `perl database_dumper.pl database="$db" loc="backups" tables="$tables" backup_name="player_tables_export" nolock`;
|
||||
|
||||
print "[Database] Press any key to continue...\n";
|
||||
|
||||
@ -932,7 +993,7 @@ sub database_dump_player_tables {
|
||||
sub database_dump_compress {
|
||||
check_for_database_dump_script();
|
||||
print "[Database] Performing database backup....\n";
|
||||
print `perl db_dumper.pl database="$db" loc="backups" compress`;
|
||||
print `perl database_dumper.pl database="$db" loc="backups" compress`;
|
||||
}
|
||||
|
||||
sub script_exit{
|
||||
@ -1008,7 +1069,7 @@ sub get_remote_file{
|
||||
}
|
||||
|
||||
#::: wget -O db_update/db_update_manifest.txt https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||
$wget = `wget -N --no-check-certificate --quiet -O $destination_file $request_url`;
|
||||
$wget = `wget -N --cache=no --no-check-certificate --quiet -O $destination_file $request_url`;
|
||||
print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download;
|
||||
if($wget=~/unable to resolve/i){
|
||||
print "Error, no connection or failed request...\n\n";
|
||||
@ -1072,6 +1133,26 @@ sub read_eqemu_config_xml {
|
||||
close(CONFIG);
|
||||
}
|
||||
|
||||
sub read_eqemu_config_json {
|
||||
use JSON;
|
||||
my $json = new JSON();
|
||||
|
||||
my $content;
|
||||
open(my $fh, '<', "eqemu_config.json") or die "cannot open file $filename"; {
|
||||
local $/;
|
||||
$content = <$fh>;
|
||||
}
|
||||
close($fh);
|
||||
|
||||
$config = $json->decode($content);
|
||||
|
||||
$db = $config->{"server"}{"database"}{"db"};
|
||||
$host = $config->{"server"}{"database"}{"host"};
|
||||
$user = $config->{"server"}{"database"}{"username"};
|
||||
$pass = $config->{"server"}{"database"}{"password"};
|
||||
|
||||
}
|
||||
|
||||
#::: Fetch Latest PEQ AA's
|
||||
sub aa_fetch{
|
||||
if(!$db){
|
||||
@ -1277,6 +1358,8 @@ sub do_windows_login_server_setup {
|
||||
|
||||
sub do_linux_login_server_setup {
|
||||
|
||||
build_linux_source();
|
||||
|
||||
for my $file (@files) {
|
||||
$destination_file = $file;
|
||||
$destination_file =~s/updates_staged\/login_server\///g;
|
||||
@ -1297,6 +1380,8 @@ sub do_linux_login_server_setup {
|
||||
get_remote_file($install_repository_request_url . "linux/login.ini", "login_template.ini");
|
||||
get_remote_file($install_repository_request_url . "linux/login_opcodes.conf", "login_opcodes.conf");
|
||||
get_remote_file($install_repository_request_url . "linux/login_opcodes_sod.conf", "login_opcodes_sod.conf");
|
||||
get_remote_file($install_repository_request_url . "linux/server_start_with_login.sh", "server_start_with_login.sh");
|
||||
system("chmod 755 *.sh");
|
||||
|
||||
get_installation_variables();
|
||||
my $db_name = $installation_variables{"mysql_eqemu_db_name"};
|
||||
@ -2181,3 +2266,134 @@ sub generate_random_password {
|
||||
return $randpassword;
|
||||
}
|
||||
|
||||
sub quest_heading_convert {
|
||||
|
||||
if(trim(get_mysql_result("SELECT value FROM variables WHERE varname = 'new_heading_conversion'")) eq "true") {
|
||||
print "Conversion script has already ran... doing this again would skew proper heading values in function calls...\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
%matches = (
|
||||
0 => ["quest::spawn2", 6],
|
||||
1 => ["eq.spawn2", 6],
|
||||
2 => ["eq.unique_spawn", 6],
|
||||
3 => ["quest::unique_spawn", 6],
|
||||
4 => ["GMMove", 3],
|
||||
5 => ["MovePCInstance", 5],
|
||||
6 => ["MovePC", 4],
|
||||
7 => ["moveto", 3],
|
||||
);
|
||||
|
||||
$total_matches = 0;
|
||||
|
||||
use Scalar::Util qw(looks_like_number);
|
||||
|
||||
my @files;
|
||||
my $start_dir = "quests/.";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
|
||||
#::: Skip non script files
|
||||
if($file!~/lua|pl/i){ next; }
|
||||
|
||||
if($file=~/lua|pl/i){
|
||||
$print_buffer = "";
|
||||
|
||||
$changes_made = 0;
|
||||
|
||||
#::: Open and read line by line
|
||||
open (FILE, $file);
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
$line = $_;
|
||||
|
||||
#::: Loop through matches
|
||||
foreach my $key (sort(keys %matches)) {
|
||||
$argument_position = $matches{$key}[1];
|
||||
$match = $matches{$key}[0];
|
||||
|
||||
if($line=~/$match/i) {
|
||||
$line_temp = $line;
|
||||
$line_temp =~s/$match\(//g;
|
||||
$line_temp =~s/\(.*?\)//gs;
|
||||
$line_temp =~s/\);.*//;
|
||||
$line_temp =~s/\).*//;
|
||||
$line_temp =~s/\):.*//;
|
||||
$line_temp =~s/\);//g;
|
||||
|
||||
@line_data = split(",", $line_temp);
|
||||
|
||||
# use Data::Dumper;
|
||||
# print Dumper(\@line_data);
|
||||
|
||||
$heading_value = $line_data[$argument_position];
|
||||
$heading_value_clean = trim($heading_value);
|
||||
$heading_value_raw = $line_data[$argument_position];
|
||||
$heading_value_before = $line_data[$argument_position - 1];
|
||||
|
||||
if (looks_like_number($heading_value) && $heading_value != 0 && ($heading_value * 2) <= 512) {
|
||||
$heading_value_new = $heading_value * 2;
|
||||
|
||||
$heading_value=~s/$heading_value_clean/$heading_value_new/g;
|
||||
|
||||
$heading_value_search = quotemeta($heading_value_before . "," . $heading_value_raw);
|
||||
$heading_value_replace = $heading_value_before . "," . $heading_value;
|
||||
|
||||
print $file . "\n";
|
||||
print $line . "\n";
|
||||
$line=~s/$heading_value_search/$heading_value_replace/g;
|
||||
print $line . "\n";
|
||||
print "\n";
|
||||
|
||||
$changes_made = 1;
|
||||
}
|
||||
elsif ($heading_value == 0){} #::: Do nothing
|
||||
elsif ($heading_value=~/GetHeading|heading|\$h/i){} #::: Do nothing
|
||||
else {
|
||||
if ($file=~/\.pl/i) {
|
||||
if($line_temp=~/#/i) {
|
||||
$line .= " - needs_heading_validation";
|
||||
}
|
||||
else {
|
||||
$line .= " # needs_heading_validation";
|
||||
}
|
||||
}
|
||||
elsif ($file=~/\.lua/i) {
|
||||
if($line_temp=~/--/i) {
|
||||
$line .= " - needs_heading_validation";
|
||||
}
|
||||
else {
|
||||
$line .= " -- needs_heading_validation";
|
||||
}
|
||||
}
|
||||
|
||||
$changes_made = 1;
|
||||
|
||||
print $line . "\n";
|
||||
}
|
||||
|
||||
$total_matches++;
|
||||
}
|
||||
}
|
||||
|
||||
$print_buffer .= $line . "\n";
|
||||
}
|
||||
close (FILE);
|
||||
|
||||
if($changes_made == 1) {
|
||||
#::: Write changes
|
||||
open (NEW_FILE, '>', $file);
|
||||
print NEW_FILE $print_buffer;
|
||||
close NEW_FILE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#::: Mark conversion as ran
|
||||
print get_mysql_result("INSERT INTO `variables` (varname, value, information, ts) VALUES ('new_heading_conversion', 'true', 'Script ran against quests folder to convert new heading values', NOW())");
|
||||
|
||||
print "Total matches: " . $total_matches . "\n";
|
||||
}
|
||||
@ -119,18 +119,15 @@ if [[ "$OS" == "Debian" ]]; then
|
||||
apt-get $apt_options install zlibc
|
||||
apt-get $apt_options install libsodium-dev
|
||||
apt-get $apt_options install libsodium18
|
||||
apt-get $apt_options install libjson-perl
|
||||
|
||||
# If libsodium18 isn't installed (Debian), let's download both that and the dev package and install them.
|
||||
if dpkg-query -s "libsodium18" 1>/dev/null 2>&1; then
|
||||
echo "Sodium library already installed."
|
||||
else
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium18_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium18.deb
|
||||
dpkg -i /home/eqemu/libsodium*.deb
|
||||
# Cleanup after ourselves
|
||||
rm -f /home/eqemu/libsodium-dev.deb
|
||||
rm -f /home/eqemu/libsodium18.deb
|
||||
fi
|
||||
# Install libsodium
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium18_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium18.deb
|
||||
dpkg -i /home/eqemu/libsodium*.deb
|
||||
# Cleanup after ourselves
|
||||
rm -f /home/eqemu/libsodium-dev.deb
|
||||
rm -f /home/eqemu/libsodium18.deb
|
||||
|
||||
#::: Install FTP for remote FTP access
|
||||
echo "proftpd-basic shared/proftpd/inetd_or_standalone select standalone" | debconf-set-selections
|
||||
@ -159,7 +156,7 @@ EOF
|
||||
# Install prereqs
|
||||
yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
||||
yum -y install deltarpm
|
||||
yum -y install open-vm-tools vim cmake boost-* zlib-devel mariadb-server mariadb-client mariadb-devel mariadb-libs mariadb-compat perl-* lua* dos2unix php-mysql proftpd
|
||||
yum -y install open-vm-tools vim cmake boost-* zlib-devel mariadb-server mariadb-client mariadb-devel mariadb-libs mariadb-compat perl-* lua* dos2unix php-mysql proftpd libuuid-devel
|
||||
yum -y groupinstall "Development Tools" "Basic Web Server" "Compatibility Libraries"
|
||||
|
||||
elif [[ "$OS" == "fedora_core" ]]; then
|
||||
|
||||
@ -368,6 +368,14 @@
|
||||
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
||||
9113|2017_07_19_show_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'show_name'|empty|
|
||||
9114|2017_07_22_aura.sql|SHOW TABLES LIKE 'auras'|empty|
|
||||
9115|2017_10_28_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'triggered_number'|empty|
|
||||
9116|2017_12_16_GroundSpawn_Respawn_Timer.sql|SHOW COLUMNS FROM `ground_spawns` WHERE Field = 'respawn_timer' AND Type = 'int(11) unsigned'|empty|
|
||||
9117|2018_02_01_NPC_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'min_hp'|empty|
|
||||
9118|2018_02_04_Charm_Stats.sql|SHOW COLUMNS FROM `npc_types` LIKE 'charm_ac'|empty|
|
||||
9119|2018_02_10_GlobalLoot.sql|SHOW TABLES LIKE 'global_loot'|empty|
|
||||
9120|2018_02_13_Heading.sql|SELECT value FROM variables WHERE varname = 'fixed_heading'|empty|
|
||||
9121|2018_02_18_bug_reports.sql|SHOW TABLES LIKE 'bug_reports'|empty|
|
||||
9122|2018_03_07_ucs_command.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'ucs'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
9015|2017_02_26_bots_spell_casting_chances_update.sql|SHOW COLUMNS FROM `bot_spell_casting_chances` LIKE 'value'|not_empty|
|
||||
9016|2017_02_26_bots_spell_casting_chances_update.sql|SHOW TABLES LIKE 'bot_spell_casting_chances'|empty|
|
||||
9017|2017_03_26_bots_spells_id_fix_for_saved_shadowknight_bots.sql|SELECT * FROM `bot_data` WHERE `class` = '5' AND `spells_id` = '3004'|not_empty|
|
||||
9018|2018_02_02_Bot_Spells_Min_Max_HP.sql|SHOW COLUMNS FROM `bot_spells_entries` LIKE 'min_hp'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
1305
utils/sql/git/bots/deprecated/2015_09_30_bots_supplemental.sql
Normal file
1305
utils/sql/git/bots/deprecated/2015_09_30_bots_supplemental.sql
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `bot_spells_entries` ADD `min_hp` SMALLINT(5) DEFAULT '0';
|
||||
ALTER TABLE `bot_spells_entries` ADD `max_hp` SMALLINT(5) DEFAULT '0';
|
||||
@ -0,0 +1,3 @@
|
||||
UPDATE `rule_values` SET `rule_value` = '32' WHERE `rule_name` = 'Character:FoodLossPerUpdate';
|
||||
UPDATE `rule_values` SET `rule_value` = '30' WHERE `rule_name` = 'Character:ItemHealthRegenCap';
|
||||
|
||||
451
utils/sql/git/optional/2018_02_11_GlobalDefiant.sql
Normal file
451
utils/sql/git/optional/2018_02_11_GlobalDefiant.sql
Normal file
@ -0,0 +1,451 @@
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50005, 50006, 50007, 50008, 50009, 50010, 50011, 50012, 50013, 50014, 50015, 50016, 50017, 50018, 50019, 50020, 50021, 50022, 50023, 50024, 50025, 50026, 50027, 50028, 50029, 50030, 50031, 50032, 50500, 50501, 50502, 50503, 50504, 50505, 50506, 50507, 50508, 50509, 50510, 50511, 50512, 50513, 50514, 50515, 50516, 50517, 50518);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Crude-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Crude-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50005, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50006, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50007, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50008, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50009, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50010, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50011, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50012, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50013, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50014, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50015, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50016, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50017, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50018, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50019, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50020, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50021, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50022, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50023, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50024, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50025, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50026, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50027, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50028, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50029, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50030, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50031, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50032, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50500, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50501, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50502, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50503, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50504, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50505, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50506, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50507, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50508, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50509, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50510, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50511, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50512, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50513, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50514, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50515, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50516, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50517, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50518, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Crude-Defiant', loottable_id=@loottable_id, max_level=15;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50033, 50034, 50035, 50036, 50037, 50038, 50039, 50040, 50041, 50042, 50043, 50044, 50045, 50046, 50047, 50048, 50049, 50050, 50051, 50052, 50053, 50054, 50055, 50056, 50057, 50058, 50059, 50060, 50519, 50520, 50521, 50522, 50523, 50524, 50525, 50526, 50527, 50528, 50529, 50530, 50531, 50532, 50533, 50534, 50535);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Simple-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Simple-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50033, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50034, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50035, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50036, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50037, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50038, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50039, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50040, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50041, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50042, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50043, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50044, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50045, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50046, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50047, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50048, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50049, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50050, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50051, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50052, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50053, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50054, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50055, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50056, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50057, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50058, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50059, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50060, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50519, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50520, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50521, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50522, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50523, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50524, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50525, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50526, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50527, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50528, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50529, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50530, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50531, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50532, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50533, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50534, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50535, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Simple-Defiant', loottable_id=@loottable_id, min_level=14, max_level=25;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50061, 50062, 50063, 50064, 50065, 50066, 50067, 50068, 50069, 50070, 50071, 50072, 50073, 50074, 50075, 50076, 50077, 50078, 50079, 50080, 50081, 50082, 50083, 50084, 50085, 50086, 50087, 50088, 50536, 50537, 50540, 50541, 50542, 50543, 50544, 50545, 50546, 50547, 50548, 50549, 50550, 50551, 50552, 50553);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Rough-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Rough-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50061, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50062, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50063, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50064, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50065, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50066, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50067, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50068, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50069, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50070, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50071, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50072, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50073, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50074, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50075, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50076, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50077, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50078, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50079, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50080, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50081, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50082, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50083, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50084, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50085, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50086, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50087, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50088, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50536, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50537, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50540, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50541, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50542, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50543, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50544, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50545, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50546, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50547, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50548, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50549, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50550, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50551, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50552, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50553, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Rough-Defiant', loottable_id=@loottable_id, min_level=24, max_level=36;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50089, 50090, 50091, 50092, 50093, 50094, 50095, 50096, 50097, 50098, 50099, 50100, 50101, 50102, 50103, 50104, 50105, 50106, 50107, 50108, 50109, 50110, 50111, 50112, 50113, 50114, 50115, 50116, 50554, 50555, 50556, 50557, 50558, 50559, 50560, 50561, 50562, 50563, 50564, 50565, 50566, 50567, 50568, 50569);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Ornate-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Ornate-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50089, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50090, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50091, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50092, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50093, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50094, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50095, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50096, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50097, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50098, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50099, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50100, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50101, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50102, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50103, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50104, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50105, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50106, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50107, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50108, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50109, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50110, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50111, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50112, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50113, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50114, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50115, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50116, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50554, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50555, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50556, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50557, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50558, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50559, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50560, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50561, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50562, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50563, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50564, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50565, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50566, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50567, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50568, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50569, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Ornate-Defiant', loottable_id=@loottable_id, min_level=35, max_level=47;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50117, 50118, 50119, 50120, 50121, 50122, 50123, 50124, 50125, 50126, 50127, 50128, 50129, 50130, 50131, 50132, 50133, 50134, 50135, 50136, 50137, 50138, 50139, 50140, 50141, 50142, 50143, 50144, 50570, 50571, 50572, 50573, 50574, 50575, 50576, 50577, 50578, 50579, 50580, 50581, 50582, 50583, 50584, 50585);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Flawed-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Flawed-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50117, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50118, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50119, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50120, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50121, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50122, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50123, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50124, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50125, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50126, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50127, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50128, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50129, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50130, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50131, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50132, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50133, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50134, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50135, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50136, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50137, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50138, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50139, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50140, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50141, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50142, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50143, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50144, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50570, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50571, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50572, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50573, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50574, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50575, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50576, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50577, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50578, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50579, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50580, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50581, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50582, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50583, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50584, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50585, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Flawed-Defiant', loottable_id=@loottable_id, enabled=0, min_level=44, max_level=55;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50145, 50146, 50147, 50148, 50149, 50150, 50151, 50152, 50153, 50154, 50155, 50156, 50157, 50158, 50159, 50160, 50161, 50162, 50163, 50164, 50165, 50166, 50167, 50168, 50169, 50170, 50171, 50172, 50173, 50174, 50175, 50176, 50177, 50178, 50586, 50587, 50588, 50589, 50590, 50591, 50592, 50593, 50594, 50595, 50596, 50597, 50598, 50599, 50600, 50601);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Intricate-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Intricate-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50145, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50146, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50147, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50148, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50149, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50150, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50151, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50152, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50153, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50154, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50155, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50156, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50157, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50158, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50159, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50160, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50161, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50162, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50163, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50164, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50165, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50166, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50167, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50168, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50169, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50170, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50171, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50172, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50173, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50174, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50175, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50176, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50177, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50178, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50586, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50587, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50588, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50589, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50590, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50591, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50592, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50593, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50594, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50595, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50596, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50597, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50598, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50599, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50600, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50601, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Intricate-Defiant', loottable_id=@loottable_id, enabled=0, min_level=54, max_level=65;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50179, 50180, 50181, 50182, 50183, 50184, 50185, 50186, 50187, 50188, 50189, 50190, 50191, 50192, 50193, 50194, 50195, 50196, 50197, 50198, 50199, 50200, 50201, 50202, 50203, 50204, 50205, 50206, 50207, 50208, 50209, 50210, 50211, 50212, 50602, 50603, 50604, 50605, 50606, 50607, 50608, 50609, 50610, 50611, 50612, 50613, 50614, 50615, 50616);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Elaborate-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Elaborate-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50179, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50180, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50181, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50182, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50183, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50184, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50185, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50186, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50187, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50188, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50189, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50190, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50191, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50192, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50193, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50194, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50195, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50196, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50197, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50198, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50199, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50200, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50201, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50202, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50203, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50204, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50205, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50206, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50207, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50208, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50209, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50210, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50211, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50212, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50602, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50603, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50604, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50605, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50606, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50607, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50608, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50609, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50610, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50611, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50612, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50613, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50614, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50615, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50616, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Elaborate-Defiant', loottable_id=@loottable_id, enabled=0, min_level=64, max_level=75;
|
||||
|
||||
DELETE FROM lootdrop_entries WHERE item_id IN (50213, 50214, 50215, 50216, 50217, 50218, 50219, 50220, 50221, 50222, 50223, 50224, 50225, 50226, 50227, 50228, 50229, 50230, 50231, 50232, 50233, 50234, 50235, 50236, 50237, 50238, 50239, 50240, 50241, 50242, 50243, 50244, 50245, 50246, 50617, 50618, 50619, 50620, 50621, 50622, 50623, 50624, 50625, 50626, 50627, 50628, 50629, 50630, 50631);
|
||||
|
||||
SELECT @loottable_id := MAX(id) + 1 FROM loottable;
|
||||
INSERT INTO loottable SET id=@loottable_id, name="GLB-Elegant-Defiant", mincash="0", maxcash="0", avgcoin="0";
|
||||
SELECT @lootdrop_id := MAX(id) + 1 FROM lootdrop;
|
||||
INSERT INTO lootdrop SET id=@lootdrop_id, name="GLB-Elegant-Defiant-Drop";
|
||||
INSERT INTO loottable_entries SET loottable_id=@loottable_id, lootdrop_id=@lootdrop_id, droplimit='0', mindrop='1', multiplier='1', probability='2';
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50213, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50214, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50215, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50216, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50217, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50218, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50219, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50220, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50221, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50222, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50223, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50224, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50225, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50226, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50227, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50228, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50229, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50230, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50231, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50232, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50233, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50234, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50235, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50236, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50237, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50238, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50239, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50240, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50241, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50242, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50243, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50244, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50245, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50246, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50617, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50618, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50619, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50620, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50621, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50622, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50623, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50624, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50625, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50626, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50627, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50628, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50629, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50630, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
INSERT INTO lootdrop_entries SET lootdrop_id=@lootdrop_id, item_id=50631, equip_item=1, item_charges=1, multiplier=1, chance=1;
|
||||
|
||||
INSERT INTO global_loot SET description='GLB-Elegant-Defiant', loottable_id=@loottable_id, enabled=0, min_level=74, max_level=86;
|
||||
4
utils/sql/git/required/2017_10_28_traps.sql
Normal file
4
utils/sql/git/required/2017_10_28_traps.sql
Normal file
@ -0,0 +1,4 @@
|
||||
alter table `traps` add column `triggered_number` tinyint(4) not null default 0;
|
||||
alter table `traps` add column `group` tinyint(4) not null default 0;
|
||||
alter table `traps` add column `despawn_when_triggered` tinyint(4) not null default 0;
|
||||
alter table `traps` add column `undetectable` tinyint(4) not null default 0;
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `ground_spawns` MODIFY `respawn_timer` int(11) unsigned NOT NULL default 300;
|
||||
UPDATE `ground_spawns` SET `respawn_timer` = `respawn_timer` / 1000;
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `npc_spells_entries` ADD `min_hp` SMALLINT(5) DEFAULT '0';
|
||||
ALTER TABLE `npc_spells_entries` ADD `max_hp` SMALLINT(5) DEFAULT '0';
|
||||
7
utils/sql/git/required/2018_02_04_Charm_Stats.sql
Normal file
7
utils/sql/git/required/2018_02_04_Charm_Stats.sql
Normal file
@ -0,0 +1,7 @@
|
||||
ALTER TABLE `npc_types` ADD `charm_ac` SMALLINT(5) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_min_dmg` INT(10) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_max_dmg` INT(10) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_attack_delay` TINYINT(3) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_accuracy_rating` MEDIUMINT(9) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_avoidance_rating` MEDIUMINT(9) DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `charm_atk` MEDIUMINT(9) DEFAULT '0';
|
||||
19
utils/sql/git/required/2018_02_10_GlobalLoot.sql
Normal file
19
utils/sql/git/required/2018_02_10_GlobalLoot.sql
Normal file
@ -0,0 +1,19 @@
|
||||
ALTER TABLE `npc_types` ADD `skip_global_loot` TINYINT DEFAULT '0';
|
||||
ALTER TABLE `npc_types` ADD `rare_spawn` TINYINT DEFAULT '0';
|
||||
|
||||
CREATE TABLE global_loot (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
description varchar(255),
|
||||
loottable_id INT NOT NULL,
|
||||
enabled TINYINT NOT NULL DEFAULT 1,
|
||||
min_level INT NOT NULL DEFAULT 0,
|
||||
max_level INT NOT NULL DEFAULT 0,
|
||||
rare TINYINT NULL,
|
||||
raid TINYINT NULL,
|
||||
race MEDIUMTEXT NULL,
|
||||
class MEDIUMTEXT NULL,
|
||||
bodytype MEDIUMTEXT NULL,
|
||||
zone MEDIUMTEXT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
3
utils/sql/git/required/2018_02_13_Heading.sql
Normal file
3
utils/sql/git/required/2018_02_13_Heading.sql
Normal file
@ -0,0 +1,3 @@
|
||||
UPDATE spawn2 SET heading = heading * 8.0 / 4.0;
|
||||
UPDATE grid_entries SET heading = heading * 8.0 / 4.0 WHERE heading <> -1;
|
||||
INSERT INTO variables (varname, value, information) VALUES ('fixed_heading', 1, 'manifest heading fix hack'); -- hack
|
||||
44
utils/sql/git/required/2018_02_18_bug_reports.sql
Normal file
44
utils/sql/git/required/2018_02_18_bug_reports.sql
Normal file
@ -0,0 +1,44 @@
|
||||
CREATE TABLE `bug_reports` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`zone` VARCHAR(32) NOT NULL DEFAULT 'Unknown',
|
||||
`client_version_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`client_version_name` VARCHAR(24) NOT NULL DEFAULT 'Unknown',
|
||||
`account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`character_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`character_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||
`reporter_spoof` TINYINT(1) NOT NULL DEFAULT '1',
|
||||
`category_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`category_name` VARCHAR(64) NOT NULL DEFAULT 'Other',
|
||||
`reporter_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||
`ui_path` VARCHAR(128) NOT NULL DEFAULT 'Unknown',
|
||||
`pos_x` FLOAT NOT NULL DEFAULT '0',
|
||||
`pos_y` FLOAT NOT NULL DEFAULT '0',
|
||||
`pos_z` FLOAT NOT NULL DEFAULT '0',
|
||||
`heading` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`time_played` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`target_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`target_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||
`optional_info_mask` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`_can_duplicate` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`_crash_bug` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`_target_info` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`_character_flags` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`_unknown_value` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`bug_report` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||
`system_info` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||
`report_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`bug_status` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`last_review` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`last_reviewer` VARCHAR(64) NOT NULL DEFAULT 'None',
|
||||
`reviewer_notes` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `id` (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB
|
||||
;
|
||||
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES
|
||||
(1, 'Bugs:ReportingSystemActive', 'true', 'Activates bug reporting'),
|
||||
(1, 'Bugs:UseOldReportingMethod', 'true', 'Forces the use of the old bug reporting system'),
|
||||
(1, 'Bugs:DumpTargetEntity', 'false', 'Dumps the target entity, if one is provided');
|
||||
1
utils/sql/git/required/2018_03_07_ucs_command.sql
Normal file
1
utils/sql/git/required/2018_03_07_ucs_command.sql
Normal file
@ -0,0 +1 @@
|
||||
INSERT INTO `command_settings` VALUES ('ucs', '0', '');
|
||||
@ -17,7 +17,6 @@ character_bind
|
||||
character_corpses
|
||||
character_corpse_items
|
||||
character_languages
|
||||
character_lookup
|
||||
character_skills
|
||||
character_spells
|
||||
character_memmed_spells
|
||||
@ -89,4 +88,4 @@ spell_globals
|
||||
timers
|
||||
trader
|
||||
trader_audit
|
||||
zone_flags
|
||||
zone_flags
|
||||
|
||||
2
utils/xmltojson/.gitignore
vendored
Normal file
2
utils/xmltojson/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
eqemu_config.xml
|
||||
eqemu_config.json
|
||||
1
utils/xmltojson/README.md
Normal file
1
utils/xmltojson/README.md
Normal file
@ -0,0 +1 @@
|
||||
Converts the old eqemu_config.xml to eqemu_config.json
|
||||
21
utils/xmltojson/build.bat
Normal file
21
utils/xmltojson/build.bat
Normal file
@ -0,0 +1,21 @@
|
||||
@echo off
|
||||
setlocal
|
||||
set name="xmltojson"
|
||||
|
||||
echo Building Linux
|
||||
set GOOS=linux
|
||||
set GOARCH=amd64
|
||||
go build -o %name%-linux-x64 main.go
|
||||
set GOARCH=386
|
||||
go build -o %name%-linux-x86 main.go
|
||||
echo Building Windows
|
||||
set GOOS=windows
|
||||
set GOARCH=amd64
|
||||
go build -o %name%-windows-x64.exe main.go
|
||||
set GOARCH=386
|
||||
go build -o %name%-windows-x86.exe main.go
|
||||
echo Building OSX
|
||||
REM set GOOS=darwin
|
||||
REM set GOARCH=amd64
|
||||
REM go build -o %name%-osx-x64 main.go
|
||||
endlocal
|
||||
11
utils/xmltojson/build.sh
Normal file
11
utils/xmltojson/build.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
export NAME="xmltojson"
|
||||
echo Building Linux
|
||||
GOOS=linux GOARCH=amd64 go build -o $NAME-linux-x64 main.go
|
||||
GOOS=linux GOARCH=386 go build -o $NAME-linux-x86 main.go
|
||||
echo Building Windows
|
||||
GOOS=windows GOARCH=amd64 go build -o $NAME-windows-x64.exe main.go
|
||||
GOOS=windows GOARCH=386 go build -o $NAME-windows-x86.exe main.go
|
||||
#echo Building OSX
|
||||
#GOOS=darwin GOARCH=amd64 go build -o $NAME-osx-x64 main.go
|
||||
85
utils/xmltojson/main.go
Normal file
85
utils/xmltojson/main.go
Normal file
@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
xj "github.com/basgys/goxml2json"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
var data []byte
|
||||
var sData string
|
||||
buf := &bytes.Buffer{}
|
||||
var buf2 bytes.Buffer
|
||||
|
||||
if data, err = ioutil.ReadFile("eqemu_config.xml"); err != nil {
|
||||
fmt.Println("Failed to open eqemu_config.xml:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//detect malformed xml in eqemuconfig
|
||||
sData = strings.Replace(string(data), "<?xml version=\"1.0\">", "<?xml version=\"1.0\"?>", 1)
|
||||
r := strings.NewReader(sData)
|
||||
dec := xj.NewDecoder(r)
|
||||
root := &xj.Node{}
|
||||
if err = dec.DecodeWithCustomPrefixes(root, "", ""); err != nil {
|
||||
fmt.Println("Failed to decode eqemu_config.xml:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if root.Children["server"] == nil || len(root.Children["server"]) < 1 {
|
||||
fmt.Println("Server element not found")
|
||||
os.Exit(1)
|
||||
}
|
||||
server := root.Children["server"][0]
|
||||
|
||||
//locked: "true" is only way to trigger locked
|
||||
if server.Children["world"] != nil && len(server.Children["world"]) > 0 {
|
||||
world := server.Children["world"][0]
|
||||
|
||||
if world.Children["locked"] != nil && len(world.Children["locked"]) > 0 {
|
||||
fmt.Println("Locked!")
|
||||
world.Children["locked"][0].Data = "true"
|
||||
}
|
||||
}
|
||||
|
||||
elements := []string{
|
||||
"chatserver",
|
||||
"directories",
|
||||
"files",
|
||||
"launcher",
|
||||
"mailserver",
|
||||
"webinterface",
|
||||
"world",
|
||||
"zones",
|
||||
}
|
||||
for _, ele := range elements {
|
||||
if server.Children[ele] != nil && len(server.Children[ele]) > 0 && len(server.Children[ele][0].Children) == 0 {
|
||||
delete(server.Children, ele)
|
||||
}
|
||||
}
|
||||
|
||||
enc := xj.NewEncoder(buf)
|
||||
err = enc.EncodeWithCustomPrefixes(root, "", "")
|
||||
if err != nil {
|
||||
fmt.Println("Failed to encode eqemu_config.xml:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//prettyprint
|
||||
if err = json.Indent(&buf2, buf.Bytes(), "", "\t"); err != nil {
|
||||
fmt.Println("Failed to encode json:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile("eqemu_config.json", buf2.Bytes(), 0744); err != nil {
|
||||
fmt.Println("Failed to write eqemu_config.json:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
BIN
utils/xmltojson/xmltojson-linux-x64
Normal file
BIN
utils/xmltojson/xmltojson-linux-x64
Normal file
Binary file not shown.
BIN
utils/xmltojson/xmltojson-linux-x86
Normal file
BIN
utils/xmltojson/xmltojson-linux-x86
Normal file
Binary file not shown.
BIN
utils/xmltojson/xmltojson-windows-x64
Normal file
BIN
utils/xmltojson/xmltojson-windows-x64
Normal file
Binary file not shown.
BIN
utils/xmltojson/xmltojson-windows-x64.exe
Normal file
BIN
utils/xmltojson/xmltojson-windows-x64.exe
Normal file
Binary file not shown.
BIN
utils/xmltojson/xmltojson-windows-x86
Normal file
BIN
utils/xmltojson/xmltojson-windows-x86
Normal file
Binary file not shown.
BIN
utils/xmltojson/xmltojson-windows-x86.exe
Normal file
BIN
utils/xmltojson/xmltojson-windows-x86.exe
Normal file
Binary file not shown.
@ -380,7 +380,7 @@ void Adventure::MoveCorpsesToGraveyard()
|
||||
std::list<uint32> dbid_list;
|
||||
std::list<uint32> charid_list;
|
||||
|
||||
std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instanceid=%d", GetInstanceID());
|
||||
std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instance_id=%d", GetInstanceID());
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success())
|
||||
|
||||
@ -395,8 +395,8 @@ void Adventure::MoveCorpsesToGraveyard()
|
||||
float z = GetTemplate()->graveyard_z;
|
||||
|
||||
query = StringFormat("UPDATE character_corpses "
|
||||
"SET zoneid = %d, instanceid = 0, "
|
||||
"x = %f, y = %f, z = %f WHERE instanceid = %d",
|
||||
"SET zone_id = %d, instance_id = 0, "
|
||||
"x = %f, y = %f, z = %f WHERE instance_id = %d",
|
||||
GetTemplate()->graveyard_zone_id,
|
||||
x, y, z, GetInstanceID());
|
||||
database.QueryDatabase(query);
|
||||
|
||||
104
world/client.cpp
104
world/client.cpp
@ -84,6 +84,7 @@ extern ClientList client_list;
|
||||
extern EQEmu::Random emu_random;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
extern volatile bool UCSServerAvailable_;
|
||||
|
||||
Client::Client(EQStreamInterface* ieqs)
|
||||
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
|
||||
@ -890,53 +891,84 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
|
||||
// set mailkey - used for duration of character session
|
||||
int MailKey = emu_random.Int(1, INT_MAX);
|
||||
|
||||
database.SetMailKey(charid, GetIP(), MailKey);
|
||||
if (UCSServerAvailable_) {
|
||||
const WorldConfig *Config = WorldConfig::get();
|
||||
std::string buffer;
|
||||
|
||||
char ConnectionType;
|
||||
EQEmu::versions::UCSVersion ConnectionType = EQEmu::versions::ucsUnknown;
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
ConnectionType = 'U';
|
||||
else if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater)
|
||||
ConnectionType = 'S';
|
||||
else
|
||||
ConnectionType = 'C';
|
||||
// chat server packet
|
||||
switch (GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
ConnectionType = EQEmu::versions::ucsTitaniumChat;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoF:
|
||||
ConnectionType = EQEmu::versions::ucsSoFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::SoD:
|
||||
ConnectionType = EQEmu::versions::ucsSoDCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::UF:
|
||||
ConnectionType = EQEmu::versions::ucsUFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF:
|
||||
ConnectionType = EQEmu::versions::ucsRoFCombined;
|
||||
break;
|
||||
case EQEmu::versions::ClientVersion::RoF2:
|
||||
ConnectionType = EQEmu::versions::ucsRoF2Combined;
|
||||
break;
|
||||
default:
|
||||
ConnectionType = EQEmu::versions::ucsUnknown;
|
||||
break;
|
||||
}
|
||||
|
||||
auto outapp2 = new EQApplicationPacket(OP_SetChatServer);
|
||||
char buffer[112];
|
||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->ChatPort,
|
||||
Config->ShortName.c_str(),
|
||||
GetCharName(),
|
||||
ConnectionType,
|
||||
MailKey
|
||||
);
|
||||
|
||||
const WorldConfig *Config = WorldConfig::get();
|
||||
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||
outapp->pBuffer[buffer.length()] = '\0';
|
||||
|
||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->ChatPort,
|
||||
Config->ShortName.c_str(),
|
||||
this->GetCharName(), ConnectionType, MailKey
|
||||
);
|
||||
outapp2->size=strlen(buffer)+1;
|
||||
outapp2->pBuffer = new uchar[outapp2->size];
|
||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
outapp2 = new EQApplicationPacket(OP_SetChatServer2);
|
||||
// mail server packet
|
||||
switch (GetClientVersion()) {
|
||||
case EQEmu::versions::ClientVersion::Titanium:
|
||||
ConnectionType = EQEmu::versions::ucsTitaniumMail;
|
||||
break;
|
||||
default:
|
||||
// retain value from previous switch
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
||||
ConnectionType = 'M';
|
||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||
Config->MailHost.c_str(),
|
||||
Config->MailPort,
|
||||
Config->ShortName.c_str(),
|
||||
GetCharName(),
|
||||
ConnectionType,
|
||||
MailKey
|
||||
);
|
||||
|
||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
||||
Config->MailHost.c_str(),
|
||||
Config->MailPort,
|
||||
Config->ShortName.c_str(),
|
||||
this->GetCharName(), ConnectionType, MailKey
|
||||
);
|
||||
outapp2->size=strlen(buffer)+1;
|
||||
outapp2->pBuffer = new uchar[outapp2->size];
|
||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||
outapp->pBuffer[buffer.length()] = '\0';
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
EnterWorld();
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ public:
|
||||
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
||||
inline uint32 GetCharID() { return charid; }
|
||||
inline const char* GetCharName() { return char_name; }
|
||||
inline EQEmu::versions::ClientVersion GetClientVersion() { return m_ClientVersion; }
|
||||
inline ClientListEntry* GetCLE() { return cle; }
|
||||
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
||||
private:
|
||||
|
||||
@ -104,6 +104,7 @@ EQEmuLogSys LogSys;
|
||||
WebInterfaceList web_interface;
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
void CheckForServerScript(bool force_download = false);
|
||||
|
||||
inline void UpdateWindowTitle(std::string new_title) {
|
||||
#ifdef _WINDOWS
|
||||
@ -116,6 +117,17 @@ int main(int argc, char** argv) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
/* If eqemu_config.json does not exist - create it from conversion... */
|
||||
if (!std::ifstream("eqemu_config.json")) {
|
||||
CheckForServerScript(true);
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
system("perl eqemu_server.pl convert_xml");
|
||||
}
|
||||
else {
|
||||
/* Download EQEmu Server Maintenance Script if doesn't exist */
|
||||
CheckForServerScript();
|
||||
}
|
||||
|
||||
/* Database Version Check */
|
||||
uint32 Database_Version = CURRENT_BINARY_DATABASE_VERSION;
|
||||
uint32 Bots_Database_Version = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
||||
@ -173,7 +185,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
Log(Logs::General, Logs::World_Server, "Connecting to MySQL...");
|
||||
Log(Logs::General, Logs::World_Server, "Connecting to MySQL %s@%s:%i...", Config->DatabaseUsername.c_str(), Config->DatabaseHost.c_str(), Config->DatabasePort);
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
@ -450,6 +462,8 @@ int main(int argc, char** argv) {
|
||||
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
|
||||
|
||||
UCSLink.SetConnection(connection);
|
||||
|
||||
zoneserver_list.UpdateUCSServerAvailable();
|
||||
});
|
||||
|
||||
server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
@ -457,6 +471,8 @@ int main(int argc, char** argv) {
|
||||
connection->GetUUID());
|
||||
|
||||
UCSLink.SetConnection(nullptr);
|
||||
|
||||
zoneserver_list.UpdateUCSServerAvailable(false);
|
||||
});
|
||||
|
||||
server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||
@ -572,4 +588,33 @@ int main(int argc, char** argv) {
|
||||
void CatchSignal(int sig_num) {
|
||||
Log(Logs::General, Logs::World_Server, "Caught signal %d", sig_num);
|
||||
RunLoops = false;
|
||||
}
|
||||
|
||||
void UpdateWindowTitle(char* iNewTitle) {
|
||||
#ifdef _WINDOWS
|
||||
char tmp[500];
|
||||
if (iNewTitle) {
|
||||
snprintf(tmp, sizeof(tmp), "World: %s", iNewTitle);
|
||||
}
|
||||
else {
|
||||
snprintf(tmp, sizeof(tmp), "World");
|
||||
}
|
||||
SetConsoleTitle(tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CheckForServerScript(bool force_download) {
|
||||
/* Fetch EQEmu Server script */
|
||||
if (!std::ifstream("eqemu_server.pl") || force_download) {
|
||||
|
||||
if(force_download)
|
||||
std::remove("eqemu_server.pl"); /* Delete local before fetch */
|
||||
|
||||
std::cout << "Pulling down EQEmu Server Maintenance Script (eqemu_server.pl)..." << std::endl;
|
||||
#ifdef _WIN32
|
||||
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
|
||||
#else
|
||||
system("wget -N --no-check-certificate --quiet -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -52,7 +52,7 @@ public:
|
||||
_world_config=new WorldConfig;
|
||||
_config=_world_config;
|
||||
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(),"server");
|
||||
return _config->parseFile();
|
||||
}
|
||||
|
||||
// Accessors for the static private object
|
||||
|
||||
@ -516,23 +516,6 @@ void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
|
||||
|
||||
}
|
||||
|
||||
void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
||||
{
|
||||
char MailKeyString[17];
|
||||
|
||||
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
||||
else
|
||||
sprintf(MailKeyString, "%08X", MailKey);
|
||||
|
||||
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
MailKeyString, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
Log(Logs::General, Logs::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
||||
{
|
||||
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
|
||||
|
||||
@ -34,7 +34,6 @@ public:
|
||||
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
|
||||
|
||||
void GetLauncherList(std::vector<std::string> &result);
|
||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||
bool GetCharacterLevel(const char *name, int &level);
|
||||
|
||||
bool LoadCharacterCreateAllocations();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user