mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
Merge git://github.com/EQEmu/Server into Development
This commit is contained in:
commit
1e13d43b71
@ -1,5 +1,69 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 11/18/2014 ==
|
||||||
|
Trevius: Mercenaries can now zone once again.
|
||||||
|
|
||||||
|
== 11/17/2014 ==
|
||||||
|
demonstar55: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though.
|
||||||
|
|
||||||
|
== 11/16/2014 ==
|
||||||
|
demonstar55: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat
|
||||||
|
|
||||||
|
Akkadius: Implemented Automatic Database update and versioning system
|
||||||
|
Akkadius: Created database revision define, this is located in version.h in common #define CURRENT_BINARY_DATABASE_VERSION 9057
|
||||||
|
- This revision define will need to be incremented each time a database update is made
|
||||||
|
- Along with a revision define increment, you will need to update the db_update manifest located in:
|
||||||
|
- https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||||
|
- An entry needs to be made at the bottom of the manifest, the entry is quite simple
|
||||||
|
- Example: 9057|2014_11_13_spells_new_updates.sql|SHOW COLUMNS FROM `spells_new` LIKE 'disallow_sit'|empty|
|
||||||
|
- This latest example is checking to see if the spells_new table contains the column 'disallow_sit', if its empty, the update needs to be ran
|
||||||
|
- More examples of match types below:
|
||||||
|
# Example: Version|Filename.sql|Query_to_Check_Condition_For_Needed_Update|match type|text to match
|
||||||
|
# 0 = Database Version
|
||||||
|
# 1 = Filename.sql
|
||||||
|
# 2 = Query_to_Check_Condition_For_Needed_Update
|
||||||
|
# 3 = Match Type - If condition from match type to Value 4 is true, update will flag for needing to be ran
|
||||||
|
# contains = If query results contains text from 4th value
|
||||||
|
# match = If query results matches text from 4th value
|
||||||
|
# missing = If query result is missing text from 4th value
|
||||||
|
# empty = If the query results in no results
|
||||||
|
# not_empty = If the query is not empty
|
||||||
|
# 4 = Text to match
|
||||||
|
- The manifest contains all database updates 'Required' to be made to the schema, and it will contain a working backport all the way back to SVN -
|
||||||
|
currently it is tested and backported through the beginning of our Github repo
|
||||||
|
- On world bootup or standalone run of db_update.pl, users will be prompted with a simple menu that we will expand upon later:
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
EQEmu: Automatic Database Upgrade Check
|
||||||
|
============================================================
|
||||||
|
Operating System is: MSWin32
|
||||||
|
(Windows) MySQL is in system path
|
||||||
|
Path = C:\Program Files\MariaDB 10.0\bin/mysql
|
||||||
|
============================================================
|
||||||
|
Binary Database Version: (9057)
|
||||||
|
Local Database Version: (9057)
|
||||||
|
|
||||||
|
Database up to Date: Continuing World Bootup...
|
||||||
|
============================================================
|
||||||
|
Retrieving latest database manifest...
|
||||||
|
URL: https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||||
|
Saved: db_update/db_update_manifest.txt
|
||||||
|
|
||||||
|
Database Management Menu (Please Select):
|
||||||
|
1) Backup Database - (Saves to Backups folder)
|
||||||
|
Ideal to perform before performing updates
|
||||||
|
2) Backup Database Compressed - (Saves to Backups folder)
|
||||||
|
Ideal to perform before performing updates
|
||||||
|
3) Check for pending Database updates
|
||||||
|
Stages updates for automatic upgrade...
|
||||||
|
0) Exit
|
||||||
|
|
||||||
|
Akkadius: Created db_update.pl, placed in utils/scripts folder, used for the automatic database update routine (Linux/Windows)
|
||||||
|
- db_update.pl script created db_version table if not created, if old one is present it will remove it
|
||||||
|
Akkadius: Created db_dumper.pl, placed in utils/scripts folder, used for the automatic database update routine backups and standalone backups (Linux/Windows)
|
||||||
|
Akkadius: World will now check the db_update.pl script on bootup, if the db_update.pl script is not present, it will fetch it remotely before running -
|
||||||
|
when db_update.pl is done running, world will continue with bootup
|
||||||
|
|
||||||
== 11/15/2014 ==
|
== 11/15/2014 ==
|
||||||
Uleat(Natedog): A better fix for OP_ShopPlayerBuy - doesn't cause the issues that I introduced
|
Uleat(Natedog): A better fix for OP_ShopPlayerBuy - doesn't cause the issues that I introduced
|
||||||
Kayen: Implemented NPC Special Ability 41 'Allow To Tank', gives NPC opportunity to take aggro over a client in melee range.
|
Kayen: Implemented NPC Special Ability 41 'Allow To Tank', gives NPC opportunity to take aggro over a client in melee range.
|
||||||
|
|||||||
@ -2084,6 +2084,19 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Fetch Automatic Database Upgrade Script */
|
||||||
|
if (!std::ifstream("db_update.pl")){
|
||||||
|
std::cout << "Pulling down automatic database upgrade script...\n" << 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/db_update.pl'); if ($response->is_success){ open(FILE, '> db_update.pl'); print FILE $response->decoded_content; close(FILE); }\"");
|
||||||
|
#else
|
||||||
|
system("wget -O db_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* Run Automatic Database Upgrade Script */
|
||||||
|
|
||||||
|
system("perl db_update.pl ran_from_world");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4383,14 +4383,14 @@ typedef struct {
|
|||||||
struct ControlBoat_Struct {
|
struct ControlBoat_Struct {
|
||||||
/*000*/ uint32 boatId; // entitylist id of the boat
|
/*000*/ uint32 boatId; // entitylist id of the boat
|
||||||
/*004*/ bool TakeControl; // 01 if taking control, 00 if releasing it
|
/*004*/ bool TakeControl; // 01 if taking control, 00 if releasing it
|
||||||
/*007*/ // no idea what these last three bytes represent
|
/*007*/ char unknown[3]; // no idea what these last three bytes represent
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AugmentInfo_Struct
|
struct AugmentInfo_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 itemid; // id of the solvent needed
|
/*000*/ uint32 itemid; // id of the solvent needed
|
||||||
/*004*/ uint8 window; // window to display the information in
|
/*004*/ uint32 window; // window to display the information in
|
||||||
/*005*/ uint8 unknown005[67]; // total packet length 72, all the rest were always 00
|
/*008*/ char augment_info[64]; // the reply has the text here
|
||||||
/*072*/
|
/*072*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -235,6 +235,18 @@ namespace RoF
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_AugmentInfo)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(AugmentInfo_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(AugmentInfo_Struct, structs::AugmentInfo_Struct);
|
||||||
|
|
||||||
|
OUT(itemid);
|
||||||
|
OUT(window);
|
||||||
|
strn0cpy(eq->augment_info, emu->augment_info, 64);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Barter)
|
ENCODE(OP_Barter)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ E(OP_AltCurrency)
|
|||||||
E(OP_AltCurrencySell)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_Animation)
|
E(OP_Animation)
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_AugmentInfo)
|
||||||
E(OP_Barter)
|
E(OP_Barter)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
E(OP_BeginCast)
|
E(OP_BeginCast)
|
||||||
|
|||||||
@ -4692,9 +4692,9 @@ struct ItemQuaternaryBodyStruct
|
|||||||
struct AugmentInfo_Struct
|
struct AugmentInfo_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 itemid; // id of the solvent needed
|
/*000*/ uint32 itemid; // id of the solvent needed
|
||||||
/*004*/ uint8 window; // window to display the information in
|
/*004*/ uint32 window; // window to display the information in
|
||||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
/*008*/ char augment_info[64]; // total packet length 76, all the rest were always 00
|
||||||
/*076*/
|
/*072*/ uint32 unknown072;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VeteranRewardItem
|
struct VeteranRewardItem
|
||||||
|
|||||||
@ -174,6 +174,18 @@ namespace SoD
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_AugmentInfo)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(AugmentInfo_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(AugmentInfo_Struct, structs::AugmentInfo_Struct);
|
||||||
|
|
||||||
|
OUT(itemid);
|
||||||
|
OUT(window);
|
||||||
|
strn0cpy(eq->augment_info, emu->augment_info, 64);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Barter)
|
ENCODE(OP_Barter)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ E(OP_Action)
|
|||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_AugmentInfo)
|
||||||
E(OP_Barter)
|
E(OP_Barter)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
E(OP_Buff)
|
E(OP_Buff)
|
||||||
|
|||||||
@ -4173,9 +4173,9 @@ struct ItemQuaternaryBodyStruct
|
|||||||
struct AugmentInfo_Struct
|
struct AugmentInfo_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 itemid; // id of the solvent needed
|
/*000*/ uint32 itemid; // id of the solvent needed
|
||||||
/*004*/ uint8 window; // window to display the information in
|
/*004*/ uint32 window; // window to display the information in
|
||||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
/*008*/ char augment_info[64]; // total packet length 76, all the rest were always 00
|
||||||
/*076*/
|
/*072*/ uint32 unknown072;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VeteranRewardItem
|
struct VeteranRewardItem
|
||||||
|
|||||||
@ -174,6 +174,18 @@ namespace SoF
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_AugmentInfo)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(AugmentInfo_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(AugmentInfo_Struct, structs::AugmentInfo_Struct);
|
||||||
|
|
||||||
|
OUT(itemid);
|
||||||
|
OUT(window);
|
||||||
|
strn0cpy(eq->augment_info, emu->augment_info, 64);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_BazaarSearch)
|
ENCODE(OP_BazaarSearch)
|
||||||
{
|
{
|
||||||
if (((*p)->size == sizeof(BazaarReturnDone_Struct)) || ((*p)->size == sizeof(BazaarWelcome_Struct))) {
|
if (((*p)->size == sizeof(BazaarReturnDone_Struct)) || ((*p)->size == sizeof(BazaarWelcome_Struct))) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ E(OP_Action)
|
|||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_AugmentInfo)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
E(OP_BecomeTrader)
|
E(OP_BecomeTrader)
|
||||||
E(OP_Buff)
|
E(OP_Buff)
|
||||||
|
|||||||
@ -4027,9 +4027,9 @@ struct ItemQuaternaryBodyStruct
|
|||||||
struct AugmentInfo_Struct
|
struct AugmentInfo_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 itemid; // id of the solvent needed
|
/*000*/ uint32 itemid; // id of the solvent needed
|
||||||
/*004*/ uint8 window; // window to display the information in
|
/*004*/ uint32 window; // window to display the information in
|
||||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
/*008*/ char augment_info[64]; // total packet length 76, all the rest were always 00
|
||||||
/*076*/
|
/*072*/ uint32 unknown072;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VeteranRewardItem
|
struct VeteranRewardItem
|
||||||
|
|||||||
@ -226,6 +226,18 @@ namespace Underfoot
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_AugmentInfo)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(AugmentInfo_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(AugmentInfo_Struct, structs::AugmentInfo_Struct);
|
||||||
|
|
||||||
|
OUT(itemid);
|
||||||
|
OUT(window);
|
||||||
|
strn0cpy(eq->augment_info, emu->augment_info, 64);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Barter)
|
ENCODE(OP_Barter)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ E(OP_AdventureMerchantSell)
|
|||||||
E(OP_AltCurrency)
|
E(OP_AltCurrency)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_AugmentInfo)
|
||||||
E(OP_Barter)
|
E(OP_Barter)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
E(OP_Buff)
|
E(OP_Buff)
|
||||||
|
|||||||
@ -4272,9 +4272,9 @@ struct ItemQuaternaryBodyStruct
|
|||||||
struct AugmentInfo_Struct
|
struct AugmentInfo_Struct
|
||||||
{
|
{
|
||||||
/*000*/ uint32 itemid; // id of the solvent needed
|
/*000*/ uint32 itemid; // id of the solvent needed
|
||||||
/*004*/ uint8 window; // window to display the information in
|
/*004*/ uint32 window; // window to display the information in
|
||||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
/*008*/ char augment_info[64]; // total packet length 76, all the rest were always 00
|
||||||
/*076*/
|
/*072*/ uint32 unknown072;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VeteranRewardItem
|
struct VeteranRewardItem
|
||||||
|
|||||||
@ -23,6 +23,14 @@
|
|||||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
||||||
|
|
||||||
#define CURRENT_VERSION "1.0.0"
|
#define CURRENT_VERSION "1.0.0"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Everytime a Database SQL is added to Github,
|
||||||
|
increment CURRENT_BINARY_DATABASE_VERSION number and make sure you update the manifest
|
||||||
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CURRENT_BINARY_DATABASE_VERSION 9057
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|||||||
214
utils/scripts/db_dumper.pl
Normal file
214
utils/scripts/db_dumper.pl
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
#!/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\n";
|
||||||
|
print "#::: Help :::#\n";
|
||||||
|
print "######################################################\n\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 ' Example: perl DB_Dumper.pl Loc="E:\Backups"' . "\n\n";
|
||||||
|
print "######################################################\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: CONFIG VARIABLES - Parsed from eqemu_config.xml
|
||||||
|
|
||||||
|
my $confile = "eqemu_config.xml"; #default
|
||||||
|
open(F, "<$confile") or die "Unable to open config: $confile - This must be in your EQEmu Server Folder with your XML config\n";
|
||||||
|
my $indb = 0;
|
||||||
|
|
||||||
|
while(<F>) {
|
||||||
|
s/\r//g;
|
||||||
|
if(/<database>/i) { $indb = 1; }
|
||||||
|
next unless($indb == 1);
|
||||||
|
if(/<\/database>/i) { $indb = 0; last; }
|
||||||
|
if(/<host>(.*)<\/host>/i) { $host = $1; }
|
||||||
|
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
|
||||||
|
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
|
||||||
|
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
$Debug = 0;
|
||||||
|
print "Arguments\n" if $Debug;
|
||||||
|
$n = 0;
|
||||||
|
while($ARGV[$n]){
|
||||||
|
print $n . ': ' . $ARGV[$n] . "\n" if $Debug;
|
||||||
|
if($ARGV[$n]=~/compress/i){
|
||||||
|
print "Compression SET\n";
|
||||||
|
$Compress = 1;
|
||||||
|
}
|
||||||
|
if($ARGV[$n]=~/database=/i){
|
||||||
|
@DB_NAME = split('=', $ARGV[$n]);
|
||||||
|
print "Database is " . $DB_NAME[1] . "\n";
|
||||||
|
$db = $DB_NAME[1];
|
||||||
|
}
|
||||||
|
if($ARGV[$n]=~/loc=/i){
|
||||||
|
@B_LOC = split('=', $ARGV[$n]);
|
||||||
|
print "Backup Directory: " . $B_LOC[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 "Backing up tables: \n\n############################\n" . $t_tables_p . "############################\n\n";
|
||||||
|
}
|
||||||
|
$n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Check for Backup Directory existence, if doesn't exist then create...
|
||||||
|
if (-d $B_LOC[1]) {
|
||||||
|
print "Directory currently exists... Adding files to it...\n\n";
|
||||||
|
}
|
||||||
|
elsif($B_LOC[1] ne ""){
|
||||||
|
print "Directory does NOT exist! Creating...\n\n";
|
||||||
|
mkdir($B_LOC[1]) or die 'Failed to create folder, maybe created the folder manually at "' . $B_LOC[1]. '" ?';
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "No save location specified... Saving to folder script is running in...\n";
|
||||||
|
}
|
||||||
|
if($B_LOC[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) . '...';
|
||||||
|
$target_file = '' . $tables_f_l . ' ' . $date . '';
|
||||||
|
print "Performing table based backup...\n";
|
||||||
|
#::: Backup Database...
|
||||||
|
print "Backing up Database " . $db . "... \n\n";
|
||||||
|
$cmd = 'mysqldump -u' . $user . ' --max_allowed_packet=512M --password="' . $pass . '" ' . $db . ' ' . $t_tables . ' > "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql"';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
}
|
||||||
|
else{ #::: Entire DB Backup
|
||||||
|
$target_file = '' . $db . ' ' . $date . '';
|
||||||
|
#::: Backup Database...
|
||||||
|
print "Backing up Database " . $db . "... \n\n";
|
||||||
|
$cmd = 'mysqldump -u' . $user . ' --max_allowed_packet=512M --password="' . $pass . '" ' . $db . ' > "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql"';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Get File Size
|
||||||
|
$fileloc = '' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql';
|
||||||
|
$filesize = -s $fileloc;
|
||||||
|
if($filesize < 1000){ print "\n" . 'Error occurred... exiting...' . "\n\n"; exit; }
|
||||||
|
print "Backup DONE... DB Backup File Size '" . $filesize . "' (" . get_filesize_str($fileloc) . ")\n\n";
|
||||||
|
|
||||||
|
#::: WinRar Get, check compression flag
|
||||||
|
if($Compress == 1){
|
||||||
|
if($OS eq "Windows"){
|
||||||
|
if(-d $localdrive . "\\Program Files\\7-Zip"){
|
||||||
|
print " ::: You have 7-Zip installed as 64 Bit...\n\n";
|
||||||
|
$S_ZIP = $localdrive . "\\Program Files\\7-Zip";
|
||||||
|
}
|
||||||
|
elsif(-d $localdrive . "\\Program Files (x86)\\7-Zip"){
|
||||||
|
print " ::: You have 7-Zip installed as 32 Bit...\n\n";
|
||||||
|
$S_ZIP = $localdrive . "\\Program Files (x86)\\7-Zip";
|
||||||
|
}
|
||||||
|
elsif(-d $localdrive . "\\Program Files (x86)\\WinRAR"){
|
||||||
|
print " ::: You have WinRAR installed as 32 Bit...\n\n";
|
||||||
|
$WinRar = $localdrive . "\\Program Files (x86)\\WinRAR";
|
||||||
|
}
|
||||||
|
elsif(-d $localdrive . "\\Program Files\\WinRAR"){
|
||||||
|
print " ::: You have WinRAR installed as 64 Bit...\n\n";
|
||||||
|
$WinRar = $localdrive . "\\Program Files\\WinRAR";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "No WinRAR installed... Will not compress...\n";
|
||||||
|
}
|
||||||
|
if($S_ZIP ne ""){
|
||||||
|
print "Compressing Database with 7-ZIP... \n\n";
|
||||||
|
$cmd = '"' . $S_ZIP . '\\7z" a -t7z -m0=lzma -mx=9 "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.7z" "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
print "\nDeleting RAW .sql Dump... \n\n";
|
||||||
|
$cmd = 'del "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
$final_file = $target_file . ".7z";
|
||||||
|
}
|
||||||
|
elsif($WinRar ne ""){
|
||||||
|
print "Compressing Database with WinRAR... \n";
|
||||||
|
$cmd = '"' . $WinRar . '\\rar" a "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.rar" "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
print "\nDeleting RAW .sql Dump... \n\n";
|
||||||
|
$cmd = 'del "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
$final_file = $target_file . ".rar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
print "Compressing Database with Tarball... \n";
|
||||||
|
$cmd = 'tar -zcvf "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.tar.gz" "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
print "\nDeleting RAW .sql Dump... \n\n";
|
||||||
|
$cmd = 'rm "' . $B_LOC[1] . '' . $file_app . '' . $target_file . '.sql" ';
|
||||||
|
printcmd($cmd);
|
||||||
|
system($cmd);
|
||||||
|
$final_file = $target_file . ".tar.gz";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Get Final File Location for display
|
||||||
|
if($B_LOC[1] ne ""){ $final_loc = $B_LOC[1] . '' . $file_app . ""; }
|
||||||
|
else{
|
||||||
|
if($OS eq "Windows"){
|
||||||
|
$final_loc = `echo %cd%`;
|
||||||
|
}
|
||||||
|
elsif($OS eq "Linux"){
|
||||||
|
$final_loc = `pwd`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Final file located: " . $final_loc . "" . $final_file . "\n\n";
|
||||||
|
|
||||||
|
sub printcmd{
|
||||||
|
print "--- CMD --- \n" . $_[0] . "\n" . $linesep . "\n\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"); }
|
||||||
|
}
|
||||||
383
utils/scripts/db_update.pl
Normal file
383
utils/scripts/db_update.pl
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
#::: Automatic Database Upgrade Script
|
||||||
|
#::: Author: Akkadius
|
||||||
|
#::: Purpose: To upgrade databases with ease and maintain versioning
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
$perl_version = $^V;
|
||||||
|
$perl_version =~s/v//g;
|
||||||
|
print "Perl Version is " . $perl_version . "\n";
|
||||||
|
if($perl_version > 5.12){ no warnings 'uninitialized'; }
|
||||||
|
no warnings;
|
||||||
|
|
||||||
|
my $confile = "eqemu_config.xml"; #default
|
||||||
|
open(F, "<$confile") or die "Unable to open config: $confile\n";
|
||||||
|
my $indb = 0;
|
||||||
|
while(<F>) {
|
||||||
|
s/\r//g;
|
||||||
|
if(/<database>/i) { $indb = 1; }
|
||||||
|
next unless($indb == 1);
|
||||||
|
if(/<\/database>/i) { $indb = 0; last; }
|
||||||
|
if(/<host>(.*)<\/host>/i) { $host = $1; }
|
||||||
|
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
|
||||||
|
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
|
||||||
|
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
print
|
||||||
|
"============================================================
|
||||||
|
EQEmu: Automatic Database Upgrade Check
|
||||||
|
============================================================
|
||||||
|
";
|
||||||
|
|
||||||
|
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($OS eq "Windows"){
|
||||||
|
$has_mysql_path = `echo %PATH%`;
|
||||||
|
if($has_mysql_path=~/MySQL|MariaDB/i){
|
||||||
|
@mysql = split(';', $has_mysql_path);
|
||||||
|
foreach my $v (@mysql){
|
||||||
|
if($v=~/MySQL|MariaDB/i){
|
||||||
|
$path = $v . "/mysql";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print " (Windows) MySQL is in system path \n";
|
||||||
|
print " Path = " . $path . "\n";
|
||||||
|
print "============================================================\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Linux Check
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
$path = `which mysql`;
|
||||||
|
if ($path eq "") {
|
||||||
|
$path = `which mariadb`;
|
||||||
|
}
|
||||||
|
$path =~s/\n//g;
|
||||||
|
|
||||||
|
print " (Linux) MySQL is in system path \n";
|
||||||
|
print " Path = " . $path . "\n";
|
||||||
|
print "============================================================\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Path not found, error and exit
|
||||||
|
if($path eq ""){
|
||||||
|
print "MySQL path not found, please add the path for automatic database upgrading to continue... \n\n";
|
||||||
|
print "Exiting...\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Create db_update working directory if not created
|
||||||
|
mkdir('db_update');
|
||||||
|
|
||||||
|
#::: Check if db_version table exists...
|
||||||
|
if(trim(GetMySQLResult("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne ""){
|
||||||
|
print GetMySQLResult("DROP TABLE db_version");
|
||||||
|
print "Old db_version table present, dropping...\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetMySQLResult("SHOW TABLES LIKE 'db_version'") eq ""){
|
||||||
|
print GetMySQLResult("
|
||||||
|
CREATE TABLE db_version (
|
||||||
|
version int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
INSERT INTO db_version (version) VALUES ('1000');");
|
||||||
|
print "Table 'db_version' does not exists.... Creating...\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); }
|
||||||
|
if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); }
|
||||||
|
|
||||||
|
$bin_db_ver = trim($db_version[1]);
|
||||||
|
$local_db_ver = trim(GetMySQLResult("SELECT version FROM db_version LIMIT 1"));
|
||||||
|
print " Binary Database Version: (" . $bin_db_ver . ")\n";
|
||||||
|
print " Local Database Version: (" . $local_db_ver . ")\n\n";
|
||||||
|
|
||||||
|
#::: If World ran this script, and our version is up to date, continue...
|
||||||
|
if($bin_db_ver == $local_db_ver && $ARGV[0] eq "ran_from_world"){
|
||||||
|
print " Database up to Date: Continuing World Bootup...\n";
|
||||||
|
print "============================================================\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$bin_db_ver){ $bin_db_ver = 9100; }
|
||||||
|
|
||||||
|
print "Retrieving latest database manifest...\n";
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
||||||
|
# GetRemoteFile("https://dl.dropboxusercontent.com/u/50023467/dl/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
||||||
|
|
||||||
|
if($local_db_ver < $bin_db_ver && $ARGV[0] eq "ran_from_world"){
|
||||||
|
print "You have missing database updates, type 1 or 2 to backup your database before running them as recommended...\n\n";
|
||||||
|
#::: Display Menu
|
||||||
|
ShowMenuPrompt();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
#::: Most likely ran standalone
|
||||||
|
print "\n";
|
||||||
|
ShowMenuPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub ShowMenuPrompt {
|
||||||
|
my %dispatch = (
|
||||||
|
1 => \&database_dump,
|
||||||
|
2 => \&database_dump_compress,
|
||||||
|
3 => \&Run_Database_Check,
|
||||||
|
0 => \&Exit,
|
||||||
|
);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
{
|
||||||
|
local $| = 1;
|
||||||
|
if(!$menu_show && $ARGV[0] eq "ran_from_world"){
|
||||||
|
$menu_show++;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
print MenuOptions(), '> ';
|
||||||
|
}
|
||||||
|
|
||||||
|
my $choice = <>;
|
||||||
|
|
||||||
|
$choice =~ s/\A\s+//;
|
||||||
|
$choice =~ s/\s+\z//;
|
||||||
|
|
||||||
|
if (defined(my $handler = $dispatch{$choice})) {
|
||||||
|
my $result = $handler->();
|
||||||
|
unless (defined $result) {
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if($ARGV[0] ne "ran_from_world"){
|
||||||
|
# warn "\n\nInvalid selection\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MenuOptions {
|
||||||
|
if(@total_updates){
|
||||||
|
$option[3] = "Run pending updates... (" . scalar (@total_updates) . ")";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$option[3] = "Check for pending Database updates
|
||||||
|
Stages updates for automatic upgrade...";
|
||||||
|
}
|
||||||
|
|
||||||
|
return <<EO_MENU;
|
||||||
|
Database Management Menu (Please Select):
|
||||||
|
1) Backup Database - (Saves to Backups folder)
|
||||||
|
Ideal to perform before performing updates
|
||||||
|
2) Backup Database Compressed - (Saves to Backups folder)
|
||||||
|
Ideal to perform before performing updates
|
||||||
|
3) $option[3]
|
||||||
|
0) Exit
|
||||||
|
|
||||||
|
EO_MENU
|
||||||
|
}
|
||||||
|
|
||||||
|
sub CheckForDatabaseDumpScript{
|
||||||
|
if(`perl db_dumper.pl`=~/Need arguments/i){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "db_dumper.pl not found... retrieving...\n\n";
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_dumper.pl", "db_dumper.pl");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ran_from_world {
|
||||||
|
print "Running from world...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub database_dump {
|
||||||
|
CheckForDatabaseDumpScript();
|
||||||
|
print "Performing database backup....\n";
|
||||||
|
print `perl db_dumper.pl database="$db" loc="backups"`;
|
||||||
|
}
|
||||||
|
sub database_dump_compress {
|
||||||
|
CheckForDatabaseDumpScript();
|
||||||
|
print "Performing database backup....\n";
|
||||||
|
print `perl db_dumper.pl database="$db" loc="backups" compress`;
|
||||||
|
}
|
||||||
|
sub Exit{ }
|
||||||
|
|
||||||
|
#::: Returns Tab Delimited MySQL Result from Command Line
|
||||||
|
sub GetMySQLResult{
|
||||||
|
my $run_query = $_[0];
|
||||||
|
if($OS eq "Windows"){ return `"$path" --user $user --password="$pass" $db -N -B -e "$run_query"`; }
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
$run_query =~s/`//g;
|
||||||
|
return `$path --user="$user" --password="$pass" $db -N -B -e "$run_query"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub GetMySQLResultFromFile{
|
||||||
|
my $update_file = $_[0];
|
||||||
|
if($OS eq "Windows"){ return `"$path" --user $user --password="$pass" --force $db < $update_file`; }
|
||||||
|
if($OS eq "Linux"){ return `"$path" --user $user --password="$pass" --force $db < $update_file`; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Gets Remote File based on URL (1st Arg), and saves to destination file (2nd Arg)
|
||||||
|
#::: Example: GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
||||||
|
sub GetRemoteFile{
|
||||||
|
my $URL = $_[0];
|
||||||
|
my $Dest_File = $_[1];
|
||||||
|
|
||||||
|
if($OS eq "Windows"){
|
||||||
|
require LWP::UserAgent;
|
||||||
|
my $ua = LWP::UserAgent->new;
|
||||||
|
$ua->timeout(10);
|
||||||
|
$ua->env_proxy;
|
||||||
|
my $response = $ua->get($URL);
|
||||||
|
|
||||||
|
if ($response->is_success){
|
||||||
|
open (FILE, '> ' . $Dest_File . '');
|
||||||
|
print FILE $response->decoded_content;
|
||||||
|
close (FILE);
|
||||||
|
print " URL: " . $URL . "\n";
|
||||||
|
print " Saved: " . $Dest_File . " \n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Error, no connection to the internet...\n\n";
|
||||||
|
die $response->status_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
#::: wget -O db_update/db_update_manifest.txt https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||||
|
$wget = `wget --quiet -O $Dest_File $URL`;
|
||||||
|
print " URL: " . $URL . "\n";
|
||||||
|
print " Saved: " . $Dest_File . " \n";
|
||||||
|
if($wget=~/unable to resolve/i){
|
||||||
|
print "Error, no connection to the internet...\n\n";
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Trim Whitespaces
|
||||||
|
sub trim {
|
||||||
|
my $string = $_[0];
|
||||||
|
$string =~ s/^\s+//;
|
||||||
|
$string =~ s/\s+$//;
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Responsible for Database Upgrade Routines
|
||||||
|
sub Run_Database_Check{
|
||||||
|
#::: Run 2 - Running pending updates...
|
||||||
|
if(defined(@total_updates)){
|
||||||
|
@total_updates = sort @total_updates;
|
||||||
|
foreach my $val (@total_updates){
|
||||||
|
$file_name = trim($m_d{$val}[1]);
|
||||||
|
print "Running Update: " . $val . " - " . $file_name . "\n";
|
||||||
|
print GetMySQLResultFromFile("db_update/$file_name");
|
||||||
|
print GetMySQLResult("UPDATE db_version SET version = $val WHERE version < $val");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Run 1 - Initial checking of needed updates...
|
||||||
|
print "Reading manifest...\n\n";
|
||||||
|
use Data::Dumper;
|
||||||
|
open (FILE, "db_update/db_update_manifest.txt");
|
||||||
|
while (<FILE>) {
|
||||||
|
chomp;
|
||||||
|
$o = $_;
|
||||||
|
if($o=~/#/i){ next; }
|
||||||
|
@manifest = split('\|', $o);
|
||||||
|
$m_d{$manifest[0]} = [@manifest];
|
||||||
|
}
|
||||||
|
|
||||||
|
@total_updates = ();
|
||||||
|
|
||||||
|
#::: Iterate through Manifest backwards from binary version down to local version...
|
||||||
|
for($i = $bin_db_ver; $i > 1000; $i--){
|
||||||
|
if(!defined($m_d{$i}[0])){ next; }
|
||||||
|
|
||||||
|
$file_name = trim($m_d{$i}[1]);
|
||||||
|
$query_check = trim($m_d{$i}[2]);
|
||||||
|
$match_type = trim($m_d{$i}[3]);
|
||||||
|
$match_text = trim($m_d{$i}[4]);
|
||||||
|
|
||||||
|
#::: Match type update
|
||||||
|
if($match_type eq "contains"){
|
||||||
|
if(trim(GetMySQLResult($query_check))=~/$match_text/i){
|
||||||
|
print "Missing DB Update " . $i . " '" . $file_name . "' \n";
|
||||||
|
FetchMissingUpdate($i, $file_name);
|
||||||
|
push(@total_updates, $i);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "DB up to date with: " . $i . " '" . $file_name . "' \n";
|
||||||
|
}
|
||||||
|
print_match_debug();
|
||||||
|
print_break();
|
||||||
|
}
|
||||||
|
if($match_type eq "missing"){
|
||||||
|
if(GetMySQLResult($query_check)=~/$match_text/i){
|
||||||
|
print "DB up to date with: " . $i . " '" . $file_name . "' \n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "Missing DB Update " . $i . " '" . $file_name . "' \n";
|
||||||
|
FetchMissingUpdate($i, $file_name);
|
||||||
|
push(@total_updates, $i);
|
||||||
|
}
|
||||||
|
print_match_debug();
|
||||||
|
print_break();
|
||||||
|
}
|
||||||
|
if($match_type eq "empty"){
|
||||||
|
if(GetMySQLResult($query_check) eq ""){
|
||||||
|
print "Missing DB Update " . $i . " '" . $file_name . "' \n";
|
||||||
|
FetchMissingUpdate($i, $file_name);
|
||||||
|
push(@total_updates, $i);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "DB up to date with: " . $i . " '" . $file_name . "' \n";
|
||||||
|
}
|
||||||
|
print_match_debug();
|
||||||
|
print_break();
|
||||||
|
}
|
||||||
|
if($match_type eq "not_empty"){
|
||||||
|
if(GetMySQLResult($query_check) ne ""){
|
||||||
|
print "Missing DB Update " . $i . " '" . $file_name . "' \n";
|
||||||
|
FetchMissingUpdate($i, $file_name);
|
||||||
|
push(@total_updates, $i);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print "DB up to date with: " . $i . " '" . $file_name . "' \n";
|
||||||
|
}
|
||||||
|
print_match_debug();
|
||||||
|
print_break();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub FetchMissingUpdate{
|
||||||
|
$db_update = $_[0];
|
||||||
|
$update_file = $_[1];
|
||||||
|
if($db_update >= 9000){
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/git/required/" . $update_file, "db_update/" . $update_file . "");
|
||||||
|
}
|
||||||
|
elsif($db_update >= 5000 && $db_update <= 9000){
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/svn/" . $update_file, "db_update/" . $update_file . "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_match_debug{
|
||||||
|
if(!$debug){ return; }
|
||||||
|
print " Match Type: '" . $match_type . "'\n";
|
||||||
|
print " Match Text: '" . $match_text . "'\n";
|
||||||
|
print " Query Check: '" . $query_check . "'\n";
|
||||||
|
print " Result: '" . trim(GetMySQLResult($query_check)) . "'\n";
|
||||||
|
}
|
||||||
|
sub print_break{
|
||||||
|
if(!$debug){ return; }
|
||||||
|
print "\n==============================================\n";
|
||||||
|
}
|
||||||
@ -1,316 +1,332 @@
|
|||||||
5001, 1_task_system.sql
|
5001|1_task_system.sql
|
||||||
5002, 2_optional_maxclients.sql
|
# 5002|2_optional_maxclients.sql
|
||||||
5003, 14_optional_merchantlist.sql
|
# 5003|14_optional_merchantlist.sql
|
||||||
5004, 35_task_stepped.sql
|
5004|35_task_stepped.sql
|
||||||
5005, 42_task_min_maxlevel.sql
|
5005|42_task_min_maxlevel.sql
|
||||||
5006, 55_zone_shutdowndeleay.sql
|
5006|55_zone_shutdowndeleay.sql
|
||||||
5007, 68_optional_character_maxexplevel.sql
|
# 5007|68_optional_character_maxexplevel.sql
|
||||||
5008, 103_optional_chat_rules.sql
|
# 5008|103_optional_chat_rules.sql
|
||||||
5009, 104_traps.sql
|
5009|104_traps.sql
|
||||||
5010, 106_optional_proc_rules.sql
|
# 5010|106_optional_proc_rules.sql
|
||||||
5011, 120_damageshieldtypes.sql
|
5011|120_damageshieldtypes.sql
|
||||||
5012, 125_aggrozone.sql
|
5012|125_aggrozone.sql
|
||||||
5013, 127_optional_spell_rules.sql
|
# 5013|127_optional_spell_rules.sql
|
||||||
5014, 129_optional_shared_plat_rule.sql
|
# 5014|129_optional_shared_plat_rule.sql
|
||||||
5015, 131_optional_combat_rules.sql
|
# 5015|131_optional_combat_rules.sql
|
||||||
5016, 133_task_repeatable.sql
|
5016|133_task_repeatable.sql
|
||||||
5017, 142_deathpeace_and_lifetap_aas.sql
|
5017|142_deathpeace_and_lifetap_aas.sql
|
||||||
5018, 158_optional_death_exp_loss.sql
|
# 5018|158_optional_death_exp_loss.sql
|
||||||
5019, 176_melody.sql
|
5019|176_melody.sql
|
||||||
5020, 189_character_.sql
|
5020|189_character_.sql
|
||||||
5021, 196_trader.sql
|
5021|196_trader.sql
|
||||||
5022, 210_undyeme.sql
|
5022|210_undyeme.sql
|
||||||
5023, 222_buyer.sql
|
5023|222_buyer.sql
|
||||||
5024, 226_account_limiting.sql
|
5024|226_account_limiting.sql
|
||||||
5025, 230_spells_table.sql
|
5025|230_spells_table.sql
|
||||||
5026, 235_horses_table.sql
|
5026|235_horses_table.sql
|
||||||
5027, 243_spawn_timers.sql
|
5027|243_spawn_timers.sql
|
||||||
5028, 247_mail.sql
|
5028|247_mail.sql
|
||||||
5029, 249_chatchannels.sql
|
5029|249_chatchannels.sql
|
||||||
5030, 250_bot_spell_update.sql
|
5030|250_bot_spell_update.sql
|
||||||
5031, 250_optional_bot_spell_update.sql
|
# 5031|250_optional_bot_spell_update.sql
|
||||||
5032, 285_optional_bot_spell_update.sql
|
# 5032|285_optional_bot_spell_update.sql
|
||||||
5033, 292_augslots.sql
|
5033|292_augslots.sql
|
||||||
5034, 294_merchant_logging.sql
|
5034|294_merchant_logging.sql
|
||||||
5035, 304_faction_list.sql
|
5035|304_faction_list.sql
|
||||||
5036, 326_aas.sql
|
5036|326_aas.sql
|
||||||
5037, 328_bot_management.sql
|
5037|328_bot_management.sql
|
||||||
5038, 328_optional_bot_management.sql
|
# 5038|328_optional_bot_management.sql
|
||||||
5039, 340_gm_ips.sql
|
5039|340_gm_ips.sql
|
||||||
5040, 356_combat.sql
|
5040|356_combat.sql
|
||||||
5041, 360_peqzone.sql
|
5041|360_peqzone.sql
|
||||||
5042, 364_ranged_dist_rule.sql
|
5042|364_ranged_dist_rule.sql
|
||||||
5043, 386_bot_save_raid.sql
|
5043|386_bot_save_raid.sql
|
||||||
5044, 434_optional_rest_state_rules.sql
|
# 5044|434_optional_rest_state_rules.sql
|
||||||
5045, 447_sof_startzone_rule.sql
|
5045|447_sof_startzone_rule.sql
|
||||||
5046, 463_altadv_vars.sql
|
5046|463_altadv_vars.sql
|
||||||
5047, 475_aa_actions.sql
|
5047|475_aa_actions.sql
|
||||||
5048, 500_spawn2_optimization.sql
|
5048|500_spawn2_optimization.sql
|
||||||
5049, 503_bugs.sql
|
5049|503_bugs.sql
|
||||||
5050, 518_drakkin_npc_type_features.sql
|
5050|518_drakkin_npc_type_features.sql
|
||||||
5051, 524_rule_values_notes.sql
|
5051|524_rule_values_notes.sql
|
||||||
5052, 527_npc_armor_tint.sql
|
5052|527_npc_armor_tint.sql
|
||||||
5053, 553_saylink_table.sql
|
5053|553_saylink_table.sql
|
||||||
5054, 564_nokeyring.sql
|
5054|564_nokeyring.sql
|
||||||
5055, 600_group_leadership.sql
|
5055|600_group_leadership.sql
|
||||||
5056, 612_instance_changes.sql
|
5056|612_instance_changes.sql
|
||||||
5057, 615_adventure_assassination.sql
|
5057|615_adventure_assassination.sql
|
||||||
5058, 619_Adventure_Recruiter_Flavor.sql
|
5058|619_Adventure_Recruiter_Flavor.sql
|
||||||
5059, 621_LDoNTraps.sql
|
5059|621_LDoNTraps.sql
|
||||||
5060, 633_ucs.sql
|
5060|633_ucs.sql
|
||||||
5061, 634_TrapTemplateDefaultValue.sql
|
5061|634_TrapTemplateDefaultValue.sql
|
||||||
5062, 643_BotsTable.sql
|
5062|643_BotsTable.sql
|
||||||
5063, 646_archery_penalty_rule.sql
|
5063|646_archery_penalty_rule.sql
|
||||||
5064, 665_heroic_resists.sql
|
5064|665_heroic_resists.sql
|
||||||
5065, 667_titles.sql
|
5065|667_titles.sql
|
||||||
5066, 687_aa_table_changes.sql
|
5066|687_aa_table_changes.sql
|
||||||
5067, 699_peqzone_rule.sql
|
5067|699_peqzone_rule.sql
|
||||||
5068, 702_aashieldblock_tint_table.sql
|
5068|702_aashieldblock_tint_table.sql
|
||||||
5069, 703_peqzone_rule.sql
|
5069|703_peqzone_rule.sql
|
||||||
5070, 704_rules.sql
|
5070|704_rules.sql
|
||||||
5071, 710_tint_set_naming.sql
|
5071|710_tint_set_naming.sql
|
||||||
5072, 721_pathing_rules.sql
|
5072|721_pathing_rules.sql
|
||||||
5073, 730_smart_delay_moving.sql
|
5073|730_smart_delay_moving.sql
|
||||||
5074, 731_rule_assist_notarget_self.sql
|
5074|731_rule_assist_notarget_self.sql
|
||||||
5075, 732_sacrifice_rules.sql
|
5075|732_sacrifice_rules.sql
|
||||||
5076, 745_slow_mitigation.sql
|
5076|745_slow_mitigation.sql
|
||||||
5077, 754_archery_base_damage_rule.sql
|
5077|754_archery_base_damage_rule.sql
|
||||||
5078, 755_sof_altadv_vars_updates.sql
|
5078|755_sof_altadv_vars_updates.sql
|
||||||
5079, 773_monk_rules.sql
|
5079|773_monk_rules.sql
|
||||||
5080, 853_optional_rule_aaexp.sql
|
# 5080|853_optional_rule_aaexp.sql
|
||||||
5081, 858_optional_rule_ip_limit_by_status.sql
|
# 5081|858_optional_rule_ip_limit_by_status.sql
|
||||||
5082, 892_optional_bots_table_mod.sql
|
# 5082|892_optional_bots_table_mod.sql
|
||||||
5083, 893_optional_bots_table_mod.sql
|
# 5083|893_optional_bots_table_mod.sql
|
||||||
5084, 898_npc_maxlevel_scalerate.sql
|
5084|898_npc_maxlevel_scalerate.sql
|
||||||
5085, 902_optional_rule_snareflee.sql
|
# 5085|902_optional_rule_snareflee.sql
|
||||||
5086, 923_spawn2_enabled.sql
|
5086|923_spawn2_enabled.sql
|
||||||
5087, 962_hot_zone.sql
|
5087|962_hot_zone.sql
|
||||||
5088, 964_reports.sql
|
5088|964_reports.sql
|
||||||
5089, 971_veteran_rewards.sql
|
5089|971_veteran_rewards.sql
|
||||||
5090, 977_raid_npc_private_corpses.sql
|
5090|977_raid_npc_private_corpses.sql
|
||||||
5091, 979_unique_spawn_by_name.sql
|
5091|979_unique_spawn_by_name.sql
|
||||||
5092, 980_account_ip.sql
|
5092|980_account_ip.sql
|
||||||
5093, 1022_botadventuring.sql
|
5093|1022_botadventuring.sql
|
||||||
5094, 1027_botactives.sql
|
5094|1027_botactives.sql
|
||||||
5095, 1030_botzoningsupport.sql
|
5095|1030_botzoningsupport.sql
|
||||||
5096, 1036_botbuffs.sql
|
5096|1036_botbuffs.sql
|
||||||
5097, 1038_botpetstatepersists.sql
|
5097|1038_botpetstatepersists.sql
|
||||||
5098, 1038_grouptablesuniquecolumndefinitions.sql
|
5098|1038_grouptablesuniquecolumndefinitions.sql
|
||||||
5099, 1039_botguilds.sql
|
5099|1039_botguilds.sql
|
||||||
5100, 1040_DeprecatedBotRaidsSystems.sql
|
5100|1040_DeprecatedBotRaidsSystems.sql
|
||||||
5101, 1057_titles.sql
|
5101|1057_titles.sql
|
||||||
5102, 1077_botgroups.sql
|
5102|1077_botgroups.sql
|
||||||
5103, 1136_spell_globals.sql
|
5103|1136_spell_globals.sql
|
||||||
5104, 1144_optional_rule_return_nodrop.sql
|
# 5104|1144_optional_rule_return_nodrop.sql
|
||||||
5105, 1195_account_suspendeduntil.sql
|
5105|1195_account_suspendeduntil.sql
|
||||||
5106, 1259_npc_skill_types.sql
|
5106|1259_npc_skill_types.sql
|
||||||
5107, 1280_bot_augs.sql
|
5107|1280_bot_augs.sql
|
||||||
5108, 1290_optional_exp_loss_rule.sql
|
# 5108|1290_optional_exp_loss_rule.sql
|
||||||
5109, 1293_guild_bank.sql
|
5109|1293_guild_bank.sql
|
||||||
5110, 1379_loginserver_trusted_server.sql
|
5110|1379_loginserver_trusted_server.sql
|
||||||
5111, 1392_recipe_learning.sql
|
5111|1392_recipe_learning.sql
|
||||||
5112, 1394_optional_rule_sod_hp_mana_end.sql
|
# 5112|1394_optional_rule_sod_hp_mana_end.sql
|
||||||
5113, 1404_faction_list.sql
|
5113|1404_faction_list.sql
|
||||||
5114, 1410_optional_sod_aas_ht_and_loh.sql
|
# 5114|1410_optional_sod_aas_ht_and_loh.sql
|
||||||
5115, 1436_login_server_table_fix.sql
|
5115|1436_login_server_table_fix.sql
|
||||||
5116, 1446_allowrest_optional.sql
|
5116|1446_allowrest_optional.sql
|
||||||
5117, 1446_allowrest_required.sql
|
5117|1446_allowrest_required.sql
|
||||||
5118, 1450_cvs.sql
|
5118|1450_cvs.sql
|
||||||
5119, 1451_guilds.sql
|
5119|1451_guilds.sql
|
||||||
5120, 1498_instance_adventure.sql
|
5120|1498_instance_adventure.sql
|
||||||
5121, 1510_global_instances.sql
|
5121|1510_global_instances.sql
|
||||||
5122, 1511_map_path_loading.sql
|
5122|1511_map_path_loading.sql
|
||||||
5123, 1513_zone_points.sql
|
5123|1513_zone_points.sql
|
||||||
5124, 1519_zone_primary_key_id.sql
|
5124|1519_zone_primary_key_id.sql
|
||||||
5125, 1542_items_table_cleanup.sql
|
5125|1542_items_table_cleanup.sql
|
||||||
5126, 1548_nimbuseffect_required.sql
|
5126|1548_nimbuseffect_required.sql
|
||||||
5127, 1562_instanced_spawnconditions.sql
|
5127|1562_instanced_spawnconditions.sql
|
||||||
5128, 1586_waypoints_optional.sql
|
5128|1586_waypoints_optional.sql
|
||||||
5129, 1610_tradeskill_required.sql
|
5129|1610_tradeskill_required.sql
|
||||||
5130, 1618_zone.sql
|
5130|1618_zone.sql
|
||||||
5131, 1625_optional_rule_class_race_exp_bonus.sql
|
# 5131|1625_optional_rule_class_race_exp_bonus.sql
|
||||||
5132, 1672_optional_rules_respawn_window.sql
|
# 5132|1672_optional_rules_respawn_window.sql
|
||||||
5133, 1679_optional_rules_blocked_buffs.sql
|
# 5133|1679_optional_rules_blocked_buffs.sql
|
||||||
5134, 1696_modify_zone_and_object_tables.sql
|
5134|1696_modify_zone_and_object_tables.sql
|
||||||
5135, 1711_account_restricted_aa.sql
|
5135|1711_account_restricted_aa.sql
|
||||||
5136, 1717_optional_rule_bash_stun_chance.sql
|
# 5136|1717_optional_rule_bash_stun_chance.sql
|
||||||
5137, 1718_optional_rules_mod3s.sql
|
# 5137|1718_optional_rules_mod3s.sql
|
||||||
5138, 1719_optional_triggerOnCastAAs.sql
|
# 5138|1719_optional_triggerOnCastAAs.sql
|
||||||
5139, 1720_optional_sql_AAs.sql
|
# 5139|1720_optional_sql_AAs.sql
|
||||||
5140, 1720_required_sql_AA_effects_update.sql
|
5140|1720_required_sql_AA_effects_update.sql
|
||||||
5141, 1721_optional_sql_drakkin_breath_update.sql
|
# 5141|1721_optional_sql_drakkin_breath_update.sql
|
||||||
5142, 1721_required_sql_altadv_vars_update.sql
|
5142|1721_required_sql_altadv_vars_update.sql
|
||||||
5143, 1723_optional_sql_new_stats_window_rule.sql
|
# 5143|1723_optional_sql_new_stats_window_rule.sql
|
||||||
5144, 1723_required_sql_corruption.sql
|
5144|1723_required_sql_corruption.sql
|
||||||
5145, 1736_optional_sql_feral_swipe.sql
|
# 5145|1736_optional_sql_feral_swipe.sql
|
||||||
5146, 1737_required_sql_rule_and_aa_update.sql
|
5146|1737_required_sql_rule_and_aa_update.sql
|
||||||
5147, 1746_optional_sql_bot_manaregen.sql
|
# 5147|1746_optional_sql_bot_manaregen.sql
|
||||||
5148, 1747_optional_HoT_zone_and_zonepoints.sql
|
# 5148|1747_optional_HoT_zone_and_zonepoints.sql
|
||||||
5149, 1750_optional_sql_reflect_rule.sql
|
# 5149|1750_optional_sql_reflect_rule.sql
|
||||||
5150, 1753_optional_haste_cap_rule.sql
|
# 5150|1753_optional_haste_cap_rule.sql
|
||||||
5151, 1753_required_sql_healing_adept_aa.sql
|
5151|1753_required_sql_healing_adept_aa.sql
|
||||||
5152, 1754_required_sql_healing_adept_aa_fix.sql
|
5152|1754_required_sql_healing_adept_aa_fix.sql
|
||||||
5153, 1755_required_sql_fear_resist_aas.sql
|
5153|1755_required_sql_fear_resist_aas.sql
|
||||||
5154, 1784_optional_corpsedrag_rules.sql
|
# 5154|1784_optional_corpsedrag_rules.sql
|
||||||
5155, 1786_required_update_to_aas.sql
|
5155|1786_required_update_to_aas.sql
|
||||||
5156, 1790_required_aa_required_level_cost.sql
|
5156|1790_required_aa_required_level_cost.sql
|
||||||
5157, 1793_resist_adjust.sql
|
5157|1793_resist_adjust.sql
|
||||||
5158, 1799_optional_rest_regen_endurance_rule.sql
|
# 5158|1799_optional_rest_regen_endurance_rule.sql
|
||||||
5159, 1802_required_doppelganger.sql
|
5159|1802_required_doppelganger.sql
|
||||||
5160, 1803_required_tasks_xpreward_signed.sql
|
5160|1803_required_tasks_xpreward_signed.sql
|
||||||
5161, 1804_required_ae_melee_updates.sql
|
5161|1804_required_ae_melee_updates.sql
|
||||||
5162, 1809_optional_rules.sql
|
# 5162|1809_optional_rules.sql
|
||||||
5163, 1813_required_doppelganger_npcid_change.sql
|
5163|1813_required_doppelganger_npcid_change.sql
|
||||||
5164, 1817_optional_npc_archery_bonus_rule.sql
|
# 5164|1817_optional_npc_archery_bonus_rule.sql
|
||||||
5165, 1823_optional_delay_death.sql
|
# 5165|1823_optional_delay_death.sql
|
||||||
5166, 1847_required_doors_dest_zone_size_32.sql
|
5166|1847_required_doors_dest_zone_size_32.sql
|
||||||
5167, 1859_optional_item_casts_use_focus_rule.sql
|
# 5167|1859_optional_item_casts_use_focus_rule.sql
|
||||||
5168, 1884_optional_bot_spells_update.sql
|
# 5168|1884_optional_bot_spells_update.sql
|
||||||
5169, 1885_optional_rules_fv_pvp_expansions.sql
|
# 5169|1885_optional_rules_fv_pvp_expansions.sql
|
||||||
5170, 1889_optional_skill_cap_rule.sql
|
# 5170|1889_optional_skill_cap_rule.sql
|
||||||
5171, 1908_required_npc_types_definitions.sql
|
5171|1908_required_npc_types_definitions.sql
|
||||||
5172, 1926_optional_stat_cap.sql
|
# 5172|1926_optional_stat_cap.sql
|
||||||
5173, 1944_spawn2.sql
|
5173|1944_spawn2.sql
|
||||||
5174, 1946_doors.sql
|
5174|1946_doors.sql
|
||||||
5175, 1960_optional_console_timeout_rule.sql
|
# 5175|1960_optional_console_timeout_rule.sql
|
||||||
5176, 1962_optional_guild_creation_window_rules.sql
|
# 5176|1962_optional_guild_creation_window_rules.sql
|
||||||
5177, 1963_optional_rule_live_like_focuses.sql
|
# 5177|1963_optional_rule_live_like_focuses.sql
|
||||||
5178, 1968_optional_enrage_rules.sql
|
# 5178|1968_optional_enrage_rules.sql
|
||||||
5179, 1972_optional_extradmg_item_cap.sql
|
# 5179|1972_optional_extradmg_item_cap.sql
|
||||||
5180, 1974_required_bot_spells_update.sql
|
5180|1974_required_bot_spells_update.sql
|
||||||
5181, 1977_underwater.sql
|
5181|1977_underwater.sql
|
||||||
5182, 1998_optional_intoxication_and_looting_rules.sql
|
# 5182|1998_optional_intoxication_and_looting_rules.sql
|
||||||
5183, 2004_charges_alt_currency.sql
|
5183|2004_charges_alt_currency.sql
|
||||||
5184, 2015_optional_specialization_training_rule.sql
|
# 5184|2015_optional_specialization_training_rule.sql
|
||||||
5185, 2016_optional_rule_bot_aa_expansion.sql
|
# 5185|2016_optional_rule_bot_aa_expansion.sql
|
||||||
5186, 2023_optional_mysqlcli.sql
|
# 5186|2023_optional_mysqlcli.sql
|
||||||
5187, 2024_optional_update_crystals.sql
|
# 5187|2024_optional_update_crystals.sql
|
||||||
5188, 2024_required_update.sql
|
5188|2024_required_update.sql
|
||||||
5189, 2057_required_discovered_items.sql
|
5189|2057_required_discovered_items.sql
|
||||||
5190, 2058_optional_rule_discovered_items.sql
|
# 5190|2058_optional_rule_discovered_items.sql
|
||||||
5191, 2062_required_version_changes.sql
|
5191|2062_required_version_changes.sql
|
||||||
5192, 2069_required_pets.sql
|
5192|2069_required_pets.sql
|
||||||
5193, 2079_player_speech.sql
|
5193|2079_player_speech.sql
|
||||||
5194, 2087_required_bots_hp_and_mana_and_spell_updates.sql
|
5194|2087_required_bots_hp_and_mana_and_spell_updates.sql
|
||||||
5195, 2098_required_zonepoint_version_changes.sql
|
5195|2098_required_zonepoint_version_changes.sql
|
||||||
5196, 2099_required_discovered_items_account_status.sql
|
5196|2099_required_discovered_items_account_status.sql
|
||||||
5197, 2104_required_group_roles.sql
|
5197|2104_required_group_roles.sql
|
||||||
5198, 2107_required_bot_stances.sql
|
5198|2107_required_bot_stances.sql
|
||||||
5199, 2129_required_lfguild.sql
|
5199|2129_required_lfguild.sql
|
||||||
5200, 2133_required_faction_loot_despawn.sql
|
5200|2133_required_faction_loot_despawn.sql
|
||||||
5201, 2136_extended_targets.sql
|
5201|2136_extended_targets.sql
|
||||||
5202, 2142_emotes.sql
|
5202|2142_emotes.sql
|
||||||
5203, 2154_optional_rule_spell_procs_resists_falloff.sql
|
# 5203|2154_optional_rule_spell_procs_resists_falloff.sql
|
||||||
5204, 2156_optional_charm_break_rule.sql
|
# 5204|2156_optional_charm_break_rule.sql
|
||||||
5205, 2159_optional_defensiveproc_rules.sql
|
# 5205|2159_optional_defensiveproc_rules.sql
|
||||||
5206, 2164_require_bots_bottimers.sql
|
5206|2164_require_bots_bottimers.sql
|
||||||
5207, 2171_optional_SpecialAttackACBonus_rule.sql
|
# 5207|2171_optional_SpecialAttackACBonus_rule.sql
|
||||||
5208, 2176_optional_aa_expansion_SOF_fix.sql
|
# 5208|2176_optional_aa_expansion_SOF_fix.sql
|
||||||
5209, 2176_optional_FrenzyBonus_rule.sql
|
# 5209|2176_optional_FrenzyBonus_rule.sql
|
||||||
5210, 2176_required_aa_updates.sql
|
5210|2176_required_aa_updates.sql
|
||||||
5211, 2178_required_aa_updates.sql
|
5211|2178_required_aa_updates.sql
|
||||||
5212, 2183_optional_bot_xp_rule.sql
|
# 5212|2183_optional_bot_xp_rule.sql
|
||||||
5213, 2185_optional_NPCFlurryChacne_rule
|
# 5213|2185_optional_NPCFlurryChacne_rule
|
||||||
5214, 2185_optional_NPCFlurryChacne_rule.sql
|
# 5214|2185_optional_NPCFlurryChacne_rule.sql
|
||||||
5215, 2185_optional_NPCFlurryChance_rule.sql
|
# 5215|2185_optional_NPCFlurryChance_rule.sql
|
||||||
5216, 2185_required_aa_updates
|
5216|2185_required_aa_updates
|
||||||
5217, 2185_required_aa_updates.sql
|
5217|2185_required_aa_updates.sql
|
||||||
5218, 2188_optional_miscspelleffect_rules
|
# 5218|2188_optional_miscspelleffect_rules
|
||||||
5219, 2188_optional_miscspelleffect_rules.sql
|
# 5219|2188_optional_miscspelleffect_rules.sql
|
||||||
5220, 2188_required_aa_updates
|
5220|2188_required_aa_updates
|
||||||
5221, 2188_required_aa_updates.sql
|
5221|2188_required_aa_updates.sql
|
||||||
5222, 2189_optional_taunt_rules
|
# 5222|2189_optional_taunt_rules
|
||||||
5223, 2189_optional_taunt_rules.sql
|
# 5223|2189_optional_taunt_rules.sql
|
||||||
5224, 2195_required_sharedplatupdates.sql
|
5224|2195_required_sharedplatupdates.sql
|
||||||
5225, 2208_optional_aa_stacking_rule.sql
|
# 5225|2208_optional_aa_stacking_rule.sql
|
||||||
5226, 2208_optional_EnableSoulAbrasionAA.sql
|
# 5226|2208_optional_EnableSoulAbrasionAA.sql
|
||||||
5227, 2208_required_aa_updates.sql
|
5227|2208_required_aa_updates.sql
|
||||||
5228, 2209_optional_additive_bonus_rule.sql
|
# 5228|2209_optional_additive_bonus_rule.sql
|
||||||
5229, 2213_loot_changes.sql
|
5229|2213_loot_changes.sql
|
||||||
5230, 2214_faction_list_mod.sql
|
5230|2214_faction_list_mod.sql
|
||||||
5231, 2215_required_aa_updates.sql
|
5231|2215_required_aa_updates.sql
|
||||||
5232, 2243_optional_char_max_level_rule.sql
|
# 5232|2243_optional_char_max_level_rule.sql
|
||||||
5233, 2260_probability.sql
|
5233|2260_probability.sql
|
||||||
5234, 2262_required_pet_discipline_update.sql
|
5234|2262_required_pet_discipline_update.sql
|
||||||
5235, 2264_required_aa_updates.sql
|
5235|2264_required_aa_updates.sql
|
||||||
5236, 2268_QueryServ.sql
|
5236|2268_QueryServ.sql
|
||||||
5237, 2268_required_updates.sql
|
5237|2268_required_updates.sql
|
||||||
5238, 2274_optional_rule_iplimitdisconnectall.sql
|
# 5238|2274_optional_rule_iplimitdisconnectall.sql
|
||||||
5239, 2278_optional_rule_targetableswarmpet.sql
|
# 5239|2278_optional_rule_targetableswarmpet.sql
|
||||||
5240, 2280_optional_rule_targetableswarmpet-rename.sql
|
# 5240|2280_optional_rule_targetableswarmpet-rename.sql
|
||||||
5241, 2283_required_npc_changes.sql
|
5241|2283_required_npc_changes.sql
|
||||||
5242, 2299_required_inspectmessage_fields.sql
|
5242|2299_required_inspectmessage_fields.sql
|
||||||
5243, 2300_optional_loot_changes.sql
|
# 5243|2300_optional_loot_changes.sql
|
||||||
5244, 2304_QueryServ.sql
|
5244|2304_QueryServ.sql
|
||||||
5245, 2340_required_maxbuffslotspet.sql
|
5245|2340_required_maxbuffslotspet.sql
|
||||||
5246, 2361_QueryServ.sql
|
5246|2361_QueryServ.sql
|
||||||
5247, 2361_required_qs_rule_values.sql
|
5247|2361_required_qs_rule_values.sql
|
||||||
5248, 2370_required_aa_updates.sql
|
5248|2370_required_aa_updates.sql
|
||||||
5249, 2376_required_aa_updates.sql
|
5249|2376_required_aa_updates.sql
|
||||||
5250, 2380_optional_merc_data.sql
|
# 5250|2380_optional_merc_data.sql
|
||||||
5251, 2380_optional_merc_merchant_npctypes_update.sql
|
# 5251|2380_optional_merc_merchant_npctypes_update.sql
|
||||||
5252, 2380_optional_merc_rules.sql
|
# 5252|2380_optional_merc_rules.sql
|
||||||
5253, 2383_required_group_ismerc.sql
|
5253|2383_required_group_ismerc.sql
|
||||||
5254, 2428_optional_levelbasedexpmods.sql
|
# 5254|2428_optional_levelbasedexpmods.sql
|
||||||
5255, 2448_optional_stun_proc_aggro_rule.sql
|
# 5255|2448_optional_stun_proc_aggro_rule.sql
|
||||||
5256, 2471_required_aa_updates.sql
|
5256|2471_required_aa_updates.sql
|
||||||
5257, 2482_required_start_zones.sql
|
5257|2482_required_start_zones.sql
|
||||||
5258, 2504_required_aa_updates.sql
|
5258|2504_required_aa_updates.sql
|
||||||
9000, 2013_02_18_Merc_Rules_and_Tables.sql
|
8000|mercs.sql|SHOW TABLES LIKE 'merc_stats'|empty|
|
||||||
9001, 2013_02_25_Impr_HT_LT.sql
|
9000|2013_02_18_Merc_Rules_and_Tables.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Mercs:ResurrectRadius%'|empty|
|
||||||
9002, 2013_03_1_Merc_Rules_and_Equipment.sql
|
9001|2013_02_25_Impr_HT_LT.sql|SHOW TABLES LIKE 'merc_inventory'|empty|
|
||||||
9003, 2013_03_23_Escape_FadingMemories.sql
|
9002|2013_03_1_Merc_Rules_and_Equipment.sql|SHOW TABLES LIKE 'merc_inventory'|empty|
|
||||||
9004, 2013_04_04_NaturesBounty.sql
|
# 9003|2013_03_23_Escape_FadingMemories.sql
|
||||||
9005, 2013_04_08_Salvage.sql
|
9004|2013_04_04_NaturesBounty.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '1230' AND `slot` = '1' AND `effectid` = '313' AND `base1` = '15' AND `base2` = '0'|empty|
|
||||||
9006, 2013_05_05_Account_Flags.sql
|
9005|2013_04_08_Salvage.sql|SHOW COLUMNS FROM `tradeskill_recipe_entries` LIKE 'salvagecount'|empty|
|
||||||
9007, 2013_05_05_Item_Tick.sql
|
9006|2013_05_05_Account_Flags.sql|SHOW TABLES LIKE 'account_flags'|empty|
|
||||||
9008, 2013_07_11_NPC_Special_Abilities.sql
|
9007|2013_05_05_Item_Tick.sql|SHOW TABLES LIKE 'item_tick'|empty|
|
||||||
9009, 2013_10_12_Merc_Special_Abilities.sql
|
9008|2013_07_11_NPC_Special_Abilities.sql|SHOW COLUMNS FROM `npc_types` LIKE 'special_abilities'|empty|
|
||||||
9010, 2013_10_12_Merc_vwMercNpcTypes.sql
|
9009|2013_10_12_Merc_Special_Abilities.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'special_abilities'|empty|
|
||||||
9011, 2013_10_31_Recipe_disabling.sql
|
# 9010|2013_10_12_Merc_vwMercNpcTypes.sql
|
||||||
9012, 2013_11_07_BaseData.sql
|
9011|2013_10_31_Recipe_disabling.sql|SHOW COLUMNS FROM `tradeskill_recipe` LIKE 'enabled'|empty|
|
||||||
9013, 2013_11_13_Instrument_Singing_Mastery.sql
|
9012|2013_11_07_BaseData.sql|SHOW TABLES LIKE 'base_data'|empty|
|
||||||
9014, 2013_11_18_AssistRadius.sql
|
9013|2013_11_13_Instrument_Singing_Mastery.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '213' AND `slot` = '1' AND `effectid` = '260' AND `base1` = '2' AND `base2` = '23'|empty|
|
||||||
9015, 2013_12_26_MerchantList_Class_Required.sql
|
9014|2013_11_18_AssistRadius.sql|SHOW COLUMNS FROM `npc_types` LIKE 'assistradius'|empty|
|
||||||
9016, 2014_01_04_SongModCapAAs.sql
|
9015|2013_12_26_MerchantList_Class_Required.sql|SHOW COLUMNS FROM `merchantlist` LIKE 'classes_required'|empty|
|
||||||
9017, 2014_01_08_SpellsNewAdditions.sql
|
9016|2014_01_04_SongModCapAAs.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '571' AND `slot` = '1' AND `effectid` = '261'|empty|
|
||||||
9018, 2014_01_09_PreservePetSize.sql
|
9017|2014_01_08_SpellsNewAdditions.sql|SHOW COLUMNS FROM `spells_new` LIKE 'persistdeath'|empty|
|
||||||
9019, 2014_01_20_MezMastery.sql
|
9018|2014_01_09_PreservePetSize.sql|SHOW COLUMNS FROM `character_pet_info` LIKE 'size'|empty|
|
||||||
9020, 2014_01_20_Not_Extendable.sql
|
9019|2014_01_20_MezMastery.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '781' AND `slot` = '1' AND `effectid` = '287'|empty|
|
||||||
9021, 2014_01_20_SpellCastingReinforcement.sql
|
9020|2014_01_20_Not_Extendable.sql|SHOW COLUMNS FROM `spells_new` LIKE 'not_extendable'|empty|
|
||||||
9022, 2014_01_20_Weather.sql
|
9021|2014_01_20_SpellCastingReinforcement.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '86' AND `slot` = '1' AND `effectid` = '128'|empty|
|
||||||
9023, 2014_01_27_CritcalMendAA.sql
|
9022|2014_01_20_Weather.sql|SHOW COLUMNS FROM `zone` LIKE 'rain_chance1'|empty|
|
||||||
9024, 2014_02_02_SpellCriticalsAA.sql
|
9023|2014_01_27_CritcalMendAA.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '230' AND `slot` = '1' AND `effectid` = '275'|empty
|
||||||
9025, 2014_02_13_Rename_instance_lockout_tables.sql
|
9024|2014_02_02_SpellCriticalsAA.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '4755' AND `slot` = '1' AND `effectid` = '294'|empty
|
||||||
9026, 2014_02_13_spells_new_update.sql
|
9025|2014_02_13_Rename_instance_lockout_tables.sql|SHOW TABLES LIKE 'instance_list'|empty|
|
||||||
9027, 2014_02_20_buff_update.sql
|
9026|2014_02_13_spells_new_update.sql|SHOW COLUMNS FROM `spells_new` LIKE 'ConeStartAngle'|empty|
|
||||||
9028, 2014_02_26_roambox_update.sql
|
9027|2014_02_20_buff_update.sql|SHOW COLUMNS FROM `character_buffs` LIKE 'caston_y'|empty|
|
||||||
9029, 2014_02_26_virulentvenomAA.sql
|
9028|2014_02_26_roambox_update.sql|SHOW COLUMNS FROM `spawngroup` LIKE 'mindelay'|empty|
|
||||||
9030, 2014_04_04_PhysicalResist.sql
|
9029|2014_02_26_virulentvenomAA.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '888' AND `slot` = '1' AND `effectid` = '250'|empty|
|
||||||
9031, 2014_04_10_No_Target_With_Hotkey.sql
|
9030|2014_04_04_PhysicalResist.sql|SHOW COLUMNS FROM `npc_types` LIKE 'PhR'|empty|
|
||||||
9032, 2014_04_12_SlowMitigation.sql
|
9031|2014_04_10_No_Target_With_Hotkey.sql|SHOW COLUMNS FROM `npc_types` LIKE 'no_target_hotkey'|empty|
|
||||||
9033, 2014_04_18_Suppress_Command_Error.sql
|
9032|2014_04_12_SlowMitigation.sql|SHOW COLUMNS FROM `npc_types` LIKE 'slow_mitigation'|contains|float
|
||||||
9034, 2014_04_25_spawn_events.sql
|
9034|2014_04_25_spawn_events.sql|SHOW COLUMNS FROM `spawn_events` LIKE 'strict'|empty|
|
||||||
9035, 2014_04_27_AISpellEffects.sql
|
9035|2014_04_27_AISpellEffects.sql|SHOW COLUMNS FROM `npc_types` LIKE 'npc_spells_effects_id'|empty|
|
||||||
9036, 2014_05_04_SlowMitigationFix.sql
|
9036|2014_05_04_SlowMitigationFix.sql|SHOW COLUMNS FROM `npc_types` LIKE 'slow_mitigation'|contains|float
|
||||||
9037, 2014_06_25_AA_Updates..sql
|
9038|2014_06_25_AA_Updates.sql|SELECT * FROM `altadv_vars` WHERE `skill_id` = '1604'|empty
|
||||||
9038, 2014_06_25_AA_Updates.sql
|
9039|2014_07_04_AA_Updates.sql|SELECT * FROM `aa_effects` WHERE `aaid` = '158' AND `slot` = '1' AND `effectid` = '238'|empty
|
||||||
9039, 2014_07_04_AA_Updates.sql
|
9040|2014_07_10_npc_spells.sql|SHOW COLUMNS FROM `npc_spells` LIKE 'engaged_no_sp_recast_min'|empty|
|
||||||
9040, 2014_07_10_npc_spells.sql
|
9041|2014_08_02_spells_new.sql|SHOW COLUMNS FROM `spells_new` LIKE 'viral_range'|empty|
|
||||||
9041, 2014_08_02_spells_new.sql
|
9042|2014_08_12_NPC_raid_targets.sql|SHOW COLUMNS FROM `npc_types` LIKE 'raid_target'|empty|
|
||||||
9042, 2014_08_12_NPC_raid_targets.sql
|
9043|2014_08_18_spells_new_update.sql|SHOW COLUMNS FROM `spells_new` LIKE 'viral_targets'|empty|
|
||||||
9043, 2014_08_18_spells_new_update.sql
|
9044|2014_08_20_merchantlist_probability.sql|SHOW COLUMNS FROM `merchantlist` LIKE 'probability'|empty|
|
||||||
9044, 2014_08_20_merchantlist_probability.sql
|
9045|2014_08_23_Complete_QueryServ_Table_Structures.sql|SHOW TABLES LIKE 'qs_player_aa_rate_hourly'|empty|
|
||||||
9045, 2014_08_23_Complete_QueryServ_Table_Structures.sql
|
9046|2014_08_23_player_events_and_player_aa_rate_hourly.sql|SHOW TABLES LIKE 'qs_player_events'|empty|
|
||||||
9046, 2014_08_23_player_events_and_player_aa_rate_hourly.sql
|
9048|2014_09_09_attack_delay.sql|SHOW COLUMNS FROM `npc_types` LIKE 'attack_delay'|empty|
|
||||||
9047, 2014_08_24_character_lookup.sql
|
9050|2014_09_20_ban_messages.sql|SHOW COLUMNS FROM `account` LIKE 'ban_reason'|empty|
|
||||||
9048, 2014_09_09_attack_delay.sql
|
9051|2014_10_11_RaidMOTD.sql|SHOW COLUMNS FROM `raid_details` LIKE 'motd'|empty|
|
||||||
9049, 2014_09_18_tellqueuesclean.sql
|
9052|2014_10_13_RaidLeadership.sql|SHOW TABLES LIKE 'raid_leaders'|empty|
|
||||||
9050, 2014_09_20_ban_messages.sql
|
9053|2014_10_18_group_mentor.sql|SHOW COLUMNS FROM `group_leaders` LIKE 'mentoree'|empty|
|
||||||
9051, 2014_10_11_RaidMOTD.sql
|
9054|2014_10_19_raid_group_mentor.sql|SHOW COLUMNS FROM `raid_leaders` LIKE 'mentoree'|empty|
|
||||||
9052, 2014_10_13_RaidLeadership.sql
|
9055|2014_10_30_special_abilities_null.sql|SHOW COLUMNS FROM `npc_types` LIKE 'special_abilities'|contains|NO
|
||||||
9053, 2014_10_18_group_mentor.sql
|
9056|2014_11_08_RaidMembers.sql|SHOW COLUMNS FROM `raid_members` LIKE 'groupid'|missing|unsigned
|
||||||
9054, 2014_10_19_raid_group_mentor.sql
|
9057|2014_11_13_spells_new_updates.sql|SHOW COLUMNS FROM `spells_new` LIKE 'disallow_sit'|empty|
|
||||||
9055, 2014_10_30_special_abilities_null.sql
|
|
||||||
9056, 2014_11_08_RaidMembers.sql
|
# Upgrade conditions:
|
||||||
9057, 2014_11_13_spells_new_updates.sql
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
# yet using the versioning system to figure out where the database is schema wise to determine
|
||||||
|
# which updates are necessary to run
|
||||||
|
#
|
||||||
|
# Example: Version|Filename.sql|Query_to_Check_Condition_For_Needed_Update|match type|text to match
|
||||||
|
# 0 = Database Version
|
||||||
|
# 1 = Filename.sql
|
||||||
|
# 2 = Query_to_Check_Condition_For_Needed_Update
|
||||||
|
# 3 = Match Type - If condition from match type to Value 4 is true, update will flag for needing to be ran
|
||||||
|
# contains = If query results contains text from 4th value
|
||||||
|
# match = If query results matches text from 4th value
|
||||||
|
# missing = If query result is missing text from 4th value
|
||||||
|
# empty = If the query results in no results
|
||||||
|
# not_empty = If the query is not empty
|
||||||
|
# 4 = Text to match
|
||||||
|
#
|
||||||
|
#
|
||||||
@ -1,4 +1,5 @@
|
|||||||
ALTER TABLE `npc_types` ADD COLUMN `special_abilities` TEXT NOT NULL DEFAULT '' AFTER `npcspecialattks`;
|
ALTER TABLE `npc_types` ADD COLUMN `special_abilities` TEXT NULL AFTER `npcspecialattks`;
|
||||||
|
ALTER TABLE `npc_types` MODIFY COLUMN `special_abilities` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL;
|
||||||
|
|
||||||
UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "1,1^") WHERE npcspecialattks LIKE BINARY '%S%';
|
UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "1,1^") WHERE npcspecialattks LIKE BINARY '%S%';
|
||||||
UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "2,1^") WHERE npcspecialattks LIKE BINARY '%E%';
|
UPDATE npc_types SET special_abilities = CONCAT(special_abilities, "2,1^") WHERE npcspecialattks LIKE BINARY '%E%';
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
ALTER TABLE `merc_stats` ADD COLUMN `special_abilities` TEXT NOT NULL DEFAULT '' AFTER `specialattks`;
|
ALTER TABLE `merc_stats` ADD COLUMN `special_abilities` TEXT NULL AFTER `specialattks`;
|
||||||
|
ALTER TABLE `merc_stats` MODIFY COLUMN `special_abilities` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL;
|
||||||
|
|
||||||
UPDATE merc_stats SET special_abilities = CONCAT(special_abilities, "1,1^") WHERE specialattks LIKE BINARY '%S%';
|
UPDATE merc_stats SET special_abilities = CONCAT(special_abilities, "1,1^") WHERE specialattks LIKE BINARY '%S%';
|
||||||
UPDATE merc_stats SET special_abilities = CONCAT(special_abilities, "2,1^") WHERE specialattks LIKE BINARY '%E%';
|
UPDATE merc_stats SET special_abilities = CONCAT(special_abilities, "2,1^") WHERE specialattks LIKE BINARY '%E%';
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
-- AA MGB update
|
|
||||||
UPDATE altadv_vars SET spellid = 5228 WHERE skill_id = 128;
|
|
||||||
UPDATE aa_actions SET spell_id = 5228, nonspell_action = 0 WHERE aaid = 128;
|
|
||||||
|
|
||||||
-- AA Project Illusion update
|
|
||||||
UPDATE altadv_vars SET spellid = 5227 WHERE skill_id = 643;
|
|
||||||
UPDATE aa_actions SET spell_id = 5227, nonspell_action = 0 WHERE aaid = 643;
|
|
||||||
|
|
||||||
-- AA Improved Reclaim Energy
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('180', '1', '241', '95', '0');
|
|
||||||
|
|
||||||
-- AA Headshot
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '1', '217', '0', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('644', '2', '346', '46', '0');
|
|
||||||
|
|
||||||
-- AA Anatomy (Rogue Assassinate)
|
|
||||||
INSERT INTO `altadv_vars` (`skill_id`, `name`, `cost`, `max_level`, `hotkey_sid`, `hotkey_sid2`, `title_sid`, `desc_sid`, `type`, `spellid`, `prereq_skill`, `prereq_minpoints`, `spell_type`, `spell_refresh`, `classes`, `berserker`, `class_type`, `cost_inc`, `aa_expansion`, `special_category`, `sof_type`, `sof_cost_inc`, `sof_max_level`, `sof_next_skill`, `clientver`, `account_time_required`, `sof_current_level`,`sof_next_id`,`level_inc`) VALUES ('1604', 'Anatomy', '5', '3', '4294967295', '4294967295', '1604', '1604', '1', '4294967295', '0', '0', '0', '0', '512', '0', '60', '1', '10', '4294967295', '3', '0', '3', '1604', '1', '0', '0', '0', '0');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '1', '439', '0', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1604', '2', '345', '48', '0');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '1', '439', '0', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1605', '2', '345', '51', '0');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '1', '439', '0', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('1606', '2', '345', '53', '0');
|
|
||||||
|
|
||||||
-- AA Finishing Blow Fix
|
|
||||||
DELETE FROM aa_effects WHERE aaid = 199 AND slot = 2;
|
|
||||||
DELETE FROM aa_effects WHERE aaid = 200 AND slot = 2;
|
|
||||||
DELETE FROM aa_effects WHERE aaid = 201 AND slot = 2;
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '1', '278', '500', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('119', '2', '440', '50', '200');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '1', '278', '500', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('120', '2', '440', '52', '200');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '1', '278', '500', '32000');
|
|
||||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('121', '2', '440', '54', '200');
|
|
||||||
@ -1 +1 @@
|
|||||||
ALTER TABLE `account` ADD COLUMN `ban_reason` TEXT NULL DEFAULT NULL AFTER `expansion`, ADD COLUMN `suspend_reason` TEXT NULL DEFAULT NULL AFTER `ban_reason`;
|
ALTER TABLE `account` ADD COLUMN `ban_reason` TEXT NULL DEFAULT NULL, ADD COLUMN `suspend_reason` TEXT NULL DEFAULT NULL AFTER `ban_reason`;
|
||||||
|
|||||||
@ -111,6 +111,15 @@ int main(int argc, char** argv) {
|
|||||||
RegisterExecutablePlatform(ExePlatformWorld);
|
RegisterExecutablePlatform(ExePlatformWorld);
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
|
/* Database Version Check */
|
||||||
|
uint32 Database_Version = CURRENT_BINARY_DATABASE_VERSION;
|
||||||
|
if (argc >= 2) {
|
||||||
|
if (strcasecmp(argv[1], "db_version") == 0) {
|
||||||
|
std::cout << "Binary Database Version: " << Database_Version << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load server configuration
|
// Load server configuration
|
||||||
_log(WORLD__INIT, "Loading server configuration..");
|
_log(WORLD__INIT, "Loading server configuration..");
|
||||||
if (!WorldConfig::LoadConfig()) {
|
if (!WorldConfig::LoadConfig()) {
|
||||||
|
|||||||
@ -7296,26 +7296,24 @@ void Client::SendMercPersonalInfo()
|
|||||||
{
|
{
|
||||||
uint32 mercTypeCount = 1;
|
uint32 mercTypeCount = 1;
|
||||||
uint32 mercCount = 1; //TODO: Un-hardcode this and support multiple mercs like in later clients than SoD.
|
uint32 mercCount = 1; //TODO: Un-hardcode this and support multiple mercs like in later clients than SoD.
|
||||||
//uint32 packetSize = 0;
|
uint32 i = 0;
|
||||||
uint32 i=0;
|
|
||||||
uint32 altCurrentType = 19; //TODO: Implement alternate currency purchases involving mercs!
|
uint32 altCurrentType = 19; //TODO: Implement alternate currency purchases involving mercs!
|
||||||
|
|
||||||
if (GetClientVersion() >= EQClientRoF)
|
|
||||||
{
|
|
||||||
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
|
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
|
||||||
|
|
||||||
if (mercData)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
int stancecount = 0;
|
int stancecount = 0;
|
||||||
stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size();
|
stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size();
|
||||||
|
|
||||||
if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES)
|
if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES)
|
||||||
{
|
{
|
||||||
SendMercMerchantResponsePacket(0);
|
SendMercMerchantResponsePacket(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mercCount > 0 && mercCount)
|
|
||||||
|
if(mercData)
|
||||||
|
{
|
||||||
|
if (GetClientVersion() >= EQClientRoF)
|
||||||
|
{
|
||||||
|
if (mercCount > 0)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, sizeof(MercenaryDataUpdate_Struct));
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataUpdate, sizeof(MercenaryDataUpdate_Struct));
|
||||||
MercenaryDataUpdate_Struct* mdus = (MercenaryDataUpdate_Struct*)outapp->pBuffer;
|
MercenaryDataUpdate_Struct* mdus = (MercenaryDataUpdate_Struct*)outapp->pBuffer;
|
||||||
@ -7353,40 +7351,19 @@ void Client::SendMercPersonalInfo()
|
|||||||
|
|
||||||
mdus->MercData[i].MercUnk05 = 1;
|
mdus->MercData[i].MercUnk05 = 1;
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int stancecount = 0;
|
if(mercTypeCount > 0 && mercCount > 0)
|
||||||
stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size();
|
|
||||||
|
|
||||||
if(mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES)
|
|
||||||
{
|
{
|
||||||
if (GetClientVersion() == EQClientSoD)
|
|
||||||
{
|
|
||||||
SendMercMerchantResponsePacket(0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct));
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryDataResponse, sizeof(MercenaryMerchantList_Struct));
|
||||||
MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer;
|
MercenaryMerchantList_Struct* mml = (MercenaryMerchantList_Struct*)outapp->pBuffer;
|
||||||
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
|
mml->MercTypeCount = mercTypeCount; //We should only have one merc entry.
|
||||||
|
|
||||||
|
|
||||||
if(mercData)
|
|
||||||
{
|
|
||||||
if(mercTypeCount > 0)
|
|
||||||
{
|
|
||||||
mml->MercTypeCount = mercTypeCount; //We only should have one merc entry.
|
|
||||||
mml->MercGrades[i] = 1;
|
mml->MercGrades[i] = 1;
|
||||||
}
|
|
||||||
mml->MercCount = mercCount;
|
mml->MercCount = mercCount;
|
||||||
if(mercCount > 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
mml->Mercs[i].MercID = mercData->MercTemplateID;
|
mml->Mercs[i].MercID = mercData->MercTemplateID;
|
||||||
mml->Mercs[i].MercType = mercData->MercType;
|
mml->Mercs[i].MercType = mercData->MercType;
|
||||||
mml->Mercs[i].MercSubType = mercData->MercSubType;
|
mml->Mercs[i].MercSubType = mercData->MercSubType;
|
||||||
@ -7403,7 +7380,7 @@ void Client::SendMercPersonalInfo()
|
|||||||
mml->Mercs[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size();
|
mml->Mercs[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size();
|
||||||
mml->Mercs[i].MercUnk03 = 0;
|
mml->Mercs[i].MercUnk03 = 0;
|
||||||
mml->Mercs[i].MercUnk04 = 1;
|
mml->Mercs[i].MercUnk04 = 1;
|
||||||
//mml->Mercs[i].MercName;
|
strn0cpy(mml->Mercs[i].MercName, GetMercInfo().merc_name , sizeof(mml->Mercs[i].MercName));
|
||||||
int stanceindex = 0;
|
int stanceindex = 0;
|
||||||
if(mml->Mercs[i].StanceCount != 0)
|
if(mml->Mercs[i].StanceCount != 0)
|
||||||
{
|
{
|
||||||
@ -7417,31 +7394,12 @@ void Client::SendMercPersonalInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
if (GetClientVersion() == EQClientSoD)
|
|
||||||
{
|
|
||||||
SendMercMerchantResponsePacket(0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (GetClientVersion() == EQClientSoD)
|
|
||||||
{
|
|
||||||
SendMercMerchantResponsePacket(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
safe_delete(outapp);
|
|
||||||
if (GetClientVersion() == EQClientSoD)
|
|
||||||
{
|
|
||||||
SendMercMerchantResponsePacket(0);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
SendMercMerchantResponsePacket(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendClearMercInfo()
|
void Client::SendClearMercInfo()
|
||||||
|
|||||||
@ -829,11 +829,11 @@ public:
|
|||||||
|
|
||||||
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
|
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
|
||||||
bool Thirsty() const {if (GetGM()) return false; return m_pp.thirst_level <= 3000;}
|
bool Thirsty() const {if (GetGM()) return false; return m_pp.thirst_level <= 3000;}
|
||||||
int32 GetHunger() const { return m_pp.hunger_level; }
|
int32 GetHunger() const { return m_pp.hunger_level; }
|
||||||
int32 GetThirst() const { return m_pp.thirst_level; }
|
int32 GetThirst() const { return m_pp.thirst_level; }
|
||||||
void SetHunger(int32 in_hunger);
|
void SetHunger(int32 in_hunger);
|
||||||
void SetThirst(int32 in_thirst);
|
void SetThirst(int32 in_thirst);
|
||||||
void SetConsumption(int32 in_hunger, int32 in_thirst);
|
void SetConsumption(int32 in_hunger, int32 in_thirst);
|
||||||
|
|
||||||
bool CheckTradeLoreConflict(Client* other);
|
bool CheckTradeLoreConflict(Client* other);
|
||||||
void LinkDead();
|
void LinkDead();
|
||||||
@ -1129,6 +1129,7 @@ public:
|
|||||||
void RemoveAutoXTargets();
|
void RemoveAutoXTargets();
|
||||||
void ShowXTargets(Client *c);
|
void ShowXTargets(Client *c);
|
||||||
void InitializeMercInfo();
|
void InitializeMercInfo();
|
||||||
|
bool CheckCanSpawnMerc(uint32 template_id);
|
||||||
bool CheckCanHireMerc(Mob* merchant, uint32 template_id);
|
bool CheckCanHireMerc(Mob* merchant, uint32 template_id);
|
||||||
bool CheckCanRetainMerc(uint32 upkeep);
|
bool CheckCanRetainMerc(uint32 upkeep);
|
||||||
bool CheckCanUnsuspendMerc();
|
bool CheckCanUnsuspendMerc();
|
||||||
@ -1142,9 +1143,11 @@ public:
|
|||||||
MercInfo& GetMercInfo() { return m_mercinfo[mercSlot]; }
|
MercInfo& GetMercInfo() { return m_mercinfo[mercSlot]; }
|
||||||
uint8 GetNumMercs();
|
uint8 GetNumMercs();
|
||||||
void SetMerc(Merc* newmerc);
|
void SetMerc(Merc* newmerc);
|
||||||
|
void SendMercResponsePackets(uint32 ResponseType);
|
||||||
void SendMercMerchantResponsePacket(int32 response_type);
|
void SendMercMerchantResponsePacket(int32 response_type);
|
||||||
void SendMercenaryUnknownPacket(uint8 type);
|
void SendMercenaryUnknownPacket(uint8 type);
|
||||||
void SendMercenaryUnsuspendPacket(uint8 type);
|
void SendMercenaryUnsuspendPacket(uint8 type);
|
||||||
|
void SendMercTimer(Merc* merc = nullptr);
|
||||||
void SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspended_time, int32 update_interval = 900000, int32 unk01 = 180000);
|
void SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspended_time, int32 update_interval = 900000, int32 unk01 = 180000);
|
||||||
void SendMercSuspendResponsePacket(uint32 suspended_time);
|
void SendMercSuspendResponsePacket(uint32 suspended_time);
|
||||||
void SendMercAssignPacket(uint32 entityID, uint32 unk01, uint32 unk02);
|
void SendMercAssignPacket(uint32 entityID, uint32 unk01, uint32 unk02);
|
||||||
@ -1538,4 +1541,3 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -3034,47 +3034,23 @@ void Client::Handle_OP_AssistGroup(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app)
|
void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
|
|
||||||
// This packet is sent by the client when an Augment item information window is opened.
|
// This packet is sent by the client when an Augment item information window is opened.
|
||||||
// We respond with an OP_ReadBook containing the type of distiller required to remove the augment.
|
// Some clients this seems to nuke the charm text (ex. Adventurer's Stone)
|
||||||
// The OP_Augment packet includes a window parameter to determine which Item window in the UI the
|
|
||||||
// text is to be displayed in. out->type = 2 indicates the BookText_Struct contains item information.
|
|
||||||
//
|
|
||||||
|
|
||||||
if (app->size != sizeof(AugmentInfo_Struct))
|
if (app->size != sizeof(AugmentInfo_Struct)) {
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AugmentInfo expected %i got %i",
|
LogFile->write(EQEMuLog::Debug, "Size mismatch in OP_AugmentInfo expected %i got %i",
|
||||||
sizeof(AugmentInfo_Struct), app->size);
|
sizeof(AugmentInfo_Struct), app->size);
|
||||||
|
|
||||||
DumpPacket(app);
|
DumpPacket(app);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*)app->pBuffer;
|
AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*)app->pBuffer;
|
||||||
|
|
||||||
char *outstring = nullptr;
|
|
||||||
|
|
||||||
const Item_Struct * item = database.GetItem(AugInfo->itemid);
|
const Item_Struct * item = database.GetItem(AugInfo->itemid);
|
||||||
|
|
||||||
if (item)
|
if (item) {
|
||||||
{
|
strn0cpy(AugInfo->augment_info, item->Name, 64);
|
||||||
MakeAnyLenString(&outstring, "You must use the solvent %s to remove this augment safely.", item->Name);
|
AugInfo->itemid = 0;
|
||||||
|
QueuePacket(app);
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, strlen(outstring) + sizeof(BookText_Struct));
|
|
||||||
|
|
||||||
BookText_Struct *out = (BookText_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
out->window = AugInfo->window;
|
|
||||||
|
|
||||||
out->type = 2;
|
|
||||||
|
|
||||||
out->invslot = 0;
|
|
||||||
|
|
||||||
strcpy(out->booktext, outstring);
|
|
||||||
|
|
||||||
safe_delete_array(outstring);
|
|
||||||
|
|
||||||
FastQueuePacket(&outapp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3842,19 +3818,23 @@ void Client::Handle_OP_BlockedBuffs(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
|
void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
|
// this sends unclean mob name, so capped at 64
|
||||||
if (app->size <= 5)
|
// a_boat006
|
||||||
|
if (app->size <= 5 || app->size > 64) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Size mismatch in OP_BoardBoad. Expected greater than 5 less than 64, got %i", app->size);
|
||||||
|
DumpPacket(app);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char *boatname;
|
char boatname[64];
|
||||||
boatname = new char[app->size - 3];
|
memcpy(boatname, app->pBuffer, app->size);
|
||||||
memset(boatname, 0, app->size - 3);
|
boatname[63] = '\0';
|
||||||
memcpy(boatname, app->pBuffer, app->size - 4);
|
|
||||||
|
|
||||||
Mob* boat = entity_list.GetMob(boatname);
|
Mob* boat = entity_list.GetMob(boatname);
|
||||||
if (boat)
|
if (!boat || (boat->GetRace() != CONTROLLED_BOAT && boat->GetRace() != 502))
|
||||||
this->BoatID = boat->GetID(); // set the client's BoatID to show that it's on this boat
|
return;
|
||||||
safe_delete_array(boatname);
|
BoatID = boat->GetID(); // set the client's BoatID to show that it's on this boat
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9719,17 +9699,13 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app)
|
|||||||
Message(7, "Mercenary Debug: Dismiss Request ( %i ) Received.", Command);
|
Message(7, "Mercenary Debug: Dismiss Request ( %i ) Received.", Command);
|
||||||
|
|
||||||
// Handle the dismiss here...
|
// Handle the dismiss here...
|
||||||
if (GetMercID()) {
|
|
||||||
Merc* merc = GetMerc();
|
Merc* merc = GetMerc();
|
||||||
|
|
||||||
if (merc) {
|
if (merc) {
|
||||||
if (CheckCanDismissMerc()) {
|
if (CheckCanDismissMerc()) {
|
||||||
merc->Dismiss();
|
merc->Dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//SendMercMerchantResponsePacket(10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
|
void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
|
||||||
@ -9769,21 +9745,22 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Mercs, ChargeMercPurchaseCost)) {
|
|
||||||
uint32 cost = Merc::CalcPurchaseCost(merc_template->MercTemplateID, GetLevel()) * 100; // Cost is in gold
|
|
||||||
TakeMoneyFromPP(cost, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set time remaining to max on Hire
|
// Set time remaining to max on Hire
|
||||||
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
||||||
|
|
||||||
// Get merc, assign it to client & spawn
|
// Get merc, assign it to client & spawn
|
||||||
Merc* merc = Merc::LoadMerc(this, merc_template, merchant_id, false);
|
Merc* merc = Merc::LoadMerc(this, merc_template, merchant_id, false);
|
||||||
|
|
||||||
if (merc) {
|
if (merc)
|
||||||
|
{
|
||||||
SpawnMerc(merc, true);
|
SpawnMerc(merc, true);
|
||||||
merc->Save();
|
merc->Save();
|
||||||
|
|
||||||
|
if (RuleB(Mercs, ChargeMercPurchaseCost)) {
|
||||||
|
uint32 cost = Merc::CalcPurchaseCost(merc_template->MercTemplateID, GetLevel()) * 100; // Cost is in gold
|
||||||
|
TakeMoneyFromPP(cost, true);
|
||||||
|
}
|
||||||
|
|
||||||
// 0 is approved hire request
|
// 0 is approved hire request
|
||||||
SendMercMerchantResponsePacket(0);
|
SendMercMerchantResponsePacket(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,8 @@ bool Client::Process() {
|
|||||||
if(Connected() || IsLD())
|
if(Connected() || IsLD())
|
||||||
{
|
{
|
||||||
// try to send all packets that weren't sent before
|
// try to send all packets that weren't sent before
|
||||||
if(!IsLD() && zoneinpacket_timer.Check()){
|
if(!IsLD() && zoneinpacket_timer.Check())
|
||||||
|
{
|
||||||
SendAllPackets();
|
SendAllPackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +146,9 @@ bool Client::Process() {
|
|||||||
|
|
||||||
if(mana_timer.Check())
|
if(mana_timer.Check())
|
||||||
SendManaUpdatePacket();
|
SendManaUpdatePacket();
|
||||||
if(dead && dead_timer.Check()) {
|
|
||||||
|
if(dead && dead_timer.Check())
|
||||||
|
{
|
||||||
database.MoveCharacterToZone(GetName(),database.GetZoneName(m_pp.binds[0].zoneId));
|
database.MoveCharacterToZone(GetName(),database.GetZoneName(m_pp.binds[0].zoneId));
|
||||||
m_pp.zone_id = m_pp.binds[0].zoneId;
|
m_pp.zone_id = m_pp.binds[0].zoneId;
|
||||||
m_pp.zoneInstance = 0;
|
m_pp.zoneInstance = 0;
|
||||||
@ -176,14 +179,16 @@ bool Client::Process() {
|
|||||||
if(TaskPeriodic_Timer.Check() && taskstate)
|
if(TaskPeriodic_Timer.Check() && taskstate)
|
||||||
taskstate->TaskPeriodicChecks(this);
|
taskstate->TaskPeriodicChecks(this);
|
||||||
|
|
||||||
if(linkdead_timer.Check()){
|
if(linkdead_timer.Check())
|
||||||
|
{
|
||||||
|
LeaveGroup();
|
||||||
Save();
|
Save();
|
||||||
if (GetMerc())
|
if (GetMerc())
|
||||||
{
|
{
|
||||||
GetMerc()->Save();
|
GetMerc()->Save();
|
||||||
GetMerc()->Depop();
|
GetMerc()->Depop();
|
||||||
}
|
}
|
||||||
LeaveGroup();
|
|
||||||
Raid *myraid = entity_list.GetRaidByClient(this);
|
Raid *myraid = entity_list.GetRaidByClient(this);
|
||||||
if (myraid)
|
if (myraid)
|
||||||
{
|
{
|
||||||
@ -192,7 +197,8 @@ bool Client::Process() {
|
|||||||
return false; //delete client
|
return false; //delete client
|
||||||
}
|
}
|
||||||
|
|
||||||
if (camp_timer.Check()) {
|
if (camp_timer.Check())
|
||||||
|
{
|
||||||
LeaveGroup();
|
LeaveGroup();
|
||||||
Save();
|
Save();
|
||||||
if (GetMerc())
|
if (GetMerc())
|
||||||
@ -228,7 +234,7 @@ bool Client::Process() {
|
|||||||
} else {
|
} else {
|
||||||
if(!ApplyNextBardPulse(bardsong, song_target, bardsong_slot))
|
if(!ApplyNextBardPulse(bardsong, song_target, bardsong_slot))
|
||||||
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
|
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
|
||||||
// SpellFinished(bardsong, bardsong_target, bardsong_slot, spells[bardsong].mana);
|
//SpellFinished(bardsong, bardsong_target, bardsong_slot, spells[bardsong].mana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +245,9 @@ bool Client::Process() {
|
|||||||
|
|
||||||
if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended)
|
if(GetMercInfo().MercTemplateID != 0 && GetMercInfo().IsSuspended)
|
||||||
{
|
{
|
||||||
if(p_timers.Expired(&database, pTimerMercSuspend, false)) {
|
//CheckMercSuspendTimer();
|
||||||
|
if(p_timers.Expired(&database, pTimerMercSuspend, false))
|
||||||
|
{
|
||||||
CheckMercSuspendTimer();
|
CheckMercSuspendTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,16 +723,13 @@ bool Client::Process() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (client_state != CLIENT_LINKDEAD && (client_state == CLIENT_ERROR || client_state == DISCONNECTED || client_state == CLIENT_KICKED || !eqs->CheckState(ESTABLISHED))) {
|
if (client_state != CLIENT_LINKDEAD && (client_state == CLIENT_ERROR || client_state == DISCONNECTED || client_state == CLIENT_KICKED || !eqs->CheckState(ESTABLISHED)))
|
||||||
|
{
|
||||||
//client logged out or errored out
|
//client logged out or errored out
|
||||||
//ResetTrade();
|
//ResetTrade();
|
||||||
if (client_state != CLIENT_KICKED) {
|
if (client_state != CLIENT_KICKED) {
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
if (GetMerc())
|
|
||||||
{
|
|
||||||
GetMerc()->Depop();
|
|
||||||
}
|
|
||||||
|
|
||||||
client_state = CLIENT_LINKDEAD;
|
client_state = CLIENT_LINKDEAD;
|
||||||
if (zoning || instalog || GetGM())
|
if (zoning || instalog || GetGM())
|
||||||
@ -732,23 +737,32 @@ bool Client::Process() {
|
|||||||
Group *mygroup = GetGroup();
|
Group *mygroup = GetGroup();
|
||||||
if (mygroup)
|
if (mygroup)
|
||||||
{
|
{
|
||||||
if (!zoning) {
|
if (!zoning)
|
||||||
|
{
|
||||||
entity_list.MessageGroup(this, true, 15, "%s logged out.", GetName());
|
entity_list.MessageGroup(this, true, 15, "%s logged out.", GetName());
|
||||||
mygroup->DelMember(this);
|
LeaveGroup();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
entity_list.MessageGroup(this, true, 15, "%s left the zone.", GetName());
|
entity_list.MessageGroup(this, true, 15, "%s left the zone.", GetName());
|
||||||
mygroup->MemberZoned(this);
|
mygroup->MemberZoned(this);
|
||||||
|
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == mygroup)
|
||||||
|
{
|
||||||
|
mygroup->DelMember(GetMerc());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Raid *myraid = entity_list.GetRaidByClient(this);
|
Raid *myraid = entity_list.GetRaidByClient(this);
|
||||||
if (myraid)
|
if (myraid)
|
||||||
{
|
{
|
||||||
if (!zoning) {
|
if (!zoning)
|
||||||
|
{
|
||||||
//entity_list.MessageGroup(this,true,15,"%s logged out.",GetName());
|
//entity_list.MessageGroup(this,true,15,"%s logged out.",GetName());
|
||||||
//mygroup->DelMember(this);
|
|
||||||
myraid->MemberZoned(this);
|
myraid->MemberZoned(this);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
//entity_list.MessageGroup(this,true,15,"%s left the zone.",GetName());
|
//entity_list.MessageGroup(this,true,15,"%s left the zone.",GetName());
|
||||||
myraid->MemberZoned(this);
|
myraid->MemberZoned(this);
|
||||||
}
|
}
|
||||||
@ -774,8 +788,14 @@ bool Client::Process() {
|
|||||||
|
|
||||||
/* Just a set of actions preformed all over in Client::Process */
|
/* Just a set of actions preformed all over in Client::Process */
|
||||||
void Client::OnDisconnect(bool hard_disconnect) {
|
void Client::OnDisconnect(bool hard_disconnect) {
|
||||||
if(hard_disconnect) {
|
if(hard_disconnect)
|
||||||
|
{
|
||||||
LeaveGroup();
|
LeaveGroup();
|
||||||
|
if (GetMerc())
|
||||||
|
{
|
||||||
|
GetMerc()->Save();
|
||||||
|
GetMerc()->Depop();
|
||||||
|
}
|
||||||
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
||||||
|
|
||||||
if (MyRaid)
|
if (MyRaid)
|
||||||
@ -791,7 +811,8 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mob *Other = trade->With();
|
Mob *Other = trade->With();
|
||||||
if(Other) {
|
if(Other)
|
||||||
|
{
|
||||||
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
||||||
FinishTrade(this);
|
FinishTrade(this);
|
||||||
|
|
||||||
|
|||||||
@ -1069,14 +1069,29 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co
|
|||||||
void Client::LeaveGroup() {
|
void Client::LeaveGroup() {
|
||||||
Group *g = GetGroup();
|
Group *g = GetGroup();
|
||||||
|
|
||||||
if(g) {
|
if(g)
|
||||||
|
{
|
||||||
if(g->GroupCount() < 3)
|
if(g->GroupCount() < 3)
|
||||||
|
{
|
||||||
g->DisbandGroup();
|
g->DisbandGroup();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
g->DelMember(this);
|
g->DelMember(this);
|
||||||
} else {
|
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
|
||||||
|
{
|
||||||
|
g->DelMember(GetMerc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
//force things a little
|
//force things a little
|
||||||
database.SetGroupID(GetName(), 0, CharacterID());
|
database.SetGroupID(GetName(), 0, CharacterID());
|
||||||
|
if (GetMerc())
|
||||||
|
{
|
||||||
|
database.SetGroupID(GetMerc()->GetName(), 0, CharacterID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isgrouped = false;
|
isgrouped = false;
|
||||||
|
|||||||
1121
zone/merc.cpp
1121
zone/merc.cpp
File diff suppressed because it is too large
Load Diff
13
zone/merc.h
13
zone/merc.h
@ -10,6 +10,12 @@
|
|||||||
#define HEALER 2
|
#define HEALER 2
|
||||||
#define MELEEDPS 9
|
#define MELEEDPS 9
|
||||||
#define CASTERDPS 12
|
#define CASTERDPS 12
|
||||||
|
|
||||||
|
#define NO_MERC_ID 0
|
||||||
|
#define MERC_STATE_NORMAL 5
|
||||||
|
#define MERC_STATE_SUSPENDED 1
|
||||||
|
#define NOT_SUSPENDED_TIME 0
|
||||||
|
|
||||||
const int MercAISpellRange = 100; // TODO: Write a method that calcs what the merc's spell range is based on spell, equipment, AA, whatever and replace this
|
const int MercAISpellRange = 100; // TODO: Write a method that calcs what the merc's spell range is based on spell, equipment, AA, whatever and replace this
|
||||||
|
|
||||||
enum MercStanceType {
|
enum MercStanceType {
|
||||||
@ -126,7 +132,7 @@ public:
|
|||||||
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
||||||
void UpdateMercInfo(Client *c);
|
void UpdateMercInfo(Client *c);
|
||||||
void UpdateMercStats(Client *c);
|
void UpdateMercStats(Client *c);
|
||||||
void UpdateMercAppearance(Client *c);
|
void UpdateMercAppearance();
|
||||||
void AddItem(uint8 slot, uint32 item_id);
|
void AddItem(uint8 slot, uint32 item_id);
|
||||||
static const char *GetRandomName();
|
static const char *GetRandomName();
|
||||||
bool Spawn(Client *owner);
|
bool Spawn(Client *owner);
|
||||||
@ -139,8 +145,8 @@ public:
|
|||||||
bool GetDepop() { return p_depop; }
|
bool GetDepop() { return p_depop; }
|
||||||
|
|
||||||
bool IsDead() { return GetHP() < 0;};
|
bool IsDead() { return GetHP() < 0;};
|
||||||
bool IsMedding() {return _medding; };
|
bool IsMedding() { return _medding; };
|
||||||
bool IsSuspended() {return _suspended; };
|
bool IsSuspended() { return _suspended; };
|
||||||
|
|
||||||
static uint32 CalcPurchaseCost( uint32 templateID , uint8 level, uint8 currency_type = 0);
|
static uint32 CalcPurchaseCost( uint32 templateID , uint8 level, uint8 currency_type = 0);
|
||||||
static uint32 CalcUpkeepCost( uint32 templateID , uint8 level, uint8 currency_type = 0);
|
static uint32 CalcUpkeepCost( uint32 templateID , uint8 level, uint8 currency_type = 0);
|
||||||
@ -329,6 +335,7 @@ private:
|
|||||||
void GetMercSize();
|
void GetMercSize();
|
||||||
void GenerateAppearance();
|
void GenerateAppearance();
|
||||||
|
|
||||||
|
|
||||||
bool LoadMercSpells();
|
bool LoadMercSpells();
|
||||||
bool CheckStance(int16 stance);
|
bool CheckStance(int16 stance);
|
||||||
std::vector<MercSpell> GetMercSpells() { return merc_spells; }
|
std::vector<MercSpell> GetMercSpells() { return merc_spells; }
|
||||||
|
|||||||
@ -400,7 +400,7 @@ void Zone::LoadTempMerchantData() {
|
|||||||
LogFile->write(EQEMuLog::Status, "Loading Temporary Merchant Lists...");
|
LogFile->write(EQEMuLog::Status, "Loading Temporary Merchant Lists...");
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
"SELECT "
|
"SELECT "
|
||||||
"ml.npcid, "
|
"DISTINCT ml.npcid, "
|
||||||
"ml.slot, "
|
"ml.slot, "
|
||||||
"ml.charges, "
|
"ml.charges, "
|
||||||
"ml.itemid "
|
"ml.itemid "
|
||||||
|
|||||||
@ -2107,9 +2107,6 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
|
|||||||
|
|
||||||
bool ZoneDatabase::LoadMercInfo(Client *client) {
|
bool ZoneDatabase::LoadMercInfo(Client *client) {
|
||||||
|
|
||||||
if(client->GetEPP().merc_name[0] == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT MercID, Slot, Name, TemplateID, SuspendedTime, "
|
std::string query = StringFormat("SELECT MercID, Slot, Name, TemplateID, SuspendedTime, "
|
||||||
"IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, "
|
"IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, "
|
||||||
"Endurance, Face, LuclinHairStyle, LuclinHairColor, "
|
"Endurance, Face, LuclinHairStyle, LuclinHairColor, "
|
||||||
@ -2120,6 +2117,9 @@ bool ZoneDatabase::LoadMercInfo(Client *client) {
|
|||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
uint8 slot = atoi(row[1]);
|
uint8 slot = atoi(row[1]);
|
||||||
|
|
||||||
@ -2156,9 +2156,6 @@ bool ZoneDatabase::LoadMercInfo(Client *client) {
|
|||||||
|
|
||||||
bool ZoneDatabase::LoadCurrentMerc(Client *client) {
|
bool ZoneDatabase::LoadCurrentMerc(Client *client) {
|
||||||
|
|
||||||
if(client->GetEPP().merc_name[0] == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint8 slot = client->GetMercSlot();
|
uint8 slot = client->GetMercSlot();
|
||||||
|
|
||||||
if(slot > MAXMERCS)
|
if(slot > MAXMERCS)
|
||||||
@ -2176,6 +2173,9 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
|
|||||||
if(!results.Success())
|
if(!results.Success())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
client->GetMercInfo(slot).mercid = atoi(row[0]);
|
client->GetMercInfo(slot).mercid = atoi(row[0]);
|
||||||
@ -2211,9 +2211,9 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
|
|||||||
if(!owner)
|
if(!owner)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(merc->GetMercID() == 0) {
|
if(merc->GetMercID() == 0)
|
||||||
|
{
|
||||||
// New merc record
|
// New merc record
|
||||||
uint32 TempNewMercID = 0;
|
|
||||||
std::string query = StringFormat("INSERT INTO mercs "
|
std::string query = StringFormat("INSERT INTO mercs "
|
||||||
"(OwnerCharacterID, Slot, Name, TemplateID, "
|
"(OwnerCharacterID, Slot, Name, TemplateID, "
|
||||||
"SuspendedTime, IsSuspended, TimerRemaining, "
|
"SuspendedTime, IsSuspended, TimerRemaining, "
|
||||||
@ -2234,6 +2234,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
|
|||||||
merc->GetEyeColor2(), merc->GetBeardColor(),
|
merc->GetEyeColor2(), merc->GetBeardColor(),
|
||||||
merc->GetBeard(), merc->GetDrakkinHeritage(),
|
merc->GetBeard(), merc->GetDrakkinHeritage(),
|
||||||
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails());
|
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails());
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success()) {
|
if(!results.Success()) {
|
||||||
owner->Message(13, results.ErrorMessage().c_str());
|
owner->Message(13, results.ErrorMessage().c_str());
|
||||||
@ -2243,7 +2244,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
merc->SetMercID(TempNewMercID);
|
merc->SetMercID(results.LastInsertedID());
|
||||||
merc->UpdateMercInfo(owner);
|
merc->UpdateMercInfo(owner);
|
||||||
database.SaveMercBuffs(merc);
|
database.SaveMercBuffs(merc);
|
||||||
return true;
|
return true;
|
||||||
@ -2266,6 +2267,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
|
|||||||
merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(),
|
merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(),
|
||||||
merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(),
|
merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(),
|
||||||
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(), merc->GetMercID());
|
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(), merc->GetMercID());
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
owner->Message(13, results.ErrorMessage().c_str());
|
owner->Message(13, results.ErrorMessage().c_str());
|
||||||
@ -2388,23 +2390,25 @@ bool ZoneDatabase::DeleteMerc(uint32 merc_id) {
|
|||||||
if(merc_id == 0)
|
if(merc_id == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool firstQueryWorked = false;
|
|
||||||
// TODO: These queries need to be ran together as a transaction.. ie,
|
// TODO: These queries need to be ran together as a transaction.. ie,
|
||||||
// if one or more fail then they all will fail to commit to the database.
|
// if one or more fail then they all will fail to commit to the database.
|
||||||
std::string query = StringFormat("DELETE FROM merc_buffs WHERE MercID = '%u'", merc_id);
|
// ...Not all mercs will have buffs, so why is it required that both deletes succeed?
|
||||||
|
std::string query = StringFormat("DELETE FROM merc_buffs WHERE MercId = '%u'", merc_id);
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!results.Success())
|
if(!results.Success())
|
||||||
LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str());
|
{
|
||||||
else
|
LogFile->write(EQEMuLog::Error, "Error Deleting Merc Buffs: %s", results.ErrorMessage().c_str());
|
||||||
firstQueryWorked = true;
|
}
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM mercs WHERE MercID = '%u'", merc_id);
|
query = StringFormat("DELETE FROM mercs WHERE MercID = '%u'", merc_id);
|
||||||
if(!results.Success()) {
|
results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
{
|
||||||
LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str());
|
LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return firstQueryWorked;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::LoadMercEquipment(Merc *merc) {
|
void ZoneDatabase::LoadMercEquipment(Merc *merc) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user