From fb308eaa01f4555d3433b21beed01980ab891c6d Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 3 Sep 2016 17:08:48 -0400 Subject: [PATCH 01/16] Rule-based update to 'Bind Wound' behavior --- changelog.txt | 4 + common/ruletypes.h | 2 + .../2016_09_03_old_bind_wound_rule.sql | 1 + zone/client.cpp | 148 ++++++++++++------ 4 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql diff --git a/changelog.txt b/changelog.txt index 2aa32e8ac..b2d7c7b05 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/03/2016 == +Uleat: Changed 'Bind Wound' behavior to match the best references that I could find for post-2004 era. + Note: If you wish to retain the old method, source in the optional '2016_09_03_old_bind_wound_rule.sql' script file. + == 08/27/2016 == Kinglykrab: Added optional IP-based account exemptions. - To use this system simply set World:EnableIPExemptions to true and create an entry in the ip_exemptions table. diff --git a/common/ruletypes.h b/common/ruletypes.h index f1898a559..7837834f9 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -145,6 +145,8 @@ RULE_BOOL(Character, UseStackablePickPocketing, true) // Allows stackable pickpo RULE_BOOL(Character, EnableAvoidanceCap, false) RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen people dodge all attacks beyond 1,000 Avoidance RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable +RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior + RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql b/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql new file mode 100644 index 000000000..87791d59b --- /dev/null +++ b/utils/sql/git/optional/2016_09_03_old_bind_wound_rule.sql @@ -0,0 +1 @@ +INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:UseOldBindWound', 'true', 'Uses the original bind wound behavior'); diff --git a/zone/client.cpp b/zone/client.cpp index 59998bfdb..3a7b60eb5 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2655,60 +2655,120 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) bind_out->type = 0; CheckIncreaseSkill(EQEmu::skills::SkillBindWound, nullptr, 5); - int maxHPBonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + - aabonuses.MaxBindWound; + if (RuleB(Character, UseOldBindWound)) { + int maxHPBonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + + aabonuses.MaxBindWound; - int max_percent = 50 + 10 * maxHPBonus; + int max_percent = 50 + maxHPBonus; - if (GetClass() == MONK && GetSkill(EQEmu::skills::SkillBindWound) > 200) { - max_percent = 70 + 10 * maxHPBonus; - } - - max_percent = mod_bindwound_percent(max_percent, bindmob); - - int max_hp = bindmob->GetMaxHP() * max_percent / 100; - - // send bindmob new hp's - if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() <= (max_hp)-1) { - // 0.120 per skill point, 0.60 per skill level, minimum 3 max 30 - int bindhps = 3; - - if (GetSkill(EQEmu::skills::SkillBindWound) > 200) { - bindhps += GetSkill(EQEmu::skills::SkillBindWound) * 4 / 10; - } - else if (GetSkill(EQEmu::skills::SkillBindWound) >= 10) { - bindhps += GetSkill(EQEmu::skills::SkillBindWound) / 4; + if (GetClass() == MONK && GetSkill(EQEmu::skills::SkillBindWound) > 200) { + max_percent = 70 + maxHPBonus; } - // Implementation of aaMithanielsBinding is a guess (the multiplier) - int bindBonus = spellbonuses.BindWound + itembonuses.BindWound + + max_percent = mod_bindwound_percent(max_percent, bindmob); + + int max_hp = bindmob->GetMaxHP() * max_percent / 100; + + // send bindmob new hp's + if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() <= (max_hp)-1) { + // 0.120 per skill point, 0.60 per skill level, minimum 3 max 30 + int bindhps = 3; + + if (GetSkill(EQEmu::skills::SkillBindWound) > 200) { + bindhps += GetSkill(EQEmu::skills::SkillBindWound) * 4 / 10; + } + else if (GetSkill(EQEmu::skills::SkillBindWound) >= 10) { + bindhps += GetSkill(EQEmu::skills::SkillBindWound) / 4; + } + + // Implementation of aaMithanielsBinding is a guess (the multiplier) + int bindBonus = spellbonuses.BindWound + itembonuses.BindWound + aabonuses.BindWound; - bindhps += bindhps * bindBonus / 100; + bindhps += bindhps * bindBonus / 100; - bindhps = mod_bindwound_hp(bindhps, bindmob); + bindhps = mod_bindwound_hp(bindhps, bindmob); - // if the bind takes them above the max bindable - // cap it at that value. Dont know if live does it this way - // but it makes sense to me. - int chp = bindmob->GetHP() + bindhps; - if (chp > max_hp) - chp = max_hp; + // if the bind takes them above the max bindable + // cap it at that value. Dont know if live does it this way + // but it makes sense to me. + int chp = bindmob->GetHP() + bindhps; + if (chp > max_hp) + chp = max_hp; - bindmob->SetHP(chp); - bindmob->SendHPUpdate(); - } else { - // I dont have the real, live - Message(15, "You cannot bind wounds above %d%% hitpoints.", - max_percent); - if (bindmob != this && bindmob->IsClient()) - bindmob->CastToClient()->Message( - 15, - "You cannot have your wounds bound above %d%% hitpoints.", - max_percent); - // Too many hp message goes here. + bindmob->SetHP(chp); + bindmob->SendHPUpdate(); + } + else { + // I dont have the real, live + Message(15, "You cannot bind wounds above %d%% hitpoints.", + max_percent); + if (bindmob != this && bindmob->IsClient()) + bindmob->CastToClient()->Message( + 15, + "You cannot have your wounds bound above %d%% hitpoints.", + max_percent); + // Too many hp message goes here. + } } - } else { + else { + int percent_base = 50; + if (GetRawSkill(EQEmu::skills::SkillBindWound) > 200) { + if ((GetClass() == MONK) || (GetClass() == BEASTLORD)) + percent_base = 70; + else if ((GetLevel() > 50) && ((GetClass() == WARRIOR) || (GetClass() == ROGUE) || (GetClass() == CLERIC))) + percent_base = 70; + } + + int percent_bonus = 0; + if (percent_base >= 70) + percent_bonus = spellbonuses.MaxBindWound + itembonuses.MaxBindWound + aabonuses.MaxBindWound; + + int max_percent = percent_base + percent_bonus; + if (max_percent < 0) + max_percent = 0; + if (max_percent > 100) + max_percent = 100; + + max_percent = mod_bindwound_percent(max_percent, bindmob); + + int max_hp = (bindmob->GetMaxHP() * max_percent) / 100; + if (max_hp > bindmob->GetMaxHP()) + max_hp = bindmob->GetMaxHP(); + + if (bindmob->GetHP() < bindmob->GetMaxHP() && bindmob->GetHP() < max_hp) { + int bindhps = 3; // base bind hp + if (percent_base >= 70) + bindhps = (GetSkill(EQEmu::skills::SkillBindWound) * 4) / 10; // 8:5 skill-to-hp ratio + else if (GetSkill(EQEmu::skills::SkillBindWound) >= 12) + bindhps = GetSkill(EQEmu::skills::SkillBindWound) / 4; // 4:1 skill-to-hp ratio + + int bonus_hp_percent = 0; + if (percent_base >= 70) + bonus_hp_percent = spellbonuses.BindWound + itembonuses.BindWound + aabonuses.BindWound; + + bindhps += (bindhps * bonus_hp_percent) / 100; + + if (bindhps < 3) + bindhps = 3; + + bindhps = mod_bindwound_hp(bindhps, bindmob); + + bindhps += bindmob->GetHP(); + if (bindhps > max_hp) + bindhps = max_hp; + + bindmob->SetHP(bindhps); + bindmob->SendHPUpdate(); + } + else { + Message(15, "You cannot bind wounds above %d%% hitpoints", max_percent); + if (bindmob != this && bindmob->IsClient()) + bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints", max_percent); + } + } + } + else { // Send client bind failed if (bindmob != this) bind_out->type = 6; // They moved From 739b1bfaa32b5af433e00208e63727136c0f0d79 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 3 Sep 2016 21:54:59 -0400 Subject: [PATCH 02/16] Fix target buffs showing PC songs --- zone/spells.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 2e99e97a9..c818c8e90 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -5458,8 +5458,10 @@ void Mob::SendBuffsToClient(Client *c) EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target) { uint32 count = 0; - uint32 buff_count = GetMaxTotalSlots(); - for(unsigned int i = 0; i < buff_count; ++i) + // for self we want all buffs, for target, we want to skip song window buffs + // since NPCs and pets don't have a song window, we still see it for them :P + uint32 buff_count = for_target ? GetMaxBuffSlots() : GetMaxTotalSlots(); + for(int i = 0; i < buff_count; ++i) { if(buffs[i].spellid != SPELL_UNKNOWN) { @@ -5491,7 +5493,7 @@ EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target) buff->type = 0; uint32 index = 0; - for(unsigned int i = 0; i < buff_count; ++i) + for(int i = 0; i < buff_count; ++i) { if(buffs[i].spellid != SPELL_UNKNOWN) { From d0bb3047f03e3471b965917c2d8527bdd1a72b08 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 4 Sep 2016 20:59:39 -0400 Subject: [PATCH 03/16] Let's fix the fear pathing flags right away after SE_ImmuneFleeing This speeds up the response to spells like Call of Challenge Before it would fix the flags the next tick, which makes the spell mostly useless --- zone/bonuses.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 2a8a0c790..1a49aaf66 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2529,6 +2529,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne case SE_ImmuneFleeing: new_bonus->ImmuneToFlee = true; + if (currently_fleeing) // lets update shit now instead of next tick + ProcessFlee(); break; case SE_DelayDeath: From 77974c83d70c349691a0f659010a684645e93c14 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 5 Sep 2016 02:31:28 -0500 Subject: [PATCH 04/16] Update eqemu_server.pl [skip ci] --- utils/scripts/eqemu_server.pl | 476 ++++++++++++++++++++++++++++------ 1 file changed, 391 insertions(+), 85 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 484c5f306..467912b51 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -24,8 +24,22 @@ $eqemu_repository_request_url = "https://raw.githubusercontent.com/EQEmu/Server/ #::: Globals $time_stamp = strftime('%m-%d-%Y', gmtime()); $db_run_stage = 0; #::: Sets database run stage check -if($Config{osname}=~/freebsd|linux/i){ $OS = "Linux"; } -if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; } +if($Config{osname}=~/freebsd|linux/i){ + $OS = "Linux"; + $os_flavor = ""; + if(-e "/etc/debian_version"){ + $os_flavor = "debian"; + } + if(-e "/etc/fedora-release"){ + $os_flavor = "fedora_core"; + } + if(-e "/etc/redhat-release"){ + $os_flavor = "red_hat"; + } +} +if($Config{osname}=~/Win|MS/i){ + $OS = "Windows"; +} $has_internet_connection = check_internet_connection(); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); @@ -38,9 +52,7 @@ get_mysql_path(); #::: Remove old eqemu_update.pl if(-e "eqemu_update.pl"){ unlink("eqemu_update.pl"); -} -#::: Create db_update working directory if not created -mkdir('db_update'); +} print "[Info] For EQEmu Server management utilities - run eqemu_server.pl\n" if $ARGV[0] eq "ran_from_world"; @@ -51,12 +63,11 @@ if(trim(get_mysql_result("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne "" } check_db_version_table(); - check_for_world_bootup_database_update(); if($db){ print "[Update] MySQL Path/Location: " . $path . "\n"; - print "[Update] Binary Revision / Local: (" . $binary_database_version . " / " . $local_database_version . ")\n"; + print "[Update] Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version . "\n"; #::: Bots #::: Make sure we're running a bots binary to begin with @@ -73,81 +84,318 @@ if($db){ exit; } } - -if($ARGV[0] eq "remove_duplicate_rules"){ - remove_duplicate_rule_values(); - exit; + +sub urlencode { + my ($rv) = @_; + $rv =~ s/([^A-Za-z0-9])/sprintf("%%%2.2X", ord($1))/ge; + return $rv; } +sub urldecode { + my ($rv) = @_; + $rv =~ s/\+/ /g; + $rv =~ s/%(..)/pack("c",hex($1))/ge; + return $rv; +} + +sub analytics_insertion { + $event_name = urlencode($_[0]); + $event_data = urlencode($_[1]); + + #::: Check for internet connection before doing analytics + if(!$has_internet_connection || $can_see_analytics_server == -1){ + return; + } + + #::: Check for analytics server connectivity so that the script doesn't break when its offline + if(!$can_see_analytics_server){ + if($OS eq "Linux"){ + $count = "c"; + } + if($OS eq "Windows"){ + $count = "n"; + } + + if (`ping analytics.akkadius.com -$count 1 -w 500`=~/Reply from|1 received/i) { + $can_see_analytics_server = 1; + } + else { + $can_see_analytics_server = -1; + } + } + + $server_name = ""; + if($long_name){ + $server_name = "&server_name=" . urlencode($long_name); + } + + if(!$extended_os){ + if($OS eq "Linux"){ + $extended_os = `cat /proc/version`; + $extended_os = trim($extended_os); + } + if($OS eq "Windows"){ + my $output = `ver`; + my @os_version = split("\n", $output); + foreach my $val (@os_version){ + if($val=~/Windows/i){ + $extended_os = trim($val); + } + } + } + } + + $url = "http://analytics.akkadius.com/"; + $url .= "?api_key=24a0bde2e5bacd65bcab06a9ac40b62c"; + $url .= "&event=" . $event_name; + $url .= "&event_data=" . $event_data; + $url .= "&OS=" . urlencode($OS); + $url .= "&extended_os=" . urlencode($extended_os); + $url .= $server_name; + + # print "Calling url :: '" . $url . "'\n"; + + if($OS eq "Windows"){ + eval('require LWP::UserAgent;'); + my $ua = LWP::UserAgent->new; + $ua->timeout(1); + $ua->env_proxy; + my $response = $ua->get($url); + } + if($OS eq "Linux"){ + $api_call = `curl -s "$url"`; + } +} + +#::: Command line argument calls +if($ARGV[0]){ + analytics_insertion("cli", trim($ARGV[0])); +} +if($ARGV[0] eq "do_install_config_xml"){ + do_install_config_xml(); + exit; +} +if($ARGV[0] eq "show_install_summary_info"){ + show_install_summary_info(); +} +if($ARGV[0] eq "remove_duplicate_rules"){ + remove_duplicate_rule_values(); + exit; +} if($ARGV[0] eq "map_files_fetch_bulk"){ map_files_fetch_bulk(); exit; } - if($ARGV[0] eq "loginserver_install_linux"){ do_linux_login_server_setup(); exit; } - if($ARGV[0] eq "new_server"){ - while(1){ - print "For a new server folder install, we assume Perl and MySQL are configured\n"; - print "This will install a fresh PEQ Database, with all server assets\n"; - print "You will need to supply database credentials to get started...\n"; - - check_for_input("MySQL User: "); - $database_user = trim($input); + new_server(); + show_install_summary_info(); + exit; +} +if($ARGV[0] eq "installer"){ + analytics_insertion("full_install", "Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); + do_installer_routines(); + show_install_summary_info(); + exit; +} +if($ARGV[0] eq "db_dump_compress"){ + database_dump_compress(); + exit; +} +if($ARGV[0] eq "login_server_setup"){ + do_windows_login_server_setup(); + exit; +} - check_for_input("MySQL Password: "); - $database_password = trim($input); +sub show_install_summary_info { + print "[Install] Installation complete...\n"; + print "[Install] Server Info (Save somewhere if needed):\n"; + + if (-e "install_variables.txt") { + $file_to_open = "install_variables.txt"; + } + elsif(-e "../install_variables.txt"){ + $file_to_open = "../install_variables.txt"; + } + open (INSTALL_VARS, $file_to_open); + while (){ + chomp; + $o = $_; + @data = split(":", $o); + print " - " . $data[0] . "\t" . $data[1] . "\n"; + } + close (INSTALL_VARS); + + if($OS eq "Windows"){ + print "[Install] Windows Utility Scripts:\n"; + print " - t_start_server.bat Starts EQEmu server with 30 dynamic zones, UCS & Queryserv, dynamic zones\n"; + print " - t_start_server_with_loginserver.bat Starts EQEmu server with 30 zones with loginserver\n"; + print " - t_stop_server.bat Stops EQEmu Server (No warning)\n"; + print " - t_database_backup.bat Backs up the Database to backups/ folder - do not run during server is online\n"; + print " - t_server_crash_report.pl Will parse any zone crashes for reporting to developers\n"; + } + if($OS eq "Linux"){ + print "[Install] Linux Utility Scripts:\n"; + print " - server_start.sh Starts EQEmu server (Quiet) with 30 dynamic zones, UCS & Queryserv, dynamic zones\n"; + print " - server_start_dev.sh Starts EQEmu server with 10 dynamic zones, UCS & Queryserv, dynamic zones all verbose\n"; + print " - server_stop.sh Stops EQEmu Server (No warning)\n"; + print " - server_status.sh Prints the status of the EQEmu Server processes\n"; + } + + print "[Configure] eqemu_config.xml Edit to change server settings and name\n"; + + analytics_insertion("install_complete", "null"); +} + +sub new_server { + $file_count = 0; + opendir(DIR, ".") or die $!; + while (my $file = readdir(DIR)) { + next if ($file =~ m/^\./); + $file_count++; + } + closedir(DIR); + + if($file_count > 1 && !-e "install_variables.txt"){ + print "[New Server] ERROR: You must run eqemu_server.pl in an empty directory\n"; + <>; + exit; + } + + if(-e "install_variables.txt"){ + get_installation_variables(); + } + + while(1){ - $check_connection = `mysql -u $database_user -p$database_password -N -B -e "SHOW PROCESSLIST" > mysqlcheck.txt`; - $mysql_pass = 0; - open (MYSQL_CHECK, "mysqlcheck.txt"); - while (){ - chomp; - $o = $_; - if($o=~/Error/i){ $mysql_pass = 0;} - if($o=~/SHOW PROCESSLIST/i){ $mysql_pass = 1; } - } - close (MYSQL_CHECK); - unlink("mysqlcheck.txt"); + $database_name = $installation_variables{"mysql_eqemu_db_name"}; + $database_user = $installation_variables{"mysql_eqemu_user"}; + $database_password = $installation_variables{"mysql_eqemu_password"}; - if($mysql_pass == 1){ - print "Success! We have a database connection\n"; - - check_for_input("Specify a database name: "); - $database_name = trim($input); - - #::: Write install vars - open (INSTALL_VARS, '>', 'install_variables.txt'); - print INSTALL_VARS ""; - print INSTALL_VARS "mysql_eqemu_db_name:" . $database_name . "\n"; - print INSTALL_VARS "mysql_eqemu_user:" . $database_user . "\n"; - print INSTALL_VARS "mysql_eqemu_password:" . $database_password . "\n"; - close (INSTALL_VARS); - - do_installer_routines(); + if($database_name ne ""){ + $mysql_pass = 1; } else { - print "Authorization failed\n"; + + print "\n"; + print "[New Server] For a new server folder install, we assume Perl and MySQL are configured\n"; + print "[New Server] This will install a fresh PEQ Database, with all server assets\n"; + print "[New Server] You will need to supply database credentials to get started...\n\n"; + + check_for_input("MySQL User: "); + $database_user = trim($input); + + check_for_input("MySQL Password: "); + $database_password = trim($input); + + $check_connection = `mysql -u $database_user -p$database_password -N -B -e "SHOW PROCESSLIST" > mysqlcheck.txt`; + $mysql_pass = 0; + open (MYSQL_CHECK, "mysqlcheck.txt"); + while (){ + chomp; + $o = $_; + if($o=~/Error/i){ $mysql_pass = 0;} + if($o=~/SHOW PROCESSLIST/i){ $mysql_pass = 1; } + } + close (MYSQL_CHECK); + unlink("mysqlcheck.txt"); + } + + if($mysql_pass == 1){ + + if(!-e "install_variables.txt"){ + print "[New Server] Success! We have a database connection\n"; + + check_for_input("Specify a NEW database name that PEQ will be installed to: "); + $database_name = trim($input); + + #::: Write install vars + open (INSTALL_VARS, '>', 'install_variables.txt'); + print INSTALL_VARS ""; + print INSTALL_VARS "mysql_eqemu_db_name:" . $database_name . "\n"; + print INSTALL_VARS "mysql_eqemu_user:" . $database_user . "\n"; + print INSTALL_VARS "mysql_eqemu_password:" . $database_password . "\n"; + close (INSTALL_VARS); + } + analytics_insertion("new_server::install", $database_name); + + if($OS eq "Linux"){ + $current_directory = `pwd`; + @directories = split('/', $current_directory); + foreach my $val (@directories){ + if(trim($val) ne ""){ + $last_directory = trim($val); + } + } + my $eqemu_server_directory = "/home/eqemu"; + my $source_dir = $eqemu_server_directory . '/' . $last_directory . '_source'; + + $current_directory = trim($current_directory); + + mkdir($source_dir) if (!-e $source_dir); + + # print 'server_dir: ' . $eqemu_server_directory . "\n"; + # print 'source_dir: ' . $source_dir . "\n"; + # print 'current_dir: \'' . $current_directory . "'\n"; + + chdir($source_dir); + + print `git clone https://github.com/EQEmu/Server.git`; + + mkdir ($source_dir . "/Server/build") if (!-e $source_dir . "/Server/build"); + chdir ($source_dir . "/Server/build"); + + print "Generating CMake build files...\n"; + if($os_flavor eq "fedora_core"){ + print `cmake -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" ..`; + } + else { + print `cmake -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" ..`; + } + print "Building EQEmu Server code. This will take a while."; + + #::: Build + print `make`; + + chdir ($current_directory); + + print `ln -s $source_dir/Server/build/bin/eqlaunch .`; + print `ln -s $source_dir/Server/build/bin/export_client_files .`; + print `ln -s $source_dir/Server/build/bin/import_client_files .`; + print `ln -s $source_dir/Server/build/bin/libcommon.a .`; + print `ln -s $source_dir/Server/build/bin/libluabind.a .`; + print `ln -s $source_dir/Server/build/bin/queryserv .`; + print `ln -s $source_dir/Server/build/bin/shared_memory .`; + print `ln -s $source_dir/Server/build/bin/ucs .`; + print `ln -s $source_dir/Server/build/bin/world .`; + print `ln -s $source_dir/Server/build/bin/zone .`; + + } + + do_installer_routines(); + + if($OS eq "Linux"){ + print `chmod 755 *.sh`; + } + + analytics_insertion("new_server::install_complete", $database_name . " :: Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); + + print "[New Server] New server folder install complete\n"; + print "[New Server] Below is your installation info:\n"; + + return; + } + else { + print "[New Server] MySQL authorization failed or no MySQL installed\n"; } } } -if($ARGV[0] eq "installer"){ - do_installer_routines(); - exit; -} - -if($ARGV[0] eq "db_dump_compress"){ database_dump_compress(); exit; } -if($ARGV[0] eq "login_server_setup"){ - do_windows_login_server_setup(); - exit; -} - sub do_installer_routines { - print "[Install] Running EQEmu Server installer routines...\n"; + print "[Install] EQEmu Server Installer... LOADING... PLEASE WAIT...\n"; #::: Make some local server directories... mkdir('logs'); @@ -170,6 +418,7 @@ sub do_installer_routines { get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); } + map_files_fetch_bulk(); opcodes_fetch(); plugins_fetch(); @@ -204,13 +453,11 @@ sub do_installer_routines { } if($OS eq "Linux"){ do_linux_login_server_setup(); - - print "[Install] Installation complete!\n"; } } sub check_for_input { - print $_[0]; + print "[Input] " . $_[0]; $input = ; chomp $input; } @@ -242,6 +489,8 @@ sub check_for_world_bootup_database_update { main_db_management(); main_db_management(); print "[Update] Continuing bootup\n"; + analytics_insertion("auto database upgrade world", $db . " :: Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); + exit; } @@ -260,7 +509,7 @@ sub check_internet_connection { if($OS eq "Windows"){ $count = "n"; } - + if (`ping 8.8.8.8 -$count 1 -w 500`=~/Reply from|1 received/i) { # print "[Update] We have a connection to the internet, continuing...\n"; return 1; @@ -287,13 +536,15 @@ sub get_perl_version { } sub do_self_update_check_routine { - #::: Check Version passed from world to update script - get_remote_file($eqemu_repository_request_url . "utils/scripts/eqemu_server.pl", "updates_staged/eqemu_server.pl", 0, 1, 1); - + + #::: Check for internet connection before updating if(!$has_internet_connection){ print "[Update] Cannot check update without internet connection...\n"; return; } + + #::: Check for script changes :: eqemu_server.pl + get_remote_file($eqemu_repository_request_url . "utils/scripts/eqemu_server.pl", "updates_staged/eqemu_server.pl", 0, 1, 1); if(-e "updates_staged/eqemu_server.pl") { @@ -383,6 +634,11 @@ sub do_install_config_xml { my($replace_key) = $o =~ />(\w+)/i){ + my($replace_name) = $o =~ /(.*)<\/longname>/; + $append = '(' . generate_random_password(5) . ')'; + $o =~ s/$replace_name/Akkas $OS PEQ Installer $append/g; } if($o=~/\/i && $in_database_tag){ my($replace_username) = $o =~ />(\w+); } - } + } } sub print_main_menu { @@ -532,7 +790,9 @@ sub print_main_menu { print ">>> EQEmu Server Main Menu >>>>>>>>>>>>\n"; print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"; print " [database] Enter database management menu \n"; - print " [assets] Manage server assets \n\n"; + print " [assets] Manage server assets \n"; + print " [new_server] New folder EQEmu/PEQ install - Assumes MySQL/Perl installed \n"; + print "\n"; print " exit \n"; print "\n"; print "Enter a command #> "; @@ -568,13 +828,52 @@ sub get_mysql_path { } sub check_for_database_dump_script{ - if(`perl db_dumper.pl`=~/Need arguments/i){ - return; + #::: Check for internet connection before updating + if(!$has_internet_connection){ + print "[Update] Cannot check update without internet connection...\n"; + return; } - else{ - print "[Database] db_dumper.pl not found... retrieving...\n"; - get_remote_file($eqemu_repository_request_url . "utils/scripts/db_dumper.pl", "db_dumper.pl"); + + #::: Check for script changes :: db_dumper.pl + get_remote_file($eqemu_repository_request_url . "utils/scripts/db_dumper.pl", "updates_staged/db_dumper.pl", 0, 1, 1); + + if(-e "updates_staged/db_dumper.pl") { + + my $remote_script_size = -s "updates_staged/db_dumper.pl"; + my $local_script_size = -s "db_dumper.pl"; + + if($remote_script_size != $local_script_size){ + print "[Update] Script has been updated, updating...\n"; + + my @files; + my $start_dir = "updates_staged/"; + find( + sub { push @files, $File::Find::name unless -d; }, + $start_dir + ); + for my $file (@files) { + if($file=~/db_dumper/i){ + $destination_file = $file; + $destination_file =~s/updates_staged\///g; + print "[Install] Installing :: " . $destination_file . "\n"; + unlink($destination_file); + copy_file($file, $destination_file); + if($OS eq "Linux"){ + system("chmod 755 db_dumper.pl"); + } + } + } + print "[Install] Done\n"; + } + else { + print "[Update] No script update necessary...\n"; + } + + unlink("updates_staged/db_dumper.pl"); } + + return; + } sub database_dump { @@ -601,7 +900,7 @@ sub database_dump_player_tables { print `perl db_dumper.pl database="$db" loc="backups" tables="$tables" backup_name="player_tables_export" nolock`; print "[Database] Press any key to continue...\n"; - + <>; #Read from STDIN } @@ -762,13 +1061,11 @@ sub read_eqemu_config_xml { my $indb = 0; while() { s/\r//g; - if(//i) { $indb = 1; } - next unless($indb == 1); - if(/<\/database>/i) { $indb = 0; last; } if(/(.*)<\/host>/i) { $host = $1; } elsif(/(.*)<\/username>/i) { $user = $1; } elsif(/(.*)<\/password>/i) { $pass = $1; } elsif(/(.*)<\/db>/i) { $db = $1; } + if(/(.*)<\/longname>/i) { $long_name = $1; } } } @@ -1016,11 +1313,11 @@ sub add_login_server_firewall_rules { $val=~s/Rule Name://g; if($val=~/EQEmu Loginserver/i && $val=~/Titanium/i){ $has_loginserver_rules_titanium = 1; - print "Found existing rule :: " . trim($val) . "\n"; + print "[Install] Found existing rule :: " . trim($val) . "\n"; } if($val=~/EQEmu Loginserver/i && $val=~/SOD/i){ $has_loginserver_rules_sod = 1; - print "Found existing rule :: " . trim($val) . "\n"; + print "[Install] Found existing rule :: " . trim($val) . "\n"; } } } @@ -1619,6 +1916,13 @@ sub get_bots_db_version{ } sub bots_db_management{ + if($OS eq "Windows"){ + @db_version = split(': ', `world db_version`); + } + if($OS eq "Linux"){ + @db_version = split(': ', `./world db_version`); + } + #::: Main Binary Database version $binary_database_version = trim($db_version[2]); @@ -1637,6 +1941,8 @@ sub bots_db_management{ $bots_local_db_version = get_bots_db_version(); + $local_database_version = $bots_local_db_version; + run_database_check(); } @@ -1718,13 +2024,13 @@ sub run_database_check{ @total_updates = (); #::: This is where we set checkpoints for where a database might be so we don't check so far back in the manifest... - if($local_database_version > 9000){ + if($local_database_version >= 9000){ $revision_check = $local_database_version; } else { $revision_check = 1000; if(get_mysql_result("SHOW TABLES LIKE 'character_data'") ne ""){ - $revision_check = 9000; + $revision_check = 8999; } } From 2947e3f39f137ec7ddd200716b0eb48d76ffc1c2 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 5 Sep 2016 02:33:18 -0500 Subject: [PATCH 05/16] Update eqemu_server.pl [skip ci] --- utils/scripts/eqemu_server.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 467912b51..f128e5248 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -30,10 +30,10 @@ if($Config{osname}=~/freebsd|linux/i){ if(-e "/etc/debian_version"){ $os_flavor = "debian"; } - if(-e "/etc/fedora-release"){ + elsif(-e "/etc/fedora-release"){ $os_flavor = "fedora_core"; } - if(-e "/etc/redhat-release"){ + elsif(-e "/etc/redhat-release"){ $os_flavor = "red_hat"; } } From 0efd0c5f738da34cab983383f7c876f6bf0f691d Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 5 Sep 2016 15:26:12 -0500 Subject: [PATCH 06/16] Update eqemu_server.pl [skip ci] --- utils/scripts/eqemu_server.pl | 168 ++++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 71 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index f128e5248..b5ddb4cc8 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -171,21 +171,9 @@ sub analytics_insertion { if($ARGV[0]){ analytics_insertion("cli", trim($ARGV[0])); } -if($ARGV[0] eq "do_install_config_xml"){ - do_install_config_xml(); - exit; -} if($ARGV[0] eq "show_install_summary_info"){ show_install_summary_info(); } -if($ARGV[0] eq "remove_duplicate_rules"){ - remove_duplicate_rule_values(); - exit; -} -if($ARGV[0] eq "map_files_fetch_bulk"){ - map_files_fetch_bulk(); - exit; -} if($ARGV[0] eq "loginserver_install_linux"){ do_linux_login_server_setup(); exit; @@ -205,10 +193,6 @@ if($ARGV[0] eq "db_dump_compress"){ database_dump_compress(); exit; } -if($ARGV[0] eq "login_server_setup"){ - do_windows_login_server_setup(); - exit; -} sub show_install_summary_info { print "[Install] Installation complete...\n"; @@ -323,56 +307,7 @@ sub new_server { analytics_insertion("new_server::install", $database_name); if($OS eq "Linux"){ - $current_directory = `pwd`; - @directories = split('/', $current_directory); - foreach my $val (@directories){ - if(trim($val) ne ""){ - $last_directory = trim($val); - } - } - my $eqemu_server_directory = "/home/eqemu"; - my $source_dir = $eqemu_server_directory . '/' . $last_directory . '_source'; - - $current_directory = trim($current_directory); - - mkdir($source_dir) if (!-e $source_dir); - - # print 'server_dir: ' . $eqemu_server_directory . "\n"; - # print 'source_dir: ' . $source_dir . "\n"; - # print 'current_dir: \'' . $current_directory . "'\n"; - - chdir($source_dir); - - print `git clone https://github.com/EQEmu/Server.git`; - - mkdir ($source_dir . "/Server/build") if (!-e $source_dir . "/Server/build"); - chdir ($source_dir . "/Server/build"); - - print "Generating CMake build files...\n"; - if($os_flavor eq "fedora_core"){ - print `cmake -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" ..`; - } - else { - print `cmake -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" ..`; - } - print "Building EQEmu Server code. This will take a while."; - - #::: Build - print `make`; - - chdir ($current_directory); - - print `ln -s $source_dir/Server/build/bin/eqlaunch .`; - print `ln -s $source_dir/Server/build/bin/export_client_files .`; - print `ln -s $source_dir/Server/build/bin/import_client_files .`; - print `ln -s $source_dir/Server/build/bin/libcommon.a .`; - print `ln -s $source_dir/Server/build/bin/libluabind.a .`; - print `ln -s $source_dir/Server/build/bin/queryserv .`; - print `ln -s $source_dir/Server/build/bin/shared_memory .`; - print `ln -s $source_dir/Server/build/bin/ucs .`; - print `ln -s $source_dir/Server/build/bin/world .`; - print `ln -s $source_dir/Server/build/bin/zone .`; - + build_linux_source(); } do_installer_routines(); @@ -394,6 +329,69 @@ sub new_server { } } +sub build_linux_source { + + $build_options = $_[0]; + + $cmake_options = ""; + $source_folder_post_fix = ""; + + if($build_options =~/bots/i){ + $cmake_options .= " -DEQEMU_ENABLE_BOTS=ON"; + $source_folder_post_fix = "_bots"; + } + + $current_directory = `pwd`; + @directories = split('/', $current_directory); + foreach my $val (@directories){ + if(trim($val) ne ""){ + $last_directory = trim($val); + } + } + my $eqemu_server_directory = "/home/eqemu"; + my $source_dir = $eqemu_server_directory . '/' . $last_directory . '_source' . $source_folder_post_fix; + + $current_directory = trim($current_directory); + + mkdir($source_dir) if (!-e $source_dir); + + # print 'server_dir: ' . $eqemu_server_directory . "\n"; + # print 'source_dir: ' . $source_dir . "\n"; + # print 'current_dir: \'' . $current_directory . "'\n"; + + chdir($source_dir); + + print `git clone https://github.com/EQEmu/Server.git`; + + mkdir ($source_dir . "/Server/build") if (!-e $source_dir . "/Server/build"); + chdir ($source_dir . "/Server/build"); + + print "Generating CMake build files...\n"; + if($os_flavor eq "fedora_core"){ + print `cmake $cmake_options -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" ..`; + } + else { + print `cmake $cmake_options -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" ..`; + } + print "Building EQEmu Server code. This will take a while."; + + #::: Build + print `make`; + + chdir ($current_directory); + + print `ln -s -f $source_dir/Server/build/bin/eqlaunch .`; + print `ln -s -f $source_dir/Server/build/bin/export_client_files .`; + print `ln -s -f $source_dir/Server/build/bin/import_client_files .`; + print `ln -s -f $source_dir/Server/build/bin/libcommon.a .`; + print `ln -s -f $source_dir/Server/build/bin/libluabind.a .`; + print `ln -s -f $source_dir/Server/build/bin/queryserv .`; + print `ln -s -f $source_dir/Server/build/bin/shared_memory .`; + print `ln -s -f $source_dir/Server/build/bin/ucs .`; + print `ln -s -f $source_dir/Server/build/bin/world .`; + print `ln -s -f $source_dir/Server/build/bin/zone .`; +} + sub do_installer_routines { print "[Install] EQEmu Server Installer... LOADING... PLEASE WAIT...\n"; @@ -495,7 +493,7 @@ sub check_for_world_bootup_database_update { } #::: Make sure that we didn't pass any arugments to the script - if(!$ARGV[0]){ + else { if(!$db){ print "[eqemu_server.pl] No database connection found... Running without\n"; } show_menu_prompt(); } @@ -528,7 +526,7 @@ sub get_perl_version { #::: Check Perl version $perl_version = $^V; $perl_version =~s/v//g; - print "[Update] Perl Version is " . $perl_version . "\n"; + print "[Update] Perl Version is " . $perl_version . "\n" if $debug; if($perl_version > 5.12){ no warnings 'uninitialized'; } @@ -688,18 +686,37 @@ sub fetch_utility_scripts { } } +sub setup_bots { + if($OS eq "Windows"){ + fetch_latest_windows_binaries_bots(); + } + if($OS eq "Linux"){ + build_linux_source("bots"); + } + bots_db_management(); + run_database_check(); + + print "Bots should be setup, run your server and the #bot command should be available in-game\n"; +} + sub show_menu_prompt { $dc = 0; while (1) { - $input = trim($input); + + if($ARGV[0] ne ""){ + $input = trim($ARGV[0]); + } + else { + $input = trim($input); + } $errored_command = 0; if($input eq "database"){ print "\n>>> Database Menu\n\n"; print " [backup_database] Back up database to backups/ directory\n"; - print " [backup_player_tables] Back up player tables to backups/ directory\n"; + print " [backup_player_tables] Back up player tables to backups/ directory\n"; print " [backup_database_compressed] Back up database compressed to backups/ directory\n"; print " \n"; print " [check_db_updates] Checks for database updates manually\n"; @@ -747,10 +764,11 @@ sub show_menu_prompt { elsif($input eq "windows_server_download_bots"){ fetch_latest_windows_binaries_bots(); $dc = 1; } elsif($input eq "fetch_dlls"){ fetch_server_dlls(); $dc = 1; } elsif($input eq "utility_scripts"){ fetch_utility_scripts(); $dc = 1; } - elsif($input eq "check_db_updates"){ main_db_management(); $dc = 1; } + elsif($input eq "check_db_updates"){ main_db_management(); main_db_management(); $dc = 1; } elsif($input eq "check_bot_db_updates"){ bots_db_management(); run_database_check(); $dc = 1; } elsif($input eq "setup_loginserver"){ do_windows_login_server_setup(); $dc = 1; } elsif($input eq "new_server"){ new_server(); $dc = 1; } + elsif($input eq "setup_bots"){ setup_bots(); $dc = 1; } elsif($input eq "exit"){ exit; } @@ -782,6 +800,13 @@ sub show_menu_prompt { else { $input = <>; } + + #::: If we're processing a CLI command, kill the loop + if($ARGV[0] ne ""){ + $input = ""; + $ARGV[0] = ""; + exit; + } } } @@ -792,6 +817,7 @@ sub print_main_menu { print " [database] Enter database management menu \n"; print " [assets] Manage server assets \n"; print " [new_server] New folder EQEmu/PEQ install - Assumes MySQL/Perl installed \n"; + print " [setup_bots] Enables bots on server - builds code and database requirements \n"; print "\n"; print " exit \n"; print "\n"; From 5b03fba463a5c74c6bde06492728a21fdf675d56 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 20:04:21 -0500 Subject: [PATCH 07/16] Update eqemu_server.pl - Fix windows installs [skip ci] --- utils/scripts/eqemu_server.pl | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index b5ddb4cc8..3d66f9df5 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -168,31 +168,13 @@ sub analytics_insertion { } #::: Command line argument calls -if($ARGV[0]){ - analytics_insertion("cli", trim($ARGV[0])); -} -if($ARGV[0] eq "show_install_summary_info"){ - show_install_summary_info(); -} -if($ARGV[0] eq "loginserver_install_linux"){ - do_linux_login_server_setup(); - exit; -} -if($ARGV[0] eq "new_server"){ - new_server(); - show_install_summary_info(); - exit; -} if($ARGV[0] eq "installer"){ + print "Hi\n"; analytics_insertion("full_install", "Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); - do_installer_routines(); + new_server(); show_install_summary_info(); exit; } -if($ARGV[0] eq "db_dump_compress"){ - database_dump_compress(); - exit; -} sub show_install_summary_info { print "[Install] Installation complete...\n"; @@ -321,6 +303,8 @@ sub new_server { print "[New Server] New server folder install complete\n"; print "[New Server] Below is your installation info:\n"; + show_install_summary_info(); + return; } else { From 5f1141dfb1e99e9874a0c699916b8116ff56b36b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 22:04:38 -0500 Subject: [PATCH 08/16] eqemu_server.pl - Auto update bots database on world bootup if bots enabled [skip ci] --- utils/scripts/eqemu_server.pl | 58 +- utils/scripts/eqemu_update.pl | 1789 --------------------------------- 2 files changed, 27 insertions(+), 1820 deletions(-) delete mode 100644 utils/scripts/eqemu_update.pl diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 3d66f9df5..0cf23b9cb 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -65,26 +65,6 @@ if(trim(get_mysql_result("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne "" check_db_version_table(); check_for_world_bootup_database_update(); -if($db){ - print "[Update] MySQL Path/Location: " . $path . "\n"; - print "[Update] Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version . "\n"; - - #::: Bots - #::: Make sure we're running a bots binary to begin with - if(trim($db_version[2]) > 0){ - $bots_local_db_version = get_bots_db_version(); - if($bots_local_db_version > 0){ - print "[Update] (Bots) Binary Revision / Local: (" . trim($db_version[2]) . " / " . $bots_local_db_version . ")\n"; - } - } - - #::: If World ran this script, and our version is up to date, continue... - if($binary_database_version <= $local_database_version && $ARGV[0] eq "ran_from_world"){ - print "[Update] Database up to Date: Continuing World Bootup...\n"; - exit; - } -} - sub urlencode { my ($rv) = @_; $rv =~ s/([^A-Za-z0-9])/sprintf("%%%2.2X", ord($1))/ge; @@ -167,15 +147,6 @@ sub analytics_insertion { } } -#::: Command line argument calls -if($ARGV[0] eq "installer"){ - print "Hi\n"; - analytics_insertion("full_install", "Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); - new_server(); - show_install_summary_info(); - exit; -} - sub show_install_summary_info { print "[Install] Installation complete...\n"; print "[Install] Server Info (Save somewhere if needed):\n"; @@ -429,6 +400,8 @@ sub do_installer_routines { print "[Database] Applying Latest Database Updates...\n"; main_db_management(); + remove_duplicate_rule_values(); + if($OS eq "Windows"){ check_windows_firewall_rules(); do_windows_login_server_setup(); @@ -455,12 +428,35 @@ sub check_for_world_bootup_database_update { $binary_database_version = trim($db_version[1]); $local_database_version = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); + #::: Bots + $bots_binary_version = trim($db_version[2]); + if($bots_binary_version > 0){ + $bots_local_db_version = get_bots_db_version(); + #::: We ran world - Database needs to update, lets backup and run updates and continue world bootup + + if($bots_local_db_version < $bots_binary_version && $ARGV[0] eq "ran_from_world"){ + print "[Update] Bots Database not up to date with binaries... Automatically updating...\n"; + print "[Update] Issuing database backup first...\n"; + database_dump_compress(); + print "[Update] Updating bots database...\n"; + sleep(1); + bots_db_management(); + run_database_check(); + print "[Update] Continuing bootup\n"; + analytics_insertion("auto database bots upgrade world", $db . " :: Binary DB Version / Local DB Version :: " . $binary_database_version . " / " . $local_database_version); + + exit; + } + else { + print "[Update] Bots database up to Date: Continuing World Bootup...\n"; + } + } + if($binary_database_version == $local_database_version && $ARGV[0] eq "ran_from_world"){ print "[Update] Database up to date...\n"; exit; } else { - #::: We ran world - Database needs to update, lets backup and run updates and continue world bootup if($local_database_version < $binary_database_version && $ARGV[0] eq "ran_from_world"){ print "[Update] Database not up to date with binaries... Automatically updating...\n"; @@ -485,7 +481,7 @@ sub check_for_world_bootup_database_update { } sub check_internet_connection { - if($OS eq "Linux"){ + if($OS eq "Linux"){ $count = "c"; } if($OS eq "Windows"){ diff --git a/utils/scripts/eqemu_update.pl b/utils/scripts/eqemu_update.pl deleted file mode 100644 index cb94dca0a..000000000 --- a/utils/scripts/eqemu_update.pl +++ /dev/null @@ -1,1789 +0,0 @@ -#!/usr/bin/perl - -########################################################### -#::: General EQEmu Server Administration Script -#::: Purpose - Handles: -#::: Automatic database versioning (bots and normal DB) -#::: Updating server assets (binary, opcodes, maps, configuration files) -#::: Original Author: Akkadius -#::: Contributors: Uleat -#::: Purpose: To upgrade databases with ease and maintain versioning -########################################################### - -use Config; -use File::Copy qw(copy); -use POSIX qw(strftime); -use File::Path; -use File::Find; -use Time::HiRes qw(usleep); - -#::: Variables -$install_repository_request_url = "https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/"; -$eqemu_repository_request_url = "https://raw.githubusercontent.com/EQEmu/Server/master/"; - -#::: Globals -$time_stamp = strftime('%m-%d-%Y', gmtime()); -$db_run_stage = 0; #::: Sets database run stage check -if($Config{osname}=~/freebsd|linux/i){ $OS = "Linux"; } -if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; } -$has_internet_connection = check_internet_connection(); -($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); - -#::: Check for script self update -do_self_update_check_routine(); -get_perl_version(); -read_eqemu_config_xml(); -get_mysql_path(); - -#::: Remove old eqemu_update.pl -if(-e "eqemu_update.pl"){ - unlink("eqemu_update.pl"); -} -#::: Create db_update working directory if not created -mkdir('db_update'); - -print "[Info] For EQEmu Server management utilities - run eqemu_server.pl\n"; - -#::: Check if db_version table exists... -if(trim(get_mysql_result("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne "" && $db){ - print get_mysql_result("DROP TABLE db_version"); - print "[Database] Old db_version table present, dropping...\n\n"; -} - -check_db_version_table(); - -check_for_world_bootup_database_update(); - -if($db){ - print "[Update] MySQL Path/Location: " . $path . "\n"; - print "[Update] Binary Revision / Local: (" . $binary_database_version . " / " . $local_database_version . ")\n"; - - #::: Bots - #::: Make sure we're running a bots binary to begin with - if(trim($db_version[2]) > 0){ - $bots_local_db_version = get_bots_db_version(); - if($bots_local_db_version > 0){ - print "[Update] (Bots) Binary Revision / Local: (" . trim($db_version[2]) . " / " . $bots_local_db_version . ")\n"; - } - } - - #::: If World ran this script, and our version is up to date, continue... - if($binary_database_version <= $local_database_version && $ARGV[0] eq "ran_from_world"){ - print "[Update] Database up to Date: Continuing World Bootup...\n"; - exit; - } -} - -if($ARGV[0] eq "remove_duplicate_rules"){ - remove_duplicate_rule_values(); - exit; -} - -if($ARGV[0] eq "map_files_fetch_bulk"){ - map_files_fetch_bulk(); - exit; -} - -if($ARGV[0] eq "loginserver_install_linux"){ - do_linux_login_server_setup(); - exit; -} - -if($ARGV[0] eq "installer"){ - print "[Install] Running EQEmu Server installer routines...\n"; - - #::: Make some local server directories... - mkdir('logs'); - mkdir('updates_staged'); - mkdir('shared'); - - do_install_config_xml(); - read_eqemu_config_xml(); - get_installation_variables(); - - $db_name = "peq"; - if($installation_variables{"mysql_eqemu_db_name"}){ - $db_name = $installation_variables{"mysql_eqemu_db_name"}; - } - - #::: Download assets - if($OS eq "Windows"){ - fetch_latest_windows_binaries(); - get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); - get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); - get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); - } - map_files_fetch_bulk(); - opcodes_fetch(); - plugins_fetch(); - quest_files_fetch(); - lua_modules_fetch(); - fetch_utility_scripts(); - - #::: Database Routines - print "[Database] Creating Database '" . $db_name . "'\n"; - print `"$path" --host $host --user $user --password="$pass" -N -B -e "DROP DATABASE IF EXISTS $db_name;"`; - print `"$path" --host $host --user $user --password="$pass" -N -B -e "CREATE DATABASE $db_name"`; - - #::: Get Binary DB version - if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); } - if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); } - $binary_database_version = trim($db_version[1]); - - #::: Local DB Version - check_db_version_table(); - $local_database_version = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); - - #::: Download PEQ latest - fetch_peq_db_full(); - print "[Database] Fetching Latest Database Updates...\n"; - main_db_management(); - print "[Database] Applying Latest Database Updates...\n"; - main_db_management(); - - if($OS eq "Windows"){ - check_windows_firewall_rules(); - do_windows_login_server_setup(); - } - if($OS eq "Linux"){ - do_linux_login_server_setup(); - - print "[Install] Installation complete!\n"; - } - - exit; -} - -if($ARGV[0] eq "db_dump_compress"){ database_dump_compress(); exit; } -if($ARGV[0] eq "login_server_setup"){ - do_windows_login_server_setup(); - exit; -} - -sub check_for_world_bootup_database_update { - if($OS eq "Windows"){ - @db_version = split(': ', `world db_version`); - } - if($OS eq "Linux"){ - @db_version = split(': ', `./world db_version`); - } - - $binary_database_version = trim($db_version[1]); - $local_database_version = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); - - if($binary_database_version == $local_database_version && $ARGV[0] eq "ran_from_world"){ - print "[Update] Database up to date...\n"; - exit; - } - else { - - #::: We ran world - Database needs to update, lets backup and run updates and continue world bootup - if($local_database_version < $binary_database_version && $ARGV[0] eq "ran_from_world"){ - print "[Update] Database not up to date with binaries... Automatically updating...\n"; - print "[Update] Issuing database backup first...\n"; - database_dump_compress(); - print "[Update] Updating database...\n"; - sleep(1); - main_db_management(); - main_db_management(); - print "[Update] Continuing bootup\n"; - exit; - } - - #::: Make sure that we didn't pass any arugments to the script - if(!$ARGV[0]){ - if(!$db){ print "[eqemu_server.pl] No database connection found... Running without\n"; } - show_menu_prompt(); - } - } -} - -sub check_internet_connection { - if($OS eq "Linux"){ - $count = "c"; - } - if($OS eq "Windows"){ - $count = "n"; - } - - if (`ping 8.8.8.8 -$count 1 -w 500`=~/Reply from|1 received/i) { - # print "[Update] We have a connection to the internet, continuing...\n"; - return 1; - } - elsif (`ping 4.2.2.2 -$count 1 -w 500`=~/Reply from|1 received/i) { - # print "[Update] We have a connection to the internet, continuing...\n"; - return 1; - } - else{ - print "[Update] No connection to the internet, can't check update\n"; - return; - } -} - -sub get_perl_version { - #::: Check Perl version - $perl_version = $^V; - $perl_version =~s/v//g; - print "[Update] Perl Version is " . $perl_version . "\n"; - if($perl_version > 5.12){ - no warnings 'uninitialized'; - } - no warnings; -} - -sub do_self_update_check_routine { - #::: Check Version passed from world to update script - get_remote_file($eqemu_repository_request_url . "utils/scripts/eqemu_server.pl", "updates_staged/eqemu_server.pl", 0, 1, 1); - - if(!$has_internet_connection){ - print "[Update] Cannot check update without internet connection...\n"; - return; - } - - if(-e "updates_staged/eqemu_server.pl") { - - my $remote_script_size = -s "updates_staged/eqemu_server.pl"; - my $local_script_size = -s "eqemu_server.pl"; - - if($remote_script_size != $local_script_size){ - print "[Update] Script has been updated, updating...\n"; - - my @files; - my $start_dir = "updates_staged/"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - if($file=~/eqemu_server/i){ - $destination_file = $file; - $destination_file =~s/updates_staged\///g; - print "[Install] Installing :: " . $destination_file . "\n"; - unlink($destination_file); - copy_file($file, $destination_file); - if($OS eq "Linux"){ - system("chmod 755 eqemu_server.pl"); - } - system("perl eqemu_server.pl start_from_world"); - } - } - print "[Install] Done\n"; - } - else { - print "[Update] No script update necessary...\n"; - } - - unlink("updates_staged/eqemu_server.pl"); - } -} - -sub get_installation_variables{ - #::: Fetch installation variables before building the config - if($OS eq "Linux"){ - open (INSTALL_VARS, "../install_variables.txt"); - } - if($OS eq "Windows"){ - open (INSTALL_VARS, "install_variables.txt"); - } - while (){ - chomp; - $o = $_; - @data = split(":", $o); - $installation_variables{trim($data[0])} = trim($data[1]); - } - close (INSTALL_VARS); -} - -sub do_install_config_xml { - get_installation_variables(); - - #::: Fetch XML template - get_remote_file($install_repository_request_url . "eqemu_config.xml", "eqemu_config_template.xml"); - - #::: Open new config file - open (NEW_CONFIG, '>', 'eqemu_config.xml'); - - $in_database_tag = 0; - - #::: Iterate through template and replace variables... - open (FILE_TEMPLATE, "eqemu_config_template.xml"); - while (){ - chomp; - $o = $_; - - #::: Find replace variables - - if($o=~/\<\!--/i){ - next; - } - - if($o=~/database/i && $o=~/\<\//i){ - $in_database_tag = 0; - } - if($o=~/database/i){ - $in_database_tag = 1; - } - - if($o=~/key/i){ - my($replace_key) = $o =~ />(\w+)/i && $in_database_tag){ - my($replace_username) = $o =~ />(\w+)/i && $in_database_tag){ - my($replace_password) = $o =~ />(\w+)/i){ - my($replace_db_name) = $o =~ />(\w+)>> Database Menu\n\n"; - print " [backup_database] Back up database to backups/ directory\n"; - print " [backup_player_tables] Back up player tables to backups/ directory\n"; - print " [backup_database_compressed] Back up database compressed to backups/ directory\n"; - print " \n"; - print " [check_db_updates] Checks for database updates manually\n"; - print " [check_bot_db_updates] Checks for bot database updates\n"; - print " \n"; - print " [aa_tables] Downloads and installs clean slate AA data from PEQ\n"; - print " [remove_duplicate_rules] Removes duplicate rules from rule_values table\n"; - print " [drop_bots_db_schema] Removes bot database schema\n"; - - print " \n> main - go back to main menu\n"; - print "Enter a command #> "; - $last_menu = trim($input); - } - elsif($input eq "assets"){ - print "\n>>> Server Assets Menu\n\n"; - print " [maps] Download latest maps\n"; - print " [opcodes] Download opcodes (Patches for eq clients)\n"; - print " [quests] Download latest quests\n"; - print " [plugins] Download latest plugins\n"; - print " [lua_modules] Download latest lua_modules\n"; - print " [utility_scripts] Download utility scripts to run and operate the EQEmu Server\n"; - if($OS eq "Windows"){ - print ">>> Windows\n"; - print " [windows_server_download] Updates server code from latest stable\n"; - print " [windows_server_download_bots] Updates server code (bots enabled) from latest\n"; - print " [fetch_dlls] Grabs dll's needed to run windows binaries\n"; - print " [setup_loginserver] Sets up loginserver for Windows\n"; - } - print " \n> main - go back to main menu\n"; - print "Enter a command #> "; - $last_menu = trim($input); - } - elsif($input eq "backup_database"){ database_dump(); $dc = 1; } - elsif($input eq "backup_player_tables"){ database_dump_player_tables(); $dc = 1; } - elsif($input eq "backup_database_compressed"){ database_dump_compress(); $dc = 1; } - elsif($input eq "drop_bots_db_schema"){ do_bots_db_schema_drop(); $dc = 1; } - elsif($input eq "aa_tables"){ aa_fetch(); $dc = 1; } - elsif($input eq "remove_duplicate_rules"){ remove_duplicate_rule_values(); $dc = 1; } - elsif($input eq "maps"){ map_files_fetch_bulk(); $dc = 1; } - elsif($input eq "opcodes"){ opcodes_fetch(); $dc = 1; } - elsif($input eq "plugins"){ plugins_fetch(); $dc = 1; } - elsif($input eq "quests"){ quest_files_fetch(); $dc = 1; } - elsif($input eq "lua_modules"){ lua_modules_fetch(); $dc = 1; } - elsif($input eq "windows_server_download"){ fetch_latest_windows_binaries(); $dc = 1; } - elsif($input eq "windows_server_download_bots"){ fetch_latest_windows_binaries_bots(); $dc = 1; } - elsif($input eq "fetch_dlls"){ fetch_server_dlls(); $dc = 1; } - elsif($input eq "utility_scripts"){ fetch_utility_scripts(); $dc = 1; } - elsif($input eq "check_db_updates"){ main_db_management(); $dc = 1; } - elsif($input eq "check_bot_db_updates"){ bots_db_management(); $dc = 1; } - elsif($input eq "setup_loginserver"){ do_windows_login_server_setup(); $dc = 1; } - elsif($input eq "exit"){ - exit; - } - elsif($input eq "main"){ - print "Returning to main menu...\n"; - print_main_menu(); - $last_menu = trim($input); - } - elsif($input eq "" && $last_menu ne ""){ - $errored_command = 1; - } - elsif($input ne ""){ - print "Invalid command '" . $input . "'\n"; - $errored_command = 1; - } - else { - print_main_menu(); - } - - #::: Errored command checking - if($errored_command == 1){ - $input = $last_menu; - } - elsif($dc == 1){ - $dc = 0; - $input = ""; - } - else { - $input = <>; - } - } -} - -sub print_main_menu { - print "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"; - print ">>> EQEmu Server Main Menu >>>>>>>>>>>>\n"; - print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"; - print " [database] Enter database management menu \n"; - print " [assets] Manage server assets \n\n"; - print " exit \n"; - print "\n"; - print "Enter a command #> "; -} - -sub get_mysql_path { - 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){ - $v =~s/\n//g; - $path = trim($v) . "/mysql"; - last; - } - } - } - } - if($OS eq "Linux"){ - $path = `which mysql`; - if ($path eq "") { - $path = `which mariadb`; - } - $path =~s/\n//g; - } - - #::: Path not found, error and exit - if($path eq ""){ - print "[Error:eqemu_server.pl] MySQL path not found, please add the path for automatic database upgrading to continue... \n\n"; - exit; - } -} - -sub check_for_database_dump_script{ - if(`perl db_dumper.pl`=~/Need arguments/i){ - return; - } - else{ - print "[Database] db_dumper.pl not found... retrieving...\n"; - get_remote_file($eqemu_repository_request_url . "utils/scripts/db_dumper.pl", "db_dumper.pl"); - } -} - -sub database_dump { - check_for_database_dump_script(); - print "[Database] Performing database backup....\n"; - print `perl db_dumper.pl database="$db" loc="backups"`; -} - -sub database_dump_player_tables { - check_for_database_dump_script(); - print "[Database] Performing database backup of player tables....\n"; - get_remote_file($eqemu_repository_request_url . "utils/sql/character_table_list.txt", "backups/character_table_list.txt"); - - $tables = ""; - open (FILE, "backups/character_table_list.txt"); - $i = 0; - while (){ - chomp; - $o = $_; - $tables .= $o . ","; - } - $tables = substr($tables, 0, -1); - - print `perl db_dumper.pl database="$db" loc="backups" tables="$tables" backup_name="player_tables_export" nolock`; - - print "[Database] Press any key to continue...\n"; - - <>; #Read from STDIN - -} - -sub database_dump_compress { - check_for_database_dump_script(); - print "[Database] Performing database backup....\n"; - print `perl db_dumper.pl database="$db" loc="backups" compress`; -} - -sub script_exit{ - #::: Cleanup staged folder... - rmtree("updates_staged/"); - exit; -} - -sub check_db_version_table{ - if(get_mysql_result("SHOW TABLES LIKE 'db_version'") eq "" && $db){ - print get_mysql_result(" - CREATE TABLE db_version ( - version int(11) DEFAULT '0' - ) ENGINE=InnoDB DEFAULT CHARSET=latin1; - INSERT INTO db_version (version) VALUES ('1000');"); - print "[Database] Table 'db_version' does not exists.... Creating...\n\n"; - } -} - -#::: Returns Tab Delimited MySQL Result from Command Line -sub get_mysql_result{ - my $run_query = $_[0]; - if(!$db){ return; } - if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" $db -N -B -e "$run_query"`; } - if($OS eq "Linux"){ - $run_query =~s/`//g; - return `$path --user="$user" --host $host --password="$pass" $db -N -B -e "$run_query"`; - } -} - -sub get_mysql_result_from_file{ - my $update_file = $_[0]; - if(!$db){ return; } - if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; } - if($OS eq "Linux"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; } -} - -#::: Gets Remote File based on request_url (1st Arg), and saves to destination file (2nd Arg) -#::: Example: get_remote_file($eqemu_repository_request_url . "utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt"); -sub get_remote_file{ - my $request_url = $_[0]; - my $destination_file = $_[1]; - my $content_type = $_[2]; - my $no_retry = $_[3]; - my $silent_download = $_[4]; - - if(!$has_internet_connection){ - print "[Download] Cannot download without internet connection...\n"; - return; - } - - #::: Build file path of the destination file so that we may check for the folder's existence and make it if necessary - - if($destination_file=~/\//i){ - my @directory_path = split('/', $destination_file); - $build_path = ""; - $directory_index = 0; - while($directory_path[$directory_index] && $directory_path[$directory_index + 1]){ - $build_path .= $directory_path[$directory_index] . "/"; - # print "checking '" . $build_path . "'\n"; - #::: If path does not exist, create the directory... - if (!-d $build_path) { - print "[Copy] folder doesn't exist, creating '" . $build_path . "'\n"; - mkdir($build_path); - } - if(!$directory_indexr_path[$directory_index + 2] && $directory_indexr_path[$directory_index + 1]){ - # print $actual_path . "\n"; - $actual_path = $build_path; - last; - } - $directory_index++; - } - } - - if($OS eq "Windows"){ - #::: For non-text type requests... - if($content_type == 1){ - $break = 0; - while($break == 0) { - eval "use LWP::Simple qw(getstore);"; - # use LWP::Simple qw(getstore); - # print "request is " . $request_url . "\n"; - # print "destination file is supposed to be " . $destination_file . "\n"; - if(!getstore($request_url, $destination_file)){ - print "[Download] Error, no connection or failed request...\n\n"; - } - # sleep(1); - #::: Make sure the file exists before continuing... - if(-e $destination_file) { - $break = 1; - print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download; - } else { $break = 0; } - usleep(500); - - if($no_retry){ - $break = 1; - } - } - } - else{ - $break = 0; - while($break == 0) { - require LWP::UserAgent; - my $ua = LWP::UserAgent->new; - $ua->timeout(10); - $ua->env_proxy; - my $response = $ua->get($request_url); - if ($response->is_success){ - open (FILE, '> ' . $destination_file . ''); - print FILE $response->decoded_content; - close (FILE); - } - else { - print "[Download] Error, no connection or failed request...\n\n"; - } - if(-e $destination_file) { - $break = 1; - print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download; - } else { $break = 0; } - usleep(500); - - if($no_retry){ - $break = 1; - } - } - } - } - 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 --no-check-certificate --quiet -O $destination_file $request_url`; - print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download; - if($wget=~/unable to resolve/i){ - print "Error, no connection or failed request...\n\n"; - #die; - } - } -} - -#::: Trim Whitespaces -sub trim { - my $string = $_[0]; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - return $string; -} - -sub read_eqemu_config_xml { - my $confile = "eqemu_config.xml"; #default - open(F, "<$confile"); - my $indb = 0; - while() { - s/\r//g; - if(//i) { $indb = 1; } - next unless($indb == 1); - if(/<\/database>/i) { $indb = 0; last; } - if(/(.*)<\/host>/i) { $host = $1; } - elsif(/(.*)<\/username>/i) { $user = $1; } - elsif(/(.*)<\/password>/i) { $pass = $1; } - elsif(/(.*)<\/db>/i) { $db = $1; } - } -} - -#::: Fetch Latest PEQ AA's -sub aa_fetch{ - if(!$db){ - print "No database present, check your eqemu_config.xml for proper MySQL/MariaDB configuration...\n"; - return; - } - - print "[Install] Pulling down PEQ AA Tables...\n"; - get_remote_file($eqemu_repository_request_url . "utils/sql/peq_aa_tables_post_rework.sql", "db_update/peq_aa_tables_post_rework.sql"); - print "[Install] Installing AA Tables...\n"; - print get_mysql_result_from_file("db_update/peq_aa_tables_post_rework.sql"); - print "[Install] Done...\n\n"; -} - -#::: Fetch Latest Opcodes -sub opcodes_fetch{ - print "[Update] Pulling down latest opcodes...\n"; - %opcodes = ( - 1 => ["opcodes", $eqemu_repository_request_url . "utils/patches/opcodes.conf"], - 2 => ["mail_opcodes", $eqemu_repository_request_url . "utils/patches/mail_opcodes.conf"], - 3 => ["Titanium", $eqemu_repository_request_url . "utils/patches/patch_Titanium.conf"], - 4 => ["Secrets of Faydwer", $eqemu_repository_request_url . "utils/patches/patch_SoF.conf"], - 5 => ["Seeds of Destruction", $eqemu_repository_request_url . "utils/patches/patch_SoD.conf"], - 6 => ["Underfoot", $eqemu_repository_request_url . "utils/patches/patch_UF.conf"], - 7 => ["Rain of Fear", $eqemu_repository_request_url . "utils/patches/patch_RoF.conf"], - 8 => ["Rain of Fear 2", $eqemu_repository_request_url . "utils/patches/patch_RoF2.conf"], - ); - $loop = 1; - while($opcodes{$loop}[0]){ - #::: Split the request_url by the patches folder to get the file name from request_url - @real_file = split("patches/", $opcodes{$loop}[1]); - $find = 0; - while($real_file[$find]){ - $file_name = $real_file[$find]; - $find++; - } - - get_remote_file($opcodes{$loop}[1], $file_name); - $loop++; - } - print "[Update] Done...\n"; -} - -sub remove_duplicate_rule_values { - $ruleset_id = trim(get_mysql_result("SELECT `ruleset_id` FROM `rule_sets` WHERE `name` = 'default'")); - print "[Database] Default Ruleset ID: " . $ruleset_id . "\n"; - - $total_removed = 0; - - #::: Store Default values... - $mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` = " . $ruleset_id); - my @lines = split("\n", $mysql_result); - foreach my $val (@lines){ - my @values = split("\t", $val); - $rule_set_values{$values[1]}[0] = $values[2]; - } - - #::: Compare default values against other rulesets to check for duplicates... - $mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` != " . $ruleset_id); - my @lines = split("\n", $mysql_result); - foreach my $val (@lines){ - my @values = split("\t", $val); - if($values[2] == $rule_set_values{$values[1]}[0]){ - print "[Database] Removing duplicate : " . $values[1] . " (Ruleset (" . $values[0] . ")) matches default value of : " . $values[2] . "\n"; - get_mysql_result("DELETE FROM `rule_values` WHERE `ruleset_id` = " . $values[0] . " AND `rule_name` = '" . $values[1] . "'"); - $total_removed++; - } - } - - print "[Database] Total duplicate rules removed... " . $total_removed . "\n"; -} - -sub copy_file { - $l_source_file = $_[0]; - $l_destination_file = $_[1]; - if($l_destination_file=~/\//i){ - my @directory_path = split('/', $l_destination_file); - $build_path = ""; - $directory_index = 0; - while($directory_path[$directory_index]){ - $build_path .= $directory_path[$directory_index] . "/"; - #::: If path does not exist, create the directory... - if (!-d $build_path) { - mkdir($build_path); - } - if(!$directory_path[$directory_index + 2] && $directory_path[$directory_index + 1]){ - # print $actual_path . "\n"; - $actual_path = $build_path; - last; - } - $directory_index++; - } - } - copy $l_source_file, $l_destination_file; -} - -sub fetch_latest_windows_binaries { - print "[Update] Fetching Latest Windows Binaries... \n"; - get_remote_file($install_repository_request_url . "master_windows_build.zip", "updates_staged/master_windows_build.zip", 1); - print "[Update] Fetched Latest Windows Binaries... \n"; - print "[Update] Extracting... --- \n"; - unzip('updates_staged/master_windows_build.zip', 'updates_staged/binaries/'); - my @files; - my $start_dir = "updates_staged/binaries"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/updates_staged\/binaries\///g; - print "[Update] Installing :: " . $destination_file . "\n"; - copy_file($file, $destination_file); - } - print "[Update] Done\n"; - - rmtree('updates_staged'); -} - -sub fetch_latest_windows_binaries_bots { - print "[Update] Fetching Latest Windows Binaries with Bots...\n"; - get_remote_file($install_repository_request_url . "master_windows_build_bots.zip", "updates_staged/master_windows_build_bots.zip", 1); - print "[Update] Fetched Latest Windows Binaries with Bots...\n"; - print "[Update] Extracting...\n"; - unzip('updates_staged/master_windows_build_bots.zip', 'updates_staged/binaries/'); - my @files; - my $start_dir = "updates_staged/binaries"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/updates_staged\/binaries\///g; - print "[Install] Installing :: " . $destination_file . "\n"; - copy_file($file, $destination_file); - } - print "[Update] Done...\n"; - - rmtree('updates_staged'); -} - -sub do_windows_login_server_setup { - print "[Install] Fetching Loginserver... \n"; - get_remote_file($install_repository_request_url . "login_server.zip", "updates_staged/login_server.zip", 1); - print "[Install] Extracting... \n"; - unzip('updates_staged/login_server.zip', 'updates_staged/login_server/'); - my @files; - my $start_dir = "updates_staged/login_server"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/updates_staged\/login_server\///g; - print "[Install] Installing :: " . $destination_file . "\n"; - copy_file($file, $destination_file); - } - print "[Install] Done... \n"; - - print "[Install] Pulling down Loginserver database tables...\n"; - get_remote_file($install_repository_request_url . "login_server_tables.sql", "db_update/login_server_tables.sql"); - print "[Install] Installing Loginserver tables...\n"; - print get_mysql_result_from_file("db_update/login_server_tables.sql"); - print "[Install] Done...\n"; - - add_login_server_firewall_rules(); - - rmtree('updates_staged'); - rmtree('db_update'); - - print "[Install] Press any key to continue...\n"; - - <>; #Read from STDIN - -} - -sub do_linux_login_server_setup { - - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/updates_staged\/login_server\///g; - print "[Install] Installing :: " . $destination_file . "\n"; - copy_file($file, $destination_file); - } - print "\n Done... \n"; - - print "[Install] Pulling down Loginserver database tables...\n"; - get_remote_file($install_repository_request_url . "login_server_tables.sql", "db_update/login_server_tables.sql"); - print "[Install] Installing Loginserver tables...\n"; - print get_mysql_result_from_file("db_update/login_server_tables.sql"); - print "[Install] Done...\n\n"; - - rmtree('updates_staged'); - rmtree('db_update'); - - get_remote_file($install_repository_request_url . "linux/login.ini", "login_template.ini"); - get_remote_file($install_repository_request_url . "linux/login_opcodes.conf", "login_opcodes.conf"); - get_remote_file($install_repository_request_url . "linux/login_opcodes.conf", "login_opcodes_sod.conf"); - - get_installation_variables(); - my $db_name = $installation_variables{"mysql_eqemu_db_name"}; - my $db_user = $installation_variables{"mysql_eqemu_user"}; - my $db_password = $installation_variables{"mysql_eqemu_password"}; - - #::: Open new config file - open (NEW_CONFIG, '>', 'login.ini'); - - #::: Iterate through template and replace variables... - open (FILE_TEMPLATE, "login_template.ini"); - while (){ - chomp; - $o = $_; - #::: Find replace variables - if($o=~/db/i){ $o = "db = " . $db_name; } - if($o=~/user/i){ $o = "user = " . $db_user; } - if($o=~/password/i){ $o = "password = " . $db_password; } - - print NEW_CONFIG $o . "\n"; - } - - close(FILE_TEMPLATE); - close(NEW_CONFIG); - unlink("login_template.ini"); - - print "[Install] Press any key to continue...\n"; - - <>; #Read from STDIN - -} - -sub add_login_server_firewall_rules { - #::: Check Loginserver Firewall install for Windows - if($OS eq "Windows"){ - $output = `netsh advfirewall firewall show rule name=all`; - @output_buffer = split("\n", $output); - $has_loginserver_rules_titanium = 0; - $has_loginserver_rules_sod = 0; - foreach my $val (@output_buffer){ - if($val=~/Rule Name/i){ - $val=~s/Rule Name://g; - if($val=~/EQEmu Loginserver/i && $val=~/Titanium/i){ - $has_loginserver_rules_titanium = 1; - print "Found existing rule :: " . trim($val) . "\n"; - } - if($val=~/EQEmu Loginserver/i && $val=~/SOD/i){ - $has_loginserver_rules_sod = 1; - print "Found existing rule :: " . trim($val) . "\n"; - } - } - } - - if($has_loginserver_rules_titanium == 0){ - print "[Install] Attempting to add EQEmu Loginserver Firewall Rules (Titanium) (TCP) port 5998 \n"; - print `netsh advfirewall firewall add rule name="EQEmu Loginserver (Titanium) (5998) TCP" dir=in action=allow protocol=TCP localport=5998`; - print "[Install] Attempting to add EQEmu Loginserver Firewall Rules (Titanium) (UDP) port 5998 \n"; - print `netsh advfirewall firewall add rule name="EQEmu Loginserver (Titanium) (5998) UDP" dir=in action=allow protocol=UDP localport=5998`; - } - if($has_loginserver_rules_sod == 0){ - print "[Install] Attempting to add EQEmu Loginserver Firewall Rules (SOD+) (TCP) port 5999 \n"; - print `netsh advfirewall firewall add rule name="EQEmu Loginserver (SOD+) (5999) TCP" dir=in action=allow protocol=TCP localport=5999`; - print "[Install] Attempting to add EQEmu Loginserver Firewall Rules (SOD+) (UDP) port 5999 \n"; - print `netsh advfirewall firewall add rule name="EQEmu Loginserver (SOD+) (5999) UDP" dir=in action=allow protocol=UDP localport=5999`; - } - - print "If firewall rules don't add you must run this script (eqemu_server.pl) as administrator\n"; - print "\n"; - print "[Install] Instructions \n"; - print "[Install] In order to connect your server to the loginserver you must point your eqemu_config.xml to your local server similar to the following:\n"; - print " - - login.eqemulator.net - 5998 - - - - - 127.0.0.1 - 5998 - - - - "; - print "[Install] When done, make sure your EverQuest client points to your loginserver's IP (In this case it would be 127.0.0.1) in the eqhosts.txt file\n"; - } -} - -sub check_windows_firewall_rules{ - $output = `netsh advfirewall firewall show rule name=all`; - @output_buffer = split("\n", $output); - $has_world_rules = 0; - $has_zone_rules = 0; - foreach my $val (@output_buffer){ - if($val=~/Rule Name/i){ - $val=~s/Rule Name://g; - if($val=~/EQEmu World/i){ - $has_world_rules = 1; - print "[Install] Found existing rule :: " . trim($val) . "\n"; - } - if($val=~/EQEmu Zone/i){ - $has_zone_rules = 1; - print "[Install] Found existing rule :: " . trim($val) . "\n"; - } - } - } - - if($has_world_rules == 0){ - print "[Install] Attempting to add EQEmu World Firewall Rules (TCP) port 9000 \n"; - print `netsh advfirewall firewall add rule name="EQEmu World (9000) TCP" dir=in action=allow protocol=TCP localport=9000`; - print "[Install] Attempting to add EQEmu World Firewall Rules (UDP) port 9000 \n"; - print `netsh advfirewall firewall add rule name="EQEmu World (9000) UDP" dir=in action=allow protocol=UDP localport=9000`; - } - if($has_zone_rules == 0){ - print "[Install] Attempting to add EQEmu Zones (7000-7500) TCP \n"; - print `netsh advfirewall firewall add rule name="EQEmu Zones (7000-7500) TCP" dir=in action=allow protocol=TCP localport=7000-7500`; - print "[Install] Attempting to add EQEmu Zones (7000-7500) UDP \n"; - print `netsh advfirewall firewall add rule name="EQEmu Zones (7000-7500) UDP" dir=in action=allow protocol=UDP localport=7000-7500`; - } -} - -sub fetch_server_dlls{ - print "[Download] Fetching lua51.dll, zlib1.dll, libmysql.dll...\n"; - get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); - get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); - get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); -} - -sub fetch_peq_db_full{ - print "[Install] Downloading latest PEQ Database... Please wait...\n"; - get_remote_file("http://edit.peqtgc.com/weekly/peq_beta.zip", "updates_staged/peq_beta.zip", 1); - print "[Install] Downloaded latest PEQ Database... Extracting...\n"; - unzip('updates_staged/peq_beta.zip', 'updates_staged/peq_db/'); - my $start_dir = "updates_staged/peq_db"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/updates_staged\/peq_db\///g; - if($file=~/peqbeta|player_tables/i){ - print "[Install] DB :: Installing :: " . $destination_file . "\n"; - get_mysql_result_from_file($file); - } - if($file=~/eqtime/i){ - print "[Install] Installing eqtime.cfg\n"; - copy_file($file, "eqtime.cfg"); - } - } -} - -sub map_files_fetch_bulk{ - print "[Install] Fetching Latest Maps... (This could take a few minutes...)\n"; - get_remote_file("http://github.com/Akkadius/EQEmuMaps/archive/master.zip", "maps/maps.zip", 1); - unzip('maps/maps.zip', 'maps/'); - my @files; - my $start_dir = "maps/EQEmuMaps-master/maps"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - $destination_file = $file; - $destination_file =~s/maps\/EQEmuMaps-master\/maps\///g; - print "[Install] Installing :: " . $destination_file . "\n"; - copy_file($file, "maps/" . $new_file); - } - print "[Install] Fetched Latest Maps\n"; - - rmtree('maps/EQEmuMaps-master'); - unlink('maps/maps.zip'); -} - -sub map_files_fetch{ - print "[Install] Fetching Latest Maps --- \n"; - - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuMaps/master/!eqemu_maps_manifest.txt", "updates_staged/eqemu_maps_manifest.txt"); - - #::: Get Data from manifest - open (FILE, "updates_staged/eqemu_maps_manifest.txt"); - $i = 0; - while (){ - chomp; - $o = $_; - @manifest_map_data = split(',', $o); - if($manifest_map_data[0] ne ""){ - $maps_manifest[$i] = [$manifest_map_data[0], $manifest_map_data[1]]; - $i++; - } - } - - #::: Download - $fc = 0; - for($m = 0; $m <= $i; $m++){ - my $file_existing = $maps_manifest[$m][0]; - my $file_existing_size = (stat $file_existing)[7]; - if($file_existing_size != $maps_manifest[$m][1]){ - print "[Install] Updating: '" . $maps_manifest[$m][0] . "'\n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuMaps/master/" . $maps_manifest[$m][0], $maps_manifest[$m][0], 1); - $fc++; - } - } - - if($fc == 0){ - print "[Install] No Map Updates found... \n\n"; - } -} - -sub quest_files_fetch{ - if (!-e "updates_staged/Quests-Plugins-master/quests/") { - print "[Update] Fetching Latest Quests --- \n"; - get_remote_file("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1); - print "[Install] Fetched latest quests...\n"; - mkdir('updates_staged'); - unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); - } - - $fc = 0; - use File::Find; - use File::Compare; - - my @files; - my $start_dir = "updates_staged/Quests-Plugins-master/quests/"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - if($file=~/\.pl|\.lua|\.ext/i){ - $staged_file = $file; - $destination_file = $file; - $destination_file =~s/updates_staged\/Quests-Plugins-master\///g; - - if (!-e $destination_file) { - copy_file($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n"; - $fc++; - } - else{ - $directory_indexff = do_file_diff($destination_file, $staged_file); - if($directory_indexff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $destination_file; - - print $directory_indexff . "\n"; - print "[Update] File Different :: '" . $destination_file . "'\n"; - print "[Update] Do you wish to update this Quest? '" . $destination_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; - my $input = ; - if($input=~/N/i){} - else{ - #::: Make a backup - copy_file($destination_file, $backup_dest); - #::: Copy staged to running - copy($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n\n"; - } - $fc++; - } - } - } - } - - rmtree('updates_staged'); - - if($fc == 0){ - print "[Update] No Quest Updates found... \n\n"; - } -} - -sub lua_modules_fetch { - if (!-e "updates_staged/Quests-Plugins-master/quests/lua_modules/") { - print "[Update] Fetching Latest LUA Modules --- \n"; - get_remote_file("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1); - print "[Update] Fetched latest LUA Modules...\n"; - unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); - } - - $fc = 0; - use File::Find; - use File::Compare; - - my @files; - my $start_dir = "updates_staged/Quests-Plugins-master/quests/lua_modules/"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - if($file=~/\.pl|\.lua|\.ext/i){ - $staged_file = $file; - $destination_file = $file; - $destination_file =~s/updates_staged\/Quests-Plugins-master\/quests\///g; - - if (!-e $destination_file) { - copy_file($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n"; - $fc++; - } - else{ - $directory_indexff = do_file_diff($destination_file, $staged_file); - if($directory_indexff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $destination_file; - print $directory_indexff . "\n"; - print "[Update] File Different :: '" . $destination_file . "'\n"; - print "[Update] Do you wish to update this LUA Module? '" . $destination_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; - my $input = ; - if($input=~/N/i){} - else{ - #::: Make a backup - copy_file($destination_file, $backup_dest); - #::: Copy staged to running - copy($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n\n"; - } - $fc++; - } - } - } - } - - if($fc == 0){ - print "[Update] No LUA Modules Updates found... \n\n"; - } -} - -sub plugins_fetch{ - if (!-e "updates_staged/Quests-Plugins-master/plugins/") { - print "[Update] Fetching Latest Plugins\n"; - get_remote_file("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1); - print "[Update] Fetched latest plugins\n"; - unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); - } - - $fc = 0; - use File::Find; - use File::Compare; - - my @files; - my $start_dir = "updates_staged/Quests-Plugins-master/plugins/"; - find( - sub { push @files, $File::Find::name unless -d; }, - $start_dir - ); - for my $file (@files) { - if($file=~/\.pl|\.lua|\.ext/i){ - $staged_file = $file; - $destination_file = $file; - $destination_file =~s/updates_staged\/Quests-Plugins-master\///g; - - if (!-e $destination_file) { - copy_file($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n"; - $fc++; - } - else{ - $directory_indexff = do_file_diff($destination_file, $staged_file); - if($directory_indexff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $destination_file; - print $directory_indexff . "\n"; - print "[Update] File Different :: '" . $destination_file . "'\n"; - print "[Update] Do you wish to update this Plugin? '" . $destination_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; - my $input = ; - if($input=~/N/i){} - else{ - #::: Make a backup - copy_file($destination_file, $backup_dest); - #::: Copy staged to running - copy($staged_file, $destination_file); - print "[Install] Installing :: '" . $destination_file . "'\n\n"; - } - $fc++; - } - } - } - } - - if($fc == 0){ - print "[Update] No Plugin Updates found... \n\n"; - } -} - -sub do_file_diff{ - $file_1 = $_[0]; - $file_2 = $_[1]; - if($OS eq "Windows"){ - eval "use Text::Diff"; - $directory_indexff = diff($file_1, $file_2, { STYLE => "Unified" }); - return $directory_indexff; - } - if($OS eq "Linux"){ - # print 'diff -u "$file_1" "$file_2"' . "\n"; - return `diff -u "$file_1" "$file_2"`; - } -} - -sub unzip { - $archive_to_unzip = $_[0]; - $dest_folder = $_[1]; - - if($OS eq "Windows"){ - eval "use Archive::Zip qw( :ERROR_CODES :CONSTANTS )"; - my $zip = Archive::Zip->new(); - unless ( $zip->read($archive_to_unzip) == AZ_OK ) { - die 'read error'; - } - print "[Unzip] Extracting...\n"; - $zip->extractTree('', $dest_folder); - } - if($OS eq "Linux"){ - print `unzip -o -q "$archive_to_unzip" -d "$dest_folder"`; - } -} - -sub are_file_sizes_different{ - $file_1 = $_[0]; - $file_2 = $_[1]; - my $file_1 = (stat $file_1)[7]; - my $file_2 = (stat $file_2)[7]; - # print $file_1 . " :: " . $file_2 . "\n"; - if($file_1 != $file_2){ - return 1; - } - return; -} - -sub do_bots_db_schema_drop{ - #"drop_bots.sql" is run before reverting database back to 'normal' - print "[Database] Fetching drop_bots.sql...\n"; - get_remote_file($eqemu_repository_request_url . "utils/sql/git/bots/drop_bots.sql", "db_update/drop_bots.sql"); - print get_mysql_result_from_file("db_update/drop_bots.sql"); - - print "[Database] Removing bot database tables...\n"; - print get_mysql_result("DELETE FROM `rule_values` WHERE `rule_name` LIKE 'Bots:%';"); - - if(get_mysql_result("SHOW TABLES LIKE 'commands'") ne "" && $db){ - print get_mysql_result("DELETE FROM `commands` WHERE `command` LIKE 'bot';"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'command_settings'") ne "" && $db){ - print get_mysql_result("DELETE FROM `command_settings` WHERE `command` LIKE 'bot';"); - } - - if(get_mysql_result("SHOW KEYS FROM `group_id` WHERE `Key_name` LIKE 'PRIMARY'") ne "" && $db){ - print get_mysql_result("ALTER TABLE `group_id` DROP PRIMARY KEY;"); - } - print get_mysql_result("ALTER TABLE `group_id` ADD PRIMARY KEY (`groupid`, `charid`, `ismerc`);"); - - if(get_mysql_result("SHOW KEYS FROM `guild_members` WHERE `Key_name` LIKE 'PRIMARY'") ne "" && $db){ - print get_mysql_result("ALTER TABLE `guild_members` DROP PRIMARY KEY;"); - } - print get_mysql_result("ALTER TABLE `guild_members` ADD PRIMARY KEY (`char_id`);"); - - print get_mysql_result("UPDATE `spawn2` SET `enabled` = 0 WHERE `id` IN (59297,59298);"); - - if(get_mysql_result("SHOW COLUMNS FROM `db_version` LIKE 'bots_version'") ne "" && $db){ - print get_mysql_result("UPDATE `db_version` SET `bots_version` = 0;"); - } - print "[Database] Done...\n"; -} - -sub modify_db_for_bots{ - #Called after the db bots schema (2015_09_30_bots.sql) has been loaded - print "[Database] Modifying database for bots...\n"; - print get_mysql_result("UPDATE `spawn2` SET `enabled` = 1 WHERE `id` IN (59297,59298);"); - - if(get_mysql_result("SHOW KEYS FROM `guild_members` WHERE `Key_name` LIKE 'PRIMARY'") ne "" && $db){ - print get_mysql_result("ALTER TABLE `guild_members` DROP PRIMARY KEY;"); - } - - if(get_mysql_result("SHOW KEYS FROM `group_id` WHERE `Key_name` LIKE 'PRIMARY'") ne "" && $db){ - print get_mysql_result("ALTER TABLE `group_id` DROP PRIMARY KEY;"); - } - print get_mysql_result("ALTER TABLE `group_id` ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`, `ismerc`);"); - - if(get_mysql_result("SHOW TABLES LIKE 'command_settings'") ne "" && get_mysql_result("SELECT `command` FROM `command_settings` WHERE `command` LIKE 'bot'") eq "" && $db){ - print get_mysql_result("INSERT INTO `command_settings` VALUES ('bot', '0', '');"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'commands'") ne "" && get_mysql_result("SELECT `command` FROM `commands` WHERE `command` LIKE 'bot'") eq "" && $db){ - print get_mysql_result("INSERT INTO `commands` VALUES ('bot', '0');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotAAExpansion'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:AAExpansion' WHERE `rule_name` LIKE 'Bots:BotAAExpansion';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:AAExpansion'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:AAExpansion', '8', 'The expansion through which bots will obtain AAs');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:CreateBotCount'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:CreationLimit' WHERE `rule_name` LIKE 'Bots:CreateBotCount';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:CreationLimit'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:CreationLimit', '150', 'Number of bots that each account can create');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotFinishBuffing'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:FinishBuffing' WHERE `rule_name` LIKE 'Bots:BotFinishBuffing';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:FinishBuffing'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:FinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotGroupBuffing'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:GroupBuffing' WHERE `rule_name` LIKE 'Bots:BotGroupBuffing';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:GroupBuffing'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:GroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotManaRegen'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:ManaRegen' WHERE `rule_name` LIKE 'Bots:BotManaRegen';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:ManaRegen'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:ManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotQuest'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:QuestableSpawnLimit' WHERE `rule_name` LIKE 'Bots:BotQuest';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:QuestableSpawnLimit'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:QuestableSpawnLimit', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:BotSpellQuest'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:QuestableSpells' WHERE `rule_name` LIKE 'Bots:BotSpellQuest';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:QuestableSpells'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:QuestableSpells', 'false', 'Anita Thrall\\\'s (Anita_Thrall.pl) Bot Spell Scriber quests.');"); - } - - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:SpawnBotCount'") ne "" && $db){ - print get_mysql_result("UPDATE `rule_values` SET `rule_name` = 'Bots:SpawnLimit' WHERE `rule_name` LIKE 'Bots:SpawnBotCount';"); - } - if(get_mysql_result("SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'Bots:SpawnLimit'") eq "" && $db){ - print get_mysql_result("INSERT INTO `rule_values` VALUES ('1', 'Bots:SpawnLimit', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid');"); - } - - convert_existing_bot_data(); -} - -sub convert_existing_bot_data{ - if(get_mysql_result("SHOW TABLES LIKE 'bots'") ne "" && $db){ - print "[Database] Converting existing bot data...\n"; - print get_mysql_result("INSERT INTO `bot_data` (`bot_id`, `owner_id`, `spells_id`, `name`, `last_name`, `zone_id`, `gender`, `race`, `class`, `level`, `creation_day`, `last_spawn`, `time_spawned`, `size`, `face`, `hair_color`, `hair_style`, `beard`, `beard_color`, `eye_color_1`, `eye_color_2`, `drakkin_heritage`, `drakkin_tattoo`, `drakkin_details`, `ac`, `atk`, `hp`, `mana`, `str`, `sta`, `cha`, `dex`, `int`, `agi`, `wis`, `fire`, `cold`, `magic`, `poison`, `disease`, `corruption`) SELECT `BotID`, `BotOwnerCharacterID`, `BotSpellsID`, `Name`, `LastName`, `LastZoneId`, `Gender`, `Race`, `Class`, `BotLevel`, UNIX_TIMESTAMP(`BotCreateDate`), UNIX_TIMESTAMP(`LastSpawnDate`), `TotalPlayTime`, `Size`, `Face`, `LuclinHairColor`, `LuclinHairStyle`, `LuclinBeard`, `LuclinBeardColor`, `LuclinEyeColor`, `LuclinEyeColor2`, `DrakkinHeritage`, `DrakkinTattoo`, `DrakkinDetails`, `AC`, `ATK`, `HP`, `Mana`, `STR`, `STA`, `CHA`, `DEX`, `_INT`, `AGI`, `WIS`, `FR`, `CR`, `MR`, `PR`, `DR`, `Corrup` FROM `bots`;"); - - print get_mysql_result("INSERT INTO `bot_inspect_messages` (`bot_id`, `inspect_message`) SELECT `BotID`, `BotInspectMessage` FROM `bots`;"); - - print get_mysql_result("RENAME TABLE `bots` TO `bots_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botstances'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_stances` (`bot_id`, `stance_id`) SELECT bs.`BotID`, bs.`StanceID` FROM `botstances` bs INNER JOIN `bot_data` bd ON bs.`BotID` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `botstances` TO `botstances_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'bottimers'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_timers` (`bot_id`, `timer_id`, `timer_value`) SELECT bt.`BotID`, bt.`TimerID`, bt.`Value` FROM `bottimers` bt INNER JOIN `bot_data` bd ON bt.`BotID` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `bottimers` TO `bottimers_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botbuffs'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_buffs` (`buffs_index`, `bot_id`, `spell_id`, `caster_level`, `duration_formula`, `tics_remaining`, `poison_counters`, `disease_counters`, `curse_counters`, `corruption_counters`, `numhits`, `melee_rune`, `magic_rune`, `persistent`) SELECT bb.`BotBuffId`, bb.`BotId`, bb.`SpellId`, bb.`CasterLevel`, bb.`DurationFormula`, bb.`TicsRemaining`, bb.`PoisonCounters`, bb.`DiseaseCounters`, bb.`CurseCounters`, bb.`CorruptionCounters`, bb.`HitCount`, bb.`MeleeRune`, bb.`MagicRune`, bb.`Persistent` FROM `botbuffs` bb INNER JOIN `bot_data` bd ON bb.`BotId` = bd.`bot_id`;"); - - if(get_mysql_result("SHOW COLUMNS FROM `botbuffs` LIKE 'dot_rune'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_buffs` bb INNER JOIN `botbuffs` bbo ON bb.`buffs_index` = bbo.`BotBuffId` SET bb.`dot_rune` = bbo.`dot_rune` WHERE bb.`bot_id` = bbo.`BotID`;"); - } - - if(get_mysql_result("SHOW COLUMNS FROM `botbuffs` LIKE 'caston_x'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_buffs` bb INNER JOIN `botbuffs` bbo ON bb.`buffs_index` = bbo.`BotBuffId` SET bb.`caston_x` = bbo.`caston_x` WHERE bb.`bot_id` = bbo.`BotID`;"); - } - - if(get_mysql_result("SHOW COLUMNS FROM `botbuffs` LIKE 'caston_y'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_buffs` bb INNER JOIN `botbuffs` bbo ON bb.`buffs_index` = bbo.`BotBuffId` SET bb.`caston_y` = bbo.`caston_y` WHERE bb.`bot_id` = bbo.`BotID`;"); - } - - if(get_mysql_result("SHOW COLUMNS FROM `botbuffs` LIKE 'caston_z'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_buffs` bb INNER JOIN `botbuffs` bbo ON bb.`buffs_index` = bbo.`BotBuffId` SET bb.`caston_z` = bbo.`caston_z` WHERE bb.`bot_id` = bbo.`BotID`;"); - } - - if(get_mysql_result("SHOW COLUMNS FROM `botbuffs` LIKE 'ExtraDIChance'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_buffs` bb INNER JOIN `botbuffs` bbo ON bb.`buffs_index` = bbo.`BotBuffId` SET bb.`extra_di_chance` = bbo.`ExtraDIChance` WHERE bb.`bot_id` = bbo.`BotID`;"); - } - - print get_mysql_result("RENAME TABLE `botbuffs` TO `botbuffs_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botinventory'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_inventories` (`inventories_index`, `bot_id`, `slot_id`, `item_id`, `inst_charges`, `inst_color`, `inst_no_drop`, `augment_1`, `augment_2`, `augment_3`, `augment_4`, `augment_5`) SELECT bi.`BotInventoryID`, bi.`BotID`, bi.`SlotID`, bi.`ItemID`, bi.`charges`, bi.`color`, bi.`instnodrop`, bi.`augslot1`, bi.`augslot2`, bi.`augslot3`, bi.`augslot4`, bi.`augslot5` FROM `botinventory` bi INNER JOIN `bot_data` bd ON bi.`BotID` = bd.`bot_id`;"); - - if(get_mysql_result("SHOW COLUMNS FROM `botinventory` LIKE 'augslot6'") ne "" && $db){ - print get_mysql_result("UPDATE `bot_inventories` bi INNER JOIN `botinventory` bio ON bi.`inventories_index` = bio.`BotInventoryID` SET bi.`augment_6` = bio.`augslot6` WHERE bi.`bot_id` = bio.`BotID`;"); - } - - print get_mysql_result("RENAME TABLE `botinventory` TO `botinventory_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botpets'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_pets` (`pets_index`, `pet_id`, `bot_id`, `name`, `mana`, `hp`) SELECT bp.`BotPetsId`, bp.`PetId`, bp.`BotId`, bp.`Name`, bp.`Mana`, bp.`HitPoints` FROM `botpets` bp INNER JOIN `bot_data` bd ON bp.`BotId` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `botpets` TO `botpets_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botpetbuffs'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_pet_buffs` (`pet_buffs_index`, `pets_index`, `spell_id`, `caster_level`, `duration`) SELECT bpb.`BotPetBuffId`, bpb.`BotPetsId`, bpb.`SpellId`, bpb.`CasterLevel`, bpb.`Duration` FROM `botpetbuffs` bpb INNER JOIN `bot_pets` bp ON bpb.`BotPetsId` = bp.`pets_index`;"); - - print get_mysql_result("RENAME TABLE `botpetbuffs` TO `botpetbuffs_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botpetinventory'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_pet_inventories` (`pet_inventories_index`, `pets_index`, `item_id`) SELECT bpi.`BotPetInventoryId`, bpi.`BotPetsId`, bpi.`ItemId` FROM `botpetinventory` bpi INNER JOIN `bot_pets` bp ON bpi.`BotPetsId` = bp.`pets_index`;"); - - print get_mysql_result("RENAME TABLE `botpetinventory` TO `botpetinventory_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botgroup'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_groups` (`groups_index`, `group_leader_id`, `group_name`) SELECT bg.`BotGroupId`, bg.`BotGroupLeaderBotId`, bg.`BotGroupName` FROM `botgroup` bg INNER JOIN `bot_data` bd ON bg.`BotGroupLeaderBotId` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `botgroup` TO `botgroup_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botgroupmembers'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_group_members` (`group_members_index`, `groups_index`, `bot_id`) SELECT bgm.`BotGroupMemberId`, bgm.`BotGroupId`, bgm.`BotId` FROM `botgroupmembers` bgm INNER JOIN `bot_groups` bg ON bgm.`BotGroupId` = bg.`groups_index` INNER JOIN `bot_data` bd ON bgm.`BotId` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `botgroupmembers` TO `botgroupmembers_old`;"); - } - - if(get_mysql_result("SHOW TABLES LIKE 'botguildmembers'") ne "" && $db){ - print get_mysql_result("INSERT INTO `bot_guild_members` (`bot_id`, `guild_id`, `rank`, `tribute_enable`, `total_tribute`, `last_tribute`, `banker`, `public_note`, `alt`) SELECT bgm.`char_id`, bgm.`guild_id`, bgm.`rank`, bgm.`tribute_enable`, bgm.`total_tribute`, bgm.`last_tribute`, bgm.`banker`, bgm.`public_note`, bgm.`alt` FROM `botguildmembers` bgm INNER JOIN `guilds` g ON bgm.`guild_id` = g.`id` INNER JOIN `bot_data` bd ON bgm.`char_id` = bd.`bot_id`;"); - - print get_mysql_result("RENAME TABLE `botguildmembers` TO `botguildmembers_old`;"); - } -} - -sub get_bots_db_version{ - #::: Check if bots_version column exists... - if(get_mysql_result("SHOW COLUMNS FROM db_version LIKE 'bots_version'") eq "" && $db){ - print get_mysql_result("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version;"); - print "[Database] Column 'bots_version' does not exists.... Adding to 'db_version' table...\n\n"; - } - $bots_local_db_version = trim(get_mysql_result("SELECT bots_version FROM db_version LIMIT 1")); - return $bots_local_db_version; -} - -sub bots_db_management{ - #::: Main Binary Database version - $binary_database_version = trim($db_version[2]); - - #::: If we have stale data from main db run - if($db_run_stage > 0 && $bots_db_management == 0){ - clear_database_runs(); - } - - if($binary_database_version == 0){ - print "[Database] Your server binaries (world/zone) are not compiled for bots...\n\n"; - return; - } - - #::: Set on flag for running bot updates... - $bots_db_management = 1; - - $bots_local_db_version = get_bots_db_version(); - - run_database_check(); -} - -sub main_db_management{ - #::: If we have stale data from bots db run - if($db_run_stage > 0 && $bots_db_management == 1){ - clear_database_runs(); - } - - #::: Main Binary Database version - $binary_database_version = trim($db_version[1]); - - $bots_db_management = 0; - run_database_check(); -} - -sub clear_database_runs{ - # print "DEBUG :: clear_database_runs\n\n"; - #::: Clear manifest data... - %m_d = (); - #::: Clear updates... - @total_updates = (); - #::: Clear stage - $db_run_stage = 0; -} - -#::: Responsible for Database Upgrade Routines -sub run_database_check{ - - if(!$db){ - print "No database present, check your eqemu_config.xml for proper MySQL/MariaDB configuration...\n"; - return; - } - - if(!@total_updates){ - #::: Pull down bots database manifest - if($bots_db_management == 1){ - print "[Database] Retrieving latest bots database manifest...\n"; - get_remote_file($eqemu_repository_request_url . "utils/sql/git/bots/bots_db_update_manifest.txt", "db_update/db_update_manifest.txt"); - } - #::: Pull down mainstream database manifest - else{ - print "[Database] Retrieving latest database manifest...\n"; - get_remote_file($eqemu_repository_request_url . "utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt"); - } - } - - #::: Run 2 - Running pending updates... - if(@total_updates || $db_run_stage == 1){ - @total_updates = sort @total_updates; - foreach my $val (@total_updates){ - $file_name = trim($m_d{$val}[1]); - print "[Database] Running Update: " . $val . " - " . $file_name . "\n"; - print get_mysql_result_from_file("db_update/$file_name"); - print get_mysql_result("UPDATE db_version SET version = $val WHERE version < $val"); - - if($bots_db_management == 1 && $val == 9000){ - modify_db_for_bots(); - } - } - $db_run_stage = 2; - } - #::: Run 1 - Initial checking of needed updates... - else{ - print "[Database] Reading manifest...\n"; - use Data::Dumper; - open (FILE, "db_update/db_update_manifest.txt"); - while () { - chomp; - $o = $_; - if($o=~/#/i){ next; } - @manifest = split('\|', $o); - $m_d{$manifest[0]} = [@manifest]; - } - #::: Setting Manifest stage... - $db_run_stage = 1; - } - - @total_updates = (); - - #::: This is where we set checkpoints for where a database might be so we don't check so far back in the manifest... - if($local_database_version){ - $revision_check = $local_database_version; - } - else { - $revision_check = 1000; - if(get_mysql_result("SHOW TABLES LIKE 'character_data'") ne ""){ - $revision_check = 9000; - } - } - - #::: Iterate through Manifest backwards from binary version down to local version... - for($i = $binary_database_version ; $i > $revision_check; $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(get_mysql_result($query_check))=~/$match_text/i){ - print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; - fetch_missing_db_update($i, $file_name); - push(@total_updates, $i); - } - else{ - print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; - } - print_match_debug(); - print_break(); - } - if($match_type eq "missing"){ - if(get_mysql_result($query_check)=~/$match_text/i){ - print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; - next; - } - else{ - print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; - fetch_missing_db_update($i, $file_name); - push(@total_updates, $i); - } - print_match_debug(); - print_break(); - } - if($match_type eq "empty"){ - if(get_mysql_result($query_check) eq ""){ - print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; - fetch_missing_db_update($i, $file_name); - push(@total_updates, $i); - } - else{ - print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; - } - print_match_debug(); - print_break(); - } - if($match_type eq "not_empty"){ - if(get_mysql_result($query_check) ne ""){ - print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; - fetch_missing_db_update($i, $file_name); - push(@total_updates, $i); - } - else{ - print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; - } - print_match_debug(); - print_break(); - } - } - print "\n"; - - if(scalar (@total_updates) == 0 && $db_run_stage == 2){ - print "[Database] No updates need to be run...\n"; - if($bots_db_management == 1){ - print "[Database] Setting Database to Bots Binary Version (" . $binary_database_version . ") if not already...\n\n"; - get_mysql_result("UPDATE db_version SET bots_version = $binary_database_version "); - } - else{ - print "[Database] Setting Database to Binary Version (" . $binary_database_version . ") if not already...\n\n"; - get_mysql_result("UPDATE db_version SET version = $binary_database_version "); - } - - clear_database_runs(); - } -} - -sub fetch_missing_db_update{ - $db_update = $_[0]; - $update_file = $_[1]; - if($db_update >= 9000){ - if($bots_db_management == 1){ - get_remote_file($eqemu_repository_request_url . "utils/sql/git/bots/required/" . $update_file, "db_update/" . $update_file . ""); - } - else{ - get_remote_file($eqemu_repository_request_url . "utils/sql/git/required/" . $update_file, "db_update/" . $update_file . ""); - } - } - elsif($db_update >= 5000 && $db_update <= 9000){ - get_remote_file($eqemu_repository_request_url . "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(get_mysql_result($query_check)) . "'\n"; -} - -sub print_break{ - if(!$debug){ return; } - print "\n==============================================\n"; -} - -sub generate_random_password { - my $passwordsize = shift; - my @alphanumeric = ('a'..'z', 'A'..'Z', 0..9); - my $randpassword = join '', - map $alphanumeric[rand @alphanumeric], 0..$passwordsize; - - return $randpassword; -} From bf283543014cc58dc4067298b77b9f7bf9f50eba Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 22:14:14 -0500 Subject: [PATCH 09/16] Upload Linux installer for Debian/Ubuntu/CentOS/Fedora utils/scripts/linux_installer/install.sh [skip ci] --- utils/scripts/linux_installer/install.sh | 236 +++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 utils/scripts/linux_installer/install.sh diff --git a/utils/scripts/linux_installer/install.sh b/utils/scripts/linux_installer/install.sh new file mode 100644 index 000000000..d9cdc0485 --- /dev/null +++ b/utils/scripts/linux_installer/install.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +#::: Determine releases +if [[ -f /etc/debian_version ]]; then + export OS=Debian +elif [[ -f /etc/fedora-release ]]; then + export OS=fedora_core +elif [[ -f /etc/redhat-release ]]; then + export OS=red_hat +else + echo "This script must be run on a Debian or RedHat derivative" + exit 1 +fi + +echo "######################################################### " +echo "#::: EverQuest Emulator Modular Installer " +echo "#::: Installer Author: Akkadius " +echo "#::: Installer Co-Author(s): N0ctrnl " +echo "#::: " +echo "#::: EQEmulator Server Software is developed and maintained " +echo "#::: by the EQEmulator Developement team " +echo "#::: " +echo "#::: Everquest is a registered trademark " +echo "#::: Daybreak Game Company LLC. " +echo "#::: " +echo "#::: EQEmulator is not associated or " +echo "#::: affiliated in any way with Daybreak Game Company LLC. " +echo "######################################################### " +echo "#: " +echo "######################################################### " +echo "#::: To be installed: " +echo "######################################################### " +echo "- Server running folder - Will be installed to the folder you ran this script " +echo "- MariaDB (MySQL) - Database engine " +echo "- Perl 5.X :: Scripting language for quest engines " +echo "- LUA Configured :: Scripting language for quest engines " +echo "- Latest PEQ Database " +echo "- Latest PEQ Quests " +echo "- Latest Plugins repository " +echo "- Maps (Latest V2) formats are loaded " +echo "- New Path files are loaded " +echo "- Optimized server binaries " +echo "######################################################### " + +# Installation variables (Don't need to change, only for advanced users) + +export eqemu_server_directory=/home/eqemu +export apt_options="-y -qq" # Set autoconfirm and silent install + +################################################################ + +read -n1 -r -p "Press any key to continue..." key + +#::: Setting up user environment (eqemu) +echo "First, we need to set your passwords..." +echo "Make sure that you remember these and keep them somewhere" +echo "" +echo "" +groupadd eqemu +useradd -g eqemu -d $eqemu_server_directory eqemu +passwd eqemu + +#::: Make server directory and go to it +mkdir $eqemu_server_directory +cd $eqemu_server_directory + +#::: Setup MySQL root user PW +read -p "Enter MySQL root (Database) password: " eqemu_db_root_password + +#::: Write install variables (later use) +echo "mysql_root:$eqemu_db_root_password" > install_variables.txt + +#::: Setup MySQL server +read -p "Enter Database Name (single word, no special characters, lower case):" eqemu_db_name +read -p "Enter (Database) MySQL EQEmu Server username: " eqemu_db_username +read -p "Enter (Database) MySQL EQEmu Server password: " eqemu_db_password + +#::: Write install variables (later use) +echo "mysql_eqemu_db_name:$eqemu_db_name" >> install_variables.txt +echo "mysql_eqemu_user:$eqemu_db_username" >> install_variables.txt +echo "mysql_eqemu_password:$eqemu_db_password" >> install_variables.txt + +if [[ "$OS" == "Debian" ]]; then + # Install pre-req packages + apt-get $apt_options install bash + apt-get $apt_options install build-essential + apt-get $apt_options install cmake + apt-get $apt_options install cpp + apt-get $apt_options install curl + apt-get $apt_options install debconf-utils + apt-get $apt_options install g++ + apt-get $apt_options install gcc + apt-get $apt_options install git + apt-get $apt_options install git-core + apt-get $apt_options install libio-stringy-perl + apt-get $apt_options install liblua5.1 + apt-get $apt_options install liblua5.1-dev + apt-get $apt_options install libluabind-dev + apt-get $apt_options install libmysql++ + apt-get $apt_options install libperl-dev + apt-get $apt_options install libperl5i-perl + apt-get $apt_options install libwtdbomysql-dev + apt-get $apt_options install lua5.1 + apt-get $apt_options install make + apt-get $apt_options install mariadb-client + apt-get $apt_options install open-vm-tools + apt-get $apt_options install unzip + apt-get $apt_options install uuid-dev + apt-get $apt_options install zlib-bin + apt-get $apt_options install zlibc + + #::: Install FTP for remote FTP access + echo "proftpd-basic shared/proftpd/inetd_or_standalone select standalone" | debconf-set-selections + apt-get -y -q install proftpd + + #::: Install MariaDB Server + export DEBIAN_FRONTEND=noninteractive + debconf-set-selections <<< 'mariadb-server-10.0 mysql-server/root_password password PASS' + debconf-set-selections <<< 'mariadb-server-10.0 mysql-server/root_password_again password PASS' + apt-get install -y mariadb-server + mysql -uroot -pPASS -e "SET PASSWORD = PASSWORD('$eqemu_db_root_password');" + +elif [[ "$OS" == "red_hat" ]]; then + # Do RedHat / CentOS stuff + # Add the MariaDB repository to yum +cat < /etc/yum.repos.d/mariadb.repo +# MariaDB 10.1 CentOS repository list - created 2016-08-20 05:42 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.1/centos7-amd64 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +enabled=1 +gpgcheck=1 +EOF + # Install prereqs + yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + yum -y install deltarpm + yum -y install open-vm-tools vim cmake boost-* zlib-devel mariadb-server mariadb-client mariadb-devel mariadb-libs mariadb-compat perl-* lua* dos2unix php-mysql proftpd + yum -y groupinstall "Development Tools" "Basic Web Server" "Compatibility Libraries" + +elif [[ "$OS" == "fedora_core" ]]; then + # Do Fedora stuff + dnf -y install open-vm-tools vim cmake boost-devel zlib-devel mariadb-server mariadb-devel mariadb-libs perl perl-DBD-MySQL perl-IO-stringy perl-devel lua-devel lua-sql-mysql dos2unix php-mysql proftpd wget compat-lua-libs compat-lua-devel compat-lua perl-Time-HiRes + dnf -y groupinstall "Development Tools" "Basic Web Server" "C Development Tools and Libraries" +fi + +if [[ "$OS" == "fedora_core" ]] || [[ "$OS" == "red_hat" ]]; then + # Start MariaDB server and set root password + echo "Starting MariaDB server..." + systemctl enable mariadb.service + systemctl start mariadb.service + sleep 5 + /usr/bin/mysqladmin -u root password $eqemu_db_root_password +fi + +#::: Configure game server database user +mysql -uroot -p$eqemu_db_root_password -e "CREATE USER '$eqemu_db_username'@'localhost' IDENTIFIED BY '$eqemu_db_password';" +mysql -uroot -p$eqemu_db_root_password -e "GRANT GRANT OPTION ON *.* TO '$eqemu_db_username'@'localhost';" +mysql -uroot -p$eqemu_db_root_password -e "GRANT ALL ON *.* TO '$eqemu_db_username'@'localhost';" + +#::: Create source and server directories +mkdir $eqemu_server_directory/source +mkdir $eqemu_server_directory/server +mkdir $eqemu_server_directory/server/export +mkdir $eqemu_server_directory/server/logs +mkdir $eqemu_server_directory/server/shared +mkdir $eqemu_server_directory/server/maps + +#::: Pull down needed files for the installer from the Install repo + +cd $eqemu_server_directory/source +git clone https://github.com/EQEmu/Server.git +mkdir $eqemu_server_directory/source/Server/build +cd $eqemu_server_directory/source/Server/build + +echo "Generating CMake build files..." +if [[ "$OS" == "fedora_core" ]]; then + cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" .. +else + cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" .. +fi +echo "Building EQEmu Server code. This will take a while." + +#::: Grab loginserver dependencies +cd $eqemu_server_directory/source/Server/dependencies +if [[ "$OS" == "Debian" ]]; then + wget http://eqemu.github.io/downloads/ubuntu_LoginServerCrypto_x64.zip + unzip ubuntu_LoginServerCrypto_x64.zip + rm ubuntu_LoginServerCrypto_x64.zip +elif [[ "$OS" == "fedora_core" ]] || [[ "$OS" == "red_hat" ]]; then + wget http://eqemu.github.io/downloads/fedora12_LoginServerCrypto_x64.zip + unzip fedora12_LoginServerCrypto_x64.zip + rm fedora12_LoginServerCrypto_x64.zip +fi +cd $eqemu_server_directory/source/Server/build + +#::: Build +make + +#::: Back to server directory +cd $eqemu_server_directory/server +wget https://dl.dropboxusercontent.com/u/50023467/dl/eqemu/eqemu_server.pl + +#::: Link build files + +cd $eqemu_server_directory/server + +#::: Map lowercase to uppercase to avoid issues +ln -s maps Maps + +ln -s $eqemu_server_directory/source/Server/build/bin/loginserver +ln -s $eqemu_server_directory/source/Server/build/bin/eqlaunch +ln -s $eqemu_server_directory/source/Server/build/bin/export_client_files +ln -s $eqemu_server_directory/source/Server/build/bin/import_client_files +ln -s $eqemu_server_directory/source/Server/build/bin/libcommon.a +ln -s $eqemu_server_directory/source/Server/build/bin/libluabind.a +ln -s $eqemu_server_directory/source/Server/build/bin/queryserv +ln -s $eqemu_server_directory/source/Server/build/bin/shared_memory +ln -s $eqemu_server_directory/source/Server/build/bin/ucs +ln -s $eqemu_server_directory/source/Server/build/bin/world +ln -s $eqemu_server_directory/source/Server/build/bin/zone + +#::: Notes + +perl $eqemu_server_directory/server/eqemu_server.pl new_server + +#::: Chown files +chown eqemu:eqemu $eqemu_server_directory/ -R +chmod 755 $eqemu_server_directory/server/*.pl +chmod 755 $eqemu_server_directory/server/*.sh From 90dc7a4e387984b45db2b572864818c05cc88f58 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 22:36:50 -0500 Subject: [PATCH 10/16] Fix linux installs [skip ci] --- utils/scripts/eqemu_server.pl | 6 +++--- utils/scripts/linux_installer/install.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 0cf23b9cb..4e98c1fbd 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -196,13 +196,13 @@ sub new_server { } closedir(DIR); - if($file_count > 1 && !-e "install_variables.txt"){ + if($file_count > 1 && (!-e "install_variables.txt" || !-e "../install_variables.txt")){ print "[New Server] ERROR: You must run eqemu_server.pl in an empty directory\n"; <>; exit; } - if(-e "install_variables.txt"){ + if(-e "install_variables.txt" || -e "../install_variables.txt"){ get_installation_variables(); } @@ -2153,4 +2153,4 @@ sub generate_random_password { map $alphanumeric[rand @alphanumeric], 0..$passwordsize; return $randpassword; -} +} \ No newline at end of file diff --git a/utils/scripts/linux_installer/install.sh b/utils/scripts/linux_installer/install.sh index d9cdc0485..5b8fb24aa 100644 --- a/utils/scripts/linux_installer/install.sh +++ b/utils/scripts/linux_installer/install.sh @@ -205,7 +205,7 @@ make #::: Back to server directory cd $eqemu_server_directory/server -wget https://dl.dropboxusercontent.com/u/50023467/dl/eqemu/eqemu_server.pl +wget https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl #::: Link build files From 4246e4f79b9fb4310c3b8e971c792a9872b67ff8 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 22:44:37 -0500 Subject: [PATCH 11/16] Fix linux installs when in new_server routine [skip ci] --- utils/scripts/eqemu_server.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 4e98c1fbd..821736fef 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -196,7 +196,7 @@ sub new_server { } closedir(DIR); - if($file_count > 1 && (!-e "install_variables.txt" || !-e "../install_variables.txt")){ + if($file_count > 1 && (!-e "install_variables.txt" && !-e "../install_variables.txt")){ print "[New Server] ERROR: You must run eqemu_server.pl in an empty directory\n"; <>; exit; @@ -243,7 +243,7 @@ sub new_server { if($mysql_pass == 1){ - if(!-e "install_variables.txt"){ + if((!-e "install_variables.txt" && !-e "../install_variables.txt")){ print "[New Server] Success! We have a database connection\n"; check_for_input("Specify a NEW database name that PEQ will be installed to: "); @@ -783,6 +783,7 @@ sub show_menu_prompt { #::: If we're processing a CLI command, kill the loop if($ARGV[0] ne ""){ + analytics_insertion("cli", trim($input)); $input = ""; $ARGV[0] = ""; exit; From 66c0da85e64a50b810698489209048751ed4c120 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Sep 2016 22:51:29 -0500 Subject: [PATCH 12/16] Take out Linux source build from the install.sh file since eqemu_server.pl is flexibly taking care of it --- utils/scripts/linux_installer/install.sh | 56 +++++------------------- 1 file changed, 11 insertions(+), 45 deletions(-) diff --git a/utils/scripts/linux_installer/install.sh b/utils/scripts/linux_installer/install.sh index 5b8fb24aa..5d43230c5 100644 --- a/utils/scripts/linux_installer/install.sh +++ b/utils/scripts/linux_installer/install.sh @@ -172,60 +172,26 @@ mkdir $eqemu_server_directory/server/logs mkdir $eqemu_server_directory/server/shared mkdir $eqemu_server_directory/server/maps -#::: Pull down needed files for the installer from the Install repo - -cd $eqemu_server_directory/source -git clone https://github.com/EQEmu/Server.git -mkdir $eqemu_server_directory/source/Server/build -cd $eqemu_server_directory/source/Server/build - -echo "Generating CMake build files..." -if [[ "$OS" == "fedora_core" ]]; then - cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DLUA_INCLUDE_DIR=/usr/include/lua-5.1/ -G "Unix Makefiles" .. -else - cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G "Unix Makefiles" .. -fi -echo "Building EQEmu Server code. This will take a while." - #::: Grab loginserver dependencies -cd $eqemu_server_directory/source/Server/dependencies -if [[ "$OS" == "Debian" ]]; then - wget http://eqemu.github.io/downloads/ubuntu_LoginServerCrypto_x64.zip - unzip ubuntu_LoginServerCrypto_x64.zip - rm ubuntu_LoginServerCrypto_x64.zip -elif [[ "$OS" == "fedora_core" ]] || [[ "$OS" == "red_hat" ]]; then - wget http://eqemu.github.io/downloads/fedora12_LoginServerCrypto_x64.zip - unzip fedora12_LoginServerCrypto_x64.zip - rm fedora12_LoginServerCrypto_x64.zip -fi -cd $eqemu_server_directory/source/Server/build - -#::: Build -make +# cd $eqemu_server_directory/source/Server/dependencies +# if [[ "$OS" == "Debian" ]]; then +# wget http://eqemu.github.io/downloads/ubuntu_LoginServerCrypto_x64.zip +# unzip ubuntu_LoginServerCrypto_x64.zip +# rm ubuntu_LoginServerCrypto_x64.zip +# elif [[ "$OS" == "fedora_core" ]] || [[ "$OS" == "red_hat" ]]; then +# wget http://eqemu.github.io/downloads/fedora12_LoginServerCrypto_x64.zip +# unzip fedora12_LoginServerCrypto_x64.zip +# rm fedora12_LoginServerCrypto_x64.zip +# fi +# cd $eqemu_server_directory/source/Server/build #::: Back to server directory cd $eqemu_server_directory/server wget https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl -#::: Link build files - -cd $eqemu_server_directory/server - #::: Map lowercase to uppercase to avoid issues ln -s maps Maps -ln -s $eqemu_server_directory/source/Server/build/bin/loginserver -ln -s $eqemu_server_directory/source/Server/build/bin/eqlaunch -ln -s $eqemu_server_directory/source/Server/build/bin/export_client_files -ln -s $eqemu_server_directory/source/Server/build/bin/import_client_files -ln -s $eqemu_server_directory/source/Server/build/bin/libcommon.a -ln -s $eqemu_server_directory/source/Server/build/bin/libluabind.a -ln -s $eqemu_server_directory/source/Server/build/bin/queryserv -ln -s $eqemu_server_directory/source/Server/build/bin/shared_memory -ln -s $eqemu_server_directory/source/Server/build/bin/ucs -ln -s $eqemu_server_directory/source/Server/build/bin/world -ln -s $eqemu_server_directory/source/Server/build/bin/zone - #::: Notes perl $eqemu_server_directory/server/eqemu_server.pl new_server From 5679f45f5bae0adc03927e011536c04d6aed1737 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 7 Sep 2016 12:45:14 -0500 Subject: [PATCH 13/16] Update readme [skip ci] --- README.md | 70 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 154703a75..c9180fa96 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,56 @@ -EQEmu -=== +# EQEmulator Core Server +|Travis CI (Linux)|Appveyor (Windows) | +|:---:|:---:| +|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) | -[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) -[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) +*** -Overview ---- +**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++** + * MySQL/MariaDB is used as the database engine (over 200+ tables) + * Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events + * Open source database (Project EQ) has content up to expansion GoD (included in server installs) + * Game server environments and databases can be heavily customized to create all new experiences + * Hundreds of Quests/events created and maintained by Project EQ -EQEmu is a custom server implementation for EverQuest +## Server Installs +### > Windows +* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows) +* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide) -Dependencies ---- +### > Debian/Ubuntu -For Windows: http://eqemu.github.io +> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh -Login Server dependencies for Windows/Linux/OSX: http://eqemu.github.io +### > CentOS/Fedora -For Debian based distros (adjust to your local flavor): +> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh -- libmysqlclient-dev -- libperl-dev -- liblua5.1-0-dev (5.2 should work as well) -- libboost-dev +## Supported Clients -Further instructions on building the source can be found on the -[wiki](http://wiki.eqemulator.org/i?M=Wiki). +|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear| +|:---:|:---:|:---:|:---:|:---:| +|||||| -Bug reports ---- - -Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug +## Bug Reports +* Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug reports or feature requests. +* The [EQEmu Forums](http://www.eqemulator.org/forums/) are also a place to submit and get help with bugs. -The [EQEmu Forums](http://www.eqemulator.org/forums/) also have forums to submit -bugs/get help with bugs. +## Contributions -Contributions ---- - -The preferred way to contribute is to fork the repo and submit a pull request on +* The preferred way to contribute is to fork the repo and submit a pull request on GitHub. If you need help with your changes, you can always post on the forums or -try IRC. You can also post unified diffs (`git diff` should do the trick) on the +try Discord. You can also post unified diffs (`git diff` should do the trick) on the [Server Code Submissions](http://www.eqemulator.org/forums/forumdisplay.php?f=669) forum, although pull requests will be much quicker and easier on all parties. -Contact ---- - - **User IRC Channel**: `#eqemu` on `irc.eqemulator.net` - - **Developer IRC Channel**: `#eqemucoders` on `irc.eqemulator.net` +## Contact + - Discord Channel: https://discord.gg/QHsm7CD + - **User Discord Channel**: `#general` + - **Developer Discord Channel**: `#eqemucoders` + +Resources +--- - [EQEmulator Forums](http://www.eqemulator.org/forums) - [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki) - From 9a3af63f65d142dfcdd0097349f74b56b94202b3 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 7 Sep 2016 15:10:16 -0500 Subject: [PATCH 14/16] Update readme [skip ci] --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c9180fa96..a56251c19 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ * Hundreds of Quests/events created and maintained by Project EQ ## Server Installs +||Windows|Linux| +|:---:|:---:|:---:| +|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)| ### > Windows * [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows) * [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide) From 64998a398d992c58a78f2e74f340f130b8a796f0 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Thu, 8 Sep 2016 21:59:15 -0400 Subject: [PATCH 15/16] Added GetAAPercent() to Perl and Lua. --- zone/client.h | 1 + zone/lua_client.cpp | 6 ++++++ zone/lua_client.h | 1 + zone/perl_client.cpp | 27 +++++++++++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/zone/client.h b/zone/client.h index df7c1fce3..da2188fc7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -796,6 +796,7 @@ public: void SendClearAA(); inline uint32 GetMaxAAXP(void) const { return max_AAXP; } inline uint32 GetAAXP() const { return m_pp.expAA; } + inline uint32 GetAAPercent() const { return m_epp.perAA; } int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id); void SetAATitle(const char *Title); void SetTitleSuffix(const char *txt); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 6c2345856..403ca82aa 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -185,6 +185,11 @@ uint32 Lua_Client::GetAAExp() { return self->GetAAXP(); } +uint32 Lua_Client::GetAAPercent() { + Lua_Safe_Call_Int(); + return self->GetAAPercent(); +} + uint32 Lua_Client::GetTotalSecondsPlayed() { Lua_Safe_Call_Int(); return self->GetTotalSecondsPlayed(); @@ -1377,6 +1382,7 @@ luabind::scope lua_register_client() { .def("GetWeight", (int(Lua_Client::*)(void))&Lua_Client::GetWeight) .def("GetEXP", (uint32(Lua_Client::*)(void))&Lua_Client::GetEXP) .def("GetAAExp", (uint32(Lua_Client::*)(void))&Lua_Client::GetAAExp) + .def("GetAAPercent", (uint32(Lua_Client::*)(void))&Lua_Client::GetAAPercent) .def("GetTotalSecondsPlayed", (uint32(Lua_Client::*)(void))&Lua_Client::GetTotalSecondsPlayed) .def("UpdateLDoNPoints", (void(Lua_Client::*)(int,uint32))&Lua_Client::UpdateLDoNPoints) .def("SetDeity", (void(Lua_Client::*)(int))&Lua_Client::SetDeity) diff --git a/zone/lua_client.h b/zone/lua_client.h index 36ea2b8a4..a0a5a9083 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -63,6 +63,7 @@ public: int GetWeight(); uint32 GetEXP(); uint32 GetAAExp(); + uint32 GetAAPercent(); uint32 GetTotalSecondsPlayed(); void UpdateLDoNPoints(int points, uint32 theme); void SetDeity(int v); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 76c085714..de334d5d0 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -871,6 +871,32 @@ XS(XS_Client_GetAAExp) XSRETURN(1); } +XS(XS_Client_GetAAPercent); +XS(XS_Client_GetAAPercent) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Client::GetAAPercent(THIS)"); + { + Client* THIS; + uint32 RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Client *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Client"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetAAPercent(); + XSprePUSH; PUSHu((UV)RETVAL); + } + XSRETURN(1); +} + XS(XS_Client_GetTotalSecondsPlayed); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_GetTotalSecondsPlayed) { @@ -6465,6 +6491,7 @@ XS(boot_Client) newXSproto(strcpy(buf, "GetWeight"), XS_Client_GetWeight, file, "$"); newXSproto(strcpy(buf, "GetEXP"), XS_Client_GetEXP, file, "$"); newXSproto(strcpy(buf, "GetAAExp"), XS_Client_GetAAExp, file, "$"); + newXSproto(strcpy(buf, "GetAAPercent"), XS_Client_GetAAPercent, file, "$"); newXSproto(strcpy(buf, "GetTotalSecondsPlayed"), XS_Client_GetTotalSecondsPlayed, file, "$"); newXSproto(strcpy(buf, "UpdateLDoNPoints"), XS_Client_UpdateLDoNPoints, file, "$$$"); newXSproto(strcpy(buf, "SetDeity"), XS_Client_SetDeity, file, "$$"); From 4816c1fc9a1a24fa6008faf716f35ad771e73212 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Fri, 9 Sep 2016 23:59:23 -0400 Subject: [PATCH 16/16] Added support for server-wide marquee messages. --- common/servertalk.h | 10 ++++++++++ world/zoneserver.cpp | 1 + zone/embparser_api.cpp | 21 +++++++++++++++++++++ zone/lua_general.cpp | 5 +++++ zone/questmgr.cpp | 14 ++++++++++++++ zone/questmgr.h | 1 + zone/worldserver.cpp | 13 +++++++++++++ 7 files changed, 65 insertions(+) diff --git a/common/servertalk.h b/common/servertalk.h index e476d023d..b0197985f 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -193,6 +193,7 @@ #define ServerOP_QSSendQuery 0x5016 #define ServerOP_CZSignalNPC 0x5017 #define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018 +#define ServerOP_WWMarquee 0x5019 /* Query Serv Generic Packet Flag/Type Enumeration */ enum { QSG_LFGuild = 0 }; @@ -1254,6 +1255,15 @@ struct CZMessagePlayer_Struct { char Message[512]; }; +struct WWMarquee_Struct { + uint32 Type; + uint32 Priority; + uint32 FadeIn; + uint32 FadeOut; + uint32 Duration; + char Message[512]; +}; + struct CZSetEntVarByNPCTypeID_Struct { uint32 npctype_id; char id[256]; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index abe6e0e18..9a9572f97 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1312,6 +1312,7 @@ bool ZoneServer::Process() { case ServerOP_CZSignalNPC: case ServerOP_CZSetEntityVariableByNPCTypeID: case ServerOP_CZSignalClient: + case ServerOP_WWMarquee: case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopPlayerCorpse: case ServerOP_ReloadTitles: diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index b9b28f0a6..adaaf3325 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3616,6 +3616,26 @@ XS(XS__crosszonesignalnpcbynpctypeid) XSRETURN_EMPTY; } +XS(XS__worldwidemarquee); +XS(XS__worldwidemarquee) +{ + dXSARGS; + if (items != 6) + Perl_croak(aTHX_ "Usage: worldwidemarquee(type, priority, fadein, fadeout, duration, message)"); + + if (items == 6) { + uint32 type = (uint32)SvIV(ST(0)); + uint32 priority = (uint32)SvIV(ST(1)); + uint32 fadein = (uint32)SvIV(ST(2)); + uint32 fadeout = (uint32)SvIV(ST(3)); + uint32 duration = (uint32)SvIV(ST(4)); + char* message = (char *)SvPV_nolen(ST(5)); + quest_manager.WorldWideMarquee(type, priority, fadein, fadeout, duration, message); + } + + XSRETURN_EMPTY; +} + XS(XS__debug); XS(XS__debug) { @@ -3749,6 +3769,7 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file); newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file); newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file); + newXS(strcpy(buf, "worldwidemarquee"), XS__worldwidemarquee, file); newXS(strcpy(buf, "debug"), XS__debug, file); newXS(strcpy(buf, "delglobal"), XS__delglobal, file); newXS(strcpy(buf, "depop"), XS__depop, file); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index d47420fe1..9f413128b 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -892,6 +892,10 @@ void lua_cross_zone_message_player_by_name(uint32 type, const char *player, cons quest_manager.CrossZoneMessagePlayerByName(type, player, message); } +void lua_world_wide_marquee(uint32 type, uint32 priority, uint32 fadein, uint32 fadeout, uint32 duration, const char *message) { + quest_manager.WorldWideMarquee(type, priority, fadein, fadeout, duration, message); +} + luabind::adl::object lua_get_qglobals(lua_State *L, Lua_NPC npc, Lua_Client client) { luabind::adl::object ret = luabind::newtable(L); @@ -1613,6 +1617,7 @@ luabind::scope lua_register_general() { luabind::def("cross_zone_signal_client_by_char_id", &lua_cross_zone_signal_client_by_char_id), luabind::def("cross_zone_signal_client_by_name", &lua_cross_zone_signal_client_by_name), luabind::def("cross_zone_message_player_by_name", &lua_cross_zone_message_player_by_name), + luabind::def("world_wide_marquee", &lua_world_wide_marquee), luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC,Lua_Client))&lua_get_qglobals), luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_Client))&lua_get_qglobals), luabind::def("get_qglobals", (luabind::adl::object(*)(lua_State*,Lua_NPC))&lua_get_qglobals), diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 78fc2b206..5803e547c 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3017,6 +3017,20 @@ void QuestManager::CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, cons safe_delete(pack); } +void QuestManager::WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message) { + uint32 message_len = strlen(Message) + 1; + auto pack = new ServerPacket(ServerOP_WWMarquee, sizeof(WWMarquee_Struct) + message_len); + WWMarquee_Struct* WWMS = (WWMarquee_Struct*) pack->pBuffer; + WWMS->Type = Type; + WWMS->Priority = Priority; + WWMS->FadeIn = FadeIn; + WWMS->FadeOut = FadeOut; + WWMS->Duration = Duration; + strn0cpy(WWMS->Message, Message, 512); + worldserver.SendPacket(pack); + safe_delete(pack); +} + bool QuestManager::EnableRecipe(uint32 recipe_id) { bool success = false; diff --git a/zone/questmgr.h b/zone/questmgr.h index 612c7815f..10c82c1ee 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -252,6 +252,7 @@ public: void CrossZoneSignalPlayerByName(const char *CharName, uint32 data); void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var); void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message); + void WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message); bool EnableRecipe(uint32 recipe_id); bool DisableRecipe(uint32 recipe_id); void ClearNPCTypeCache(int npctype_id); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 0f00ed0c5..60a4e7385 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1838,6 +1838,19 @@ void WorldServer::Process() { } break; } + case ServerOP_WWMarquee: + { + WWMarquee_Struct* WWMS = (WWMarquee_Struct*) pack->pBuffer; + std::list client_list; + entity_list.GetClientList(client_list); + auto iter = client_list.begin(); + std::string Message = WWMS->Message; + while (iter != client_list.end()) { + Client* client = (*iter); + client->SendMarqueeMessage(WWMS->Type, WWMS->Priority, WWMS->FadeIn, WWMS->FadeOut, WWMS->Duration, Message); + iter++; + } + } case ServerOP_ReloadWorld: { ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer;