diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/HPMHookGen/HPMDataCheckGen.pl | 12 | ||||
-rwxr-xr-x | tools/HPMHookGen/HPMHookGen.pl | 281 | ||||
-rwxr-xr-x | tools/ci/retry.sh | 33 | ||||
-rwxr-xr-x | tools/ci/travis.sh | 202 | ||||
-rwxr-xr-x | tools/configconverter.pl | 968 | ||||
-rw-r--r-- | tools/doxygen/Hercules128.png | bin | 0 -> 19237 bytes | |||
-rw-r--r-- | tools/doxygen/Hercules48.png | bin | 0 -> 4954 bytes | |||
-rw-r--r-- | tools/doxygen/Makefile.in | 70 | ||||
-rw-r--r-- | tools/doxygen/doxygen.conf | 505 | ||||
-rw-r--r-- | tools/doxygen/footer.html | 21 | ||||
-rw-r--r-- | tools/doxygen/header.html | 55 | ||||
-rw-r--r-- | tools/doxygen/layoutFile.xml | 194 | ||||
-rw-r--r-- | tools/doxygen/pages_index.html | 39 | ||||
-rw-r--r-- | tools/doxygen/style.css | 1440 | ||||
-rw-r--r-- | tools/item_merge.lua | 2 | ||||
-rw-r--r-- | tools/itemdb_jobmask_converter.pl | 100 | ||||
-rw-r--r-- | tools/skilldbconverter.php | 1201 |
17 files changed, 4958 insertions, 165 deletions
diff --git a/tools/HPMHookGen/HPMDataCheckGen.pl b/tools/HPMHookGen/HPMDataCheckGen.pl index 3965668d9..e78a7bd93 100644 --- a/tools/HPMHookGen/HPMDataCheckGen.pl +++ b/tools/HPMHookGen/HPMDataCheckGen.pl @@ -3,7 +3,7 @@ # This file is part of Hercules. # http://herc.ws - http://github.com/HerculesWS/Hercules # -# Copyright (C) 2014-2015 Hercules Dev Team +# Copyright (C) 2014-2016 Hercules Dev Team # # Hercules is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -42,11 +42,13 @@ foreach my $file (@files) { my @filepath = split(/[\/\\]/, $data->{compounddef}->{$filekey}->{location}->[0]->{file}); my $foldername = uc($filepath[-2]); next if $filepath[-1] eq "HPM.h"; # Skip the HPM core, plugins don't need it - my $filename = uc($filepath[-1]); $filename =~ s/-/_/g; $filename =~ s/\.[^.]*$//; + my $filename = uc($filepath[-1]); $filename =~ s/[.-]/_/g; $filename =~ s/\.[^.]*$//; my $plugintypes = 'SERVER_TYPE_UNKNOWN'; if ($foldername eq 'COMMON') { - if ($filename eq 'MAPINDEX') { + if ($filename eq 'MAPINDEX_H') { $plugintypes = 'SERVER_TYPE_CHAR|SERVER_TYPE_MAP'; + } elsif ($filename eq 'GRFIO_H') { + $plugintypes = 'SERVER_TYPE_MAP'; } else { $plugintypes = 'SERVER_TYPE_ALL'; } @@ -57,7 +59,7 @@ foreach my $file (@files) { name => $data->{compounddef}->{$filekey}->{compoundname}->[0], type => $plugintypes, }; - my $name = "${foldername}_${filename}_H"; + my $name = "${foldername}_${filename}"; push @{ $out{$name} }, $symboldata; } @@ -91,6 +93,8 @@ print FH <<"EOF"; * as it will get overwritten. */ +/* GENERATED FILE DO NOT EDIT */ + #ifndef HPM_DATA_CHECK_H #define HPM_DATA_CHECK_H diff --git a/tools/HPMHookGen/HPMHookGen.pl b/tools/HPMHookGen/HPMHookGen.pl index 6f7f9e0a4..35c531ea8 100755 --- a/tools/HPMHookGen/HPMHookGen.pl +++ b/tools/HPMHookGen/HPMHookGen.pl @@ -3,7 +3,7 @@ # This file is part of Hercules. # http://herc.ws - http://github.com/HerculesWS/Hercules # -# Copyright (C) 2013-2015 Hercules Dev Team +# Copyright (C) 2013-2017 Hercules Dev Team # # Hercules is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ sub parse($$) { $p =~ s/^.*?\)\((.*)\).*$/$1/; # Clean up extra parentheses )(around the arglist) # Retrieve return type - unless ($d =~ /^(.+)\(\*\s*[a-zA-Z0-9_]+_interface::([^\)]+)\s*\)\s*\(.*\)$/) { + unless ($d =~ /^(.+)\(\*\s*[a-zA-Z0-9_]+_interface(?:_private)?::([^\)]+)\s*\)\s*\(.*\)$/) { print "Error: unable to parse '$d'\n"; return {}; } @@ -148,7 +148,7 @@ sub parse($$) { $type1 .= "$1 "; next; } - if ($current =~ /^(struct|enum)\s+(.*)$/) { # enum and struct names + if ($current =~ /^(struct|enum|union)\s+(.*)$/) { # union, enum and struct names $current = $2 // ''; $type1 .= "$1 "; } @@ -187,28 +187,29 @@ sub parse($$) { $post_code = "va_end(${callvar});"; $var = ''; $variadic = 1; - } elsif (!$indirectionlvl) { # Increase indirection level when necessary + } else { # Increase indirection level when necessary $dereference = '*'; $addressof = '&'; } $indirectionlvl++ if ($array); # Arrays are pointer, no matter how cute you write them push(@args, { - var => $var, - callvar => $callvar, - type => $type1.$array.$type2, - orig => $type1 eq '...' ? '...' : trim("$type1 $indir$var$array $type2"), - indir => $indirectionlvl, - hookf => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $dereference$indir$var$array $type2"), - hookc => trim("$addressof$callvar"), - origc => trim($callvar), - pre => $pre_code, - post => $post_code, + var => $var, + callvar => $callvar, + type => $type1.$array.$type2, + orig => $type1 eq '...' ? '...' : trim("$type1 $indir$var$array $type2"), + indir => $indirectionlvl, + hookpref => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $dereference$indir$var$array $type2"), + hookpostf => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $indir$var$array $type2"), + hookprec => trim("$addressof$callvar"), + hookpostc => trim("$callvar"), + origc => trim($callvar), + pre => $pre_code, + post => $post_code, }); $lastvar = $var; } - my $rtmemset = 0; my $rtinit = ''; foreach ($rt) { # Decide initialization for the return value my $x = $_; @@ -237,13 +238,16 @@ sub parse($$) { $rtinit = ' = HCS_STATUS_FAIL'; } elsif ($x =~ /^enum\s+bg_queue_types$/) { # Known enum bg_queue_types $rtinit = ' = BGQT_INVALID'; - } elsif ($x =~ /^(?:enum\s+)?DBOptions$/) { # Known enum DBOptions + } elsif ($x =~ /^enum\s+parsefunc_rcode$/) { # Known enum parsefunc_rcode + $rtinit = ' = PACKET_UNKNOWN'; + } elsif ($x =~ /^enum\s+DBOptions$/) { # Known enum DBOptions $rtinit = ' = DB_OPT_BASE'; + } elsif ($x =~ /^enum\s+thread_priority$/) { # Known enum thread_priority + $rtinit = ' = THREADPRIO_NORMAL'; } elsif ($x eq 'DBComparator' or $x eq 'DBHasher' or $x eq 'DBReleaser') { # DB function pointers $rtinit = ' = NULL'; - } elsif ($x =~ /^struct\s+.*$/ or $x eq 'DBData' or $x eq 'DBKey') { # Structs and unions - $rtinit = ''; - $rtmemset = 1; + } elsif ($x =~ /^(?:struct|union)\s+.*$/) { # Structs and unions + $rtinit = ' = { 0 }'; } elsif ($x =~ /^float|double$/) { # Floating point variables $rtinit = ' = 0.'; } elsif ($x =~ /^(?:(?:un)?signed\s+)?(?:char|int|long|short)$/ @@ -265,7 +269,6 @@ sub parse($$) { vname => $variadic ? "v$name" : $name, type => $rt, typeinit => $rtinit, - memset => $rtmemset, variadic => $variadic, args => \@args, notes => $notes, @@ -273,6 +276,7 @@ sub parse($$) { } my %key2original; +my %key2pointer; my @files = grep { -f } glob 'doxyoutput/xml/*interface*.xml'; my %ifs; my %keys = ( @@ -291,6 +295,7 @@ foreach my $file (@files) { # Loop through the xml files my $loc = $data->{compounddef}->{$filekey}->{location}->[0]; next unless $loc->{file} =~ /src\/(map|char|login|common)\//; next if $loc->{file} =~ /\/HPM.*\.h/; # Don't allow hooking into the HPM itself + next if $loc->{file} =~ /\/memmgr\.h/; # Don't allow hooking into the memory manager my $servertype = $1; my $key = $data->{compounddef}->{$filekey}->{compoundname}->[0]; my $original = $key; @@ -302,14 +307,18 @@ foreach my $file (@files) { # Loop through the xml files } elsif ($key eq "mapindex_interface") { push @servertypes, ("map", "char"); # Currently not used by the login server $servermask = 'SERVER_TYPE_MAP|SERVER_TYPE_CHAR'; + } elsif ($key eq "grfio_interface") { + push @servertypes, ("map"); # Currently not used by the login and char servers + $servermask = 'SERVER_TYPE_MAP'; } else { push @servertypes, ("map", "char", "login"); $servermask = 'SERVER_TYPE_ALL'; } my @filepath = split(/[\/\\]/, $loc->{file}); my $foldername = uc($filepath[-2]); - my $filename = uc($filepath[-1]); $filename =~ s/-/_/g; $filename =~ s/\.[^.]*$//; - my $guardname = "${foldername}_${filename}_H"; + my $filename = uc($filepath[-1]); $filename =~ s/[.-]/_/g; $filename =~ s/\.[^.]*$//; + my $guardname = "${foldername}_${filename}"; + my $private = $key =~ /_interface_private$/ ? 1 : 0; # Some known interfaces with different names if ($key =~ /battleground/) { @@ -330,8 +339,6 @@ foreach my $file (@files) { # Loop through the xml files $key = "chr"; } elsif ($key eq "db_interface") { $key = "DB"; - } elsif ($key eq "malloc_interface") { - $key = "iMalloc"; } elsif ($key eq "socket_interface") { $key = "sockt"; } elsif ($key eq "sql_interface") { @@ -344,6 +351,9 @@ foreach my $file (@files) { # Loop through the xml files } else { $key =~ s/_interface//; } + $key =~ s/^(.*)_private$/PRIV__$1/ if $private; + my $pointername = $key; + $pointername =~ s/^PRIV__(.*)$/$1->p/ if $private; my $sectiondef = $data->{compounddef}->{$filekey}->{sectiondef}; foreach my $v (@$sectiondef) { # Loop through the sections @@ -353,10 +363,16 @@ foreach my $file (@files) { # Loop through the xml files my $bstart = $b->{location}->[0]->{bodystart} || $b->{location}->[0]->{line}; $astart <=> $bstart } @$memberdef) { # Loop through the members + next unless $f->{kind} eq 'variable'; # Skip macros my $t = $f->{argsstring}->[0]; + my $def = $f->{definition}->[0]; + if ($f->{type}->[0] =~ /^\s*LoginParseFunc\s*\*\s*$/) { + $t = ')(int fd, struct login_session_data *sd)'; # typedef LoginParseFunc + $def =~ s/^LoginParseFunc\s*\*\s*(.*)$/enum parsefunc_rcode(* $1) (int fd, struct login_session_data *sd)/; + } next unless ref $t ne 'HASH' and $t =~ /^[^\[]/; # If it's not a string, or if it starts with an array subscript, we can skip it - my $if = parse($t, $f->{definition}->[0]); + my $if = parse($t, $def); next unless scalar keys %$if; # If it returns an empty hash reference, an error must've occurred # Skip variadic functions, we only allow hooks on their arglist equivalents. @@ -407,10 +423,10 @@ foreach my $file (@files) { # Loop through the xml files $if->{postcall} .= ', '; } $if->{handlerdef} .= $arg->{orig}; - $if->{predef} .= $arg->{hookf}; - $if->{precall} .= $arg->{hookc}; - $if->{postdef} .= $arg->{hookf}; - $if->{postcall} .= $arg->{hookc}; + $if->{predef} .= $arg->{hookpref}; + $if->{precall} .= $arg->{hookprec}; + $if->{postdef} .= $arg->{hookpostf}; + $if->{postcall} .= $arg->{hookpostc}; $if->{origcall} .= $arg->{origc}; $i++; $j++; } @@ -431,6 +447,7 @@ foreach my $file (@files) { # Loop through the xml files $if->{origcall} .= ");"; $key2original{$key} = $original; + $key2pointer{$key} = $pointername; $ifs{$key} = [] unless $ifs{$key}; push(@{ $ifs{$key} }, $if); } @@ -442,35 +459,18 @@ foreach my $file (@files) { # Loop through the xml files $fileguards{$key} = { guard => $guardname, type => $servermask, + private => $private, }; } my $year = (localtime)[5] + 1900; -foreach my $servertype (keys %keys) { - my $keysref = $keys{$servertype}; - # Some interfaces use different names - my %exportsymbols = map { - $_ => &{ sub ($) { - return 'battlegrounds' if $_ =~ /^bg$/; - return 'pc_groups' if $_ =~ /^pcg$/; - return $_; - }}($_); - } @$keysref; - - my ($maxlen, $idx) = (0, 0); - my $fname; - - if ($servertype eq 'all') { - $fname = "../../src/common/HPMSymbols.inc.h"; - open(FH, ">", $fname) - or die "cannot open > $fname: $!"; - print FH <<"EOF"; +my $fileheader = <<"EOF"; /** * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2015-$year Hercules Dev Team + * Copyright (C) 2013-$year Hercules Dev Team * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -491,10 +491,35 @@ foreach my $servertype (keys %keys) { * as it will get overwritten. */ +/* GENERATED FILE DO NOT EDIT */ +EOF + +foreach my $servertype (keys %keys) { + my $keysref = $keys{$servertype}; + # Some interfaces use different names + my %exportsymbols = map { + $_ => &{ sub ($) { + return 'battlegrounds' if $_ =~ /^bg$/; + return 'pc_groups' if $_ =~ /^pcg$/; + return $_; + }}($_); + } @$keysref; + + my ($maxlen, $idx) = (0, 0); + my $fname; + + if ($servertype eq 'all') { + $fname = "../../src/common/HPMSymbols.inc.h"; + open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + + print FH <<"EOF"; +$fileheader #if !defined(HERCULES_CORE) EOF foreach my $key (@$keysref) { + next if $fileguards{$key}->{private}; print FH <<"EOF"; #ifdef $fileguards{$key}->{guard} /* $key */ struct $key2original{$key} *$key; @@ -510,9 +535,11 @@ HPExport const char *HPM_shared_symbols(int server_type) EOF foreach my $key (@$keysref) { + next if $fileguards{$key}->{private}; print FH <<"EOF"; #ifdef $fileguards{$key}->{guard} /* $key */ -if ((server_type&($fileguards{$key}->{type})) && !HPM_SYMBOL("$exportsymbols{$key}", $key)) return "$exportsymbols{$key}"; + if ((server_type&($fileguards{$key}->{type})) != 0 && !HPM_SYMBOL("$exportsymbols{$key}", $key)) + return "$exportsymbols{$key}"; #endif // $fileguards{$key}->{guard} EOF } @@ -522,6 +549,36 @@ EOF } EOF close FH; + + $fname = "../../src/plugins/HPMHooking/HPMHooking.Defs.inc"; + open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + + print FH <<"EOF"; +$fileheader +EOF + + foreach my $key (@$keysref) { + print FH <<"EOF"; +#ifdef $fileguards{$key}->{guard} /* $key */ +EOF + + foreach my $if (@{ $ifs{$key} }) { + my ($predef, $postdef) = ($if->{predef}, $if->{postdef}); + $predef =~ s/preHookFunc/HPMHOOK_pre_${key}_$if->{name}/; + $postdef =~ s/postHookFunc/HPMHOOK_post_${key}_$if->{name}/; + + print FH <<"EOF"; +typedef $predef +typedef $postdef +EOF + } + print FH <<"EOF"; +#endif // $fileguards{$key}->{guard} +EOF + } + close FH; + next; } @@ -530,43 +587,20 @@ EOF or die "cannot open > $fname: $!"; print FH <<"EOF"; -/** - * This file is part of Hercules. - * - * Copyright (C) 2013-$year Hercules Dev Team - * - * Hercules is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * NOTE: This file was auto-generated and should never be manually edited, - * as it will get overwritten. - */ - +$fileheader struct HookingPointData HookingPoints[] = { EOF foreach my $key (@$keysref) { - print FH "/* ".$key." */\n"; + print FH "/* $key2original{$key} */\n"; foreach my $if (@{ $ifs{$key} }) { print FH <<"EOF"; - { HP_POP($key\->$if->{name}, $if->{hname}) }, + { HP_POP($key2pointer{$key}\->$if->{name}, $if->{hname}) }, EOF $idx += 2; - $maxlen = length($key."->".$if->{name}) if( length($key."->".$if->{name}) > $maxlen ); + $maxlen = length($key."->".$if->{name}) if (length($key."->".$if->{name}) > $maxlen); } } print FH <<"EOF"; @@ -581,36 +615,12 @@ EOF or die "cannot open > $fname: $!"; print FH <<"EOF"; -/** - * This file is part of Hercules. - * http://herc.ws - http://github.com/HerculesWS/Hercules - * - * Copyright (C) 2013-$year Hercules Dev Team - * - * Hercules is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * NOTE: This file was auto-generated and should never be manually edited, - * as it will get overwritten. - */ - +$fileheader EOF foreach my $key (@$keysref) { print FH <<"EOF"; -memcpy(&HPMHooks.source.$key, $key, sizeof(struct $key2original{$key})); +HPMHooks.source.$key = *$key2pointer{$key}; EOF } close FH; @@ -620,31 +630,7 @@ EOF or die "cannot open > $fname: $!"; print FH <<"EOF"; -/** - * This file is part of Hercules. - * http://herc.ws - http://github.com/HerculesWS/Hercules - * - * Copyright (C) 2013-$year Hercules Dev Team - * - * Hercules is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * NOTE: This file was auto-generated and should never be manually edited, - * as it will get overwritten. - */ - +$fileheader struct { EOF @@ -695,36 +681,12 @@ EOF or die "cannot open > $fname: $!"; print FH <<"EOF"; -/** - * This file is part of Hercules. - * http://herc.ws - http://github.com/HerculesWS/Hercules - * - * Copyright (C) 2013-$year Hercules Dev Team - * - * Hercules is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * NOTE: This file was auto-generated and should never be manually edited, - * as it will get overwritten. - */ - +$fileheader EOF foreach my $key (@$keysref) { print FH <<"EOF"; -/* $key */ +/* $key2original{$key} */ EOF foreach my $if (@{ $ifs{$key} }) { @@ -732,7 +694,6 @@ EOF unless ($if->{type} eq 'void') { $initialization = "\n\t$if->{type} retVal___$if->{typeinit};"; - $initialization .= "\n\tmemset(&retVal___, '\\0', sizeof($if->{type}));" if $if->{memset}; } $beforeblock3 .= "\n\t\t\t$_" foreach (@{ $if->{before} }); @@ -744,14 +705,14 @@ EOF print FH <<"EOF"; $if->{handlerdef} {$if->{notes} int hIndex = 0;${initialization} - if( HPMHooks.count.$if->{hname}_pre ) { + if (HPMHooks.count.$if->{hname}_pre > 0) { $if->{predef} *HPMforce_return = false; - for(hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_pre; hIndex++ ) {$beforeblock3 + for (hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_pre; hIndex++) {$beforeblock3 preHookFunc = HPMHooks.list.$if->{hname}_pre[hIndex].func; $if->{precall}$afterblock3 } - if( *HPMforce_return ) { + if (*HPMforce_return) { *HPMforce_return = false; return$retval; } @@ -759,9 +720,9 @@ $if->{handlerdef} {$if->{notes} {$beforeblock2 $if->{origcall}$afterblock2 } - if( HPMHooks.count.$if->{hname}_post ) { + if (HPMHooks.count.$if->{hname}_post > 0) { $if->{postdef} - for(hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_post; hIndex++ ) {$beforeblock3 + for (hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_post; hIndex++) {$beforeblock3 postHookFunc = HPMHooks.list.$if->{hname}_post[hIndex].func; $if->{postcall}$afterblock3 } diff --git a/tools/ci/retry.sh b/tools/ci/retry.sh new file mode 100755 index 000000000..6e79af1d5 --- /dev/null +++ b/tools/ci/retry.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2016 Hercules Dev Team +# Copyright (C) 2016 Haru <haru@herc.ws> +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +n=0 + +while true; do + $@ && break + if [[ $n -ge 5 ]]; then + exit -1 + fi + WAITTIME=$((2**n)) + echo "Execution of $@ failed. Retrying in $WAITTIME seconds..." + sleep $WAITTIME + n=$((n+1)) +done diff --git a/tools/ci/travis.sh b/tools/ci/travis.sh new file mode 100755 index 000000000..9a6322df6 --- /dev/null +++ b/tools/ci/travis.sh @@ -0,0 +1,202 @@ +#!/bin/bash + +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2014-2015 Hercules Dev Team +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Base Author: Haru @ http://herc.ws + +MODE="$1" +shift + +function foo { + for i in "$@"; do + echo "> $i" + done +} + +function usage { + echo "usage:" + echo " $0 createdb <dbname> [dbuser] [dbpassword] [dbhost]" + echo " $0 importdb <dbname> [dbuser] [dbpassword] [dbhost]" + echo " $0 build [configure args]" + echo " $0 test <dbname> [dbuser] [dbpassword] [dbhost]" + echo " $0 getplugins" + exit 1 +} + +function aborterror { + echo $@ + exit 1 +} + +function run_server { + echo "Running: $1 --run-once $2" + $1 --run-once $2 2>runlog.txt + export errcode=$? + export teststr=$(cat runlog.txt) + if [[ -n "${teststr}" ]]; then + echo "Errors found in running server $1." + cat runlog.txt + aborterror "Errors found in running server $1." + else + echo "No errors found for server $1." + fi + if [ ${errcode} -ne 0 ]; then + echo "server $1 terminated with exit code ${errcode}" + aborterror "Test failed" + fi +} + +function run_test { + echo "Running: test_$1" + ./test_$1 2>runlog.txt + export errcode=$? + export teststr=$(cat runlog.txt) + if [[ -n "${teststr}" ]]; then + echo "Errors found in running test $1." + cat runlog.txt + aborterror "Errors found in running test $1." + else + echo "No errors found for test $1." + fi + if [ ${errcode} -ne 0 ]; then + echo "test $1 terminated with exit code ${errcode}" + aborterror "Test failed" + fi +} + +# Defaults +DBNAME=ragnarok +DBUSER=ragnarok +DBPASS=ragnarok +DBHOST=localhost + +case "$MODE" in + createdb|importdb|test) + if [ -z "$1" ]; then + usage + fi + DBNAME="$1" + if [ -n "$2" ]; then + DBUSER_ARG="-u $2" + DBUSER="$2" + fi + if [ -n "$3" ]; then + DBPASS_ARG="-p$3" + DBPASS="$3" + fi + if [ -n "$4" ]; then + DBHOST_ARG="-h $4" + DBHOST="$4" + fi + ;; +esac + +case "$MODE" in + createdb) + echo "Creating database $DBNAME..." + mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG -e "create database $DBNAME;" || aborterror "Unable to create database." + ;; + importdb) + echo "Importing tables into $DBNAME..." + mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG $DBNAME < sql-files/main.sql || aborterror "Unable to import main database." + mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG $DBNAME < sql-files/logs.sql || aborterror "Unable to import logs database." + ;; + build) + (cd tools && ./validateinterfaces.py silent) || aborterror "Interface validation error." + ./configure $@ || (cat config.log && aborterror "Configure error, aborting build.") + make -j3 || aborterror "Build failed." + make plugins -j3 || aborterror "Build failed." + make plugin.script_mapquit -j3 || aborterror "Build failed." + make test || aborterror "Build failed." + ;; + test) + cat > conf/travis_sql_connection.conf << EOF +sql_connection: { + //default_codepage: "" + //case_sensitive: false + db_hostname: "$DBHOST" + db_username: "$DBUSER" + db_password: "$DBPASS" + db_database: "$DBNAME" + //codepage:"" +} +EOF + [ $? -eq 0 ] || aborterror "Unable to write database configuration, aborting tests." + cat > conf/import/login-server.conf << EOF +login_configuration: { + account: { + @include "conf/travis_sql_connection.conf" + ipban: { + @include "conf/travis_sql_connection.conf" + } + } +} +EOF + [ $? -eq 0 ] || aborterror "Unable to override login-server configuration, aborting tests." + cat > conf/import/char-server.conf << EOF +char_configuration: { + @include "conf/travis_sql_connection.conf" +} +EOF + [ $? -eq 0 ] || aborterror "Unable to override char-server configuration, aborting tests." + cat > conf/import/map-server.conf << EOF +map_configuration: { + @include "conf/travis_sql_connection.conf" +} +EOF + [ $? -eq 0 ] || aborterror "Unable to override map-server configuration, aborting tests." + cat > conf/import/inter-server.conf << EOF +inter_configuration: { + log: { + @include "conf/travis_sql_connection.conf" + } +} +EOF + [ $? -eq 0 ] || aborterror "Unable to override inter-server configuration, aborting tests." + ARGS="--load-script npc/dev/test.txt " + ARGS="--load-plugin script_mapquit $ARGS --load-script npc/dev/ci_test.txt" + PLUGINS="--load-plugin HPMHooking --load-plugin sample" + echo "run tests" + # run_test spinlock # Not running the spinlock test for the time being (too time consuming) + run_test libconfig + echo "run all servers without HPM" + run_server ./login-server + run_server ./char-server + run_server ./map-server "$ARGS" + echo "run all servers wit HPM" + run_server ./login-server "$PLUGINS" + run_server ./char-server "$PLUGINS" + run_server ./map-server "$ARGS $PLUGINS" + ;; + getplugins) + echo "Cloning plugins repository..." + # Nothing to clone right now, all relevant plugins are part of the repository. + #git clone http://github.com/HerculesWS/StaffPlugins.git || aborterror "Unable to fetch plugin repository" + #if [ -f StaffPlugins/Haru/script_mapquit/script_mapquit.c -a -f StaffPlugins/Haru/script_mapquit/examples/ci_test.txt ]; then + # pushd src/plugins || aborterror "Unable to enter plugins directory." + # ln -s ../../StaffPlugins/Haru/script_mapquit/script_mapquit.c ./ + # popd + #else + # echo "Plugin not found, skipping advanced tests." + #fi + ;; + *) + usage + ;; +esac diff --git a/tools/configconverter.pl b/tools/configconverter.pl new file mode 100755 index 000000000..dc511aaef --- /dev/null +++ b/tools/configconverter.pl @@ -0,0 +1,968 @@ +#!/usr/bin/perl +# +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2016 Hercules Dev Team +# Copyright (C) 2016 Haru +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +use strict; +use warnings; + +my $silent = 0; +my $confpath = 'conf'; + +sub parse_config($$) { + my ($input, $defaults) = @_; + + my %output = (); + + for my $line (<$input>) { + chomp $line; + $line =~ s/^\s*//; $line =~ s/\s*$//; + if ($line =~ /^([a-z0-9A-Z_.]+)\s*:\s*(.*)$/) { + my ($variable, $value) = ($1, $2); + if ($defaults->{$variable}) { + next if $defaults->{$variable}->{parse}->($variable, $value, $defaults->{$variable}, \%output); + print "Error: Invalid value for setting '$variable: $value'\n"; + next; + } else { + print "Found unhandled configuration setting: '$variable: $value'\n"; + next; + } + } elsif ($line =~ m{^\s*(?://.*)?$}) { + next; + } else { + print "Error: Unable to parse line '$line'\n"; + } + } + return \%output; +} + +sub cfg_add($$$$) { + my ($variable, $value, $default, $output) = @_; + $output->{$variable} = {value => $value, print => $default->{print}, path => $default->{path}} unless $value eq $default->{default}; +} + +sub cfg_append($$$$) { + my ($variable, $value, $default, $output) = @_; + for my $default_value (@{$default->{default}}) { + return if $value eq $default_value; + } + $output->{$variable} = {value => [], print => $default->{print}, path => $default->{path}} unless $output->{$variable}; + push(@{$output->{$variable}->{value}}, $value); +} + +sub parsecfg_string_sub($$$$$) { + my ($variable, $value, $default, $output, $func) = @_; + if ($value =~ m{\s*"((?:\\"|.)*)"\s*(?://.*)?$}i) { + $func->($variable, $1, $default, $output); + return 1; + } elsif ($value =~ m{\s*((?:\\"|.)*)\s*(?://.*)?$}i) { + $func->($variable, $1, $default, $output); + return 1; + } + return 0; +} + +sub parsecfg_string($$$$) { + my ($variable, $value, $default, $output) = @_; + return parsecfg_string_sub($variable, $value, $default, $output, \&cfg_add); +} + +sub parsecfg_stringarr($$$$) { + my ($variable, $value, $default, $output) = @_; + return parsecfg_string_sub($variable, $value, $default, $output, \&cfg_append); +} + +sub parsecfg_int($$$$) { + my ($variable, $value, $default, $output) = @_; + if ($value =~ m{\s*(-?[0-9]+)\s*(?://.*)?$}) { + cfg_add($variable, int $1, $default, $output); + return 1; + } elsif ($value =~ m{\s*(0x[0-9A-F]+)\s*(?://.*)?$}) { + cfg_add($variable, hex $1, $default, $output); + return 1; + } elsif ($value =~ m{\s*(no|false|off)\s*(?://.*)?$}) { + cfg_add($variable, 0, $default, $output); + return 1; + } + return 0; +} + +sub parsecfg_bool($$$$) { + my ($variable, $value, $default, $output) = @_; + if ($value =~ m{\s*(yes|true|1|on)\s*(?://.*)?$}i) { + cfg_add($variable, "true", $default, $output); + return 1; + } elsif ($value =~ m{\s*(no|false|0|off)\s*(?://.*)?$}i) { + cfg_add($variable, "false", $default, $output); + return 1; + } + return 0; +} + +sub print_config($) { + my ($config) = @_; + + for my $variable (keys %$config) { + my $fullpath = $config->{$variable}->{path}; + $fullpath .= $variable if $fullpath =~ m{[:/]$}; + my ($filename, $configpath) = split(/:/, $fullpath, 2); + next unless $filename and $configpath; + my @path = split(/\//, $configpath); + next unless @path; + + my %output = (); + + my $setting = \%output; + while (scalar @path > 1) { + my $nodename = shift @path; + $setting->{$nodename} = {print => \&printcfg_tree, value => {}} unless $setting->{$nodename}; + $setting = $setting->{$nodename}->{value}; + } + $setting->{$path[0]} = {print => $config->{$variable}->{print}, value => $config->{$variable}->{value}}; + verbose("- Found setting: '$variable'.\n Please manually move the setting to '$filename.conf' as in the following example:\n", + "- '$filename.conf': (from $variable)\n"); + $output{$_}->{print}->($_, $output{$_}->{value}, 0) for keys %output; + } +} + +sub indent($$) { + my ($message, $nestlevel) = @_; + return print "\t" x ($nestlevel + 1) . $message; +} + +sub printcfg_tree($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: {\n", $nestlevel); + $value->{$_}{print}->($_, $value->{$_}{value}, $nestlevel + 1) for keys %$value; + indent("}\n", $nestlevel); +} + +sub printcfg_nil($$$) { +} + +sub printcfg_string($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: \"$value\"\n", $nestlevel); +} + +sub printcfg_int($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: $value\n", $nestlevel); +} + +sub printcfg_hexint($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent(sprintf("%s: 0x%x\n", $variable, $value), $nestlevel); +} + +sub printcfg_bool($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: $value\n", $nestlevel); +} + +sub printcfg_point($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: {\n", $nestlevel); + + my @point = split(/,/, $value, 3); + indent("map: \"$point[0]\"\n", $nestlevel + 1); + indent("x: $point[1]\n", $nestlevel + 1); + indent("y: $point[2]\n", $nestlevel + 1); + + indent("}\n", $nestlevel); +} + +sub printcfg_items($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: (\n", $nestlevel); + + my @items = split(/,/, $value); + while (scalar @items >= 3) { + my $id = shift @items; + my $amount = shift @items; + my $stackable = (shift @items) ? "true" : "false"; + indent("{\n", $nestlevel); + indent("id: $id\n", $nestlevel + 1); + indent("amount: $amount\n", $nestlevel + 1); + indent("stackable: $stackable\n", $nestlevel + 1); + indent("},\n", $nestlevel); + } + + indent(")\n", $nestlevel); +} + +sub printcfg_md5hash($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: (\n", $nestlevel); + + for (@$value) { + my ($group_id, $hash) = split(/,/, $_, 2); + $group_id =~ s/\s*$//; $group_id =~ s/^\s*//; + $hash =~ s/\s*$//; $hash =~ s/^\s*//; + + indent("{\n", $nestlevel); + indent("group_id: $group_id\n", $nestlevel + 1); + indent("hash: \"$hash\"\n", $nestlevel + 1); + indent("},\n", $nestlevel); + } + + indent(")\n", $nestlevel); +} + +sub printcfg_strlist($$$) { + my ($variable, $value, $nestlevel) = @_; + + indent("$variable: (\n", $nestlevel); + + for my $string (split(/,/, $value)) { + $string =~ s/\s*$//; $string =~ s/^\s*//; + + indent("\"$string\",\n", $nestlevel + 1); + } + + indent(")\n", $nestlevel); +} + +sub process_conf($$) { + my ($files, $defaults) = @_; + my $found = 0; + for my $file (@$files) { + print "\nChecking $file..."; + print " Ok\n" and next unless open my $FH, '<', $file; # File not found or already converted + print " Old file is still present\n"; + my $output = parse_config($FH, $defaults); + close($FH); + my $count = scalar keys %$output; + print "$count non-default settings found."; + verbose(" The file '$file' is no longer used by Hercules and can be deleted.\n", "\n") and next unless $count; + verbose(" Please review and migrate the settings as described, then delete the file '$file', as it is no longer used by Hercules.\n", "\n"); + print_config($output); + $found = 1; + } + return $found; +} + +sub verbose($;$) { + my ($verbose_message, $silent_message) = @_; + return print $verbose_message unless $silent; + return print $silent_message if defined $silent_message; + return 1; +} + +my @defaults = ( + { + files => ['char-server.conf', 'import/char_conf.txt'], + settings => { + autosave_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/database/", default => 60}, + bind_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/inter/", default => "127.0.0.1"}, + char_aegis_delete => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/player/deletion/use_aegis_delete", default => "false"}, + char_del_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/player/deletion/delay", default => 86400}, + char_del_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/player/deletion/level", default => 0}, + char_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/inter/", default => "127.0.0.1"}, + char_maintenance_min_group_id => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/permission/maintenance_min_group_id", default => 99}, + char_name_letters => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/player/name/name_letters", default => "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"}, + char_name_option => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/player/name/name_option", default => 1}, + char_new => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/permission/enable_char_creation", default => "true"}, + char_new_display => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/permission/display_new", default => "false"}, + char_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/inter/", default => 6121}, + char_server_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/permission/server_type", default => 0}, + console_silent => {parse => \&parsecfg_int, print => \&printcfg_int, path => "console:console/", default => 0}, + db_path => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/database/", default => "db"}, + fame_list_alchemist => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/fame/alchemist", default => 10}, + fame_list_blacksmith => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/fame/blacksmith", default => 10}, + fame_list_taekwon => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/fame/taekwon", default => 10}, + gm_allow_group => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/permission/", default => -1}, + guild_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/", default => 100}, + log_char => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/database/", default => "true"}, + login_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/inter/", default => "127.0.0.1"}, + login_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/inter/", default => 6900}, + max_connect_user => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/permission/", default => -1}, + name_ignoring_case => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/player/name/", default => "false"}, + passwd => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/inter/", default => "p1"}, + pincode_changetime => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/pincode/change_time", default => 0}, + pincode_charselect => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/pincode/request", default => 0}, + pincode_enabled => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "char-server:char_configuration/pincode/enabled", default => "true"}, + pincode_maxtry => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/pincode/max_tries", default => 3}, + save_log => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "console:console/", default => "true"}, + server_name => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/", default => "Hercules"}, + start_items => {parse => \&parsecfg_string, print => \&printcfg_items, path => "char-server:char_configuration/player/new/", default => "1201,1,0,2301,1,0"}, + start_point_pre => {parse => \&parsecfg_string, print => \&printcfg_point, path => "char-server:char_configuration/player/new/", default => "new_1-1,53,111"}, + start_point_re => {parse => \&parsecfg_string, print => \&printcfg_point, path => "char-server:char_configuration/player/new/", default => "iz_int,97,90"}, + start_zeny => {parse => \&parsecfg_int, print => \&printcfg_int, path => "char-server:char_configuration/player/new/zeny", default => 0}, + stdout_with_ansisequence => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "console:console/", default => "false"}, + timestamp_format => {parse => \&parsecfg_string, print => \&printcfg_string, path => "console:console/", default => "[%d/%b %H:%M]"}, + unknown_char_name => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/player/name/", default => "Unknown"}, + userid => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/inter/", default => "s1"}, + wisp_server_name => {parse => \&parsecfg_string, print => \&printcfg_string, path => "char-server:char_configuration/", default => "Server"}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/char_conf.txt"}, + } + }, + { + files => ['inter-server.conf', 'import/inter_conf.txt'], + settings => { + party_share_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/", default => 15}, + log_inter => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "inter-server:inter_configuration/log/", default => "true"}, + inter_log_filename => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/log/", default => "log/inter.log"}, + mysql_reconnect_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/mysql_reconnect/type", default => 2}, + mysql_reconnect_count => {parse => \&parsecfg_int, print => \&printcfg_int, path => "inter-server:inter_configuration/mysql_reconnect/count", default => 1}, + log_login_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/login_db", default => "loginlog"}, + char_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "char"}, + interlog_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "interlog"}, + ragsrvinfo_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "ragsrvinfo"}, + acc_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "acc_reg_num_db"}, + acc_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "acc_reg_str_db"}, + char_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "char_reg_num_db"}, + char_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "char_reg_str_db"}, + global_acc_reg_num_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "global_acc_reg_num_db"}, + global_acc_reg_str_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/registry/", default => "global_acc_reg_str_db"}, + hotkey_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "hotkey"}, + scdata_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "sc_data"}, + cart_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "cart_inventory"}, + inventory_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "inventory"}, + charlog_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "charlog"}, + storage_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "storage"}, + skill_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "skill"}, + memo_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "memo"}, + party_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "party"}, + pet_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "pet"}, + friend_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "friends"}, + mail_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mail"}, + auction_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "auction"}, + quest_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "quest"}, + homunculus_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "homunculus"}, + skill_homunculus_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "skill_homunculus"}, + mercenary_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mercenary"}, + mercenary_owner_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "mercenary_owner"}, + elemental_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "elemental"}, + account_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/pc/", default => "account_data"}, + guild_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/main_db", default => "guild"}, + guild_alliance_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/alliance_db", default => "guild_alliance"}, + guild_castle_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/castle_db", default => "guild_castle"}, + guild_expulsion_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/expulsion_db", default => "guild_expulsion"}, + guild_member_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/member_db", default => "guild_member"}, + guild_skill_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/skill_db", default => "guild_skill"}, + guild_position_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/position_db", default => "guild_position"}, + guild_storage_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/guild/storage_db", default => "guild_storage"}, + mapreg_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "mapreg"}, + autotrade_merchants_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "autotrade_merchants"}, + autotrade_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "autotrade_data"}, + npc_market_data_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/", default => "npc_market_data"}, + default_codepage => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/", default => ""}, + 'sql.db_hostname' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + char_server_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + map_server_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + log_db_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + 'sql.db_port' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + char_server_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + map_server_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + log_db_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + 'sql.db_username' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + char_server_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + map_server_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + log_db_id => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + 'sql.db_password' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + char_server_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + map_server_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + log_db_pw => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + 'sql.db_database' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + char_server_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + map_server_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + log_db_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + 'sql.codepage' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + log_codepage => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + interreg_db => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "interreg"}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/inter_conf.txt"}, + } + }, + { + files => ['login-server.conf', 'import/login_conf.txt'], + settings => { + bind_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "login-server:login_configuration/inter/", default => "127.0.0.1"}, + login_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/inter/", default => 6900}, + timestamp_format => {parse => \&parsecfg_string, print => \&printcfg_string, path => "console:console/", default => "[%d/%b %H:%M]"}, + stdout_with_ansisequence => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "console:console/", default => "false"}, + console_silent => {parse => \&parsecfg_int, print => \&printcfg_int, path => "console:console/", default => 0}, + new_account => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/account/", default => "true"}, + new_acc_length_limit => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/account/", default => "true"}, + allowed_regs => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/", default => 1}, + time_allowed => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/", default => 10}, + log_login => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/log/", default => "true"}, + date_format => {parse => \&parsecfg_string, print => \&printcfg_string, path => "login-server:login_configuration/log/", default => "%Y-%m-%d %H:%M:%S"}, + group_id_to_connect => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/permission/", default => -1}, + min_group_id_to_connect => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/permission/", default => -1}, + start_limited_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/", default => -1}, + check_client_version => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/permission/", default => "false"}, + client_version_to_connect => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/permission/", default => 20}, + use_MD5_passwords => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/account/", default => "false"}, + 'ipban.enable' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/account/ipban/enabled", default => "true"}, + 'ipban.sql.db_hostname' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + 'ipban.sql.db_port' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + 'ipban.sql.db_username' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + 'ipban.sql.db_password' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + 'ipban.sql.db_database' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + 'ipban.sql.codepage' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + 'ipban.sql.ipban_table' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/ipban_table", default => "ipbanlist"}, + 'ipban.dynamic_pass_failure_ban' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/account/ipban/dynamic_pass_failure/enabled", default => "true"}, + 'ipban.dynamic_pass_failure_ban_interval' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/ipban/dynamic_pass_failure/ban_interval", default => 5}, + 'ipban.dynamic_pass_failure_ban_limit' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/ipban/dynamic_pass_failure/ban_limit", default => 7}, + 'ipban.dynamic_pass_failure_ban_duration' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/ipban/dynamic_pass_failure/ban_duration", default => 5}, + ipban_cleanup_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/account/ipban/cleanup_interval", default => 60}, + ip_sync_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "login-server:login_configuration/inter/ip_sync_interval", default => 10}, + use_dnsbl => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/permission/DNS_blacklist/enabled", default => "false"}, + dnsbl_servers => {parse => \&parsecfg_string, print => \&printcfg_strlist, path => "login-server:login_configuration/permission/DNS_blacklist/dnsbl_servers", default => "bl.blocklist.de, socks.dnsbl.sorbs.net"}, + 'account.sql.db_hostname' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_hostname", default => "127.0.0.1"}, + 'account.sql.db_port' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "sql_connection:sql_connection/db_port", default => 3306}, + 'account.sql.db_username' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_username", default => "ragnarok"}, + 'account.sql.db_password' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_password", default => "ragnarok"}, + 'account.sql.db_database' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/db_database", default => "ragnarok"}, + 'account.sql.codepage' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "sql_connection:sql_connection/codepage", default => ""}, + 'account.sql.case_sensitive' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "sql_connection:sql_connection/case_sensitive", default => "false"}, + 'account.sql.account_db' => {parse => \&parsecfg_string, print => \&printcfg_string, path => "inter-server:inter_configuration/database_names/account_db", default => "login"}, + client_hash_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "login-server:login_configuration/permission/hash/enabled", default => "false"}, + client_hash => {parse => \&parsecfg_stringarr, print => \&printcfg_md5hash, path => "login-server:login_configuration/permission/hash/MD5_hashes", default => []}, + 'account.sql.accreg_db' => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "global_reg_value"}, + import => {parse => \&parsecfg_stringarr, print => \&printcfg_nil, path => "", default => ["conf/inter-server.conf", "conf/import/login_conf.txt"]}, + } + }, + { + files => ['map-server.conf', 'import/map_conf.txt'], + settings => { + userid => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/inter/", default => "s1"}, + passwd => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/inter/", default => "p1"}, + char_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/inter/", default => "127.0.0.1"}, + bind_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/inter/", default => "127.0.0.1"}, + char_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "map-server:map_configuration/inter/", default => 6121}, + map_ip => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/inter/", default => "127.0.0.1"}, + map_port => {parse => \&parsecfg_int, print => \&printcfg_int, path => "map-server:map_configuration/inter/", default => 5121}, + timestamp_format => {parse => \&parsecfg_string, print => \&printcfg_string, path => "console:console/", default => "[%d/%b %H:%M]"}, + stdout_with_ansisequence => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "console:console/", default => "false"}, + console_msg_log => {parse => \&parsecfg_int, print => \&printcfg_int, path => "console:console/", default => 0}, + console_silent => {parse => \&parsecfg_int, print => \&printcfg_int, path => "console:console/", default => 0}, + db_path => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/database/", default => "db"}, + enable_spy => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "map-server:map_configuration/", default => "false"}, + use_grf => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "map-server:map_configuration/", default => "false"}, + autosave_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "map-server:map_configuration/database/", default => 300}, + minsave_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "map-server:map_configuration/database/", default => 100}, + save_settings => {parse => \&parsecfg_int, print => \&printcfg_hexint, path => "map-server:map_configuration/database/", default => 511}, + default_language => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/", default => "English"}, + help_txt => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/", default => "conf/help.txt"}, + charhelp_txt => {parse => \&parsecfg_string, print => \&printcfg_string, path => "map-server:map_configuration/", default => "conf/charhelp.txt"}, + help2_txt => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/help2.txt"}, + import => {parse => \&parsecfg_stringarr, print => \&printcfg_nil, path => "", default => ["conf/maps.conf", "conf/import/map_conf.txt"]}, + } + }, + { + files => ['logs.conf', 'import/log_conf.txt'], + settings => { + enable_logs => {parse => \&parsecfg_int, print => \&printcfg_hexint, path => "logs:map_log/enable", default => 0xFFFFF}, + sql_logs => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/database/use_sql", default => "true"}, + log_filter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/item/", default => 1}, + refine_items_log => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/item/", default => 5}, + rare_items_log => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/item/", default => 100}, + price_items_log => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/item/", default => 1000}, + amount_items_log => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/item/", default => 100}, + log_branch => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/", default => "false"}, + log_zeny => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/", default => 0}, + log_mvpdrop => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/", default => "false"}, + log_commands => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/", default => "true"}, + log_npc => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/", default => "false"}, + log_chat => {parse => \&parsecfg_int, print => \&printcfg_int, path => "logs:map_log/filter/chat/", default => 0}, + log_chat_woe_disable => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "logs:map_log/filter/chat/", default => "false"}, + log_gm_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "atcommandlog"}, + log_branch_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "branchlog"}, + log_chat_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "chatlog"}, + log_mvpdrop_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "mvplog"}, + log_npc_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "npclog"}, + log_pick_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "picklog"}, + log_zeny_db => {parse => \&parsecfg_string, print => \&printcfg_string, path => "logs:map_log/database/", default => "zenylog"}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/log_conf.txt"}, + } + }, + { + files => ['script.conf', 'import/script_conf.txt'], + settings => { + warn_func_mismatch_paramnum => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "script:script_configuration/", default => "true"}, + check_cmdcount => {parse => \&parsecfg_int, print => \&printcfg_int, path => "script:script_configuration/", default => 655360}, + check_gotocount => {parse => \&parsecfg_int, print => \&printcfg_int, path => "script:script_configuration/", default => 2048}, + input_min_value => {parse => \&parsecfg_int, print => \&printcfg_int, path => "script:script_configuration/", default => 0}, + input_max_value => {parse => \&parsecfg_int, print => \&printcfg_int, path => "script:script_configuration/", default => 10000000}, + warn_func_mismatch_argtypes => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "script:script_configuration/", default => "true"}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/script_conf.txt"}, + } + }, + { + files => ['packet.conf', 'import/packet_conf.txt'], + settings => { + debug => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "socket:socket_configuration/", default => "false"}, + stall_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/", default => 60}, + epoll_maxevents => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/", default => 1024}, + socket_max_client_packet => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/", default => 65535}, + enable_ip_rules => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "socket:socket_configuration/ip_rules/enable", default => "true"}, + order => {parse => \&parsecfg_string, print => \&printcfg_string, path => "socket:socket_configuration/ip_rules/", default => "deny,allow"}, + allow => {parse => \&parsecfg_stringarr, print => \&printcfg_strlist, path => "socket:socket_configuration/ip_rules/allow_list", default => []}, + deny => {parse => \&parsecfg_stringarr, print => \&printcfg_strlist, path => "socket:socket_configuration/ip_rules/deny_list", default => []}, + ddos_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/ddos/interval", default => 3000}, + ddos_count => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/ddos/count", default => 5}, + ddos_autoreset => {parse => \&parsecfg_int, print => \&printcfg_int, path => "socket:socket_configuration/ddos/autoreset", default => 600000}, + import => {parse => \&parsecfg_string, print => \&printcfg_nil, path => "", default => "conf/import/packet_conf.txt"}, + } + }, + { + files => ['battle.conf', 'battle/battle.conf', 'battle/client.conf', 'battle/drops.conf', 'battle/exp.conf', 'battle/gm.conf', 'battle/guild.conf', 'battle/battleground.conf', 'battle/items.conf', 'battle/monster.conf', 'battle/party.conf', 'battle/pet.conf', 'battle/homunc.conf', 'battle/player.conf', 'battle/skill.conf', 'battle/status.conf', 'battle/feature.conf', 'battle/misc.conf', 'import/battle_conf.txt'], + settings => { + bg_flee_penalty => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battleground:", default => 20}, + bg_update_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battleground:", default => 1000}, + 'feature.buying_store' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/buying_store", default => "true"}, + 'feature.search_stores' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/search_stores", default => "true"}, + 'feature.atcommand_suggestions' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/atcommand_suggestions", default => "false"}, + 'feature.banking' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/banking", default => "true"}, + 'feature.auction' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/auction", default => "false"}, + 'feature.roulette' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "feature:features/roulette", default => "false"}, + atcommand_spawn_quantity_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "gm:", default => 100}, + atcommand_slave_clone_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "gm:", default => 25}, + partial_name_scan => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "gm:", default => "true"}, + atcommand_max_stat_bypass => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "gm:", default => "false"}, + ban_hack_trade => {parse => \&parsecfg_int, print => \&printcfg_int, path => "gm:", default => 5}, + atcommand_mobinfo_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "gm:", default => 0}, + gm_ignore_warpable_area => {parse => \&parsecfg_int, print => \&printcfg_int, path => "gm:", default => 2}, + atcommand_levelup_events => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "gm:", default => "false"}, + guild_emperium_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "guild:", default => "true"}, + guild_exp_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 50}, + guild_max_castles => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 0}, + guild_skill_relog_delay => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "guild:", default => "false"}, + castle_defense_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 100}, + gvg_flee_penalty => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 20}, + require_glory_guild => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "guild:", default => "false"}, + max_guild_alliance => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 3}, + guild_notice_changemap => {parse => \&parsecfg_int, print => \&printcfg_int, path => "guild:", default => 2}, + guild_castle_invite => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "guild:", default => "false"}, + guild_castle_expulsion => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "guild:", default => "false"}, + hom_setting => {parse => \&parsecfg_int, print => \&printcfg_hexint, path => "homunc:", default => 0x1D}, + homunculus_friendly_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "homunc:", default => 100}, + hom_rename => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "homunc:", default => "false"}, + hvan_explosion_intimate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "homunc:", default => 45000}, + homunculus_show_growth => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "homunc:", default => "true"}, + homunculus_autoloot => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "homunc:", default => "true"}, + homunculus_auto_vapor => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "homunc:", default => "true"}, + homunculus_max_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "homunc:", default => 99}, + homunculus_S_max_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "homunc:", default => 150}, + enable_baseatk => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 9}, + enable_perfect_flee => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + enable_critical => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 17}, + mob_critical_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + critical_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + attack_walk_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 15}, + pc_damage_walk_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 20}, + damage_walk_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + multihit_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 80}, + player_damage_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + undead_detect_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 0}, + attribute_recover => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "battle:", default => "false"}, + min_hitrate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 5}, + max_hitrate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + agi_penalty_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + agi_penalty_target => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + agi_penalty_count => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 3}, + agi_penalty_num => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 10}, + vit_penalty_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + vit_penalty_target => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + vit_penalty_count => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 3}, + vit_penalty_num => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 5}, + weapon_defense_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 0}, + magic_defense_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 0}, + attack_direction_change => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 0}, + attack_attr_none => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 14}, + equip_natural_break_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 0}, + equip_self_break_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + equip_skill_break_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 100}, + delay_battle_damage => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "battle:", default => "true"}, + arrow_decrement => {parse => \&parsecfg_int, print => \&printcfg_int, path => "battle:", default => 1}, + autospell_check_range => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "battle:", default => "false"}, + knockback_left => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "battle:", default => "true"}, + snap_dodge => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "battle:", default => "false"}, + packet_obfuscation => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 1}, + min_chat_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + min_hair_style => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + max_hair_style => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 29}, + min_hair_color => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + max_hair_color => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 8}, + min_cloth_color => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + max_cloth_color => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 4}, + min_body_style => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + max_body_style => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 4}, + hide_woe_damage => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "true"}, + pet_hair_style => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 100}, + area_size => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 14}, + max_walk_path => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 17}, + max_lv => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 99}, + aura_lv => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 99}, + client_limit_unit_lv => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + wedding_modifydisplay => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + save_clothcolor => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "true"}, + save_body_style => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + wedding_ignorepalette => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + xmas_ignorepalette => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + summer_ignorepalette => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + hanbok_ignorepalette => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + display_version => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + display_hallucination => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "true"}, + display_status_timers => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "true"}, + client_reshuffle_dice => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "true"}, + client_sort_storage => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "client:", default => "false"}, + client_accept_chatdori => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 0}, + client_emblem_max_blank_percent => {parse => \&parsecfg_int, print => \&printcfg_int, path => "client:", default => 100}, + item_auto_get => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "drops:", default => "false"}, + flooritem_lifetime => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 60000}, + item_first_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 3000}, + item_second_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1000}, + item_third_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1000}, + mvp_item_first_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + mvp_item_second_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + mvp_item_third_get_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 2000}, + item_rate_common => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_rate_common_boss => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_common_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_common_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_heal => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_rate_heal_boss => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_heal_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_heal_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_use => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_rate_use_boss => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_use_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_use_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_equip => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_rate_equip_boss => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_equip_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_equip_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_card => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_rate_card_boss => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_card_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_card_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_mvp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_mvp_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_mvp_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_adddrop => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_add_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_add_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_rate_treasure => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 100}, + item_drop_treasure_min => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + item_drop_treasure_max => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 10000}, + item_logarithmic_drops => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "drops:", default => "false"}, + drop_rate0item => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "drops:", default => "false"}, + drops_by_luk => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 0}, + drops_by_luk2 => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 0}, + alchemist_summon_reward => {parse => \&parsecfg_int, print => \&printcfg_int, path => "drops:", default => 1}, + base_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + job_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + multi_level_up => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "exp:", default => "false"}, + max_exp_gain_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + exp_calc_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + exp_bonus_attacker => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 25}, + exp_bonus_max_attacker => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 12}, + mvp_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + quest_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + heal_exp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + resurrection_exp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + shop_exp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + pvp_exp => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "exp:", default => "true"}, + death_penalty_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 1}, + death_penalty_base => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + death_penalty_job => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 100}, + zeny_penalty => {parse => \&parsecfg_int, print => \&printcfg_int, path => "exp:", default => 0}, + disp_experience => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "exp:", default => "false"}, + disp_zeny => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "exp:", default => "false"}, + use_statpoint_table => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "exp:", default => "true"}, + vending_max_value => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 1000000000}, + vending_over_max => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + vending_tax => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 200}, + buyer_name => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + weapon_produce_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 100}, + potion_produce_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 100}, + produce_item_name_input => {parse => \&parsecfg_int, print => \&printcfg_hexint, path => "items:", default => 0x03}, + dead_branch_active => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + random_monster_checklv => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "false"}, + ignore_items_gender => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + item_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "false"}, + item_use_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 100}, + cashfood_use_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 60000}, + gtb_sc_immunity => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 50}, + autospell_stacking => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "false"}, + item_restricted_consumption_type => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + item_enabled_npc => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "items:", default => "true"}, + unequip_restricted_equipment => {parse => \&parsecfg_int, print => \&printcfg_int, path => "items:", default => 0}, + pk_mode => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + manner_system => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 31}, + pk_min_level => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 55}, + pk_level_range => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + skill_log => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + battle_log => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + etc_log => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + warp_point_debug => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + night_at_start => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + day_duration => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + night_duration => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + duel_allow_pvp => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + duel_allow_gvg => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + duel_allow_teleport => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + duel_autoleave_when_die => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "true"}, + duel_time_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 60}, + duel_only_on_same_map => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + official_cell_stack_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 1}, + custom_cell_stack_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 1}, + check_occupied_cells => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "true"}, + at_mapflag => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + at_timeout => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + auction_feeperhour => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 12000}, + auction_maximumprice => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 500000000}, + searchstore_querydelay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 10}, + searchstore_maxresults => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 30}, + cashshop_show_points => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + mail_show_status => {parse => \&parsecfg_int, print => \&printcfg_int, path => "misc:", default => 0}, + mon_trans_disable_in_gvg => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "false"}, + case_sensitive_aegisnames => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "misc:", default => "true"}, + mvp_hp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + monster_hp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + monster_max_aspd => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 199}, + monster_ai => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + monster_chase_refresh => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 3}, + mob_warp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + mob_active_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + boss_active_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + view_range_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + chase_range_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + monster_active_enable => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + override_mob_names => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + monster_damage_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + monster_loot_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + mob_skill_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + mob_skill_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + mob_count_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + mob_spawn_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + plant_spawn_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + boss_spawn_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 100}, + no_spawn_on_player => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + force_random_spawn => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "false"}, + slaves_inherit_mode => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 2}, + slaves_inherit_speed => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 3}, + summons_trigger_autospells => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + retaliate_to_master => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + mob_changetarget_byskill => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "false"}, + monster_class_change_full_recover => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + show_mob_info => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + zeny_from_mobs => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "false"}, + mobs_level_up => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "false"}, + mobs_level_up_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 1}, + dynamic_mobs => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + mob_remove_damaged => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + mob_remove_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 300000}, + mob_npc_event_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 1}, + ksprotection => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 0}, + mob_slave_keep_target => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + mvp_tomb_enabled => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + show_monster_hp_bar => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "true"}, + mob_size_influence => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "monster:", default => "false"}, + mob_icewall_walk_block => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 220}, + boss_icewall_walk_block => {parse => \&parsecfg_int, print => \&printcfg_int, path => "monster:", default => 1}, + show_steal_in_same_party => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "party:", default => "false"}, + party_update_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:", default => 1000}, + party_hp_mode => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:", default => 0}, + show_party_share_picker => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "party:", default => "true"}, + 'show_picker.item_type' => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:show_picker_item_type", default => 112}, + party_item_share_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:", default => 0}, + idle_no_share => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:", default => 0}, + party_even_share_bonus => {parse => \&parsecfg_int, print => \&printcfg_int, path => "party:", default => 0}, + display_party_name => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "party:", default => "false"}, + pet_catch_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 100}, + pet_rename => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + pet_friendly_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 100}, + pet_hungry_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 100}, + pet_hungry_friendly_decrease => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 5}, + pet_equip_required => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "true"}, + pet_attack_support => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + pet_damage_support => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + pet_support_min_friendly => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 900}, + pet_equip_min_friendly => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 900}, + pet_status_support => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + pet_support_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 100}, + pet_attack_exp_to_master => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + pet_attack_exp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 100}, + pet_lv_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 0}, + pet_max_stats => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 99}, + pet_max_atk1 => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 500}, + pet_max_atk2 => {parse => \&parsecfg_int, print => \&printcfg_int, path => "pet:", default => 1000}, + pet_disable_in_gvg => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "pet:", default => "false"}, + hp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 100}, + sp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 100}, + left_cardfix_to_right => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + restart_hp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + restart_sp_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + player_skillfree => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + player_skillup_limit => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + quest_skill_learn => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + quest_skill_reset => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + basic_skill_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + player_invincible_time => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 5000}, + fix_warp_hit_delay_abuse => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + natural_healhp_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 6000}, + natural_healsp_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 8000}, + natural_heal_skill_interval => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 10000}, + natural_heal_weight_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 50}, + max_aspd => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 190}, + max_third_aspd => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 193}, + max_walk_speed => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 300}, + max_hp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 1000000}, + max_sp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 1000000}, + max_parameter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 99}, + max_third_parameter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 130}, + max_extended_parameter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 125}, + max_baby_parameter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 80}, + max_baby_third_parameter => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 117}, + max_def => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 99}, + over_def_bonus => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + max_cart_weight => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 8000}, + prevent_logout => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 10000}, + show_hp_sp_drain => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + show_hp_sp_gain => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + show_katar_crit_bonus => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + friend_auto_add => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + invite_request_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + bone_drop => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + character_size => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + idle_no_autoloot => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + min_npc_vendchat_distance => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 3}, + vendchat_near_hiddennpc => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "false"}, + snovice_call_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "player:", default => 0}, + idletime_criteria => {parse => \&parsecfg_int, print => \&printcfg_hexint, path => "player:", default => 0x1F}, + costume_refine_def => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + shadow_refine_def => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + shadow_refine_atk => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + player_warp_keep_direction => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "player:", default => "true"}, + casting_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 100}, + delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 100}, + delay_dependon_dex => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + delay_dependon_agi => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + min_skill_delay_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 100}, + default_walk_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 300}, + no_skill_delay => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 2}, + castrate_dex_scale => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 150}, + vcast_stat_scale => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 530}, + skill_amotion_leniency => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 90}, + skill_delay_attack_enable => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + skill_add_range => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + skill_out_range_consume => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + skillrange_by_distance => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 14}, + skillrange_from_weapon => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + skill_caster_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + clear_skills_on_death => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + clear_skills_on_warp => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 15}, + defunit_not_enemy => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + skill_min_damage => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 6}, + combo_delay_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 100}, + auto_counter_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 15}, + skill_reiteration => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + skill_nofootset => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 1}, + gvg_traps_target_all => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 1}, + traps_setting => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + summon_flora_setting => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 3}, + song_timer_reset => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + skill_wall_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + player_cloak_check_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 1}, + monster_cloak_check_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 4}, + land_skill_limit => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 9}, + display_skill_fail => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + chat_warpportal => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + sense_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 1}, + finger_offensive_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + gx_allhit => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + gx_disptype => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 1}, + devotion_level_difference => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 10}, + player_skill_partner_check => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + skill_removetrap_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + backstab_bow_penalty => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + skill_steal_max_tries => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + copyskill_restrict => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 2}, + berserk_cancels_buffs => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + max_heal => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 9999}, + max_heal_lv => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 11}, + emergency_call => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 11}, + guild_aura => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 31}, + skip_teleport_lv1_menu => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + allow_skill_without_day => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + allow_es_magic_player => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + sg_miracle_skill_ratio => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 2}, + sg_miracle_skill_duration => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 3600000}, + sg_angel_skill_ratio => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 10}, + skill_add_heal_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 7}, + eq_single_target_reflectable => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + 'invincible.nodamage' => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "false"}, + dancing_weaponswitch_fix => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + skill_trap_type => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + mob_max_skilllvl => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 100}, + bowling_bash_area => {parse => \&parsecfg_int, print => \&printcfg_int, path => "skill:", default => 0}, + stormgust_knockback => {parse => \&parsecfg_bool, print => \&printcfg_bool, path => "skill:", default => "true"}, + status_cast_cancel => {parse => \&parsecfg_int, print => \&printcfg_int, path => "status:", default => 0}, + pc_status_def_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "status:", default => 100}, + mob_status_def_rate => {parse => \&parsecfg_int, print => \&printcfg_int, path => "status:", default => 100}, + pc_max_status_def => {parse => \&parsecfg_int, print => \&printcfg_int, path => "status:", default => 100}, + mob_max_status_def => {parse => \&parsecfg_int, print => \&printcfg_int, path => "status:", default => 100}, + import => {parse => \&parsecfg_stringarr, print => \&printcfg_nil, path => "", default => ['conf/battle/battle.conf', 'conf/battle/client.conf', 'conf/battle/drops.conf', 'conf/battle/exp.conf', 'conf/battle/gm.conf', 'conf/battle/guild.conf', 'conf/battle/battleground.conf', 'conf/battle/items.conf', 'conf/battle/monster.conf', 'conf/battle/party.conf', 'conf/battle/pet.conf', 'conf/battle/homunc.conf', 'conf/battle/player.conf', 'conf/battle/skill.conf', 'conf/battle/status.conf', 'conf/battle/feature.conf', 'conf/battle/misc.conf', 'conf/import/battle_conf.txt']}, + } + }, +); + +for (@ARGV) { + if (/^-q$/) { $silent = 1; } + elsif (/^-v$/) { $silent = 0; } + elsif (-d) { $confpath = $_; } + else { undef $confpath } +} + +verbose(<<'EOF'); +=============== Hercules Configuration Migration Helper =============== += _ _ _ = += | | | | | | = += | |_| | ___ _ __ ___ _ _| | ___ ___ = += | _ |/ _ \ '__/ __| | | | |/ _ \/ __| = += | | | | __/ | | (__| |_| | | __/\__ \ = += \_| |_/\___|_| \___|\__,_|_|\___||___/ = +======================================================================= +This tool will assist you through the migration of the old (txt-based) +configuration files to the new (libconfig-based) format. +Please follow the displayed instructions. +======================================================================= + +EOF + +die "Usage: ./$0 [-q | -v] [path to the conf directory]\nIf no options are passed, it acts as if called as ./$0 conf\n" unless defined $confpath and -d $confpath; + +my $count = 0; +for (@defaults) { + my @files = map { $confpath . '/' . $_ } @{$_->{files}}; + $count += process_conf(\@files, $_->{settings}) +} +verbose("\nThere are no files to migrate.\n") unless $count; diff --git a/tools/doxygen/Hercules128.png b/tools/doxygen/Hercules128.png Binary files differnew file mode 100644 index 000000000..79919da9b --- /dev/null +++ b/tools/doxygen/Hercules128.png diff --git a/tools/doxygen/Hercules48.png b/tools/doxygen/Hercules48.png Binary files differnew file mode 100644 index 000000000..022893953 --- /dev/null +++ b/tools/doxygen/Hercules48.png diff --git a/tools/doxygen/Makefile.in b/tools/doxygen/Makefile.in new file mode 100644 index 000000000..233779f05 --- /dev/null +++ b/tools/doxygen/Makefile.in @@ -0,0 +1,70 @@ +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2016 Hercules Dev Team +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# @configure_input@ + +@SET_MAKE@ + +COMMON_D = ../../src/common +MAP_D = ../../src/map +CHAR_D = ../../src/char +LOGIN_D = ../../src/login +PLUGIN_D = ../../src/plugins +COMMON_C = $(wildcard $(COMMON_D)/*.c) +COMMON_H = $(wildcard $(COMMON_D)/*.h) +MAP_C = $(wildcard $(MAP_D)/*.c) +MAP_H = $(wildcard $(MAP_D)/*.h) +CHAR_C = $(wildcard $(CHAR_D)/*.c) +CHAR_H = $(wildcard $(CHAR_D)/*.h) +LOGIN_C = $(wildcard $(LOGIN_D)/*.c) +LOGIN_H = $(wildcard $(LOGIN_D)/*.h) +ALL_C = $(COMMON_C) $(MAP_C) $(CHAR_C) $(LOGIN_C) +ALL_H = $(COMMON_H) $(MAP_H) $(CHAR_H) $(LOGIN_H) + +HAVE_DOXYGEN=@HAVE_DOXYGEN@ +ifeq ($(HAVE_DOXYGEN),yes) + ALL_DEPENDS = docs +else + ALL_DEPENDS = needs_doxygen +endif + +##################################################################### +.PHONY: clean buildclean + +all: $(ALL_DEPENDS) + +buildclean: + +clean: buildclean + @echo " CLEAN docs" + @rm -rf docs + +Makefile: Makefile.in + @$(MAKE) -C ../.. tools/doxygen/Makefile + +##################################################################### + +docs: $(ALL_C) $(ALL_H) doxygen.conf + @echo " Generating Doxygen documentation..." + @doxygen doxygen.conf + +##################################################################### + +needs_doxygen: + @echo "doxygen not found or disabled by the configure script" + @exit 1 diff --git a/tools/doxygen/doxygen.conf b/tools/doxygen/doxygen.conf new file mode 100644 index 000000000..043b36dc8 --- /dev/null +++ b/tools/doxygen/doxygen.conf @@ -0,0 +1,505 @@ +# Doxyfile 1.8.8 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "Hercules" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = Hercules48.png +OUTPUT_DIRECTORY = docs +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = ../../ +STRIP_FROM_INC_PATH = ../../ +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = h=C +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NNO +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YENO +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NNO +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NNO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = "git log -n 1 --pretty=format:%h -- " +LAYOUT_FILE = layoutFile.xml +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../src/map \ + ../../src/common \ + ../../src/char \ + ../../src/login \ + ../../src/config +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.h +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. +USE_MDFILE_AS_MAINPAGE = +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. +CLANG_OPTIONS = +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 30 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = ../../src \ + ../../3rdparty +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external class will be listed in the +# class index. If set to NO only the inherited external classes will be listed. +# The default value is: NO. +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in +# the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = YES +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +DOT_GRAPH_MAX_NODES = 100 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/tools/doxygen/footer.html b/tools/doxygen/footer.html new file mode 100644 index 000000000..aecaafcc4 --- /dev/null +++ b/tools/doxygen/footer.html @@ -0,0 +1,21 @@ +<!-- HTML footer for doxygen 1.8.8--> +<!-- start footer part --> +<!--BEGIN GENERATE_TREEVIEW--> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + $navpath + <li class="footer">$generatedby + <a href="http://www.doxygen.org/index.html"> + <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li> + </ul> +</div> +<!--END GENERATE_TREEVIEW--> +<!--BEGIN !GENERATE_TREEVIEW--> +<hr class="footer"/><address class="footer"><small> +$generatedby  <a href="http://www.doxygen.org/index.html"> +<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/> +</a> $doxygenversion +</small></address> +<!--END !GENERATE_TREEVIEW--> +</body> +</html> diff --git a/tools/doxygen/header.html b/tools/doxygen/header.html new file mode 100644 index 000000000..31aae0ea2 --- /dev/null +++ b/tools/doxygen/header.html @@ -0,0 +1,55 @@ +<!-- HTML header for doxygen 1.8.8--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=9"/> +<meta name="generator" content="Doxygen $doxygenversion"/> +<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> +<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME--> +<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/> +<script type="text/javascript" src="$relpath^jquery.js"></script> +<script type="text/javascript" src="$relpath^dynsections.js"></script> +$treeview +$search +$mathjax +<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" /> +$extrastylesheet +</head> +<body> +<div id="top"><!-- do not remove this div, it is closed by doxygen! --> + +<!--BEGIN TITLEAREA--> +<div id="titlearea"> +<table cellspacing="0" cellpadding="0"> + <tbody> + <tr style="height: 56px;"> + <!--BEGIN PROJECT_LOGO--> + <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td> + <!--END PROJECT_LOGO--> + <!--BEGIN PROJECT_NAME--> + <td style="padding-left: 0.5em;"> + <div id="projectname">$projectname + <!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER--> + </div> + <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF--> + </td> + <!--END PROJECT_NAME--> + <!--BEGIN !PROJECT_NAME--> + <!--BEGIN PROJECT_BRIEF--> + <td style="padding-left: 0.5em;"> + <div id="projectbrief">$projectbrief</div> + </td> + <!--END PROJECT_BRIEF--> + <!--END !PROJECT_NAME--> + <!--BEGIN DISABLE_INDEX--> + <!--BEGIN SEARCHENGINE--> + <td>$searchbox</td> + <!--END SEARCHENGINE--> + <!--END DISABLE_INDEX--> + </tr> + </tbody> +</table> +</div> +<!--END TITLEAREA--> +<!-- end header part --> diff --git a/tools/doxygen/layoutFile.xml b/tools/doxygen/layoutFile.xml new file mode 100644 index 000000000..740548619 --- /dev/null +++ b/tools/doxygen/layoutFile.xml @@ -0,0 +1,194 @@ +<doxygenlayout version="1.0"> + <!-- Generated by doxygen 1.8.8 --> + <!-- Navigation index tabs for HTML output --> + <navindex> + <tab type="mainpage" visible="yes" title=""/> + <tab type="pages" visible="yes" title="" intro=""/> + <tab type="modules" visible="yes" title="" intro=""/> + <tab type="namespaces" visible="yes" title=""> + <tab type="namespacelist" visible="yes" title="" intro=""/> + <tab type="namespacemembers" visible="yes" title="" intro=""/> + </tab> + <tab type="classes" visible="yes" title=""> + <tab type="classlist" visible="yes" title="" intro=""/> + <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> + <tab type="hierarchy" visible="yes" title="" intro=""/> + <tab type="classmembers" visible="yes" title="" intro=""/> + </tab> + <tab type="files" visible="yes" title=""> + <tab type="filelist" visible="yes" title="" intro=""/> + <tab type="globals" visible="yes" title="" intro=""/> + </tab> + <tab type="examples" visible="yes" title="" intro=""/> + </navindex> + + <!-- Layout definition for a class page --> + <class> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <inheritancegraph visible="$CLASS_GRAPH"/> + <collaborationgraph visible="$COLLABORATION_GRAPH"/> + <memberdecl> + <nestedclasses visible="yes" title=""/> + <publictypes title=""/> + <services title=""/> + <interfaces title=""/> + <publicslots title=""/> + <signals title=""/> + <publicmethods title=""/> + <publicstaticmethods title=""/> + <publicattributes title=""/> + <publicstaticattributes title=""/> + <protectedtypes title=""/> + <protectedslots title=""/> + <protectedmethods title=""/> + <protectedstaticmethods title=""/> + <protectedattributes title=""/> + <protectedstaticattributes title=""/> + <packagetypes title=""/> + <packagemethods title=""/> + <packagestaticmethods title=""/> + <packageattributes title=""/> + <packagestaticattributes title=""/> + <properties title=""/> + <events title=""/> + <privatetypes title=""/> + <privateslots title=""/> + <privatemethods title=""/> + <privatestaticmethods title=""/> + <privateattributes title=""/> + <privatestaticattributes title=""/> + <friends title=""/> + <related title="" subtitle=""/> + <membergroups visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <services title=""/> + <interfaces title=""/> + <constructors title=""/> + <functions title=""/> + <related title=""/> + <variables title=""/> + <properties title=""/> + <events title=""/> + </memberdef> + <allmemberslink visible="yes"/> + <usedfiles visible="$SHOW_USED_FILES"/> + <authorsection visible="yes"/> + </class> + + <!-- Layout definition for a namespace page --> + <namespace> + <briefdescription visible="yes"/> + <memberdecl> + <nestednamespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <classes visible="yes" title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection visible="yes"/> + </namespace> + + <!-- Layout definition for a file page --> + <file> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <includegraph visible="$INCLUDE_GRAPH"/> + <includedbygraph visible="$INCLUDED_BY_GRAPH"/> + <sourcelink visible="yes"/> + <memberdecl> + <classes visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + <memberdef> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection/> + </file> + + <!-- Layout definition for a group page --> + <group> + <briefdescription visible="yes"/> + <groupgraph visible="$GROUP_GRAPHS"/> + <memberdecl> + <nestedgroups visible="yes" title=""/> + <dirs visible="yes" title=""/> + <files visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <classes visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + <membergroups visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + <memberdef> + <pagedocs/> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + </memberdef> + <authorsection visible="yes"/> + </group> + + <!-- Layout definition for a directory page --> + <directory> + <briefdescription visible="yes"/> + <directorygraph visible="yes"/> + <memberdecl> + <dirs visible="yes"/> + <files visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + </directory> +</doxygenlayout> diff --git a/tools/doxygen/pages_index.html b/tools/doxygen/pages_index.html new file mode 100644 index 000000000..c9ca5b58c --- /dev/null +++ b/tools/doxygen/pages_index.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> + <meta http-equiv="X-UA-Compatible" content="IE=9"/> + <title>Hercules documentation</title> + <link href="docs/doxygen.css" rel="stylesheet" type="text/css" /> +</head> +<body> + <div id="top"> + <div id="titlearea"> + <table cellspacing="0" cellpadding="0"> + <tbody> + <tr style="height: 56px;"> + <td id="projectlogo"><img alt="Logo" src="docs/Hercules48.png"/></td> + <td id="projectalign" style="padding-left: 0.5em;"> + <div id="projectname">Hercules</div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="header"> + <div class="headertitle"> + <div class="title">Hercules Documentation</div> + </div> + </div><!--header--> + <div class="contents"> + <ul> + <li><a href="docs/">Doxygen</a></li> + <li><a href="gcov_pre.html">Coverage Report: pre-renewal build</a> <a href="gcov_pre.txt">(raw data)</a></li> + <li><a href="gcov_re.html">Coverage Report: renewal build</a> <a href="gcov_re.txt">(raw data)</a></li> + <li><a href="https://github.com/HerculesWS/Hercules">GitHub</a></li> + <li><a href="https://gitlab.com/HerculesWS/Hercules">GitLab</a></li> + </ul> + </div><!-- contents --> + <hr class="footer"> +</body></html> diff --git a/tools/doxygen/style.css b/tools/doxygen/style.css new file mode 100644 index 000000000..02e8b0152 --- /dev/null +++ b/tools/doxygen/style.css @@ -0,0 +1,1440 @@ +/* The standard CSS for doxygen 1.8.8 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('ftv2doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/tools/item_merge.lua b/tools/item_merge.lua index 38708f452..2ef08eb7b 100644 --- a/tools/item_merge.lua +++ b/tools/item_merge.lua @@ -16,7 +16,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. --- Base Author: Dastgir @ http://hercules.ws +-- Base Author: Dastgir @ http://herc.ws -- -- This script requires lua 5.1 to run. diff --git a/tools/itemdb_jobmask_converter.pl b/tools/itemdb_jobmask_converter.pl new file mode 100644 index 000000000..11a5e7a5f --- /dev/null +++ b/tools/itemdb_jobmask_converter.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl +# +# This file is part of Hercules. +# http://herc.ws - http://github.com/HerculesWS/Hercules +# +# Copyright (C) 2016 Hercules Dev Team +# +# Hercules is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Base Author: Dastgir @ http://herc.ws + +# This script converts item_db.conf Jobmask field into groups format +# usage example: perl tools/itemdb_jobmask_converter.pl < db/item_db2.conf > db/item_db_out.conf + +use strict; +use warnings; + +sub parsedb (@) { + my @input = @_; + my @jobNames = ( + "Novice", + "Swordsman", + "Magician", + "Archer", + "Acolyte", + "Merchant", + "Thief", + "Knight", + "Priest", + "Wizard", + "Blacksmith", + "Hunter", + "Assassin", + "Unused", + "Crusader", + "Monk", + "Sage", + "Rogue", + "Alchemist", + "Bard", + "Unused", + "Taekwon", + "Star_Gladiator", + "Soul_Linker", + "Gunslinger", + "Ninja", + "Gangsi", + "Death_Knight", + "Dark_Collector", + "Kagerou", + "Rebellion" + ); + my $jobSize = $#jobNames + 1; + + foreach (@input) { + chomp $_; + if ($_ =~ /^\s*Job\s*:\s*(?<Job>(?:0x)?[0-9A-Fa-f]+)/x) { + my %cols = map { $_ => $+{$_} } keys %+; + my $jobMask = hex($cols{Job}); + my $allJobs = 0xFFFFFFFF; + my $allJobsExceptNovice = 0xFFFFFFFE; + if ($jobMask < 0 || $jobMask eq "") { + print "$_\n"; + next; + } + print "\tJob: {\n"; + if (($jobMask&$allJobs) == $allJobs) { + print "\t\tAll: true\n"; + } elsif (($jobMask&$allJobsExceptNovice) == $allJobsExceptNovice) { + print "\t\tAll: true\n"; + print "\t\tNovice: false\n"; + } elsif ($jobMask == 0) { + print "\t\tAll: false\n"; + } else { + for (my $i = 0; $i < $jobSize; $i++) { + my $currBit = 1<<$i; + if (($jobMask & $currBit) == $currBit) { + print "\t\t$jobNames[$i]: true\n" unless $jobNames[$i] eq "Unused"; + } + } + } + print "\t}\n"; + } else { + print "$_\n"; + } + } +} + +parsedb(<>); diff --git a/tools/skilldbconverter.php b/tools/skilldbconverter.php new file mode 100644 index 000000000..d926e4474 --- /dev/null +++ b/tools/skilldbconverter.php @@ -0,0 +1,1201 @@ +<?php +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* _ _ _ +* | | | | | | +* | |_| | ___ _ __ ___ _ _| | ___ ___ +* | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +* | | | | __/ | | (__| |_| | | __/\__ \ +* \_| |_/\___|_| \___|\__,_|_|\___||___/ +* +* * * * * * * * * * * * * * License * * * * * * * * * * * * * * * * * * * * * * +* This file is part of Hercules. +* http://herc.ws - http://github.com/HerculesWS/Hercules +* +* Copyright (C) 2016- Smokexyz/Hercules Dev Team +* +* Hercules is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* Credits : Smokexyz */ + +// Credits before anything else. +printcredits(); + +if(!isset($argv[1])) + gethelp(); + +function issetarg($arg) { + global $argv; + for($i=1; $i<sizeof($argv); $i++) { + if(strncmp($argv[$i],$arg,strlen($arg)) == 0) + return $i; + } + return 0; +} + +$renewal = (issetarg("-re") || issetarg("--renewal")); +$prere = (issetarg("-pre-re") || issetarg("--pre-renewal")); +$constants = (!issetarg("-itid") && !issetarg("--use-itemid")); +$help = (issetarg("-h") || issetarg("--help")); +$directory = function() use($argv) { + $arg = issetarg("--directory")?issetarg("--directory"):(issetarg("-dir")?issetarg("-dir"):0); + if ($arg) { + $part = explode("=", $argv[$arg]); + if(!isset($part[1])) { + die("A directory path was not provided!\n"); + } else if(!is_dir($part[1])) { + die("The given directory ".$part[1]." doesn't exist.\n"); + } else { + return $part[1]; + } + } +}; + +$dir = $directory(); + +if ($dir) { + print "Read/Write Directory has been set to '".$dir."'\n"; + print "Please ensure all skill_db TXT files are placed in this path.\n"; + print "Please also provide the correct version of the database (re/pre-re).\n"; + define('DIRPATH', $dir); +} + +$debug = (issetarg("-dbg") || issetarg("--with-debug")); + +if ($debug) { + print "\033[0mDebug Mode Enabled.\n"; + $t_init = microtime_float(); +} + +if($help || (!$renewal && !$prere) || ($renewal && $prere)) { + gethelp(); +} + +if ($renewal) { + print "Renewal enabled.\n"; + print "skill_db.txt and associated files (cast, nocastdex, require & unit) will be converted.\n"; + if(!defined('DIRPATH')) + define('DIRPATH', '../db/re/'); + define('RENEWAL', true); +} else if ($prere) { + print "Pre-Renewal enabled.\n"; + print "skill_db.txt and associated files (cast, nocastdex, require & unit) will be converted.\n"; + if(!defined('DIRPATH')) + define('DIRPATH', '../db/pre-re/'); +} + +// check for existence of files. + +$file_check = [ + DIRPATH."skill_require_db.txt", + DIRPATH."skill_cast_db.txt", + DIRPATH."skill_castnodex_db.txt", + DIRPATH."skill_unit_db.txt", + DIRPATH."skill_db.txt" +]; + +if($constants) array_push($file_check, DIRPATH."item_db.conf"); + +foreach($file_check as $file) { + if(file_exists($file)) + print $file." - Found\n"; + else + die($file." - Not Found!\n"); +} + +if ($constants) { + print "Using of Item Constants : enabled\n"; +} else { + print "Using of Item Constants : disabled.\n"; +} + +/* Begin the Loading of Files */ + +$i=0; +$file="skill_require_db.txt"; +$requiredb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +print "Reading '".DIRPATH.$file."' ...\n"; +while(!feof($requiredb)) +{ + $line = fgets($requiredb); + if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue; + $line = strstr(preg_replace('/\s+/','',$line), "//", true); + $arr = explode(",", $line); + if(!isset($arr[0])) continue; + $skreq['ID'][$i] = $arr[0]; + $skreq['HPCost'][$i] = $arr[1]; + $skreq['MaxHPTrigger'][$i] = $arr[2]; + $skreq['SPCost'][$i] = $arr[3]; + $skreq['HPRateCost'][$i] = $arr[4]; + $skreq['SPRateCost'][$i] = $arr[5]; + $skreq['ZenyCost'][$i] = $arr[6]; + $skreq['Weapons'][$i] = $arr[7]; + $skreq['AmmoTypes'][$i] = $arr[8]; + $skreq['AmmoAmount'][$i] = $arr[9]; + $skreq['State'][$i] = $arr[10]; + $skreq['SpiritSphere'][$i] = $arr[11]; + $k=0; + for($j=12; $j<=31; $j+=2) { + $skreqit['ItemId'][$i][$k] = isset($arr[$j])?$arr[$j]:0; + $skreqit['Amount'][$i][$k] = isset($arr[$j+1])?$arr[$j+1]:0; + $k++; + } + $i++; +} +if ($debug) { + print "[Debug] Read require_db Memory: ".print_mem()."\n"; +} +fclose($requiredb); + +$file="skill_cast_db.txt"; +$skillcastdb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +print "Reading '".DIRPATH.$file."' ...\n"; +$i=0; +while(!feof($skillcastdb)) +{ + $line = fgets($skillcastdb); + if (substr($line, 0, 2) == "//" || strlen($line) < 10) continue; + $arr = explode(",",$line); + if (!isset($arr[0])) continue; + $skcast["ID"][$i] = $arr[0]; // SkillCastDBId + $skcast["casttime"][$i] = $arr[1]; + $skcast["actdelay"][$i] = $arr[2]; + $skcast["walkdelay"][$i] = $arr[3]; + $skcast["data1"][$i] = $arr[4]; + $skcast["data2"][$i] = $arr[5]; + $skcast["cooldown"][$i] = $arr[6]; + if(defined('RENEWAL')) $skcast["fixedcast"][$i] = $arr[7]; + + $i++; +} +if($debug) { + print "[Debug] Read cast_db Memory: ".print_mem()."\n"; +} +fclose($skillcastdb); + +$file="skill_castnodex_db.txt"; +$castnodex = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +print "Reading '".DIRPATH.$file."' ...\n"; +$i=0; +while(!feof($castnodex)) +{ + $line = fgets($castnodex); + if(substr($line, 0, 2) == "//" || strlen($line) <= 2) continue; + $line = strstr(preg_replace('/\s+/','',$line), "//", true); + $arr = explode(",",$line); + $sknodex["ID"][$i] = $arr[0]; + $sknodex["cast"][$i] = isset($arr[1])?$arr[1]:0; + $sknodex["delay"][$i] = isset($arr[2])?$arr[2]:0; + $i++; +} +if($debug) { + print "[Debug] Read cast_nodex Memory: ".print_mem()."\n"; +} +fclose($castnodex); + +/*** +* Read item_db.conf to gather aegis item name informations. +*/ +if ($constants) { + $itemdb[] = array(); + + $file = "item_db.conf"; + if(file_exists(DIRPATH.$file)) { + $itemconf = fopen(DIRPATH.$file, "r") or die ("Unable to open '".DIRPATH.$file."'.\n"); + print "Reading '".DIRPATH.$file."' ...\n"; + + $started = false; + $i=0; + while(!feof($itemconf)) { + $line = fgets($itemconf); + $line = trim($line); + if(strcmp($line,"{\n")) + $started = true; + else if (strcmp($line,"},\n")) + $started = false; + //echo str_replace(" ","",$line)."\n"; + + if($started == true) { + $p = explode(":", $line); + if(isset($p[0])) { + if($p[0] == "Id") { + //echo $p[0]." ".(isset($p[1])?$p[1]:NULL)."\n"; + $itemdb['ID'][$i] = intval($p[1]); + } + if($p[0] == "AegisName") { + //echo $p[0]." ".(isset($p[1])?str_replace("\"","",$p[1]):NULL)."\n"; + $itemdb['name'][$i] = str_replace("\"","",$p[1]); + $i++; + } + } + } + } + if($debug) { + print "[Debug] Read item_db Memory: ".print_mem()."\n"; + } + fclose($itemconf); + } else { + print "Unable to open '".DIRPATH.$file."'... defaulting to using Item ID's instead of Constants.\n"; + $constants = false; + } +} + +/* * * +* Bring forth the contents of skill_unit_db.txt and store them. +*/ +$i=0; +$file="skill_unit_db.txt"; +$unitdb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +print "Reading '".DIRPATH.$file."' ...\n"; +while(!feof($unitdb)) { + $line = fgets($unitdb); + if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue; + $line = strstr(preg_replace('/\s+/','',$line), "//", true); + $arr = explode(",",$line); + $skunit['ID'][$i] = $arr[0]; + $skunit['UnitID'][$i] = $arr[1]; + $skunit['UnitID2'][$i] = $arr[2]; + $skunit['Layout'][$i] = $arr[3]; + $skunit['Range'][$i] = $arr[4]; + $skunit['Interval'][$i] = $arr[5]; + $skunit['Target'][$i] = $arr[6]; + $skunit['Flag'][$i] = hexdec($arr[7]); + $i++; +} +if($debug) { + print "[Debug] Read unit_db Memory: ".print_mem()."\n"; +} +fclose($unitdb); + +$putsk = ""; // initialize variable for file_put_contents. +// Publish all comments +$putsk .= getcomments((defined('RENEWAL')?true:false)); + +$putsk .= "skill_db: (\n"; +// Get Main Skilldb File +$file="skill_db.txt"; +$skmain = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +print "Reading '".DIRPATH.$file."' ...\n"; +$linecount = 0; + +// Get Number of entries +while(!feof($skmain)) { + $line = fgets($skmain); + if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue; + $linecount++; +} +if($debug) { + print "[Debug] Read skill_db Memory: ".print_mem()."\n"; +} +fclose($skmain); +print $linecount." entries found in skill_db.txt.\n"; + +$i=0; +$skmain = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n"); +// Begin converting process. +$max_level = 10; +$max_items = 10; +while(!feof($skmain)) { + $line = fgets($skmain); + if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue; + $arr = explode(",", $line); + // id,range,hit,inf,element,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count,name,description + $id = $arr[0]; + $range = $arr[1]; + $hit = $arr[2]; + $inf = $arr[3]; + $element = $arr[4]; + $nk = $arr[5]; + $splash = $arr[6]; + $max = $arr[7]; + $max = ($max < 1) ? 1 : $max; + $list_num = $arr[8]; + $castcancel = $arr[9]; + $cast_defence_rate = $arr[10]; + $inf2 = $arr[11]; + $maxcount = $arr[12]; + $skill_type = $arr[13]; + $blow_count = $arr[14]; + $name = $arr[15]; + if(strlen(substr($arr[16], 0, strpos($arr[16], "//")))) + $description = substr($arr[16], 0, strpos($arr[16], "//")); + else + $description = $arr[16]; + + $putsk .= "{\n". + "\tId: ".$id."\n". + "\tName: \"".trim($name)."\"\n". + "\tDescription: \"".trim($description)."\"\n". + "\tMaxLevel: ".$max."\n"; + if($range) $putsk .= "\tRange: ".leveled_guessfill($range, $max_level, $id)."\n"; + if($hit==8) $putsk .= "\tHit: \"BDT_MULTIHIT\"\n"; + else if($hit==6) $putsk .= "\tHit: \"BDT_SKILL\"\n"; + if($inf) $putsk .= "\tSkillType: ".getinf($inf)."\n"; + if($inf2) $putsk .= "\tSkillInfo: ".getinf2($inf2)."\n"; + if($skill_type != "none") $putsk .= "\tAttackType: \"".ucfirst($skill_type)."\"\n"; + if($element) $putsk .= "\tElement: ".leveled_ele($element, $max_level, $id)."\n"; + if($nk && $nk != "0x0") $putsk .= "\tDamageType: ".getnk($nk)."\n"; + if($splash) $putsk .= "\tSplashRange: ".leveled_guessfill($splash, $max_level, $id)."\n"; + if($list_num != "1") $putsk .= "\tNumberOfHits: ".leveled_guessfill($list_num, $max_level, $id)."\n"; + if($castcancel == "yes") $putsk .= "\tInterruptCast: true\n"; + if($cast_defence_rate) $putsk .= "\tCastDefRate: ".$cast_defence_rate."\n"; + if($maxcount) $putsk .= "\tSkillInstances: ".leveled_guessfill($maxcount, $max_level, $id)."\n"; + if($blow_count) $putsk .= "\tKnockBackTiles: ".leveled_guessfill($blow_count, $max_level, $id)."\n"; + // Cast Db + $key = array_search($id, $skcast['ID']); + if($key !== FALSE) { + if($skcast['casttime'][$key]) $putsk .= "\tCastTime: ".leveled_guessfill($skcast['casttime'][$key], $max_level, $id)."\n"; + if($skcast['actdelay'][$key]) $putsk .= "\tAfterCastActDelay: ".leveled_guessfill($skcast['actdelay'][$key], $max_level, $id)."\n"; + if($skcast['walkdelay'][$key] !== '0') $putsk .= "\tAfterCastWalkDelay: ".leveled_guessfill($skcast['walkdelay'][$key], $max_level, $id)."\n"; + if($skcast['data1'][$key] !== '0') $putsk .= "\tSkillData1: ".leveled_guessfill($skcast['data1'][$key], $max_level, $id)."\n"; + if($skcast['data2'][$key] !== '0') $putsk .= "\tSkillData2: ".leveled_guessfill($skcast['data2'][$key], $max_level, $id)."\n"; + if($skcast['cooldown'][$key] !== '0') $putsk .= "\tCoolDown: ".leveled_guessfill($skcast['cooldown'][$key], $max_level, $id)."\n"; + if(defined('RENEWAL') && strlen($skcast['fixedcast'][$key]) > 1 && $skcast['fixedcast'][$key] !== '0') + $putsk .= "\tFixedCastTime: ".leveled_guessfill($skcast['fixedcast'][$key], $max_level, $id)."\n"; + } + // Cast NoDex + unset($key); + $key = array_search($id, $sknodex['ID']); + if($key !== FALSE) { + if (isset($sknodex["cast"][$key]) && $sknodex["cast"][$key] != 0) $putsk .= "\tCastTimeOptions: ".getnocast($sknodex["cast"][$key], $id)."\n"; + if (isset($sknodex["delay"][$key]) && $sknodex["delay"][$key] != 0) $putsk .= "\tSkillDelayOptions: ".getnocast($sknodex["delay"][$key], $id)."\n"; + unset($sknodex["ID"][$key]); + unset($sknodex["cast"][$key]); + unset($sknodex["delay"][$key]); + } + + // require DB + unset($key); + $key = array_search($id, $skreq['ID']); + if($key !== FALSE) { + $putsk .= "\tRequirements: {\n"; + if ($skreq['HPCost'][$key]) $putsk .= "\t\tHPCost: ".leveled_guessfill($skreq['HPCost'][$key], $max_level, $id, 1)."\n"; + if ($skreq['SPCost'][$key]) $putsk .= "\t\tSPCost: ".leveled_guessfill($skreq['SPCost'][$key], $max_level, $id, 1)."\n"; + if ($skreq['HPRateCost'][$key]) $putsk .= "\t\tHPRateCost: ".leveled_guessfill($skreq['HPRateCost'][$key], $max_level, $id, 1)."\n"; + if ($skreq['SPRateCost'][$key]) $putsk .= "\t\tSPRateCost: ".leveled_guessfill($skreq['SPRateCost'][$key], $max_level, $id, 1)."\n"; + if ($skreq['ZenyCost'][$key]) $putsk .= "\t\tZenyCost: ".leveled_guessfill($skreq['ZenyCost'][$key], $max_level, $id, 1)."\n"; + if ($skreq['Weapons'][$key] != 99) $putsk .= "\t\tWeaponTypes: ".getweapontypes($skreq['Weapons'][$key], $id)."\n"; + if ($skreq['AmmoTypes'][$key] == 99) $putsk .= "\t\tAmmoTypes: \"All\"\n"; + else if ($skreq['AmmoTypes'][$key]) $putsk .= "\t\tAmmoTypes: ".getammotypes($skreq['AmmoTypes'][$key], $id)."\n"; + if ($skreq['AmmoAmount'][$key]) $putsk .= "\t\tAmmoAmount: ".leveled_guessfill($skreq['AmmoAmount'][$key], $max_level, $id, 1)."\n"; + if ($skreq['State'][$key] != "none" && $skreq['State'][$key]) $putsk .= "\t\tState: \"".getstate($skreq['State'][$key],$id)."\"\n"; + if ($skreq['SpiritSphere'][$key]) $putsk .= "\t\tSpiritSphereCost: ".leveled_guessfill($skreq['SpiritSphere'][$key], $max_level, $id, 1)."\n"; + if ($skreqit['ItemId'][$key][0] > 0) { + $putsk .= "\t\tItems: {\n"; + for ($index=0; $index<sizeof($skreqit['ItemId'][$key]); $index++) { + $itemID = $skreqit['ItemId'][$key][$index]; // Required Item + $itemamt = $skreqit['Amount'][$key][$index]; // Required Amount + + if (strpos($itemID, ':') == true) { + $items = explode(":", $itemID); + $it = 0; + while (isset($items) && isset($items[$it])) { + if ($constants && $itemID) { + $itkey = array_search($items[$it], $itemdb['ID']); + if($itkey === FALSE) + $itemname = "ID".$items[$it]; + else + $itemname = $itemdb['name'][$itkey]; + $putsk .= "\t\t\t".trim($itemname).": ".leveled($itemamt, $max_level, $id, 2)."\n"; + } else if (intval($itemID)) { + $putsk .= "\t\t\tID".$items[$it].": ".leveled($itemamt, $max_level, $id, 2)."\n"; + } + $it++; + } + } else { + if ($constants && $itemID) { + $itkey = array_search($skreqit['ItemId'][$key][$index], $itemdb['ID']); + if($itkey === FALSE) + $itemname = "ID".$itemID; + else + $itemname = $itemdb['name'][$itkey]; + $putsk .= "\t\t\t".trim($itemname).": ".leveled($itemamt, $max_items, $id, 2)."\n"; + } else if ($itemID) { + $putsk .= "\t\t\tID".$itemID.": ".leveled($itemamt, $max_items, $id, 2)."\n"; + } + } + } + $putsk .= "\t\t}\n"; + } + $putsk .= "\t}\n"; + } + + unset($key); + $key = array_search($id, $skunit['ID']); + if($key !== FALSE) { + $putsk .= "\tUnit: {\n"; + if(isset($skunit['UnitID'][$key])) { + if(isset($skunit['UnitID2'][$key]) && strlen($skunit['UnitID2'][$key])) { + $putsk .= "\t\tId: [ ".$skunit['UnitID'][$key].", ".$skunit['UnitID2'][$key]." ]\n"; + } else $putsk .= "\t\tId: ".$skunit['UnitID'][$key]."\n"; + } + if(isset($skunit['Layout'][$key]) && $skunit['Layout'][$key] != 0) $putsk .= "\t\tLayout: ".leveled_guessfill($skunit['Layout'][$key], $max_level, $id, 1)."\n"; + if(isset($skunit['Range'][$key]) && $skunit['Range'][$key] != 0) $putsk .= "\t\tRange: ".leveled_guessfill($skunit['Range'][$key], $max_level, $id, 1)."\n"; +# if(isset($skunit['Interval'][$key])) $putsk .= "\t\tInterval: ".leveled_guessfill($skunit['Interval'][$key], $max_level, $id, 1)."\n"; +# in memory present space only for one interval, but in old db intervals present for each level + if(isset($skunit['Interval'][$key])) $putsk .= "\t\tInterval: ".intval($skunit['Interval'][$key])."\n"; + if(isset($skunit['Target'][$key]) && $skunit['Target'][$key] != "noone") $putsk .= "\t\tTarget: \"".trim(ucfirst($skunit['Target'][$key]))."\"\n"; + if(isset($skunit['Flag'][$key]) && $skunit['Flag'][$key] != "") { + $putsk .= "\t\tFlag: ".getunitflag($skunit['Flag'][$key], $id)."\n"; + } + $putsk .= "\t}\n"; + } + // close skill + $putsk .= "},\n"; + // Display progress bar + show_status($i++, $linecount); +} +show_status($linecount, $linecount); +/** + * Print final messages and exit the script, conversion has completed. + */ +print "\n"; +print "The skill database has been successfully converted to Hercules' libconfig\n"; +print "format and has been saved as '".DIRPATH."skill_db.conf'.\n"; +print "The following files are now deprecated and can be deleted -\n"; +print DIRPATH."skill_db.txt\n"; +print DIRPATH."skill_cast_db.txt\n"; +print DIRPATH."skill_castnodex_db.txt\n"; +print DIRPATH."skill_require_db.txt\n"; +print DIRPATH."skill_unit_db.txt\n"; +$putsk .= ")"; +$skconf = "skill_db.conf"; +file_put_contents(DIRPATH.$skconf, $putsk); +if($debug) { + print "[Debug] Memory after converting: ".print_mem()."\n"; + print "[Debug] Execution Time : ".(microtime_float()-$t_init)."s\n"; +} +fclose($skmain); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Functions +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +function microtime_float() +{ + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); +} + +function show_status($done, $total) { + $perc = floor(($done / $total) * 100); + $perc = floor($perc/2); + $left = 50-$perc; + $finalperc = $perc * 2; + $write = sprintf("[%'={$perc}s>%-{$left}s] - $finalperc%% - $done/$total\r", "", ""); + fwrite(STDERR, $write); +} +function get_element($ele,$id) +{ + switch($ele) + { + case -1: return "Ele_Weapon"; + case -2: return "Ele_Endowed"; + case -3: return "Ele_Random"; + case 0: return "Ele_Neutral"; + case 1: return "Ele_Water"; + case 2: return "Ele_Earth"; + case 3: return "Ele_Fire"; + case 4: return "Ele_Wind"; + case 5: return "Ele_Poison"; + case 6: return "Ele_Holy"; + case 7: return "Ele_Dark"; + case 8: return "Ele_Ghost"; + case 9: return "Ele_Undead"; + default: print "\rWarningUnknown Element ".$ele." provided for skill Id ".$id."\n"; + } + + return NULL; +} +function leveled_ele($str, $max, $skill_id) +{ + if(strpos($str, ':') == true) + { + $lvs = explode(":", $str); + $retval = "{\n"; + for($i = 0; $i < $max && isset($lvs[$i]); $i++) { + $retval .= "\t\tLv".($i+1).": \"".get_element($lvs[$i],$skill_id)."\"\n"; + } + $retval .= "\t}"; + } else { + $retval = "\"".get_element($str,$skill_id)."\""; + } + + return $retval; +} + +function leveled($str, $max, $id, $tab=0) +{ + switch($tab) { + case 1: + $ittab = "\t\t\t"; + $endtab = "\t\t"; + break; + case 2: + $ittab = "\t\t\t\t"; + $endtab = "\t\t\t"; + break; + default: + $ittab = "\t\t"; + $endtab = "\t"; + break; + } + + $retval = ""; + if(strpos($str, ':') == true) { + $lvs = explode(":", trim($str)); + $retval = "{\n"; + for ($i = 0; $i < $max && isset($lvs[$i]); $i++) { + $retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n"; + } + $retval .= $endtab."}"; + } else { + $retval = intval($str); + } + + return $retval; +} + +function leveled_guessfill($str, $max, $id, $tab=0) +{ + switch($tab) { + case 1: + $ittab = "\t\t\t"; + $endtab = "\t\t"; + break; + case 2: + $ittab = "\t\t\t\t"; + $endtab = "\t\t\t"; + break; + default: + $ittab = "\t\t"; + $endtab = "\t"; + break; + } + + $retval = ""; + if(strpos($str, ':') == true) { + $lvs = explode(":", trim($str)); + $retval = "{\n"; + for ($i = 0; $i < $max && isset($lvs[$i]); $i++) { + $retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n"; + } + if ($i < $max) { + /* Algorithm borrowed from skill_split_atoi(), as used by the old parser */ + for ($step = 1; $step <= $i/2; $step++) { + $diff = $lvs[$i - 1] - $lvs[$i - $step - 1]; + for ($j = $i - 1; $j >= $step; $j--) + if ($lvs[$j] - $lvs[$j - $step] != $diff) + break; + + if ($j >= $step) //No match, try next step. + continue; + + for(; $i < $max; $i++) { //Apply linear increase + $lvs[$i] = $lvs[$i - $step] + $diff; + if ($lvs[$i] < 1 && $lvs[$i - 1] >= 0) { + //Check if we have switched from + to -, cap the decrease to 0 in said cases. + $lvs[$i] = 1; + $diff = 0; + $step = 1; + } + $retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n"; + } + $retval .= $endtab."}"; + return $retval; + } + //Okay.. we can't figure this one out, just fill out the stuff with the previous value. + for (; $i < $max; $i++) { + $lvs[$i] = $lvs[$i - 1]; + $retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n"; + } + } + $retval .= $endtab."}"; + } else { + $retval = intval($str); + } + + return $retval; +} + +function getstate($state,$id) +{ + if( strcmp($state,"hiding") == 0 ) return "Hiding"; + else if( strcmp($state,"cloaking") == 0 ) return "Cloaking"; + else if( strcmp($state,"hidden") == 0 ) return "Hidden"; + else if( strcmp($state,"riding") == 0 ) return "Riding"; + else if( strcmp($state,"falcon") == 0 ) return "Falcon"; + else if( strcmp($state,"cart") == 0 ) return "Cart"; + else if( strcmp($state,"shield") == 0 ) return "Shield"; + else if( strcmp($state,"sight") == 0 ) return "Sight"; + else if( strcmp($state,"explosionspirits") == 0 ) return "ExplosionSpirits"; + else if( strcmp($state,"cartboost") == 0 ) return "CartBoost"; + else if( strcmp($state,"recover_weight_rate") == 0 ) return "NotOverWeight"; + else if( strcmp($state,"move_enable") == 0 ) return "Moveable"; + else if( strcmp($state,"water") == 0 ) return "InWater"; + else if( strcmp($state,"dragon") == 0 ) return "Dragon"; + else if( strcmp($state,"warg") == 0 ) return "Warg"; + else if( strcmp($state,"ridingwarg") == 0 ) return "RidingWarg"; + else if( strcmp($state,"mado") == 0 ) return "MadoGear"; + else if( strcmp($state,"elementalspirit") == 0 ) return "ElementalSpirit"; + else if( strcmp($state,"poisonweapon") == 0 ) return "PoisonWeapon"; + else if( strcmp($state,"rollingcutter") == 0 ) return "RollingCutter"; + else if( strcmp($state,"mh_fighting") == 0 ) return "MH_Fighting"; + else if( strcmp($state,"mh_grappling") == 0 ) return "MH_Grappling"; + else if( strcmp($state,"peco") == 0 ) return "Peco"; + else print "\rWarning - Invalid State ".$state." provided for Skill ID ".$id.", please correct this manually.\n"; +} + +function getinf($inf) +{ + $bitmask = array( + "Passive" => 0, + "Enemy" => 1, + "Place" => 2, + "Self" => 4, + "Friend" => 16, + "Trap" => 32, + ); + + $retval = "{\n"; + foreach ($bitmask as $key => $val) + { + if($inf&$val) + $retval .= "\t\t".$key.": true\n"; + } + $retval .= "\t}"; + + return $retval; +} + +function getinf2($inf2=0x0000) +{ + $bitmask = array( + "Quest" => intval(0x0001), // = quest skill + "NPC" => intval(0x0002), // = npc skill + "Wedding" => intval(0x0004), // = wedding skill + "Spirit" => intval(0x0008), // = spirit skill + "Guild" => intval(0x0010), // = guild skill + "Song" => intval(0x0020), // = song/dance + "Ensemble" => intval(0x0040), // = ensemble skill + "Trap" => intval(0x0080), // = trap + "TargetSelf" => intval(0x0100), // = skill that damages/targets yourself + "NoCastSelf" => intval(0x0200), // = cannot be casted on self (if inf = 4, auto-select target skill) + "PartyOnly" => intval(0x0400), // = usable only on party-members (and enemies if skill is offensive) + "GuildOnly" => intval(0x0800), // = usable only on guild-mates (and enemies if skill is offensive) + "NoEnemy" => intval(0x1000), // = disable usage on enemies (for non-offensive skills). + "IgnoreLandProtector" => intval(0x2000), // = skill ignores land protector (e.g. arrow shower) + "Chorus" => intval(0x4000) // = chorus skill + ); + + $inf2 = intval(substr($inf2, 2),16); + + $retval = "{\n"; + foreach($bitmask as $key => $val) { + if($inf2&$val) { + $retval .= "\t\t".$key.": true\n"; + } + } + $retval .= "\t}"; + + return $retval; +} + +function getnk($nk) +{ + $bitmask = array( + "NoDamage" => intval(0x01), //- No damage skill + "SplashArea" => intval(0x02), //- Has splash area (requires source modification) + "SplitDamage" => intval(0x04), //- Damage should be split among targets (requires 0x02 in order to work) + "IgnoreCards" => intval(0x08), //- Skill ignores caster's % damage cards (misc type always ignores) + "IgnoreElement" => intval(0x10), //- Skill ignores elemental adjustments + "IgnoreDefense" => intval(0x20), //- Skill ignores target's defense (misc type always ignores) + "IgnoreFlee" => intval(0x40), //- Skill ignores target's flee (magic type always ignores) + "IgnoreDefCards" => intval(0x80) //- Skill ignores target's def cards + ); + $nk = intval($nk,16); + $retval = "{\n"; + foreach($bitmask as $key => $val) { + if($nk&$val) { + $retval .= "\t\t".$key.": true\n"; + } + } + $retval .= "\t}"; + + return $retval; +} + +function getnocast($opt, $id) +{ + $bitmask = array( + 'Default' => 0, //- everything affects the skill's cast time + 'IgnoreDex' => 1, //- skill's cast time is not affected by dex + 'IgnoreStatusEffect' => 2, //- skill's cast time is not affected by statuses (Suffragium, etc) + 'IgnoreItemBonus' => 4 //- skill's cast time is not affected by item bonuses (equip, cards) + ); + + if($opt > array_sum($bitmask) || $opt < 0) + print "\rWarning - a bitmask for CastNoDex entry for skill ID ".$id." is higher than total of masks or lower than 0."; + + $retval = "{\n"; + foreach($bitmask as $key => $val) { + if($opt&$val) { + $retval .= "\t\t".$key.": true\n"; + } + } + $retval .= "\t}"; + + return $retval; +} + +function getweapontypes($list, $id) +{ + $bitmask = array( + 0 => "NoWeapon", + 1 => "Daggers", + 2 => "1HSwords", + 3 => "2HSwords", + 4 => "1HSpears", + 5 => "2HSpears", + 6 => "1HAxes", + 7 => "2HAxes", + 8 => "Maces", + 9 => "2HMaces", + 10 => "Staves", + 11 => "Bows", + 12 => "Knuckles", + 13 => "Instruments", + 14 => "Whips", + 15 => "Books", + 16 => "Katars", + 17 => "Revolvers", + 18 => "Rifles", + 19 => "GatlingGuns", + 20 => "Shotguns", + 21 => "GrenadeLaunchers", + 22 => "FuumaShurikens", + 23 => "2HStaves", + 24 => "MaxSingleWeaponType", + 25 => "DWDaggers", + 26 => "DWSwords", + 27 => "DWAxes", + 28 => "DWDaggerSword", + 29 => "DWDaggerAxe", + 30 => "DWSwordAxe", + ); + if(strpos($list, ':') == true) { + $type = explode(":", $list); + $wmask = 0; + for($i=0; $i<sizeof($type); $i++) { + $wmask |= 1<<$type[$i]; + if($type[$i] > 30 || $type[$i] < 0) + print "\rWarning - Invalid weapon type ".$i." for skill ID ".$id."\n"; + } + $retval = "{\n"; + for($j=0; $j<sizeof($type); $j++) { + if($wmask&1<<$type[$j]) + $retval .= "\t\t\t".$bitmask[$type[$j]].": true\n"; + } + $retval .= "\t\t}"; + } else { + $retval = "{\n"; + $retval .= "\t\t\t".$bitmask[$list].": true\n"; + $retval .= "\t\t}"; + } + + return $retval; +} + +function getammotypes($list, $id) { + $bitmask = array( + 1 => "A_ARROW", + 2 => "A_DAGGER", + 3 => "A_BULLET", + 4 => "A_SHELL", + 5 => "A_GRENADE", + 6 => "A_SHURIKEN", + 7 => "A_KUNAI", + 8 => "A_CANNONBALL", + 9 => "A_THROWWEAPON" + ); + + if(strpos($list, ':') == true) { + $type = explode(":", $list); + $wmask = 0; + for($i=0; $i<sizeof($type); $i++) { + $wmask |= 1<<$type[$i]; + if($type[$i] > 9 || $type[$i] < 1) { + print "\rWarning - Invalid weapon type ".$i." for skill ID ".$id."\n"; + } + } + $retval = "{\n"; + for($j=0; $j<sizeof($type); $j++) { + if($wmask&1<<$type[$j]) { + $retval .= "\t\t\t".$bitmask[$type[$j]].": true\n"; + } + } + $retval .= "\t\t}"; + } else { + $retval = "{\n"; + $retval .= "\t\t\t".$bitmask[$list].": true\n"; + $retval .= "\t\t}"; + } + + return $retval; +} + +function getunitflag($flag, $id) +{ + $bitmask = array( + 'UF_DEFNOTENEMY' => intval(0x001), //0x001(UF_DEFNOTENEMY)If 'defunit_not_enemy' is set, the target is changed to 'friend' + 'UF_NOREITERATION' => intval(0x002), //0x002(UF_NOREITERATION)Spell cannot be stacked + 'UF_NOFOOTSET' => intval(0x004), //0x004(UF_NOFOOTSET)Spell cannot be cast near/on targets + 'UF_NOOVERLAP' => intval(0x008), //0x008(UF_NOOVERLAP)Spell effects do not overlap + 'UF_PATHCHECK' => intval(0x010), //0x010(UF_PATHCHECK)Only cells with a shootable path will be placed + 'UF_NOPC' => intval(0x020), //0x020(UF_NOPC)Spell cannot affect players. + 'UF_NOMOB' => intval(0x040), //0x040(UF_NOMOB)Spell cannot affect mobs. + 'UF_SKILL' => intval(0x080), //0x080(UF_SKILL)Spell CAN affect skills. + 'UF_DANCE' => intval(0x100), //0x100(UF_DANCE)Dance skill + 'UF_ENSEMBLE' => intval(0x200), //0x200(UF_ENSEMBLE)Ensemble skill + 'UF_SONG' => intval(0x400), //0x400(UF_SONG)Song skill + 'UF_DUALMODE' => intval(0x800), //0x800(UF_DUALMODE)Spell has effects both at an interval and when you step in/out + 'UF_RANGEDSINGLEUNIT' => intval(0x2000) //0x2000(UF_RANGEDSINGLEUNIT)Layout hack, use layout range propriety but only display center. + ); + + $count = 0; + if($flag <= 0) return 0; + + $ret = "{\n"; + foreach($bitmask as $key => $val) { + if($flag&$val) { + $ret .= "\t\t\t".$key.": true\n"; + } + } + + if($flag > array_sum($bitmask)) + print "\rWarning - Invalid Unit Flag ".$flag." provided for skill Id ".$id."\n"; + + $ret .= "\t\t}"; + + return $ret; +} + +function print_mem() +{ + return convert(memory_get_usage(true)); +} + +function convert($size) +{ + $unit=array('b','kb','mb','gb','tb','pb'); + return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i]; +} + +function gethelp() +{ + print "Usage: php skilldbconverter.php [option]\n"; + print "Options:\n"; + print "\t-re [--renewal] for renewal skill database conversion.\n"; + print "\t-pre-re [--pre-renewal] for pre-renewal skill database conversion.\n"; + print "\t-itid [--use-itemid] to use item IDs instead of constants.\n"; + print "\t-dir [--directory] provide a custom directory.\n"; + print "\t (Must include the correct -pre-re/-re option)\n"; + print "\t-dbg [--with-debug] print debug information.\n"; + print "\t-h [--help] to display this help text.\n\n"; + print "----------------------- Additional Notes ----------------------\n"; + print "Important!\n"; + print "* Please be advised that either and only one of the arguments -re/-pre-re\n"; + print " must be specified on execution.\n"; + print "* When using the -dir option, -re/-pre-re options must be specified. \n"; + print "* This tool isn't designed to convert renewal data to pre-renewal.\n"; + print "* This tool should ideally be used from the 'tools/' folder, which can be found\n"; + print " in the root of your Hercules installation. This tool will not delete any files\n"; + print " from any of the directories that it reads from or prints to.\n\n"; + print "* Prior to using this tool, please ensure at least 30MB of free RAM.\n"; + print "----------------------- Usage Example -------------------------\n"; + print "- Renewal Conversion: php skilldbconverter.php --renewal\n"; + print "- Pre-renewal Conversion: php skilldbconverter.php --pre-renewal\n"; + print "----------------------------------------------------------------\n"; + exit; +} + +function printcredits() +{ + print " _ _ _ \n"; + print " | | | | | | \n"; + print " | |_| | ___ _ __ ___ _ _| | ___ ___ \n"; + print " | _ |/ _ \ '__/ __| | | | |/ _ \/ __|\n"; + print " | | | | __/ | | (__| |_| | | __/\__ \ \n"; + print " \_| |_/\___|_| \___|\__,_|_|\___||___/\n"; + print "Hercules Skill Database TXT to Libconfig Converter by Smokexyz\n"; + print "Copyright (C) 2016 Hercules\n"; + print "-----------------------------------------------\n\n"; +} + +function getcomments($re) +{ + return "//================= Hercules Database ========================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//================= License ==================================================== +//= This file is part of Hercules. +//= http://herc.ws - http://github.com/HerculesWS/Hercules +//= +//= Copyright (C) 2014-2016 Hercules Dev Team +//= +//= Hercules is free software: you can redistribute it and/or modify +//= it under the terms of the GNU General Public License as published by +//= the Free Software Foundation, either version 3 of the License, or +//= (at your option) any later version. +//= +//= This program is distributed in the hope that it will be useful, +//= but WITHOUT ANY WARRANTY; without even the implied warranty of +//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//= GNU General Public License for more details. +//= +//= You should have received a copy of the GNU General Public License +//= along with this program. If not, see <http://www.gnu.org/licenses/>. +//============================================================================== +//= ".($re?"Renewal":"Pre-Renewal")." Skill Database [Hercules] +//============================================================================== +//= @Format Notes: +//= - All string entries are case-sensitive and must be quoted. +//= - All setting names are case-sensitive and must be keyed accurately. + + +/****************************************************************************** +********************************* Entry structure ***************************** +******************************************************************************* +{ + // ------------------------------ Mandatory Fields ---------------------------- + Id: ID (int) (Required) + Name: \"Skill Name\" (string) (Required) + MaxLevel: Skill Level (int) (Required) + // ------------------------------ Optional Fields ----------------------------- + Description: \"Skill Description\" (string) (optional but recommended) + Range: Skill Range (int) (optional, defaults to 0) (can be grouped by Levels) + Note: Range < 5 is considered Melee range. + Hit: Hit Type (int) (optional, default \"BDT_NORMAL\") + Types - \"BDT_SKILL\", \"BDT_MULTIHIT\" or \"BDT_NORMAL\" + SkillType: { (bool, defaults to \"Passive\") + Passive: true/false (boolean, defaults to false) + Enemy: true/false (boolean, defaults to false) + Place: true/false (boolean, defaults to false) + Self: true/false (boolean, defaults to false) + Friend: true/false (boolean, defaults to false) + Trap: true/false (boolean, defaults to false) + } + SkillInfo: { (bool, defaults to \"None\") + Quest: true/false (boolean, defaults to false) + NPC: true/false (boolean, defaults to false) + Wedding: true/false (boolean, defaults to false) + Spirit: true/false (boolean, defaults to false) + Guild: true/false (boolean, defaults to false) + Song: true/false (boolean, defaults to false) + Ensemble: true/false (boolean, defaults to false) + Trap: true/false (boolean, defaults to false) + TargetSelf: true/false (boolean, defaults to false) + NoCastSelf: true/false (boolean, defaults to false) + PartyOnly: true/false (boolean, defaults to false) + GuildOnly: true/false (boolean, defaults to false) + NoEnemy: true/false (boolean, defaults to false) + IgnoreLandProtector: true/false (boolean, defaults to false) + Chorus: true/false (boolean, defaults to false) + FreeCastReduced: true/false (boolean, defaults to false) + Works like skill SA_FREECAST, allow move and attack with reduced speed. + FreeCastNormal: true/false (boolean, defaults to false) + Works like FreeCastReduced, but not reduce speed. + } + AttackType: \"Attack Type\" (string, defaults to \"None\") + Types: \"None\", \"Weapon\", \"Magic\" or \"Misc\" + Element: \"Element Type\" (string) (Optional field - Default \"Ele_Neutral\") + (can be grouped by Levels) + Types: \"Ele_Neutral\", \"Ele_Water\", \"Ele_Earth\", \"Ele_Fire\", \"Ele_Wind\" + \"Ele_Poison\", \"Ele_Holy\", \"Ele_Dark\", \"Ele_Ghost\", \"Ele_Undead\" + \"Ele_Weapon\" - Uses weapon's element. + \"Ele_Endowed\" - Uses Endowed element. + \"Ele_Random\" - Uses random element. + DamageType: { (bool, default to \"NoDamage\") + NoDamage: true/false No damage skill + SplashArea: true/false Has splash area (requires source modification) + SplitDamage: true/false Damage should be split among targets (requires 'SplashArea' in order to work) + IgnoreCards: true/false Skill ignores caster's % damage cards (misc type always ignores) + IgnoreElement: true/false Skill ignores elemental adjustments + IgnoreDefense: true/false Skill ignores target's defense (misc type always ignores) + IgnoreFlee: true/false Skill ignores target's flee (magic type always ignores) + IgnoreDefCards: true/false Skill ignores target's def cards + } + SplashRange: Damage Splash Area (int, defaults to 0) (can be grouped by Levels) + Note: -1 for screen-wide. + NumberOfHits: Number of Hits (int, defaults to 1) (can be grouped by Levels) + Note: when positive, damage is increased by hits, + negative values just show number of hits without + increasing total damage. + InterruptCast: Cast Interruption (bool, defaults to false) + CastDefRate: Cast Defense Reduction (int, defaults to 0) + SkillInstances: Skill instances (int, defaults to 0) (can be grouped by Levels) + Notes: max amount of skill instances to place on the ground when + player_land_skill_limit/monster_land_skill_limit is enabled. For skills + that attack using a path, this is the path length to be used. + KnockBackTiles: Knock-back by 'n' Tiles (int, defaults to 0) (can be grouped by Levels) + CastTime: Skill cast Time (in ms) (int, defaults to 0) (can be grouped by Levels) + AfterCastActDelay: Skill Delay (in ms) (int, defaults to 0) (can be grouped by Levels) + AfterCastWalkDelay: Walk Delay (in ms) (int, defaults to 0) (can be grouped by Levels) + SkillData1: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels) + SkillData2: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels) + CoolDown: Skill Cooldown (in ms) (int, defaults to 0) (can be grouped by Levels) + ".($re? + "FixedCastTime: Fixed Cast Time (in ms) (int, defaults to 0) (can be grouped by Levels) + Note: when 0, uses 20% of cast time and less than + 0 means no fixed cast time.":"")." + CastTimeOptions: { + IgnoreDex: true/false (boolean, defaults to false) + IgnoreStatusEffect: true/false (boolean, defaults to false) + IgnoreItemBonus: true/false (boolean, defaults to false) + Note: Delay setting 'IgnoreDex' only makes sense when + delay_dependon_dex is enabled. + } + SkillDelayOptions: { + IgnoreDex: true/false (boolean, defaults to false) + IgnoreStatusEffect: true/false (boolean, defaults to false) + IgnoreItemBonus: true/false (boolean, defaults to false) + Note: Delay setting 'IgnoreDex' only makes sense when + delay_dependon_dex is enabled. + } + Requirements: { + HPCost: HP Cost (int, defaults to 0) (can be grouped by Levels) + SPCost: SP Cost (int, defaults to 0) (can be grouped by Levels) + HPRateCost: HP % Cost (int, defaults to 0) (can be grouped by Levels) + Note: If positive, it is a percent of your current hp, + otherwise it is a percent of your max hp. + SPRateCost: SP % Cost (int, defaults to 0) (can be grouped by Levels) + Note: If positive, it is a percent of your current sp, + otherwise it is a percent of your max sp. + ZenyCost: Zeny Cost (int, defaults to 0) (can be grouped by Levels) + WeaponTypes: { (bool or string, defaults to \"All\") + NoWeapon: true/false (boolean, defaults to false) + Daggers: true/false (boolean, defaults to false) + 1HSwords: true/false (boolean, defaults to false) + 2HSwords: true/false (boolean, defaults to false) + 1HSpears: true/false (boolean, defaults to false) + 2HSpears: true/false (boolean, defaults to false) + 1HAxes: true/false (boolean, defaults to false) + 2HAxes: true/false (boolean, defaults to false) + Maces: true/false (boolean, defaults to false) + 2HMaces: true/false (boolean, defaults to false) + Staves: true/false (boolean, defaults to false) + Bows: true/false (boolean, defaults to false) + Knuckles: true/false (boolean, defaults to false) + Instruments: true/false (boolean, defaults to false) + Whips: true/false (boolean, defaults to false) + Books: true/false (boolean, defaults to false) + Katars: true/false (boolean, defaults to false) + Revolvers: true/false (boolean, defaults to false) + Rifles: true/false (boolean, defaults to false) + GatlingGuns: true/false (boolean, defaults to false) + Shotguns: true/false (boolean, defaults to false) + GrenadeLaunchers: true/false (boolean, defaults to false) + FuumaShurikens: true/false (boolean, defaults to false) + 2HStaves: true/false (boolean, defaults to false) + MaxSingleWeaponType: true/false (boolean, defaults to false) + DWDaggers: true/false (boolean, defaults to false) + DWSwords: true/false (boolean, defaults to false) + DWAxes: true/false (boolean, defaults to false) + DWDaggerSword: true/false (boolean, defaults to false) + DWDaggerAxe: true/false (boolean, defaults to false) + DWSwordAxe: true/false (boolean, defaults to false) + } + AmmoTypes: { (for all types use string \"All\") + A_ARROW: true/false (boolean, defaults to false) + A_DAGGER: true/false (boolean, defaults to false) + A_BULLET: true/false (boolean, defaults to false) + A_SHELL: true/false (boolean, defaults to false) + A_GRENADE: true/false (boolean, defaults to false) + A_SHURIKEN: true/false (boolean, defaults to false) + A_KUNAI: true/false (boolean, defaults to false) + A_CANNONBALL: true/false (boolean, defaults to false) + A_THROWWEAPON: true/false (boolean, defaults to false) + } + AmmoAmount: Ammunition Amount (int, defaults to 0) (can be grouped by Levels) + State: \"Required State\" (string, defaults to \"None\") (can be grouped by Levels) + Types : 'None' = Nothing special + 'Moveable' = Requires to be able to move + 'NotOverWeight' = Requires to be less than 50% weight + 'InWater' = Requires to be standing on a water cell + 'Cart' = Requires a Pushcart + 'Riding' = Requires to ride either a peco or a dragon + 'Falcon' = Requires a Falcon + 'Sight' = Requires Sight skill activated + 'Hiding' = Requires Hiding skill activated + 'Cloaking' = Requires Cloaking skill activated + 'ExplosionSpirits' = Requires Fury skill activated + 'CartBoost' = Requires a Pushcart and Cart Boost skill activated + 'Shield' = Requires a 0,shield equipped + 'Warg' = Requires a Warg + 'Dragon' = Requires to ride a Dragon + 'RidingWarg' = Requires to ride a Warg + 'Mado' = Requires to have an active mado + 'PoisonWeapon' = Requires to be under Poisoning Weapon. + 'RollingCutter' = Requires at least one Rotation Counter from Rolling Cutter. + 'ElementalSpirit' = Requires to have an Elemental Spirit summoned. + 'MH_Fighting' = Requires Eleanor fighthing mode + 'MH_Grappling' = Requires Eleanor grappling mode + 'Peco' = Requires riding a peco + SpiritSphereCost: Spirit Sphere Cost (int, defaults to 0) (can be grouped by Levels) + Items: { + ItemID or Aegis_Name : Amount (int, defaults to 0) (can be grouped by Levels) + Item example: \"ID717\" or \"Blue_Gemstone\". + Notes: Items with amount 0 will not be consumed. + Amount can also be grouped by levels. + } + } + Unit: { + Id: [ UnitID, UnitID2 ] (int, defaults to 0) (can be grouped by Levels) + Layout: Unit Layout (int, defaults to 0) (can be grouped by Levels) + Range: Unit Range (int, defaults to 0) (can be grouped by Levels) + Interval: Unit Interval (int, defaults to 0) (can be grouped by Levels) + Target: \"Unit Target\" (string, defaults to \"None\") + Types: + All - affects everyone + NotEnemy - affects anyone who isn't an enemy + Friend - affects party, guildmates and neutral players + Party - affects party only + Guild - affects guild only + Ally - affects party and guildmates only + Sameguild - affects guild but not allies + Enemy - affects enemies only + None - affects nobody + Flag: { + UF_DEFNOTENEMY: true/false (boolean, defaults to false) + UF_NOREITERATION: true/false (boolean, defaults to false) + UF_NOFOOTSET: true/false (boolean, defaults to false) + UF_NOOVERLAP: true/false (boolean, defaults to false) + UF_PATHCHECK: true/false (boolean, defaults to false) + UF_NOPC: true/false (boolean, defaults to false) + UF_NOMOB: true/false (boolean, defaults to false) + UF_SKILL: true/false (boolean, defaults to false) + UF_DANCE: true/false (boolean, defaults to false) + UF_ENSEMBLE: true/false (boolean, defaults to false) + UF_SONG: true/false (boolean, defaults to false) + UF_DUALMODE: true/false (boolean, defaults to false) + UF_RANGEDSINGLEUNI: true/false (boolean, defaults to false) + } + } +} +* This file has been generated by Smokexyz's skilldbconverter.php tool. +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n"; +} |