From ecdc0f709609f88b41f965cafd832e477994ac11 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Tue, 23 Aug 2016 13:54:51 -0400 Subject: [PATCH 1/6] Fixed so mobs that depop at end of pathgrid still path and depop whiel zones are empty. This makes these mobs no longer always appear at start locations for the 1st person in a zone after long idle. --- zone/entity.cpp | 16 ++++++++++------ zone/mob.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/zone/entity.cpp b/zone/entity.cpp index d398c9bf6..975b793e9 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -478,14 +478,18 @@ void EntityList::MobProcess() size_t sz = mob_list.size(); #ifdef IDLE_WHEN_EMPTY - // spawn_events can cause spawns and deaths while zone empty. - // At the very least, process that. - if (numclients < 1) { - mob_dead = mob->CastToNPC()->GetDepop(); - } - else { + if (numclients > 0 || + mob->GetWanderType() == 4 || mob->GetWanderType() == 6) { + // Normal processing, or assuring that spawns that should + // path and depop do that. Otherwise all of these type mobs + // will be up and at starting positions when idle zone wakes up. mob_dead = !mob->Process(); } + else { + // spawn_events can cause spawns and deaths while zone empty. + // At the very least, process that. + mob_dead = mob->CastToNPC()->GetDepop(); + } #else mob_dead = !mob->Process(); #endif diff --git a/zone/mob.h b/zone/mob.h index 3106df4ff..ff4879edd 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -843,6 +843,7 @@ public: inline void SetFocused(bool nState) { focused = nState; } inline const bool IsFocused() const { return focused; } inline const bool IsRoamer() const { return roamer; } + inline const int GetWanderType() const { return wandertype; } inline const bool IsRooted() const { return rooted || permarooted; } inline const bool HasVirus() const { return has_virus; } int GetSnaredAmount(); From 5039aa07a5a5cbf89b212df44375682247f189d9 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Tue, 23 Aug 2016 14:50:29 -0400 Subject: [PATCH 2/6] updated changelog --- changelog.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/changelog.txt b/changelog.txt index 7647ea8ec..cde46e646 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,12 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/23/2016 == +noudess: Force mobs on a depop @ end pathgrid to still do this on idle zones. +This makes them be more random after a zone is idle, rather than always showing +up at start point when 1st person logs into an idle zone. Much more like live. +I dion't think this will be much of a performance problem. Once they path and +depop, no mkore cpu usage. + == 08/14/2016 == mackal: Implement Linked Spell Reuse Timers - For whatever reason this is a bit unfriendly, but that's how it is on live. From 25de25a7773b4d1374d2e39533a9108817120ca9 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 25 Aug 2016 18:00:13 -0500 Subject: [PATCH 3/6] Update eqemu_server.pl - Add internet connection checks for people using EQEmu locally [skip ci] --- utils/scripts/eqemu_update.pl | 1205 +++++++++++++++++++-------------- 1 file changed, 713 insertions(+), 492 deletions(-) diff --git a/utils/scripts/eqemu_update.pl b/utils/scripts/eqemu_update.pl index a7da3c792..e794a3710 100644 --- a/utils/scripts/eqemu_update.pl +++ b/utils/scripts/eqemu_update.pl @@ -1,74 +1,56 @@ #!/usr/bin/perl ########################################################### -#::: Automatic (Database) Upgrade Script -#::: Author: Akkadius +#::: 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 ########################################################### -$menu_displayed = 0; - use Config; use File::Copy qw(copy); use POSIX qw(strftime); use File::Path; use File::Find; -use URI::Escape; -use Time::HiRes qw(usleep); +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 $console_output .= " Operating System is: $Config{osname}\n"; if($Config{osname}=~/freebsd|linux/i){ $OS = "Linux"; } if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; } +$has_internet_connection = check_internet_connection(); -#::: If current version is less than what world is reporting, then download a new one... -$current_version = 14; +#::: Check for script self update +do_self_update_check_routine(); -if($ARGV[0] eq "V"){ - if($ARGV[1] > $current_version){ - print "eqemu_update.pl Automatic Database Upgrade Needs updating...\n"; - print " Current version: " . $current_version . "\n"; - print " New version: " . $ARGV[1] . "\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl", "eqemu_update.pl"); - exit; - } - else{ - print "[Upgrade Script] No script update necessary \n"; - } - exit; -} - -#::: Sets database run stage check -$db_run_stage = 0; +print "[Info] For EQEmu Server management utilities - run eqemu_server.pl\n"; +#::: Check Perl version $perl_version = $^V; $perl_version =~s/v//g; -print "Perl Version is " . $perl_version . "\n"; -if($perl_version > 5.12){ no warnings 'uninitialized'; } +print "[Update] Perl Version is " . $perl_version . "\n"; +if($perl_version > 5.12){ + no warnings 'uninitialized'; +} no warnings; +#::: Remove old eqemu_update.pl +if(-e "eqemu_update.pl"){ + unlink("eqemu_update.pl"); +} + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); -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; } -} - -$console_output = -"============================================================ - EQEmu: Automatic Upgrade Check -============================================================ -"; +read_eqemu_config_xml(); if($OS eq "Windows"){ $has_mysql_path = `echo %PATH%`; @@ -81,9 +63,6 @@ if($OS eq "Windows"){ last; } } - $console_output .= " (Windows) MySQL is in system path \n"; - $console_output .= " Path = " . $path . "\n"; - $console_output .= "============================================================\n"; } } @@ -91,101 +70,14 @@ if($OS eq "Windows"){ if($OS eq "Linux"){ $path = `which mysql`; if ($path eq "") { - $path = `which mariadb`; + $path = `which mariadb`; } $path =~s/\n//g; - - $console_output .= " (Linux) MySQL is in system path \n"; - $console_output .= " Path = " . $path . "\n"; - $console_output .= "============================================================\n"; } #::: Path not found, error and exit if($path eq ""){ - print "MySQL path not found, please add the path for automatic database upgrading to continue... \n\n"; - print "script_exiting...\n"; - exit; -} - -if($ARGV[0] eq "install_peq_db"){ - - $db_name = "peq"; - if($ARGV[1]){ - $db_name = $ARGV[1]; - } - - $db = $db_name; - - #::: Database Routines - print "MariaDB :: 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"`; - if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); } - if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); } - $bin_db_ver = trim($db_version[1]); - check_db_version_table(); - $local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); - fetch_peq_db_full(); - print "\nFetching Latest Database Updates...\n"; - main_db_management(); - print "\nApplying Latest Database Updates...\n"; - main_db_management(); - - print get_mysql_result("UPDATE `launcher` SET `dynamics` = 30 WHERE `name` = 'zone'"); -} - -if($ARGV[0] eq "remove_duplicate_rules"){ - remove_duplicate_rule_values(); - exit; -} - -if($ARGV[0] eq "installer"){ - print "Running EQEmu Server installer routines...\n"; - mkdir('logs'); - mkdir('updates_staged'); - mkdir('shared'); - fetch_latest_windows_binaries(); - map_files_fetch_bulk(); - opcodes_fetch(); - plugins_fetch(); - quest_files_fetch(); - lua_modules_fetch(); - - #::: Binary dll's - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/lua51.dll", "lua51.dll", 1); - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/zlib1.dll", "zlib1.dll", 1); - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/libmysql.dll", "libmysql.dll", 1); - - #::: Server scripts - fetch_utility_scripts(); - - #::: Database Routines - print "MariaDB :: Creating Database 'peq'\n"; - print `"$path" --host $host --user $user --password="$pass" -N -B -e "DROP DATABASE IF EXISTS peq;"`; - print `"$path" --host $host --user $user --password="$pass" -N -B -e "CREATE DATABASE peq"`; - if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); } - if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); } - $bin_db_ver = trim($db_version[1]); - check_db_version_table(); - $local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); - fetch_peq_db_full(); - print "\nFetching Latest Database Updates...\n"; - main_db_management(); - print "\nApplying Latest Database Updates...\n"; - main_db_management(); - - print get_mysql_result("UPDATE `launcher` SET `dynamics` = 30 WHERE `name` = 'zone'"); - - if($OS eq "Windows"){ - check_windows_firewall_rules(); - do_windows_login_server_setup(); - } - exit; -} - -if($ARGV[0] eq "db_dump_compress"){ database_dump_compress(); exit; } -if($ARGV[0] eq "login_server_setup"){ - do_windows_login_server_setup(); + print "[Error:eqemu_server.pl] MySQL path not found, please add the path for automatic database upgrading to continue... \n\n"; exit; } @@ -195,7 +87,7 @@ mkdir('db_update'); #::: 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 "Old db_version table present, dropping...\n\n"; + print "[Database] Old db_version table present, dropping...\n\n"; } sub check_db_version_table{ @@ -205,7 +97,7 @@ sub check_db_version_table{ version int(11) DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO db_version (version) VALUES ('1000');"); - print "Table 'db_version' does not exists.... Creating...\n\n"; + print "[Database] Table 'db_version' does not exists.... Creating...\n\n"; } } @@ -218,173 +110,406 @@ $bin_db_ver = trim($db_version[1]); $local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1")); #::: If ran from Linux startup script, supress output -if($bin_db_ver == $local_db_ver && $ARGV[0] eq "ran_from_start"){ - print "Database up to date...\n"; +if($bin_db_ver == $local_db_ver && $ARGV[0] eq "ran_from_world"){ + print "[Update] Database up to date...\n"; exit; } -else{ - print $console_output if $db; +else { + + #::: We ran world - Database needs to update, lets backup and run updates and continue world bootup + if($local_db_ver < $bin_db_ver && $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(); + } } if($db){ - print " Binary Revision / Local: (" . $bin_db_ver . " / " . $local_db_ver . ")\n"; + print "[Update] MySQL Path/Location: " . $path . "\n"; + print "[Update] Binary Revision / Local: (" . $bin_db_ver . " / " . $local_db_ver . ")\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 " (Bots) Binary Revision / Local: (" . trim($db_version[2]) . " / " . $bots_local_db_version . ")\n"; + 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 World ran this script, and our version is up to date, continue... if($bin_db_ver <= $local_db_ver && $ARGV[0] eq "ran_from_world"){ - print " Database up to Date: Continuing World Bootup...\n"; - print "============================================================\n"; + print "[Update] Database up to Date: Continuing World Bootup...\n"; exit; } +} +if($ARGV[0] eq "remove_duplicate_rules"){ + remove_duplicate_rule_values(); + exit; } -if($local_db_ver < $bin_db_ver && $ARGV[0] eq "ran_from_world"){ - print "You have missing database updates, type 1 or 2 to backup your database before running them as recommended...\n\n"; - #::: Display Menu - show_menu_prompt(); -} -else{ - #::: Most likely ran standalone - print "\n"; - show_menu_prompt(); +if($ARGV[0] eq "map_files_fetch_bulk"){ + map_files_fetch_bulk(); + exit; } -sub do_update_self{ - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl", "eqemu_update.pl"); - die "Rerun eqemu_update.pl"; +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`); } + $bin_db_ver = trim($db_version[1]); + + #::: Local DB Version + check_db_version_table(); + $local_db_ver = 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_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 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("chown eqemu 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 + 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_dump, - 2 => \&database_dump_compress, - 3 => \&main_db_management, - 4 => \&bots_db_management, - 5 => \&opcodes_fetch, - 6 => \&map_files_fetch, - 7 => \&plugins_fetch, - 8 => \&quest_files_fetch, - 9 => \&lua_modules_fetch, - 10 => \&aa_fetch, - 11 => \&fetch_latest_windows_binaries, - 12 => \&fetch_server_dlls, - 13 => \&do_windows_login_server_setup, - 14 => \&remove_duplicate_rule_values, - 15 => \&fetch_utility_scripts, - 18 => \&fetch_latest_windows_binaries_bots, - 19 => \&do_bots_db_schema_drop, - 20 => \&do_update_self, - 21 => \&database_dump_player_tables, - 0 => \&script_exit, - ); - while (1) { - { - local $| = 1; - if(!$menu_show && ($ARGV[0] eq "ran_from_world" || $ARGV[0] eq "ran_from_start")){ - $menu_show++; - next; - } - print menu_options(), '> '; - $menu_displayed++; - if($menu_displayed > 50){ - print "Safety: Menu looping too many times, exiting...\n"; - exit; - } + $dc = 0; + while (1) { + $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_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); } - - my $choice = <>; - - $choice =~ s/\A\s+//; - $choice =~ s/\s+\z//; - - if (defined(my $handler = $dispatch{$choice})) { - my $result = $handler->(); - unless (defined $result) { - exit 0; + 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 { - if($ARGV[0] ne "ran_from_world"){ - # warn "\n\nInvalid selection\n\n"; - } + print_main_menu(); + } + + #::: Errored command checking + if($errored_command == 1){ + $input = $last_menu; + } + elsif($dc == 1){ + $dc = 0; + $input = ""; + } + else { + $input = <>; } } } -sub menu_options { - if(@total_updates){ - if($bots_db_management == 1){ - $option[3] = "Check and stage pending REQUIRED Database updates"; - $bots_management = "Run pending REQUIRED updates... (" . scalar (@total_updates) . ")"; - } - else{ - $option[3] = "Run pending REQUIRED updates... (" . scalar (@total_updates) . ")"; - if(get_mysql_result("SHOW TABLES LIKE 'bots'") eq ""){ - $bots_management = "Install bots database pre-requisites (Requires bots server binaries)"; - } - else{ - $bots_management = "Check for Bot pending REQUIRED database updates... (Must have bots enabled)"; - } - } - } - else{ - $option[3] = "Check and stage pending REQUIRED Database updates"; - $bots_management = "Check for Bot REQUIRED database updates... (Must have bots enabled)"; - } - -return <>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\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 check_for_database_dump_script{ @@ -392,25 +517,21 @@ sub check_for_database_dump_script{ return; } else{ - print "db_dumper.pl not found... retrieving...\n\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_dumper.pl", "db_dumper.pl"); + 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 ran_from_world { - print "Running from world...\n"; -} - sub database_dump { check_for_database_dump_script(); - print "Performing database backup....\n"; + 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 "Performing database backup of player tables....\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/character_table_list.txt", "backups/character_table_list.txt"); + 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"); @@ -424,7 +545,7 @@ sub database_dump_player_tables { print `perl db_dumper.pl database="$db" loc="backups" tables="$tables" backup_name="player_tables_export" nolock`; - print "\nPress any key to continue...\n"; + print "[Database] Press any key to continue...\n"; <>; #Read from STDIN @@ -432,7 +553,7 @@ sub database_dump_player_tables { sub database_dump_compress { check_for_database_dump_script(); - print "Performing database backup....\n"; + print "[Database] Performing database backup....\n"; print `perl db_dumper.pl database="$db" loc="backups" compress`; } @@ -460,30 +581,40 @@ sub get_mysql_result_from_file{ if($OS eq "Linux"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; } } -#::: Gets Remote File based on URL (1st Arg), and saves to destination file (2nd Arg) -#::: Example: get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt"); +#::: 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 $URL = $_[0]; - my $Dest_File = $_[1]; + 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($Dest_File=~/\//i){ - my @dir_path = split('/', $Dest_File); + + if($destination_file=~/\//i){ + my @directory_path = split('/', $destination_file); $build_path = ""; - $di = 0; - while($dir_path[$di]){ - $build_path .= $dir_path[$di] . "/"; + $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) { + if (!-d $build_path) { + print "[Copy] folder doesn't exist, creating '" . $build_path . "'\n"; mkdir($build_path); } - if(!$dir_path[$di + 2] && $dir_path[$di + 1]){ + if(!$directory_indexr_path[$directory_index + 2] && $directory_indexr_path[$directory_index + 1]){ # print $actual_path . "\n"; $actual_path = $build_path; last; } - $di++; + $directory_index++; } } @@ -492,51 +623,59 @@ sub get_remote_file{ if($content_type == 1){ $break = 0; while($break == 0) { - use LWP::Simple qw(getstore); - if(!getstore($URL, $Dest_File)){ - # print "Error, no connection or failed request...\n\n"; + 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 $Dest_File) { + if(-e $destination_file) { $break = 1; - print " [URL] :: " . $URL . "\n"; - print " [Saved] :: " . $Dest_File . "\n"; + 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; + my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; - my $response = $ua->get($URL); + my $response = $ua->get($request_url); if ($response->is_success){ - open (FILE, '> ' . $Dest_File . ''); + open (FILE, '> ' . $destination_file . ''); print FILE $response->decoded_content; close (FILE); } else { - # print "Error, no connection or failed request...\n\n"; + print "[Download] Error, no connection or failed request...\n\n"; } - if(-e $Dest_File) { + if(-e $destination_file) { $break = 1; - print " [URL] :: " . $URL . "\n"; - print " [Saved] :: " . $Dest_File . "\n"; + 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 $Dest_File $URL`; - print " o URL: (" . $URL . ")\n"; - print " o Saved: (" . $Dest_File . ") \n"; - if($wget=~/unable to resolve/i){ + $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; } @@ -551,6 +690,22 @@ sub trim { 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){ @@ -558,48 +713,48 @@ sub aa_fetch{ return; } - print "Pulling down PEQ AA Tables...\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/peq_aa_tables_post_rework.sql", "db_update/peq_aa_tables_post_rework.sql"); - print "\n\nInstalling AA Tables...\n"; + 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 "\nDone...\n\n"; + print "[Install] Done...\n\n"; } #::: Fetch Latest Opcodes sub opcodes_fetch{ - print "Pulling down latest opcodes...\n"; + print "[Update] Pulling down latest opcodes...\n"; %opcodes = ( - 1 => ["opcodes", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/opcodes.conf"], - 2 => ["mail_opcodes", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/mail_opcodes.conf"], - 3 => ["Titanium", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_Titanium.conf"], - 4 => ["Secrets of Faydwer", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoF.conf"], - 5 => ["Seeds of Destruction", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoD.conf"], - 6 => ["Underfoot", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_UF.conf"], - 7 => ["Rain of Fear", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF.conf"], - 8 => ["Rain of Fear 2", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF2.conf"], + 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 URL by the patches folder to get the file name from URL + #::: 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++; } - - print "\nDownloading (" . $opcodes{$loop}[0] . ") File: '" . $file_name . "'...\n\n"; + get_remote_file($opcodes{$loop}[1], $file_name); $loop++; } - print "\nDone...\n\n"; + print "[Update] Done...\n"; } -sub remove_duplicate_rule_values{ +sub remove_duplicate_rule_values { $ruleset_id = trim(get_mysql_result("SELECT `ruleset_id` FROM `rule_sets` WHERE `name` = 'default'")); - print "Default Ruleset ID: " . $ruleset_id . "\n"; + 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); @@ -607,50 +762,51 @@ sub remove_duplicate_rule_values{ 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 "DUPLICATE : " . $values[1] . " (Ruleset (" . $values[0] . ")) matches default value of : " . $values[2] . ", removing...\n"; + 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 "Total duplicate rules removed... " . $total_removed . "\n"; + print "[Database] Total duplicate rules removed... " . $total_removed . "\n"; } -sub copy_file{ +sub copy_file { $l_source_file = $_[0]; - $l_dest_file = $_[1]; - if($l_dest_file=~/\//i){ - my @dir_path = split('/', $l_dest_file); + $l_destination_file = $_[1]; + if($l_destination_file=~/\//i){ + my @directory_path = split('/', $l_destination_file); $build_path = ""; - $di = 0; - while($dir_path[$di]){ - $build_path .= $dir_path[$di] . "/"; + $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(!$dir_path[$di + 2] && $dir_path[$di + 1]){ + if(!$directory_path[$directory_index + 2] && $directory_path[$directory_index + 1]){ # print $actual_path . "\n"; $actual_path = $build_path; last; } - $di++; + $directory_index++; } } - copy $l_source_file, $l_dest_file; + copy $l_source_file, $l_destination_file; } -sub fetch_latest_windows_binaries{ - print "\n --- Fetching Latest Windows Binaries... --- \n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/master_windows_build.zip", "updates_staged/master_windows_build.zip", 1); - print "\n --- Fetched Latest Windows Binaries... --- \n"; - print "\n --- Extracting... --- \n"; +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"; @@ -659,21 +815,21 @@ sub fetch_latest_windows_binaries{ $start_dir ); for my $file (@files) { - $dest_file = $file; - $dest_file =~s/updates_staged\/binaries\///g; - print "Installing :: " . $dest_file . "\n"; - copy_file($file, $dest_file); + $destination_file = $file; + $destination_file =~s/updates_staged\/binaries\///g; + print "[Update] Installing :: " . $destination_file . "\n"; + copy_file($file, $destination_file); } - print "\n --- Done... --- \n"; + print "[Update] Done\n"; rmtree('updates_staged'); } -sub fetch_latest_windows_binaries_bots{ - print "\n --- Fetching Latest Windows Binaries with Bots... --- \n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/master_windows_build_bots.zip", "updates_staged/master_windows_build_bots.zip", 1); - print "\n --- Fetched Latest Windows Binaries with Bots... --- \n"; - print "\n --- Extracting... --- \n"; +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"; @@ -682,20 +838,20 @@ sub fetch_latest_windows_binaries_bots{ $start_dir ); for my $file (@files) { - $dest_file = $file; - $dest_file =~s/updates_staged\/binaries\///g; - print "Installing :: " . $dest_file . "\n"; - copy_file($file, $dest_file); + $destination_file = $file; + $destination_file =~s/updates_staged\/binaries\///g; + print "[Install] Installing :: " . $destination_file . "\n"; + copy_file($file, $destination_file); } - print "\n --- Done... --- \n"; + print "[Update] Done...\n"; rmtree('updates_staged'); } -sub do_windows_login_server_setup{ - print "\n --- Fetching Loginserver... --- \n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/login_server.zip", "updates_staged/login_server.zip", 1); - print "\n --- Extracting... --- \n"; +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"; @@ -704,31 +860,85 @@ sub do_windows_login_server_setup{ $start_dir ); for my $file (@files) { - $dest_file = $file; - $dest_file =~s/updates_staged\/login_server\///g; - print "Installing :: " . $dest_file . "\n"; - copy_file($file, $dest_file); + $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] Done... \n"; - print "Pulling down Loginserver database tables...\n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/login_server_tables.sql", "db_update/login_server_tables.sql"); - print "\n\nInstalling Loginserver tables...\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 "\nDone...\n\n"; + print "[Install] Done...\n"; add_login_server_firewall_rules(); rmtree('updates_staged'); rmtree('db_update'); - print "\nPress any key to continue...\n"; + 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{ +sub add_login_server_firewall_rules { #::: Check Loginserver Firewall install for Windows if($OS eq "Windows"){ $output = `netsh advfirewall firewall show rule name=all`; @@ -750,22 +960,22 @@ sub add_login_server_firewall_rules{ } if($has_loginserver_rules_titanium == 0){ - print "Attempting to add EQEmu Loginserver Firewall Rules (Titanium) (TCP) port 5998 \n"; + 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 "Attempting to add EQEmu Loginserver Firewall Rules (Titanium) (UDP) port 5998 \n"; + 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 "Attempting to add EQEmu Loginserver Firewall Rules (SOD+) (TCP) port 5999 \n"; + 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 "Attempting to add EQEmu Loginserver Firewall Rules (SOD+) (UDP) port 5999 \n"; + 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_update.pl) as administrator\n"; + print "If firewall rules don't add you must run this script (eqemu_server.pl) as administrator\n"; print "\n"; - print "#::: Instructions \n"; - print "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 "[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 @@ -780,7 +990,7 @@ sub add_login_server_firewall_rules{ "; - print "\nWhen 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"; + 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"; } } @@ -794,84 +1004,84 @@ sub check_windows_firewall_rules{ $val=~s/Rule Name://g; if($val=~/EQEmu World/i){ $has_world_rules = 1; - print "Found existing rule :: " . trim($val) . "\n"; + print "[Install] Found existing rule :: " . trim($val) . "\n"; } if($val=~/EQEmu Zone/i){ $has_zone_rules = 1; - print "Found existing rule :: " . trim($val) . "\n"; + print "[Install] Found existing rule :: " . trim($val) . "\n"; } } } if($has_world_rules == 0){ - print "Attempting to add EQEmu World Firewall Rules (TCP) port 9000 \n"; + 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 "Attempting to add EQEmu World Firewall Rules (UDP) port 9000 \n"; + 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 "Attempting to add EQEmu Zones (7000-7500) TCP \n"; + 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 "Attempting to add EQEmu Zones (7000-7500) UDP \n"; + 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 "Fetching lua51.dll, zlib1.dll, libmysql.dll...\n"; - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/lua51.dll", "lua51.dll", 1); - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/zlib1.dll", "zlib1.dll", 1); - get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/libmysql.dll", "libmysql.dll", 1); + 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 "Downloading latest PEQ Database... Please wait...\n"; + 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 "Downloaded latest PEQ Database... Extracting...\n"; + 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"; + my $start_dir = "updates_staged/peq_db"; find( sub { push @files, $File::Find::name unless -d; }, $start_dir ); for my $file (@files) { - $dest_file = $file; - $dest_file =~s/updates_staged\\peq_db\///g; + $destination_file = $file; + $destination_file =~s/updates_staged\/peq_db\///g; if($file=~/peqbeta|player_tables/i){ - print "MariaDB :: Installing :: " . $dest_file . "\n"; + print "[Install] DB :: Installing :: " . $destination_file . "\n"; get_mysql_result_from_file($file); } if($file=~/eqtime/i){ - print "Installing eqtime.cfg\n"; + print "[Install] Installing eqtime.cfg\n"; copy_file($file, "eqtime.cfg"); } } } sub map_files_fetch_bulk{ - print "\n --- Fetching Latest Maps... (This could take a few minutes...) --- \n"; + 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"; + my $start_dir = "maps/EQEmuMaps-master/maps"; find( sub { push @files, $File::Find::name unless -d; }, $start_dir ); for my $file (@files) { - $dest_file = $file; - $dest_file =~s/maps\\EQEmuMaps-master\\maps\///g; - print "Installing :: " . $dest_file . "\n"; + $destination_file = $file; + $destination_file =~s/maps\/EQEmuMaps-master\/maps\///g; + print "[Install] Installing :: " . $destination_file . "\n"; copy_file($file, "maps/" . $new_file); } - print "\n --- Fetched Latest Maps... --- \n"; + print "[Install] Fetched Latest Maps\n"; rmtree('maps/EQEmuMaps-master'); unlink('maps/maps.zip'); } sub map_files_fetch{ - print "\n --- Fetching Latest Maps --- \n"; + 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"); @@ -894,22 +1104,22 @@ sub map_files_fetch{ my $file_existing = $maps_manifest[$m][0]; my $file_existing_size = (stat $file_existing)[7]; if($file_existing_size != $maps_manifest[$m][1]){ - print "Updating: '" . $maps_manifest[$m][0] . "'\n"; + 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 "\nNo Map Updates found... \n\n"; + print "[Install] No Map Updates found... \n\n"; } } sub quest_files_fetch{ if (!-e "updates_staged/Quests-Plugins-master/quests/") { - print "\n --- Fetching Latest Quests --- \n"; + 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 "\nFetched latest quests...\n"; + print "[Install] Fetched latest quests...\n"; mkdir('updates_staged'); unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); } @@ -927,30 +1137,30 @@ sub quest_files_fetch{ for my $file (@files) { if($file=~/\.pl|\.lua|\.ext/i){ $staged_file = $file; - $dest_file = $file; - $dest_file =~s/updates_staged\/Quests-Plugins-master\///g; + $destination_file = $file; + $destination_file =~s/updates_staged\/Quests-Plugins-master\///g; - if (!-e $dest_file) { - copy_file($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n"; + if (!-e $destination_file) { + copy_file($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n"; $fc++; } else{ - $diff = do_file_diff($dest_file, $staged_file); - if($diff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file; + $directory_indexff = do_file_diff($destination_file, $staged_file); + if($directory_indexff ne ""){ + $backup_dest = "updates_backups/" . $time_stamp . "/" . $destination_file; - print $diff . "\n"; - print "\nFile Different :: '" . $dest_file . "'\n"; - print "\nDo you wish to update this Quest? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; + 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($dest_file, $backup_dest); + copy_file($destination_file, $backup_dest); #::: Copy staged to running - copy($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n\n"; + copy($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n\n"; } $fc++; } @@ -961,15 +1171,15 @@ sub quest_files_fetch{ rmtree('updates_staged'); if($fc == 0){ - print "\nNo Quest Updates found... \n\n"; + print "[Update] No Quest Updates found... \n\n"; } } -sub lua_modules_fetch{ +sub lua_modules_fetch { if (!-e "updates_staged/Quests-Plugins-master/quests/lua_modules/") { - print "\n --- Fetching Latest LUA Modules --- \n"; + 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 "\nFetched latest LUA Modules...\n"; + print "[Update] Fetched latest LUA Modules...\n"; unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); } @@ -986,29 +1196,29 @@ sub lua_modules_fetch{ for my $file (@files) { if($file=~/\.pl|\.lua|\.ext/i){ $staged_file = $file; - $dest_file = $file; - $dest_file =~s/updates_staged\/Quests-Plugins-master\/quests\///g; + $destination_file = $file; + $destination_file =~s/updates_staged\/Quests-Plugins-master\/quests\///g; - if (!-e $dest_file) { - copy_file($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n"; + if (!-e $destination_file) { + copy_file($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n"; $fc++; } else{ - $diff = do_file_diff($dest_file, $staged_file); - if($diff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file; - print $diff . "\n"; - print "\nFile Different :: '" . $dest_file . "'\n"; - print "\nDo you wish to update this LUA Module? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; + $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($dest_file, $backup_dest); + copy_file($destination_file, $backup_dest); #::: Copy staged to running - copy($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n\n"; + copy($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n\n"; } $fc++; } @@ -1017,15 +1227,15 @@ sub lua_modules_fetch{ } if($fc == 0){ - print "\nNo LUA Modules Updates found... \n\n"; + print "[Update] No LUA Modules Updates found... \n\n"; } } sub plugins_fetch{ if (!-e "updates_staged/Quests-Plugins-master/plugins/") { - print "\n --- Fetching Latest Plugins --- \n"; + 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 "\nFetched latest plugins...\n"; + print "[Update] Fetched latest plugins\n"; unzip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/'); } @@ -1042,29 +1252,29 @@ sub plugins_fetch{ for my $file (@files) { if($file=~/\.pl|\.lua|\.ext/i){ $staged_file = $file; - $dest_file = $file; - $dest_file =~s/updates_staged\/Quests-Plugins-master\///g; + $destination_file = $file; + $destination_file =~s/updates_staged\/Quests-Plugins-master\///g; - if (!-e $dest_file) { - copy_file($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n"; + if (!-e $destination_file) { + copy_file($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n"; $fc++; } else{ - $diff = do_file_diff($dest_file, $staged_file); - if($diff ne ""){ - $backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file; - print $diff . "\n"; - print "\nFile Different :: '" . $dest_file . "'\n"; - print "\nDo you wish to update this Plugin? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n"; + $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($dest_file, $backup_dest); + copy_file($destination_file, $backup_dest); #::: Copy staged to running - copy($staged_file, $dest_file); - print "Installing :: '" . $dest_file . "'\n\n"; + copy($staged_file, $destination_file); + print "[Install] Installing :: '" . $destination_file . "'\n\n"; } $fc++; } @@ -1073,7 +1283,7 @@ sub plugins_fetch{ } if($fc == 0){ - print "\nNo Plugin Updates found... \n\n"; + print "[Update] No Plugin Updates found... \n\n"; } } @@ -1082,8 +1292,8 @@ sub do_file_diff{ $file_2 = $_[1]; if($OS eq "Windows"){ eval "use Text::Diff"; - $diff = diff($file_1, $file_2, { STYLE => "Unified" }); - return $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"; @@ -1091,7 +1301,7 @@ sub do_file_diff{ } } -sub unzip{ +sub unzip { $archive_to_unzip = $_[0]; $dest_folder = $_[1]; @@ -1101,11 +1311,11 @@ sub unzip{ unless ( $zip->read($archive_to_unzip) == AZ_OK ) { die 'read error'; } - print "Extracting...\n"; + print "[Unzip] Extracting...\n"; $zip->extractTree('', $dest_folder); } if($OS eq "Linux"){ - print `unzip -o "$archive_to_unzip" -d "$dest_folder"`; + print `unzip -o -q "$archive_to_unzip" -d "$dest_folder"`; } } @@ -1123,11 +1333,11 @@ sub are_file_sizes_different{ sub do_bots_db_schema_drop{ #"drop_bots.sql" is run before reverting database back to 'normal' - print "Fetching drop_bots.sql...\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/git/bots/drop_bots.sql", "db_update/drop_bots.sql"); + 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 "Restoring normality...\n"; + 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){ @@ -1153,11 +1363,12 @@ sub do_bots_db_schema_drop{ 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 "Modifying database for bots...\n"; + 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){ @@ -1238,7 +1449,7 @@ sub modify_db_for_bots{ sub convert_existing_bot_data{ if(get_mysql_result("SHOW TABLES LIKE 'bots'") ne "" && $db){ - print "Converting existing bot data...\n"; + 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`;"); @@ -1335,7 +1546,7 @@ 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 "\nColumn 'bots_version' does not exists.... Adding to 'db_version' table...\n\n"; + 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; @@ -1351,7 +1562,7 @@ sub bots_db_management{ } if($bin_db_ver == 0){ - print "Your server binaries (world/zone) are not compiled for bots...\n"; + print "[Database] Your server binaries (world/zone) are not compiled for bots...\n\n"; return; } @@ -1397,22 +1608,22 @@ sub run_database_check{ if(!@total_updates){ #::: Pull down bots database manifest if($bots_db_management == 1){ - print "Retrieving latest bots database manifest...\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/git/bots/bots_db_update_manifest.txt", "db_update/db_update_manifest.txt"); + 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 "Retrieving latest database manifest...\n"; - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt"); + 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){ + 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 "Running Update: " . $val . " - " . $file_name . "\n"; + 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"); @@ -1424,7 +1635,7 @@ sub run_database_check{ } #::: Run 1 - Initial checking of needed updates... else{ - print "Reading manifest...\n\n"; + print "[Database] Reading manifest...\n"; use Data::Dumper; open (FILE, "db_update/db_update_manifest.txt"); while () { @@ -1458,23 +1669,23 @@ sub run_database_check{ #::: Match type update if($match_type eq "contains"){ if(trim(get_mysql_result($query_check))=~/$match_text/i){ - print "Missing DB Update " . $i . " '" . $file_name . "' \n"; + print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; fetch_missing_db_update($i, $file_name); push(@total_updates, $i); } else{ - print "DB up to date with: " . $i . " - '" . $file_name . "' \n"; + 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 "DB up to date with: " . $i . " - '" . $file_name . "' \n"; + print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; next; } else{ - print "Missing DB Update " . $i . " '" . $file_name . "' \n"; + print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; fetch_missing_db_update($i, $file_name); push(@total_updates, $i); } @@ -1483,24 +1694,24 @@ sub run_database_check{ } if($match_type eq "empty"){ if(get_mysql_result($query_check) eq ""){ - print "Missing DB Update " . $i . " '" . $file_name . "' \n"; + print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; fetch_missing_db_update($i, $file_name); push(@total_updates, $i); } else{ - print "DB up to date with: " . $i . " - '" . $file_name . "' \n"; + 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 "Missing DB Update " . $i . " '" . $file_name . "' \n"; + print "[Database] missing update: " . $i . " '" . $file_name . "' \n"; fetch_missing_db_update($i, $file_name); push(@total_updates, $i); } else{ - print "DB up to date with: " . $i . " - '" . $file_name . "' \n"; + print "[Database] has update: " . $i . " - '" . $file_name . "' \n"; } print_match_debug(); print_break(); @@ -1509,13 +1720,13 @@ sub run_database_check{ print "\n"; if(scalar (@total_updates) == 0 && $db_run_stage == 2){ - print "No updates need to be run...\n"; + print "[Database] No updates need to be run...\n"; if($bots_db_management == 1){ - print "Setting Database to Bots Binary Version (" . $bin_db_ver . ") if not already...\n\n"; + print "[Database] Setting Database to Bots Binary Version (" . $bin_db_ver . ") if not already...\n\n"; get_mysql_result("UPDATE db_version SET bots_version = $bin_db_ver"); } - else{ - print "Setting Database to Binary Version (" . $bin_db_ver . ") if not already...\n\n"; + else{ + print "[Database] Setting Database to Binary Version (" . $bin_db_ver . ") if not already...\n\n"; get_mysql_result("UPDATE db_version SET version = $bin_db_ver"); } @@ -1528,14 +1739,14 @@ sub fetch_missing_db_update{ $update_file = $_[1]; if($db_update >= 9000){ if($bots_db_management == 1){ - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/git/bots/required/" . $update_file, "db_update/" . $update_file . ""); + get_remote_file($eqemu_repository_request_url . "utils/sql/git/bots/required/" . $update_file, "db_update/" . $update_file . ""); } else{ - get_remote_file("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/git/required/" . $update_file, "db_update/" . $update_file . ""); + 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("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/svn/" . $update_file, "db_update/" . $update_file . ""); + get_remote_file($eqemu_repository_request_url . "utils/sql/svn/" . $update_file, "db_update/" . $update_file . ""); } } @@ -1546,7 +1757,17 @@ sub print_match_debug{ 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 85c28185a2da449c1a2b8f7305082ec398d5f412 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 25 Aug 2016 18:01:17 -0500 Subject: [PATCH 4/6] Update eqemu_server.pl - Add internet connection checks for people who are using EQEmu locally [skip ci] --- utils/scripts/eqemu_server.pl | 58 +++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index 47955266d..e794a3710 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -27,6 +27,7 @@ $db_run_stage = 0; #::: Sets database run stage check $console_output .= " Operating System is: $Config{osname}\n"; if($Config{osname}=~/freebsd|linux/i){ $OS = "Linux"; } if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; } +$has_internet_connection = check_internet_connection(); #::: Check for script self update do_self_update_check_routine(); @@ -86,7 +87,7 @@ mkdir('db_update'); #::: 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 "Old db_version table present, dropping...\n\n"; + print "[Database] Old db_version table present, dropping...\n\n"; } sub check_db_version_table{ @@ -96,7 +97,7 @@ sub check_db_version_table{ version int(11) DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO db_version (version) VALUES ('1000');"); - print "Table 'db_version' does not exists.... Creating...\n\n"; + print "[Database] Table 'db_version' does not exists.... Creating...\n\n"; } } @@ -241,10 +242,37 @@ if($ARGV[0] eq "login_server_setup"){ exit; } +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 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); + 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"; @@ -560,6 +588,12 @@ sub get_remote_file{ 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 @@ -600,7 +634,7 @@ sub get_remote_file{ #::: Make sure the file exists before continuing... if(-e $destination_file) { $break = 1; - print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n"; + print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download; } else { $break = 0; } usleep(500); @@ -613,7 +647,7 @@ sub get_remote_file{ $break = 0; while($break == 0) { require LWP::UserAgent; - my $ua = LWP::UserAgent->new; + my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get($request_url); @@ -627,7 +661,7 @@ sub get_remote_file{ } if(-e $destination_file) { $break = 1; - print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n"; + print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download; } else { $break = 0; } usleep(500); @@ -640,7 +674,7 @@ sub get_remote_file{ 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"; + 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; @@ -853,7 +887,7 @@ sub do_windows_login_server_setup { sub do_linux_login_server_setup { for my $file (@files) { - $destination_file = $file; + $destination_file = $file; $destination_file =~s/updates_staged\/login_server\///g; print "[Install] Installing :: " . $destination_file . "\n"; copy_file($file, $destination_file); @@ -1277,7 +1311,7 @@ sub unzip { unless ( $zip->read($archive_to_unzip) == AZ_OK ) { die 'read error'; } - print "Extracting...\n"; + print "[Unzip] Extracting...\n"; $zip->extractTree('', $dest_folder); } if($OS eq "Linux"){ @@ -1512,7 +1546,7 @@ 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 "\nColumn 'bots_version' does not exists.... Adding to 'db_version' table...\n\n"; + 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; @@ -1528,7 +1562,7 @@ sub bots_db_management{ } if($bin_db_ver == 0){ - print "Your server binaries (world/zone) are not compiled for bots...\n\n"; + print "[Database] Your server binaries (world/zone) are not compiled for bots...\n\n"; return; } @@ -1736,4 +1770,4 @@ sub generate_random_password { map $alphanumeric[rand @alphanumeric], 0..$passwordsize; return $randpassword; -} \ No newline at end of file +} From 385823461b7f77050d5b5f661f9baac6fe887a61 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 25 Aug 2016 18:30:04 -0500 Subject: [PATCH 5/6] Update eqemu_server.pl [skip ci] --- utils/scripts/eqemu_server.pl | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index e794a3710..e91df2914 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -202,6 +202,8 @@ if($ARGV[0] eq "installer"){ 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;"`; @@ -313,7 +315,12 @@ sub do_self_update_check_routine { sub get_installation_variables{ #::: Fetch installation variables before building the config - open (INSTALL_VARS, "../install_variables.txt"); + if($OS eq "Linux"){ + open (INSTALL_VARS, "../install_variables.txt"); + } + if($OS eq "Windows"){ + open (INSTALL_VARS, "install_variables.txt"); + } while (){ chomp; $o = $_; @@ -440,14 +447,14 @@ sub show_menu_prompt { 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 ">>> 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 #> "; + print "Enter a command #> "; $last_menu = trim($input); } elsif($input eq "backup_database"){ database_dump(); $dc = 1; } From 4de9b2c53e56f59941d2cceec2153d14e06ee714 Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Fri, 26 Aug 2016 06:34:51 -0700 Subject: [PATCH 6/6] Add TiltX and TiltY manipulation to objects (Perl) Translate OP_GroundSpawn for Titanium #perl plugin http://wiki.eqemulator.org/i?Module=Pastebin&Paste=u9IbA6Ql --- common/eq_packet_structs.h | 24 ++-- common/patches/rof.cpp | 4 +- common/patches/rof2.cpp | 4 +- common/patches/titanium.cpp | 40 +++++++ common/patches/titanium_ops.h | 1 + common/patches/uf.cpp | 4 +- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../required/2016_08_26_object_size_tilt.sql | 4 + zone/object.cpp | 51 +++++++- zone/object.h | 8 +- zone/perl_object.cpp | 110 +++++++++++++++++- zone/zone.cpp | 8 +- 13 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 utils/sql/git/required/2016_08_26_object_size_tilt.sql diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index a1b614b97..cf411ef72 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -2509,23 +2509,25 @@ struct BookRequest_Struct { */ struct Object_Struct { /*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list -/*08*/ uint16 size; // +/*08*/ float size; // /*10*/ uint16 solidtype; // /*12*/ uint32 drop_id; // Unique object id for zone /*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in /*18*/ uint16 zone_instance; // /*20*/ uint32 unknown020; // /*24*/ uint32 unknown024; // -/*28*/ float heading; // heading -/*32*/ float z; // z coord -/*36*/ float x; // x coord -/*40*/ float y; // y coord -/*44*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF -/*76*/ uint32 unknown076; // -/*80*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject -/*84*/ uint32 unknown084; //set to 0xFF -/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object -/*92*/ +/*28*/ float tilt_x; +/*32*/ float tilt_y; +/*36*/ float heading; // heading +/*40*/ float z; // z coord +/*44*/ float x; // x coord +/*76*/ float y; // y coord +/*80*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF +/*84*/ uint32 unknown076; // +/*88*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject +/*92*/ uint32 unknown084; //set to 0xFF + uint32 spawn_id; // Spawn Id of client interacting with object + }; // 01 = generic drop, 02 = armor, 19 = weapon //[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 7c5f302cb..8ab38905f 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -987,8 +987,8 @@ namespace RoF VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 5bb93f14a..aedd7b592 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1062,8 +1062,8 @@ namespace RoF2 VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index cc10f6487..9e93051b1 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -595,6 +595,46 @@ namespace Titanium dest->FastQueuePacket(&in, ack_req); } + ENCODE(OP_GroundSpawn) + { + // We are not encoding the spawn_id field here, but it doesn't appear to matter. + // + EQApplicationPacket *in = *p; + *p = nullptr; + + //store away the emu struct + unsigned char *__emu_buffer = in->pBuffer; + Object_Struct *emu = (Object_Struct *)__emu_buffer; + + in->size = strlen(emu->object_name) + sizeof(structs::Object_Struct) - 1; + in->pBuffer = new unsigned char[in->size]; + + structs::Object_Struct *eq = (structs::Object_Struct *) in->pBuffer; + + eq->drop_id = emu->drop_id; + eq->heading = emu->heading; + eq->linked_list_addr[0] = 0; + eq->linked_list_addr[1] = 0; + strcpy(eq->object_name, emu->object_name); + eq->object_type = emu->object_type; + eq->spawn_id = 0; + eq->unknown008[0] = 0; + eq->unknown008[1] = 0; + eq->unknown020 = 0; + eq->unknown024 = 0; + eq->unknown076 = 0; + eq->unknown084 = 0xffffffff; + eq->z = emu->z; + eq->x = emu->x; + eq->y = emu->y; + eq->zone_id = emu->zone_id; + eq->zone_instance = emu->zone_instance; + + + delete[] __emu_buffer; + dest->FastQueuePacket(&in, ack_req); + } + ENCODE(OP_GuildMemberList) { //consume the packet diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index 9ca0ba770..5e65dd7c0 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -40,6 +40,7 @@ E(OP_DzLeaderStatus) E(OP_DzMemberList) E(OP_Emote) E(OP_FormattedMessage) +E(OP_GroundSpawn) E(OP_GuildMemberLevelUpdate) E(OP_GuildMemberList) E(OP_Illusion) diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index af81fea06..ba5bf7622 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -875,8 +875,8 @@ namespace UF // This next field is actually a float. There is a groundspawn in freeportwest (sack of money sitting on some barrels) which requires this // field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same // issue. - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); //X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); //Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/version.h b/common/version.h index 38731b3ba..f06a68c05 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9097 +#define CURRENT_BINARY_DATABASE_VERSION 9098 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 283500c3b..4030395c3 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -351,6 +351,7 @@ 9095|2016_01_08_command_find_aliases.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| 9096|2016_03_05_secondary_recall.sql|SHOW COLUMNS FROM `character_bind` LIKE 'slot'|empty| 9097|2016_07_03_npc_class_as_last_name.sql|SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'NPC:UseClassAsLastName'|empty| +9098|2016_08_26_object_size_tilt.sql|SHOW COLUMNS FROM `object` LIKE 'size'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2016_08_26_object_size_tilt.sql b/utils/sql/git/required/2016_08_26_object_size_tilt.sql new file mode 100644 index 000000000..ded4d841d --- /dev/null +++ b/utils/sql/git/required/2016_08_26_object_size_tilt.sql @@ -0,0 +1,4 @@ +ALTER TABLE `object` + ADD COLUMN `size` FLOAT NOT NULL DEFAULT '100' AFTER `unknown84`, + ADD COLUMN `tilt_x` FLOAT NOT NULL DEFAULT '0' AFTER `size`, + ADD COLUMN `tilt_y` FLOAT NOT NULL DEFAULT '0' AFTER `tilt_x`; \ No newline at end of file diff --git a/zone/object.cpp b/zone/object.cpp index f74d2dd0d..a9672ee4f 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -63,6 +63,9 @@ Object::Object(uint32 id, uint32 type, uint32 icon, const Object_Struct& object, // Set drop_id to zero - it will be set when added to zone with SetID() m_data.drop_id = 0; + m_data.size = object.size; + m_data.tilt_x = object.tilt_x; + m_data.tilt_y = object.tilt_y; } //creating a re-ocurring ground spawn. @@ -653,10 +656,12 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec // Save new record for object std::string query = StringFormat("UPDATE object SET " "zoneid = %i, xpos = %f, ypos = %f, zpos = %f, heading = %f, " - "itemid = %i, charges = %i, objectname = '%s', type = %i, icon = %i " + "itemid = %i, charges = %i, objectname = '%s', type = %i, icon = %i, " + "size = %f, tilt_x = %f, tilt_y = %f " "WHERE id = %i", object.zone_id, object.x, object.y, object.z, object.heading, - item_id, charges, object_name, type, icon, id); + item_id, charges, object_name, type, icon, + object.size, object.tilt_x, object.tilt_y, id); safe_delete_array(object_name); auto results = QueryDatabase(query); if (!results.Success()) { @@ -750,6 +755,16 @@ float Object::GetHeadingData() return this->m_data.heading; } +float Object::GetTiltX() +{ + return this->m_data.tilt_x; +} + +float Object::GetTiltY() +{ + return this->m_data.tilt_y; +} + void Object::SetX(float pos) { this->m_data.x = pos; @@ -778,6 +793,34 @@ void Object::SetY(float pos) safe_delete(app2); } +void Object::SetTiltX(float pos) +{ + this->m_data.tilt_x = pos; + + auto app = new EQApplicationPacket(); + auto app2 = new EQApplicationPacket(); + this->CreateDeSpawnPacket(app); + this->CreateSpawnPacket(app2); + entity_list.QueueClients(0, app); + entity_list.QueueClients(0, app2); + safe_delete(app); + safe_delete(app2); +} + +void Object::SetTiltY(float pos) +{ + this->m_data.tilt_y = pos; + + auto app = new EQApplicationPacket(); + auto app2 = new EQApplicationPacket(); + this->CreateDeSpawnPacket(app); + this->CreateSpawnPacket(app2); + entity_list.QueueClients(0, app); + entity_list.QueueClients(0, app2); + safe_delete(app); + safe_delete(app2); +} + void Object::Depop() { auto app = new EQApplicationPacket(); @@ -828,7 +871,7 @@ void Object::SetModelName(const char* modelname) safe_delete(app2); } -void Object::SetSize(uint16 size) +void Object::SetSize(float size) { m_data.size = size; auto app = new EQApplicationPacket(); @@ -854,7 +897,7 @@ void Object::SetSolidType(uint16 solidtype) safe_delete(app2); } -uint16 Object::GetSize() +float Object::GetSize() { return m_data.size; } diff --git a/zone/object.h b/zone/object.h index c7ebdd677..896fc4276 100644 --- a/zone/object.h +++ b/zone/object.h @@ -154,10 +154,14 @@ public: void SetX(float pos); void SetY(float pos); void SetZ(float pos); + void SetTiltX(float pos); + void SetTiltY(float pos); + float GetTiltX(); + float GetTiltY(); void SetModelName(const char* modelname); const char* GetModelName(); - uint16 GetSize(); - void SetSize(uint16 size); + float GetSize(); + void SetSize(float size); uint16 GetSolidType(); void SetSolidType(uint16 size); diff --git a/zone/perl_object.cpp b/zone/perl_object.cpp index be52fef1d..f8fc9a4ee 100644 --- a/zone/perl_object.cpp +++ b/zone/perl_object.cpp @@ -968,7 +968,7 @@ XS(XS_Object_GetSize) Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); { Object * THIS; - uint16 RETVAL; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { @@ -981,7 +981,7 @@ XS(XS_Object_GetSize) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSize(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); } @@ -995,7 +995,7 @@ XS(XS_Object_SetSize) Perl_croak(aTHX_ "Usage: Object::SetSize(THIS, type)"); { Object * THIS; - uint16 size = (uint16)SvUV(ST(1)); + float size = (float)SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -1011,6 +1011,106 @@ XS(XS_Object_SetSize) XSRETURN_EMPTY; } +XS(XS_Object_SetTiltX); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_SetTiltX) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Object::SetTiltX(THIS, pos)"); + { + Object * THIS; + float pos = (float)SvNV(ST(1)); + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->SetTiltX(pos); + } + XSRETURN_EMPTY; +} + +XS(XS_Object_SetTiltY); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_SetTiltY) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Object::SetTiltY(THIS, pos)"); + { + Object * THIS; + float pos = (float)SvNV(ST(1)); + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->SetTiltY(pos); + } + XSRETURN_EMPTY; +} + +XS(XS_Object_GetTiltX); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_GetTiltX) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); + { + Object * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTiltX(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + +XS(XS_Object_GetTiltY); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_GetTiltY) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); + { + Object * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTiltY(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -1066,6 +1166,10 @@ XS(boot_Object) newXSproto(strcpy(buf, "GetSolidType"),XS_Object_GetSolidType, file, "$"); newXSproto(strcpy(buf, "SetSize"),XS_Object_SetSize, file, "$$"); newXSproto(strcpy(buf, "GetSize"),XS_Object_GetSize, file, "$"); + newXSproto(strcpy(buf, "SetTiltX"),XS_Object_SetTiltX, file, "$$"); + newXSproto(strcpy(buf, "SetTiltY"),XS_Object_SetTiltY, file, "$"); + newXSproto(strcpy(buf, "GetTiltX"),XS_Object_GetTiltX, file, "$$"); + newXSproto(strcpy(buf, "GetTiltY"),XS_Object_GetTiltY, file, "$"); XSRETURN_YES; } #endif //EMBPERL_XS_CLASSES diff --git a/zone/zone.cpp b/zone/zone.cpp index 1165d7e9b..3dd8e55d8 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -161,7 +161,8 @@ bool Zone::LoadZoneObjects() { std::string query = StringFormat("SELECT id, zoneid, xpos, ypos, zpos, heading, " "itemid, charges, objectname, type, icon, unknown08, " - "unknown10, unknown20, unknown24, unknown76 fROM object " + "unknown10, unknown20, unknown24, unknown76, size, tilt_x, " + "tilt_y FROM object " "WHERE zoneid = %i AND (version = %u OR version = -1)", zoneid, instanceversion); auto results = database.QueryDatabase(query); @@ -241,11 +242,14 @@ bool Zone::LoadZoneObjects() { data.object_type = type; data.linked_list_addr[0] = 0; data.linked_list_addr[1] = 0; - data.size = (uint32)atoi(row[11]); + data.solidtype = (uint32)atoi(row[12]); data.unknown020 = (uint32)atoi(row[13]); data.unknown024 = (uint32)atoi(row[14]); data.unknown076 = (uint32)atoi(row[15]); + data.size = atof(row[16]); + data.tilt_x = atof(row[17]); + data.tilt_y = atof(row[18]); data.unknown084 = 0; ItemInst* inst = nullptr;