Jelajahi Sumber

Support Java 10

Removing JSR223, it's limited to only one script at the time making
server boot time really slow (up to 12 minutes, now server loads under
50 seconds).
If you still want to use JSR223 I have open-sourced a version that
supports Java 10:
https://bitbucket.org/l2jserver/l2j-server-script-engine/
Updated dependencies.
Removed Jython support completely.
Improved unit testing.
Zoey76 6 tahun lalu
induk
melakukan
bbd4a88530
38 mengubah file dengan 1072 tambahan dan 1201 penghapusan
  1. 0 1
      .settings/.gitignore
  2. 5 6
      .settings/org.eclipse.buildship.core.prefs
  3. 3 3
      .settings/org.eclipse.jdt.core.prefs
  4. 1 1
      bitbucket-pipelines.yml
  5. 13 14
      build.gradle
  6. 0 28
      dist/doc/3rdPartyLicenses/ecj.html
  7. 0 32
      dist/doc/3rdPartyLicenses/java-engine.txt
  8. 0 32
      dist/doc/3rdPartyLicenses/jython-engine.txt
  9. 0 191
      dist/doc/3rdPartyLicenses/jython.txt
  10. 1 2
      dist/game/GameServer_loop.sh
  11. 2 2
      dist/game/config/General.properties
  12. 1 8
      dist/game/startGameServer.bat
  13. 0 1
      dist/libs/.gitignore
  14. TEMPAT SAMPAH
      dist/libs/java-engine-1.8.jar
  15. TEMPAT SAMPAH
      dist/libs/jython-engine-2.2.1.jar
  16. TEMPAT SAMPAH
      gradle/wrapper/gradle-wrapper.jar
  17. 5 5
      gradle/wrapper/gradle-wrapper.properties
  18. 3 3
      gradlew
  19. 10 5
      src/main/java/com/l2jserver/Config.java
  20. 3 16
      src/main/java/com/l2jserver/gameserver/GameServer.java
  21. 7 17
      src/main/java/com/l2jserver/gameserver/handler/EffectHandler.java
  22. 10 1
      src/main/java/com/l2jserver/gameserver/handler/IHandler.java
  23. 4 6
      src/main/java/com/l2jserver/gameserver/handler/VoicedCommandHandler.java
  24. 5 4
      src/main/java/com/l2jserver/gameserver/instancemanager/QuestManager.java
  25. 4 6
      src/main/java/com/l2jserver/gameserver/model/events/AbstractScript.java
  26. 1 1
      src/main/java/com/l2jserver/gameserver/model/stats/BaseStats.java
  27. 0 107
      src/main/java/com/l2jserver/gameserver/script/Expression.java
  28. 0 533
      src/main/java/com/l2jserver/gameserver/scripting/L2ScriptEngineManager.java
  29. 298 0
      src/main/java/com/l2jserver/gameserver/scripting/ScriptEngineManager.java
  30. 0 2
      src/main/java/com/l2jserver/gameserver/taskmanager/TaskManager.java
  31. 0 47
      src/main/java/com/l2jserver/gameserver/taskmanager/tasks/TaskJython.java
  32. 12 20
      src/main/java/com/l2jserver/gameserver/taskmanager/tasks/TaskScript.java
  33. 2 4
      src/main/java/com/l2jserver/tools/configurator/ConfigUserInterface.java
  34. 2 2
      src/main/java/com/l2jserver/tools/dbinstaller/frontend/swing/DBConfigGUI.java
  35. 4 2
      src/main/java/com/l2jserver/tools/gsregistering/GUserInterface.java
  36. 2 2
      src/main/java/com/l2jserver/util/Rnd.java
  37. 53 97
      src/test/java/com/l2jserver/gameserver/model/stats/FormulasTest.java
  38. 621 0
      src/test/resources/data/stats/statBonus.xml

+ 0 - 1
.settings/.gitignore

@@ -1 +0,0 @@
-/gradle.prefs

+ 5 - 6
.settings/org.eclipse.buildship.core.prefs

@@ -1,11 +1,10 @@
+build.commands=org.eclipse.jdt.core.javabuilder
 connection.arguments=
-containers=org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/
+connection.java.home=null
 connection.jvm.arguments=
-build.commands=org.eclipse.jdt.core.javabuilder
 connection.project.dir=../L2J_DataPack
-natures=org.eclipse.jdt.core.javanature
-eclipse.preferences.version=1
-connection.java.home=null
+containers=org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/
 derived.resources=.gradle,build
+eclipse.preferences.version=1
+natures=org.eclipse.jdt.core.javanature
 project.path=\:L2J_Server
-connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)

+ 3 - 3
.settings/org.eclipse.jdt.core.prefs

@@ -10,9 +10,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=10
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=10
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -103,7 +103,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
 org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.source=10
 org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=0

+ 1 - 1
bitbucket-pipelines.yml

@@ -1,4 +1,4 @@
-image: java:8
+image: openjdk:10.0.2-13-jre-sid
 
 pipelines:
   default:

+ 13 - 14
build.gradle

@@ -4,7 +4,8 @@ apply plugin: 'eclipse'
 
 defaultTasks('clean', 'build')
 
-sourceCompatibility = JavaVersion.VERSION_1_8
+sourceCompatibility = JavaVersion.VERSION_1_10
+targetCompatibility = JavaVersion.VERSION_1_10
 
 repositories {
     mavenCentral()
@@ -18,20 +19,22 @@ dependencies {
 	compile 'com.mchange:c3p0:0.9.5.2'
 	compile 'com.mchange:mchange-commons-java:0.2.12'
 	compile 'com.jolbox:bonecp:0.8.0.RELEASE'
-	compile 'com.sun.mail:javax.mail:1.6.0'
-	compile 'com.zaxxer:HikariCP:2.7.2'
+	compile 'com.sun.mail:javax.mail:1.6.1'
+	compile 'com.zaxxer:HikariCP:3.2.0'
 	compile 'mysql:mysql-connector-java:6.0.6'
-	compile 'org.mariadb.jdbc:mariadb-java-client:2.1.2'
+	compile 'org.mariadb.jdbc:mariadb-java-client:2.2.6'
 	compile 'org.bitlet:weupnp:0.1.4'
-	compile 'org.eclipse.jdt.core.compiler:ecj:4.4.2'
-	compile 'com.google.code.gson:gson:2.8.2'
-	compile 'com.google.guava:guava:23.0'
-	compile 'org.python:jython:2.2.1'
+	compile 'com.google.code.gson:gson:2.8.5'
+	compile 'com.google.guava:guava:25.1-jre'
 	compile 'org.slf4j:slf4j-api:1.7.25'
 	compile 'org.slf4j:slf4j-jdk14:1.7.25'
+	compile 'org.mdkt.compiler:InMemoryJavaCompiler:1.3.0'
 	compile fileTree(dir: 'dist/libs', include: '*.jar')
-	testCompile 'org.testng:testng:6.11'
-	testCompile 'org.jmockit:jmockit:1.35'
+	testCompile 'org.testng:testng:6.14.3'
+	testCompile 'org.mockito:mockito-core:2.21.0'
+	testCompile 'com.beust:jcommander:1.72'
+	testCompile 'net.bytebuddy:byte-buddy:1.8.17'
+	testCompile 'org.objenesis:objenesis:2.6'
 }
 
 def generalManifest = manifest {
@@ -146,10 +149,6 @@ task zip(type: Zip, dependsOn: build) {
 
 build.finalizedBy(zip)
 
-task wrapper(type: Wrapper) {
-	gradleVersion = '3.5'
-}
-
 eclipse {
 	project {
 		name = 'L2J_Server'

+ 0 - 28
dist/doc/3rdPartyLicenses/ecj.html

@@ -1,28 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-<title>About</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
- 
-<p>June 2, 2006</p>	
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
-being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
-apply to your use of any object code in the Content.  Check the Redistributor's license that was 
-provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
-
-</body>
-</html>

+ 0 - 32
dist/doc/3rdPartyLicenses/java-engine.txt

@@ -1,32 +0,0 @@
-Copyright (c) 2006, Sun Microsystems, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without 
-modification, are permitted provided that the following conditions are met:
-
- - Redistributions of source code must retain the above copyright notice, this 
-   list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright notice, 
-   this list of conditions and the following disclaimer in the documentation 
-   and/or other materials provided with the distribution.
-
- - Neither the name of the Sun Microsystems, Inc. nor the names of 
-   contributors may be used to endorse or promote products derived from this 
-   software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
-CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
-DAMAGE.

+ 0 - 32
dist/doc/3rdPartyLicenses/jython-engine.txt

@@ -1,32 +0,0 @@
-Copyright (c) 2006, Sun Microsystems, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without 
-modification, are permitted provided that the following conditions are met:
-
- - Redistributions of source code must retain the above copyright notice, this 
-   list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright notice, 
-   this list of conditions and the following disclaimer in the documentation 
-   and/or other materials provided with the distribution.
-
- - Neither the name of the Sun Microsystems, Inc. nor the names of 
-   contributors may be used to endorse or promote products derived from this 
-   software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
-CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
-DAMAGE.

+ 0 - 191
dist/doc/3rdPartyLicenses/jython.txt

@@ -1,191 +0,0 @@
-====================================
-The Jython License
-====================================
-
-
-A. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING JYTHON
-==============================================================================================================
-
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
-----------------------------------------------------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Jython") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Jython alone
-or in any derivative version, provided, however, that PSF's License
-Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2007
-Python Software Foundation; All Rights Reserved" are retained in
-Jython alone or in any derivative version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Jython or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Jython.
-
-4. PSF is making Jython available to Licensee on an "AS IS"
-basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF JYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF JYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING JYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee.  This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Jython, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
- 
-Jython 2.0, 2.1 License
---------------------------------------------
-
-Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Jython Developers
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
- - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in
-   the documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Jython Developers nor the names of
-   its contributors may be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
-
-JPython 1.1.x Software License.
-______________________________________________________________________
-
-  1. This LICENSE AGREEMENT is between the Corporation for National Research
-     Initiatives, having an office at 1895 Preston White Drive, Reston, VA
-     20191 ("CNRI"), and the Individual or Organization ("Licensee")
-     accessing and using JPython version 1.1.x in source or binary form and
-     its associated documentation as provided herein ("Software").
-
-  2. Subject to the terms and conditions of this License Agreement, CNRI
-     hereby grants Licensee a non-exclusive, non-transferable, royalty-free,
-     world-wide license to reproduce, analyze, test, perform and/or display
-     publicly, prepare derivative works, distribute, and otherwise use the
-     Software alone or in any derivative version, provided, however, that
-     CNRI's License Agreement and CNRI's notice of copyright, i.e.,
-     "Copyright ©1996-1999 Corporation for National Research Initiatives;
-     All Rights Reserved" are both retained in the Software, alone or in any
-     derivative version prepared by Licensee.
-
-     Alternatively, in lieu of CNRI's License Agreement, Licensee may
-     substitute the following text (omitting the quotes), provided, however,
-     that such text is displayed prominently in the Software alone or in any
-     derivative version prepared by Licensee: "JPython (Version 1.1.x) is
-     made available subject to the terms and conditions in CNRI's License
-     Agreement. This Agreement may be located on the Internet using the
-     following unique, persistent identifier (known as a handle):
-     1895.22/1006. The License may also be obtained from a proxy server on
-     the Web using the following URL: http://hdl.handle.net/1895.22/1006."
-
-  3. In the event Licensee prepares a derivative work that is based on or
-     incorporates the Software or any part thereof, and wants to make the
-     derivative work available to the public as provided herein, then
-     Licensee hereby agrees to indicate in any such work, in a prominently
-     visible way, the nature of the modifications made to CNRI's Software.
-
-  4. Licensee may not use CNRI trademarks or trade name, including JPython
-     or CNRI, in a trademark sense to endorse or promote products or
-     services of Licensee, or any third party. Licensee may use the mark
-     JPython in connection with Licensee's derivative versions that are
-     based on or incorporate the Software, but only in the form
-     "JPython-based ___________________," or equivalent.
-
-  5. CNRI is making the Software available to Licensee on an "AS IS" basis.
-     CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY
-     OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY
-     REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
-     PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE
-     ANY THIRD PARTY RIGHTS.
-
-  6. CNRI SHALL NOT BE LIABLE TO LICENSEE OR OTHER USERS OF THE SOFTWARE FOR
-     ANY INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
-     USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE
-     THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. SOME STATES DO NOT
-     ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY SO THE ABOVE DISCLAIMER
-     MAY NOT APPLY TO LICENSEE.
-
-  7. This License Agreement may be terminated by CNRI (i) immediately upon
-     written notice from CNRI of any material breach by the Licensee, if the
-     nature of the breach is such that it cannot be promptly remedied; or
-     (ii) sixty (60) days following notice from CNRI to Licensee of a
-     material remediable breach, if Licensee has not remedied such breach
-     within that sixty-day period.
-
-  8. This License Agreement shall be governed by and interpreted in all
-     respects by the law of the State of Virginia, excluding conflict of law
-     provisions. Nothing in this Agreement shall be deemed to create any
-     relationship of agency, partnership, or joint venture between CNRI and
-     Licensee.
-
-  9. By clicking on the "ACCEPT" button where indicated, or by installing,
-     copying or otherwise using the Software, Licensee agrees to be bound by
-     the terms and conditions of this License Agreement.
-
-                               [ACCEPT BUTTON]
-
-B. HISTORY OF THE SOFTWARE
-=======================================================
-
-JPython was created in late 1997 by Jim Hugunin. Jim was also the
-primary developer while he was at CNRI. In February 1999 Barry Warsaw
-took over as primary developer and released JPython version 1.1.
-
-In October 2000 Barry helped move the software to SourceForge
-where it was renamed to Jython. Jython 2.0 and 2.1 were developed
-under the Jython specific license below.
-
-From the 2.2 release on, Jython contributors have signed
-Python Software Foundation contributor agreements and releases are
-covered under the Python Software Foundation license version 2.
-
-The standard library is covered by the Python Software Foundation
-license as well. See the Lib/LICENSE file for details.
-
-The zxJDBC package was written by Brian Zimmer and originally licensed
-under the GNU Public License.  The package is now covered by the Jython
-Software License.
-
-The command line interpreter is covered by the Apache Software
-License.  See the org/apache/LICENSE file for details.

+ 1 - 2
dist/game/GameServer_loop.sh

@@ -7,8 +7,7 @@
 while :; do
 	[ -f log/java0.log.0 ] && mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log"
 	[ -f log/stdout.log ] && mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log"
-	java -Dpython.cachedir=../cachedir -Xms1024m -Xmx1792m -jar l2jserver.jar > log/stdout.log 2>&1
+	java -Xms512m -Xmx2g -jar l2jserver.jar > log/stdout.log 2>&1
 	[ $? -ne 2 ] && break
-#	/etc/init.d/mysql restart
 	sleep 10
 done

+ 2 - 2
dist/game/config/General.properties

@@ -879,11 +879,11 @@ Developer = False
 
 # Don't load Handlers
 # Default: False
-AltDevNoHandlers = False
+NoHandlers = False
 
 # Don't load quests.
 # Default: False
-AltDevNoQuests = False
+NoQuests = False
 
 # Don't load spawntable.
 # Default: False

+ 1 - 8
dist/game/startGameServer.bat

@@ -5,14 +5,7 @@ title Game Server Console
 echo Starting L2J Game Server.
 echo.
 
-java -Dpython.cachedir=../cachedir -Xms1024m -Xmx1792m -jar l2jserver.jar
-
-REM NOTE: If you have a powerful machine, you could modify/add some extra parameters for performance, like:
-REM -Xms1536m
-REM -Xmx3072m
-REM -XX:+AggressiveOpts
-REM Use this parameters carefully, some of them could cause abnormal behavior, deadlocks, etc.
-REM More info here: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
+java -Xms512m -Xmx2g -jar l2jserver.jar
 
 if ERRORLEVEL 2 goto restart
 if ERRORLEVEL 1 goto error

+ 0 - 1
dist/libs/.gitignore

@@ -1 +0,0 @@
-/cachedir/

TEMPAT SAMPAH
dist/libs/java-engine-1.8.jar


TEMPAT SAMPAH
dist/libs/jython-engine-2.2.1.jar


TEMPAT SAMPAH
gradle/wrapper/gradle-wrapper.jar


+ 5 - 5
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 3 - 3
gradlew

@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD="maximum"
 
-warn ( ) {
+warn () {
     echo "$*"
 }
 
-die ( ) {
+die () {
     echo
     echo "$*"
     echo
@@ -155,7 +155,7 @@ if $cygwin ; then
 fi
 
 # Escape application args
-save ( ) {
+save () {
     for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
     echo " "
 }

+ 10 - 5
src/main/java/com/l2jserver/Config.java

@@ -78,6 +78,12 @@ public final class Config
 {
 	private static final Logger LOG = LoggerFactory.getLogger(Config.class);
 	
+	/**
+	 * Informs(logs) the scripts being loaded.<BR>
+	 * Apply only when executing script from files.<BR>
+	 */
+	public static final boolean VERBOSE_LOADING = false;
+	
 	// --------------------------------------------------
 	// Constants
 	// --------------------------------------------------
@@ -461,8 +467,8 @@ public final class Config
 	public static boolean HTML_ACTION_CACHE_DEBUG;
 	public static boolean PACKET_HANDLER_DEBUG;
 	public static boolean DEVELOPER;
-	public static boolean ALT_DEV_NO_HANDLERS;
-	public static boolean ALT_DEV_NO_QUESTS;
+	public static boolean NO_HANDLERS;
+	public static boolean NO_QUESTS;
 	public static boolean ALT_DEV_NO_SPAWNS;
 	public static boolean ALT_DEV_SHOW_QUESTS_LOAD_IN_LOGS;
 	public static boolean ALT_DEV_SHOW_SCRIPTS_LOAD_IN_LOGS;
@@ -1760,8 +1766,8 @@ public final class Config
 			HTML_ACTION_CACHE_DEBUG = General.getBoolean("HtmlActionCacheDebug", false);
 			PACKET_HANDLER_DEBUG = General.getBoolean("PacketHandlerDebug", false);
 			DEVELOPER = General.getBoolean("Developer", false);
-			ALT_DEV_NO_HANDLERS = General.getBoolean("AltDevNoHandlers", false) || Boolean.getBoolean("nohandlers");
-			ALT_DEV_NO_QUESTS = General.getBoolean("AltDevNoQuests", false) || Boolean.getBoolean("noquests");
+			NO_HANDLERS = General.getBoolean("NoHandlers", false) || Boolean.getBoolean("nohandlers");
+			NO_QUESTS = General.getBoolean("NoQuests", false) || Boolean.getBoolean("noquests");
 			ALT_DEV_NO_SPAWNS = General.getBoolean("AltDevNoSpawns", false) || Boolean.getBoolean("nospawns");
 			ALT_DEV_SHOW_QUESTS_LOAD_IN_LOGS = General.getBoolean("AltDevShowQuestsLoadInLogs", false);
 			ALT_DEV_SHOW_SCRIPTS_LOAD_IN_LOGS = General.getBoolean("AltDevShowScriptsLoadInLogs", false);
@@ -3937,7 +3943,6 @@ public final class Config
 				parseFile(new File(IP_CONFIG_FILE));
 			}
 			else
-			// Auto configuration...
 			{
 				LOG.info("Using automatic network configuration.");
 				autoIpConfig();

+ 3 - 16
src/main/java/com/l2jserver/gameserver/GameServer.java

@@ -137,7 +137,7 @@ import com.l2jserver.gameserver.network.L2GameClient;
 import com.l2jserver.gameserver.network.L2GamePacketHandler;
 import com.l2jserver.gameserver.pathfinding.PathFinding;
 import com.l2jserver.gameserver.script.faenor.FaenorScriptEngine;
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
+import com.l2jserver.gameserver.scripting.ScriptEngineManager;
 import com.l2jserver.gameserver.taskmanager.KnownListUpdateTaskManager;
 import com.l2jserver.gameserver.taskmanager.TaskManager;
 import com.l2jserver.mmocore.SelectorConfig;
@@ -178,9 +178,7 @@ public final class GameServer
 		
 		new File("log/game").mkdirs();
 		
-		// load script engines
-		printSection("Engines");
-		L2ScriptEngineManager.getInstance();
+		ScriptEngineManager.getInstance();
 		
 		printSection("World");
 		// start game time control early
@@ -293,18 +291,7 @@ public final class GameServer
 		AirShipManager.getInstance();
 		GraciaSeedsManager.getInstance();
 		
-		try
-		{
-			LOG.info("{}: Loading server scripts:", getClass().getSimpleName());
-			if (!Config.ALT_DEV_NO_HANDLERS || !Config.ALT_DEV_NO_QUESTS)
-			{
-				L2ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
-			}
-		}
-		catch (IOException ioe)
-		{
-			LOG.error("{}: Failed loading scripts.cfg, scripts are not going to be loaded!", getClass().getSimpleName());
-		}
+		ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
 		
 		SpawnTable.getInstance().load();
 		DayNightSpawnManager.getInstance().trim().notifyChangeMode();

+ 7 - 17
src/main/java/com/l2jserver/gameserver/handler/EffectHandler.java

@@ -18,12 +18,11 @@
  */
 package com.l2jserver.gameserver.handler;
 
-import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
 import com.l2jserver.gameserver.model.effects.AbstractEffect;
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
+import com.l2jserver.gameserver.scripting.ScriptEngineManager;
 
 /**
  * @author BiggBoss, UnAfraid
@@ -61,27 +60,18 @@ public final class EffectHandler implements IHandler<Class<? extends AbstractEff
 		return _handlers.size();
 	}
 	
-	public void executeScript()
+	public void executeScript() throws Exception
 	{
-		try
-		{
-			
-			File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "handlers/EffectMasterHandler.java");
-			L2ScriptEngineManager.getInstance().executeScript(file);
-		}
-		catch (Exception e)
-		{
-			throw new Error("Problems while running EffectMansterHandler", e);
-		}
+		ScriptEngineManager.getInstance().executeScript("handlers/EffectMasterHandler.java");
 	}
 	
-	private static final class SingletonHolder
+	public static EffectHandler getInstance()
 	{
-		protected static final EffectHandler _instance = new EffectHandler();
+		return SingletonHolder.INSTANCE;
 	}
 	
-	public static EffectHandler getInstance()
+	private static final class SingletonHolder
 	{
-		return SingletonHolder._instance;
+		protected static final EffectHandler INSTANCE = new EffectHandler();
 	}
 }

+ 10 - 1
src/main/java/com/l2jserver/gameserver/handler/IHandler.java

@@ -19,13 +19,22 @@
 package com.l2jserver.gameserver.handler;
 
 /**
+ * Handler Interface.
  * @author UnAfraid
+ * @author Zoey76
  * @param <K>
  * @param <V>
  */
 public interface IHandler<K, V>
 {
-	public void registerHandler(K handler);
+	@SuppressWarnings("unchecked")
+	default void registerByClass(Class<?> clazz) throws Exception
+	{
+		final Object object = clazz.getDeclaredConstructor().newInstance();
+		registerHandler((K) object);
+	}
+	
+	public void registerHandler(K object);
 	
 	public void removeHandler(K handler);
 	

+ 4 - 6
src/main/java/com/l2jserver/gameserver/handler/VoicedCommandHandler.java

@@ -36,8 +36,7 @@ public class VoicedCommandHandler implements IHandler<IVoicedCommandHandler, Str
 	@Override
 	public void registerHandler(IVoicedCommandHandler handler)
 	{
-		String[] ids = handler.getVoicedCommandList();
-		for (String id : ids)
+		for (String id : handler.getVoicedCommandList())
 		{
 			_datatable.put(id, handler);
 		}
@@ -46,8 +45,7 @@ public class VoicedCommandHandler implements IHandler<IVoicedCommandHandler, Str
 	@Override
 	public synchronized void removeHandler(IVoicedCommandHandler handler)
 	{
-		String[] ids = handler.getVoicedCommandList();
-		for (String id : ids)
+		for (String id : handler.getVoicedCommandList())
 		{
 			_datatable.remove(id);
 		}
@@ -72,11 +70,11 @@ public class VoicedCommandHandler implements IHandler<IVoicedCommandHandler, Str
 	
 	public static VoicedCommandHandler getInstance()
 	{
-		return SingletonHolder._instance;
+		return SingletonHolder.INSTANCE;
 	}
 	
 	private static class SingletonHolder
 	{
-		protected static final VoicedCommandHandler _instance = new VoicedCommandHandler();
+		protected static final VoicedCommandHandler INSTANCE = new VoicedCommandHandler();
 	}
 }

+ 5 - 4
src/main/java/com/l2jserver/gameserver/instancemanager/QuestManager.java

@@ -19,7 +19,6 @@
 package com.l2jserver.gameserver.instancemanager;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
@@ -27,7 +26,7 @@ import java.util.logging.Logger;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.quest.Quest;
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
+import com.l2jserver.gameserver.scripting.ScriptEngineManager;
 import com.l2jserver.gameserver.scripting.ScriptManager;
 import com.l2jserver.util.Util;
 
@@ -90,7 +89,9 @@ public final class QuestManager extends ScriptManager<Quest>
 				quest.unload(false);
 			}
 		}
+		
 		_quests.clear();
+		
 		// Unload scripts.
 		for (Quest script : _scripts.values())
 		{
@@ -103,9 +104,9 @@ public final class QuestManager extends ScriptManager<Quest>
 		
 		try
 		{
-			L2ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
+			ScriptEngineManager.getInstance().executeScriptList(new File(Config.DATAPACK_ROOT, "data/scripts.cfg"));
 		}
-		catch (IOException e)
+		catch (Exception e)
 		{
 			_log.log(Level.SEVERE, getClass().getSimpleName() + ": Failed loading scripts.cfg, no script going to be loaded!", e);
 		}

+ 4 - 6
src/main/java/com/l2jserver/gameserver/model/events/AbstractScript.java

@@ -39,8 +39,6 @@ import java.util.function.Function;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.script.ScriptException;
-
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.GameTimeController;
 import com.l2jserver.gameserver.ai.CtrlIntention;
@@ -144,7 +142,7 @@ import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
+import com.l2jserver.gameserver.scripting.ScriptEngineManager;
 import com.l2jserver.gameserver.scripting.ScriptManager;
 import com.l2jserver.gameserver.util.MinionList;
 import com.l2jserver.util.Rnd;
@@ -164,7 +162,7 @@ public abstract class AbstractScript implements INamable
 	
 	public AbstractScript()
 	{
-		_scriptFile = L2ScriptEngineManager.getInstance().getCurrentLoadingScript();
+		_scriptFile = ScriptEngineManager.getInstance().getCurrentLoadingScript();
 		initializeAnnotationListeners();
 	}
 	
@@ -336,10 +334,10 @@ public abstract class AbstractScript implements INamable
 	{
 		try
 		{
-			L2ScriptEngineManager.getInstance().executeScript(getScriptFile());
+			ScriptEngineManager.getInstance().executeScript(getScriptFile());
 			return true;
 		}
-		catch (ScriptException e)
+		catch (Exception e)
 		{
 			return false;
 		}

+ 1 - 1
src/main/java/com/l2jserver/gameserver/model/stats/BaseStats.java

@@ -244,7 +244,7 @@ public enum BaseStats
 		}
 		else
 		{
-			throw new Error("[BaseStats] File not found: " + file.getName());
+			throw new Error("[BaseStats] File not found: " + file.getAbsolutePath());
 		}
 	}
 }

+ 0 - 107
src/main/java/com/l2jserver/gameserver/script/Expression.java

@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2004-2018 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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.
- * 
- * L2J Server 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/>.
- */
-package com.l2jserver.gameserver.script;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.script.ScriptContext;
-
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
-
-public class Expression
-{
-	protected static final Logger _log = Logger.getLogger(Expression.class.getName());
-	private final ScriptContext _context;
-	@SuppressWarnings("unused")
-	private final String _lang;
-	@SuppressWarnings("unused")
-	private final String _code;
-	
-	public static Object eval(String lang, String code)
-	{
-		try
-		{
-			return L2ScriptEngineManager.getInstance().eval(lang, code);
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-			return null;
-		}
-	}
-	
-	public static Object eval(ScriptContext context, String lang, String code)
-	{
-		try
-		{
-			return L2ScriptEngineManager.getInstance().eval(lang, code, context);
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-			return null;
-		}
-	}
-	
-	public static Expression create(ScriptContext context, String lang, String code)
-	{
-		try
-		{
-			return new Expression(context, lang, code);
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-			return null;
-		}
-	}
-	
-	private Expression(ScriptContext pContext, String pLang, String pCode)
-	{
-		_context = pContext;
-		_lang = pLang;
-		_code = pCode;
-	}
-	
-	public <T> void addDynamicVariable(String name, T value)
-	{
-		try
-		{
-			_context.setAttribute(name, value, ScriptContext.ENGINE_SCOPE);
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-		}
-	}
-	
-	public void removeDynamicVariable(String name)
-	{
-		try
-		{
-			_context.removeAttribute(name, ScriptContext.ENGINE_SCOPE);
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-		}
-	}
-	
-}

+ 0 - 533
src/main/java/com/l2jserver/gameserver/scripting/L2ScriptEngineManager.java

@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2004-2018 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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.
- * 
- * L2J Server 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/>.
- */
-package com.l2jserver.gameserver.scripting;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-
-import com.l2jserver.Config;
-import com.l2jserver.script.jython.JythonScriptEngine;
-
-/**
- * Caches script engines and provides functionality for executing and managing scripts.
- * @author KenM
- */
-public final class L2ScriptEngineManager
-{
-	private static final Logger _log = Logger.getLogger(L2ScriptEngineManager.class.getName());
-	
-	public static final File SCRIPT_FOLDER = new File(Config.DATAPACK_ROOT.getAbsolutePath(), "data/scripts");
-	
-	public static L2ScriptEngineManager getInstance()
-	{
-		return SingletonHolder._instance;
-	}
-	
-	private final Map<String, ScriptEngine> _nameEngines = new HashMap<>();
-	private final Map<String, ScriptEngine> _extEngines = new HashMap<>();
-	private final List<ScriptManager<?>> _scriptManagers = new LinkedList<>();
-	
-	private File _currentLoadingScript;
-	
-	// Configs
-	// TODO move to config file
-	/**
-	 * Informs(logs) the scripts being loaded.<BR>
-	 * Apply only when executing script from files.<BR>
-	 */
-	private static final boolean VERBOSE_LOADING = false;
-	
-	/**
-	 * If the script engine supports compilation the script is compiled before execution.<BR>
-	 */
-	private static final boolean ATTEMPT_COMPILATION = true;
-	
-	/**
-	 * Clean an previous error log(if such exists) for the script being loaded before trying to load.<BR>
-	 * Apply only when executing script from files.<BR>
-	 */
-	private static final boolean PURGE_ERROR_LOG = true;
-	
-	protected L2ScriptEngineManager()
-	{
-		ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
-		List<ScriptEngineFactory> factories = scriptEngineManager.getEngineFactories();
-		
-		for (ScriptEngineFactory factory : factories)
-		{
-			try
-			{
-				ScriptEngine engine = factory.getScriptEngine();
-				boolean reg = false;
-				for (String name : factory.getNames())
-				{
-					ScriptEngine existentEngine = _nameEngines.get(name);
-					
-					if (existentEngine != null)
-					{
-						double engineVer = Double.parseDouble(factory.getEngineVersion());
-						double existentEngVer = Double.parseDouble(existentEngine.getFactory().getEngineVersion());
-						
-						if (engineVer <= existentEngVer)
-						{
-							continue;
-						}
-					}
-					
-					reg = true;
-					_nameEngines.put(name, engine);
-				}
-				
-				if (reg)
-				{
-					_log.info("Script Engine: " + factory.getEngineName() + " " + factory.getEngineVersion() + " - Language: " + factory.getLanguageName() + " - Language Version: " + factory.getLanguageVersion());
-				}
-				
-				for (String ext : factory.getExtensions())
-				{
-					if (!ext.equals("java") || factory.getLanguageName().equals("java"))
-					{
-						_extEngines.put(ext, engine);
-					}
-				}
-			}
-			catch (Exception e)
-			{
-				_log.log(Level.WARNING, "Failed initializing factory: " + e.getMessage(), e);
-			}
-		}
-		
-		preConfigure();
-	}
-	
-	private void preConfigure()
-	{
-		// Jython sys.path
-		String dataPackDirForwardSlashes = SCRIPT_FOLDER.getPath().replaceAll("\\\\", "/");
-		String configScript = "import sys;sys.path.insert(0,'" + dataPackDirForwardSlashes + "');";
-		try
-		{
-			eval("jython", configScript);
-		}
-		catch (ScriptException e)
-		{
-			_log.severe("Failed preconfiguring jython: " + e.getMessage());
-		}
-	}
-	
-	private ScriptEngine getEngineByName(String name)
-	{
-		return _nameEngines.get(name);
-	}
-	
-	private ScriptEngine getEngineByExtension(String ext)
-	{
-		return _extEngines.get(ext);
-	}
-	
-	public void executeScriptList(File list) throws IOException
-	{
-		if (Config.ALT_DEV_NO_QUESTS)
-		{
-			if (!Config.ALT_DEV_NO_HANDLERS)
-			{
-				try
-				{
-					executeScript(new File(SCRIPT_FOLDER, "handlers/MasterHandler.java"));
-					_log.info("Handlers loaded, all other scripts skipped");
-				}
-				catch (ScriptException se)
-				{
-					_log.log(Level.WARNING, "", se);
-				}
-			}
-			return;
-		}
-		
-		if (list.isFile())
-		{
-			try (FileInputStream fis = new FileInputStream(list);
-				InputStreamReader isr = new InputStreamReader(fis);
-				LineNumberReader lnr = new LineNumberReader(isr))
-			{
-				String line;
-				while ((line = lnr.readLine()) != null)
-				{
-					if (Config.ALT_DEV_NO_HANDLERS && line.contains("MasterHandler.java"))
-					{
-						continue;
-					}
-					
-					String[] parts = line.trim().split("#");
-					
-					if ((parts.length > 0) && !parts[0].isEmpty() && (parts[0].charAt(0) != '#'))
-					{
-						line = parts[0];
-						
-						if (line.endsWith("/**"))
-						{
-							line = line.substring(0, line.length() - 3);
-						}
-						else if (line.endsWith("/*"))
-						{
-							line = line.substring(0, line.length() - 2);
-						}
-						
-						File file = new File(SCRIPT_FOLDER, line);
-						
-						if (file.isDirectory() && parts[0].endsWith("/**"))
-						{
-							executeAllScriptsInDirectory(file, true, 32);
-						}
-						else if (file.isDirectory() && parts[0].endsWith("/*"))
-						{
-							executeAllScriptsInDirectory(file);
-						}
-						else if (file.isFile())
-						{
-							try
-							{
-								executeScript(file);
-							}
-							catch (ScriptException e)
-							{
-								reportScriptFileError(file, e);
-							}
-						}
-						else
-						{
-							_log.warning("Failed loading: (" + file.getCanonicalPath() + ") @ " + list.getName() + ":" + lnr.getLineNumber() + " - Reason: doesnt exists or is not a file.");
-						}
-					}
-				}
-			}
-		}
-		else
-		{
-			throw new IllegalArgumentException("Argument must be an file containing a list of scripts to be loaded");
-		}
-	}
-	
-	public void executeAllScriptsInDirectory(File dir)
-	{
-		executeAllScriptsInDirectory(dir, false, 0);
-	}
-	
-	public void executeAllScriptsInDirectory(File dir, boolean recurseDown, int maxDepth)
-	{
-		executeAllScriptsInDirectory(dir, recurseDown, maxDepth, 0);
-	}
-	
-	private void executeAllScriptsInDirectory(File dir, boolean recurseDown, int maxDepth, int currentDepth)
-	{
-		if (dir.isDirectory())
-		{
-			final File[] files = dir.listFiles();
-			if (files == null)
-			{
-				return;
-			}
-			
-			for (File file : files)
-			{
-				if (file.isDirectory() && recurseDown && (maxDepth > currentDepth))
-				{
-					if (VERBOSE_LOADING)
-					{
-						_log.info("Entering folder: " + file.getName());
-					}
-					executeAllScriptsInDirectory(file, recurseDown, maxDepth, currentDepth + 1);
-				}
-				else if (file.isFile())
-				{
-					try
-					{
-						String name = file.getName();
-						int lastIndex = name.lastIndexOf('.');
-						String extension;
-						if (lastIndex != -1)
-						{
-							extension = name.substring(lastIndex + 1);
-							ScriptEngine engine = getEngineByExtension(extension);
-							if (engine != null)
-							{
-								executeScript(engine, file);
-							}
-						}
-					}
-					catch (ScriptException e)
-					{
-						reportScriptFileError(file, e);
-					}
-				}
-			}
-		}
-		else
-		{
-			throw new IllegalArgumentException("The argument directory either doesnt exists or is not an directory.");
-		}
-	}
-	
-	public void executeScript(File file) throws ScriptException
-	{
-		String name = file.getName();
-		int lastIndex = name.lastIndexOf('.');
-		String extension;
-		if (lastIndex != -1)
-		{
-			extension = name.substring(lastIndex + 1);
-		}
-		else
-		{
-			throw new ScriptException("Script file (" + name + ") doesnt has an extension that identifies the ScriptEngine to be used.");
-		}
-		
-		ScriptEngine engine = getEngineByExtension(extension);
-		if (engine == null)
-		{
-			throw new ScriptException("No engine registered for extension (" + extension + ")");
-		}
-		executeScript(engine, file);
-	}
-	
-	public void executeScript(String engineName, File file) throws ScriptException
-	{
-		ScriptEngine engine = getEngineByName(engineName);
-		if (engine == null)
-		{
-			throw new ScriptException("No engine registered with name (" + engineName + ")");
-		}
-		executeScript(engine, file);
-	}
-	
-	public void executeScript(ScriptEngine engine, File file) throws ScriptException
-	{
-		if (VERBOSE_LOADING)
-		{
-			_log.info("Loading Script: " + file.getAbsolutePath());
-		}
-		
-		if (PURGE_ERROR_LOG)
-		{
-			String name = file.getAbsolutePath() + ".error.log";
-			File errorLog = new File(name);
-			if (errorLog.isFile())
-			{
-				errorLog.delete();
-			}
-		}
-		
-		final String relativeName = file.getAbsolutePath().substring(SCRIPT_FOLDER.getAbsolutePath().length() + 1).replace('\\', '/');
-		try (FileInputStream fis = new FileInputStream(file);
-			InputStreamReader isr = new InputStreamReader(fis);
-			BufferedReader reader = new BufferedReader(isr))
-		{
-			if ((engine instanceof Compilable) && ATTEMPT_COMPILATION)
-			{
-				ScriptContext context = new SimpleScriptContext();
-				context.setAttribute("mainClass", getClassForFile(file).replace('/', '.').replace('\\', '.'), ScriptContext.ENGINE_SCOPE);
-				context.setAttribute(ScriptEngine.FILENAME, relativeName, ScriptContext.ENGINE_SCOPE);
-				context.setAttribute("classpath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
-				context.setAttribute("sourcepath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
-				context.setAttribute(JythonScriptEngine.JYTHON_ENGINE_INSTANCE, engine, ScriptContext.ENGINE_SCOPE);
-				
-				setCurrentLoadingScript(file);
-				ScriptContext ctx = engine.getContext();
-				try
-				{
-					engine.setContext(context);
-					Compilable eng = (Compilable) engine;
-					CompiledScript cs = eng.compile(reader);
-					cs.eval(context);
-				}
-				finally
-				{
-					engine.setContext(ctx);
-					setCurrentLoadingScript(null);
-					context.removeAttribute(ScriptEngine.FILENAME, ScriptContext.ENGINE_SCOPE);
-					context.removeAttribute("mainClass", ScriptContext.ENGINE_SCOPE);
-				}
-			}
-			else
-			{
-				ScriptContext context = new SimpleScriptContext();
-				context.setAttribute("mainClass", getClassForFile(file).replace('/', '.').replace('\\', '.'), ScriptContext.ENGINE_SCOPE);
-				context.setAttribute(ScriptEngine.FILENAME, relativeName, ScriptContext.ENGINE_SCOPE);
-				context.setAttribute("classpath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
-				context.setAttribute("sourcepath", SCRIPT_FOLDER.getAbsolutePath(), ScriptContext.ENGINE_SCOPE);
-				setCurrentLoadingScript(file);
-				try
-				{
-					engine.eval(reader, context);
-				}
-				finally
-				{
-					setCurrentLoadingScript(null);
-					engine.getContext().removeAttribute(ScriptEngine.FILENAME, ScriptContext.ENGINE_SCOPE);
-					engine.getContext().removeAttribute("mainClass", ScriptContext.ENGINE_SCOPE);
-				}
-				
-			}
-		}
-		catch (IOException e)
-		{
-			_log.log(Level.WARNING, "Error executing script!", e);
-		}
-	}
-	
-	public static String getClassForFile(File script)
-	{
-		String path = script.getAbsolutePath();
-		String scpPath = SCRIPT_FOLDER.getAbsolutePath();
-		if (path.startsWith(scpPath))
-		{
-			int idx = path.lastIndexOf('.');
-			return path.substring(scpPath.length() + 1, idx);
-		}
-		return null;
-	}
-	
-	public ScriptContext getScriptContext(ScriptEngine engine)
-	{
-		return engine.getContext();
-	}
-	
-	public ScriptContext getScriptContext(String engineName)
-	{
-		ScriptEngine engine = getEngineByName(engineName);
-		if (engine == null)
-		{
-			throw new IllegalStateException("No engine registered with name (" + engineName + ")");
-		}
-		return getScriptContext(engine);
-	}
-	
-	public Object eval(ScriptEngine engine, String script, ScriptContext context) throws ScriptException
-	{
-		if ((engine instanceof Compilable) && ATTEMPT_COMPILATION)
-		{
-			Compilable eng = (Compilable) engine;
-			CompiledScript cs = eng.compile(script);
-			return context != null ? cs.eval(context) : cs.eval();
-		}
-		return context != null ? engine.eval(script, context) : engine.eval(script);
-	}
-	
-	public Object eval(String engineName, String script) throws ScriptException
-	{
-		return eval(engineName, script, null);
-	}
-	
-	public Object eval(String engineName, String script, ScriptContext context) throws ScriptException
-	{
-		ScriptEngine engine = getEngineByName(engineName);
-		if (engine == null)
-		{
-			throw new ScriptException("No engine registered with name (" + engineName + ")");
-		}
-		return eval(engine, script, context);
-	}
-	
-	public Object eval(ScriptEngine engine, String script) throws ScriptException
-	{
-		return eval(engine, script, null);
-	}
-	
-	public void reportScriptFileError(File script, ScriptException e)
-	{
-		String dir = script.getParent();
-		String name = script.getName() + ".error.log";
-		if (dir != null)
-		{
-			final File file = new File(dir + "/" + name);
-			try (FileOutputStream fos = new FileOutputStream(file))
-			{
-				String errorHeader = "Error on: " + file.getCanonicalPath() + Config.EOL + "Line: " + e.getLineNumber() + " - Column: " + e.getColumnNumber() + Config.EOL + Config.EOL;
-				fos.write(errorHeader.getBytes());
-				fos.write(e.getMessage().getBytes());
-				_log.warning("Failed executing script: " + script.getAbsolutePath() + ". See " + file.getName() + " for details.");
-			}
-			catch (IOException ioe)
-			{
-				_log.log(Level.WARNING, "Failed executing script: " + script.getAbsolutePath() + Config.EOL + e.getMessage() + "Additionally failed when trying to write an error report on script directory. Reason: " + ioe.getMessage(), ioe);
-			}
-		}
-		else
-		{
-			_log.log(Level.WARNING, "Failed executing script: " + script.getAbsolutePath() + Config.EOL + e.getMessage() + "Additionally failed when trying to write an error report on script directory.", e);
-		}
-	}
-	
-	public void registerScriptManager(ScriptManager<?> manager)
-	{
-		_scriptManagers.add(manager);
-	}
-	
-	public void removeScriptManager(ScriptManager<?> manager)
-	{
-		_scriptManagers.remove(manager);
-	}
-	
-	public List<ScriptManager<?>> getScriptManagers()
-	{
-		return _scriptManagers;
-		
-	}
-	
-	/**
-	 * @param currentLoadingScript The currentLoadingScript to set.
-	 */
-	protected void setCurrentLoadingScript(File currentLoadingScript)
-	{
-		_currentLoadingScript = currentLoadingScript;
-	}
-	
-	/**
-	 * @return Returns the currentLoadingScript.
-	 */
-	public File getCurrentLoadingScript()
-	{
-		return _currentLoadingScript;
-	}
-	
-	private static class SingletonHolder
-	{
-		protected static final L2ScriptEngineManager _instance = new L2ScriptEngineManager();
-	}
-}

+ 298 - 0
src/main/java/com/l2jserver/gameserver/scripting/ScriptEngineManager.java

@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2004-2018 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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.
+ * 
+ * L2J Server 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/>.
+ */
+package com.l2jserver.gameserver.scripting;
+
+import static com.l2jserver.Config.VERBOSE_LOADING;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.script.ScriptException;
+
+import org.mdkt.compiler.InMemoryJavaCompiler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.l2jserver.Config;
+
+/**
+ * Script engine manager.
+ * @author KenM
+ * @author Zoey76
+ */
+public final class ScriptEngineManager
+{
+	private static final Logger LOG = LoggerFactory.getLogger(ScriptEngineManager.class);
+	
+	public static final File SCRIPT_FOLDER = new File(Config.DATAPACK_ROOT.getAbsolutePath(), "data/scripts");
+	
+	private static final String CLASS_PATH = SCRIPT_FOLDER.getAbsolutePath() + ";" + System.getProperty("java.class.path");
+	
+	private static final String MAIN = "main";
+	
+	private static final String[] EMPTY_STRING_ARRAY = new String[0];
+	
+	private static final Class<?>[] ARG_MAIN = new Class[]
+	{
+		String[].class
+	};
+	
+	private static final InMemoryJavaCompiler COMPILER = InMemoryJavaCompiler.newInstance().useOptions("-classpath", CLASS_PATH);
+	
+	public void executeScriptList(File list) throws Exception
+	{
+		if (Config.NO_QUESTS)
+		{
+			if (!Config.NO_HANDLERS)
+			{
+				addSource(new File(SCRIPT_FOLDER, "handlers/MasterHandler.java"));
+				LOG.info("Handlers loaded, all other scripts skipped!");
+			}
+			return;
+		}
+		
+		if (list.isFile())
+		{
+			try (FileInputStream fis = new FileInputStream(list);
+				InputStreamReader isr = new InputStreamReader(fis);
+				LineNumberReader lnr = new LineNumberReader(isr))
+			{
+				String line;
+				while ((line = lnr.readLine()) != null)
+				{
+					if (Config.NO_HANDLERS && line.contains("MasterHandler.java"))
+					{
+						continue;
+					}
+					
+					String[] parts = line.trim().split("#");
+					
+					if ((parts.length > 0) && !parts[0].isEmpty() && (parts[0].charAt(0) != '#'))
+					{
+						line = parts[0];
+						
+						if (line.endsWith("/**"))
+						{
+							line = line.substring(0, line.length() - 3);
+						}
+						else if (line.endsWith("/*"))
+						{
+							line = line.substring(0, line.length() - 2);
+						}
+						
+						final File file = new File(SCRIPT_FOLDER, line);
+						if (file.isDirectory() && parts[0].endsWith("/**"))
+						{
+							executeAllScriptsInDirectory(file, true);
+						}
+						else if (file.isDirectory() && parts[0].endsWith("/*"))
+						{
+							executeAllScriptsInDirectory(file, false);
+						}
+						else if (file.isFile())
+						{
+							addSource(file);
+						}
+						else
+						{
+							LOG.warn("Failed loading: ({}) @ {}:{} - Reason: doesnt exists or is not a file.", file.getCanonicalPath(), list.getName(), lnr.getLineNumber());
+						}
+					}
+				}
+			}
+		}
+		else
+		{
+			throw new IllegalArgumentException("Argument must be an file containing a list of scripts to be loaded");
+		}
+		
+		final Map<String, Class<?>> classes = COMPILER.compileAll();
+		for (Entry<String, Class<?>> e : classes.entrySet())
+		{
+			runMain(e.getValue());
+		}
+	}
+	
+	private void executeAllScriptsInDirectory(File dir, boolean recurseDown)
+	{
+		if (dir.isDirectory())
+		{
+			final File[] files = dir.listFiles();
+			if (files == null)
+			{
+				return;
+			}
+			
+			for (File file : files)
+			{
+				if (file.isDirectory() && recurseDown)
+				{
+					if (VERBOSE_LOADING)
+					{
+						LOG.info("Entering folder: {}", file.getName());
+					}
+					executeAllScriptsInDirectory(file, recurseDown);
+				}
+				else if (file.isFile())
+				{
+					addSource(file);
+				}
+			}
+		}
+		else
+		{
+			throw new IllegalArgumentException("The argument directory either doesnt exists or is not an directory.");
+		}
+	}
+	
+	public Class<?> compileScript(File file)
+	{
+		try (FileInputStream fis = new FileInputStream(file);
+			InputStreamReader isr = new InputStreamReader(fis);
+			BufferedReader reader = new BufferedReader(isr))
+		{
+			return COMPILER.compile(getClassForFile(file), readerToString(reader));
+		}
+		catch (Exception ex)
+		{
+			LOG.warn("Error executing script!", ex);
+		}
+		return null;
+	}
+	
+	public void executeScript(File file) throws Exception
+	{
+		final Class<?> clazz = compileScript(file);
+		
+		runMain(clazz);
+	}
+	
+	public void executeScript(String file) throws Exception
+	{
+		executeScript(new File(SCRIPT_FOLDER, file));
+	}
+	
+	public void addSource(File file)
+	{
+		if (VERBOSE_LOADING)
+		{
+			LOG.info("Loading Script: {}", file.getAbsolutePath());
+		}
+		
+		try (FileInputStream fis = new FileInputStream(file);
+			InputStreamReader isr = new InputStreamReader(fis);
+			BufferedReader reader = new BufferedReader(isr))
+		{
+			COMPILER.addSource(getClassForFile(file), readerToString(reader));
+		}
+		catch (Exception ex)
+		{
+			LOG.warn("Error executing script!", ex);
+		}
+	}
+	
+	private static String getClassForFile(File script)
+	{
+		final String path = script.getAbsolutePath();
+		final String scpPath = SCRIPT_FOLDER.getAbsolutePath();
+		if (path.startsWith(scpPath))
+		{
+			final int idx = path.lastIndexOf('.');
+			return path.substring(scpPath.length() + 1, idx).replace('/', '.').replace('\\', '.');
+		}
+		return null;
+	}
+	
+	private static void runMain(Class<?> clazz) throws Exception
+	{
+		final boolean isPublicClazz = Modifier.isPublic(clazz.getModifiers());
+		final Method mainMethod = findMethod(clazz, MAIN, ARG_MAIN);
+		if (mainMethod != null)
+		{
+			if (!isPublicClazz)
+			{
+				mainMethod.setAccessible(true);
+			}
+			
+			mainMethod.invoke(null, new Object[]
+			{
+				EMPTY_STRING_ARRAY
+			});
+		}
+	}
+	
+	private static String readerToString(Reader reader) throws ScriptException
+	{
+		try (BufferedReader in = new BufferedReader(reader))
+		{
+			final StringBuilder result = new StringBuilder();
+			String line;
+			while ((line = in.readLine()) != null)
+			{
+				result.append(line).append(System.lineSeparator());
+			}
+			return result.toString();
+		}
+		catch (IOException ex)
+		{
+			throw new ScriptException(ex);
+		}
+	}
+	
+	private static Method findMethod(Class<?> clazz, String methodName, Class<?>[] args)
+	{
+		try
+		{
+			final Method mainMethod = clazz.getMethod(methodName, args);
+			final int modifiers = mainMethod.getModifiers();
+			if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers))
+			{
+				return mainMethod;
+			}
+		}
+		catch (NoSuchMethodException ignored)
+		{
+		}
+		return null;
+	}
+	
+	public File getCurrentLoadingScript()
+	{
+		return null;
+	}
+	
+	public static ScriptEngineManager getInstance()
+	{
+		return SingletonHolder.INSTANCE;
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final ScriptEngineManager INSTANCE = new ScriptEngineManager();
+	}
+}

+ 0 - 2
src/main/java/com/l2jserver/gameserver/taskmanager/TaskManager.java

@@ -44,7 +44,6 @@ import com.l2jserver.gameserver.taskmanager.tasks.TaskClanLeaderApply;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskCleanUp;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskDailySkillReuseClean;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskGlobalVariablesSave;
-import com.l2jserver.gameserver.taskmanager.tasks.TaskJython;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskOlympiadSave;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskRaidPointsReset;
 import com.l2jserver.gameserver.taskmanager.tasks.TaskRecom;
@@ -190,7 +189,6 @@ public final class TaskManager
 		registerTask(new TaskCleanUp());
 		registerTask(new TaskDailySkillReuseClean());
 		registerTask(new TaskGlobalVariablesSave());
-		registerTask(new TaskJython());
 		registerTask(new TaskOlympiadSave());
 		registerTask(new TaskRaidPointsReset());
 		registerTask(new TaskRecom());

+ 0 - 47
src/main/java/com/l2jserver/gameserver/taskmanager/tasks/TaskJython.java

@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2004-2018 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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.
- * 
- * L2J Server 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/>.
- */
-package com.l2jserver.gameserver.taskmanager.tasks;
-
-import org.python.util.PythonInterpreter;
-
-import com.l2jserver.gameserver.taskmanager.Task;
-import com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask;
-
-/**
- * @author Layane
- */
-public class TaskJython extends Task
-{
-	public static final String NAME = "jython";
-	private final PythonInterpreter _python = new PythonInterpreter();
-	
-	@Override
-	public String getName()
-	{
-		return NAME;
-	}
-	
-	@Override
-	public void onTimeElapsed(ExecutedTask task)
-	{
-		_python.cleanup();
-		_python.exec("import sys");
-		_python.execfile("data/scripts/cron/" + task.getParams()[2]);
-	}
-}

+ 12 - 20
src/main/java/com/l2jserver/gameserver/taskmanager/tasks/TaskScript.java

@@ -20,9 +20,7 @@ package com.l2jserver.gameserver.taskmanager.tasks;
 
 import java.io.File;
 
-import javax.script.ScriptException;
-
-import com.l2jserver.gameserver.scripting.L2ScriptEngineManager;
+import com.l2jserver.gameserver.scripting.ScriptEngineManager;
 import com.l2jserver.gameserver.taskmanager.Task;
 import com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask;
 
@@ -42,26 +40,20 @@ public class TaskScript extends Task
 	@Override
 	public void onTimeElapsed(ExecutedTask task)
 	{
-		final File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "cron/" + task.getParams()[2]);
-		if (file.isFile())
+		final File file = new File(ScriptEngineManager.SCRIPT_FOLDER, "cron/" + task.getParams()[2]);
+		if (!file.isFile())
 		{
-			try
-			{
-				L2ScriptEngineManager.getInstance().executeScript(file);
-			}
-			catch (ScriptException e)
-			{
-				_log.warning("Failed loading: " + task.getParams()[2]);
-				L2ScriptEngineManager.getInstance().reportScriptFileError(file, e);
-			}
-			catch (Exception e)
-			{
-				_log.warning("Failed loading: " + task.getParams()[2]);
-			}
+			_log.warning("File Not Found: " + task.getParams()[2]);
+			return;
 		}
-		else
+		
+		try
 		{
-			_log.warning("File Not Found: " + task.getParams()[2]);
+			ScriptEngineManager.getInstance().compileScript(file);
+		}
+		catch (Exception e)
+		{
+			_log.warning("Failed loading: " + task.getParams()[2]);
 		}
 	}
 }

+ 2 - 4
src/main/java/com/l2jserver/tools/configurator/ConfigUserInterface.java

@@ -62,6 +62,7 @@ import javax.swing.SwingConstants;
 import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
 import javax.swing.UIManager;
+import javax.swing.WindowConstants;
 
 import com.l2jserver.tools.configurator.ConfigUserInterface.ConfigFile.ConfigComment;
 import com.l2jserver.tools.configurator.ConfigUserInterface.ConfigFile.ConfigProperty;
@@ -83,9 +84,6 @@ public class ConfigUserInterface extends JFrame implements ActionListener
 	
 	private ResourceBundle _bundle;
 	
-	/**
-	 * @param args
-	 */
 	public static void main(String[] args)
 	{
 		try
@@ -110,7 +108,7 @@ public class ConfigUserInterface extends JFrame implements ActionListener
 	{
 		setBundle(bundle);
 		setTitle(bundle.getString("toolName"));
-		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 		this.setSize(750, 500);
 		setLayout(new GridBagLayout());
 		

+ 2 - 2
src/main/java/com/l2jserver/tools/dbinstaller/frontend/swing/DBConfigGUI.java

@@ -26,13 +26,13 @@ import java.text.MessageFormat;
 import java.util.prefs.Preferences;
 
 import javax.swing.JButton;
-import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPasswordField;
 import javax.swing.JTextField;
 import javax.swing.SpringLayout;
 import javax.swing.SwingConstants;
+import javax.swing.WindowConstants;
 
 import com.l2jserver.tools.dbinstaller.RunTasks;
 import com.l2jserver.tools.images.ImagesTable;
@@ -74,7 +74,7 @@ public class DBConfigGUI extends AbstractGUI
 		int height = 240;
 		Dimension resolution = Toolkit.getDefaultToolkit().getScreenSize();
 		
-		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 		setBounds((resolution.width - width) / 2, (resolution.height - height) / 2, width, height);
 		setResizable(false);
 		

+ 4 - 2
src/main/java/com/l2jserver/tools/gsregistering/GUserInterface.java

@@ -41,6 +41,7 @@ import javax.swing.JProgressBar;
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
 import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
 import javax.swing.table.DefaultTableModel;
 import javax.swing.table.TableCellRenderer;
 import javax.swing.table.TableColumn;
@@ -68,7 +69,7 @@ public class GUserInterface extends BaseGameServerRegister implements ActionList
 		_frame = new JFrame();
 		getFrame().setTitle(getBundle().getString("toolName"));
 		getFrame().setSize(600, 400);
-		getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		getFrame().setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 		getFrame().setLayout(new GridBagLayout());
 		GridBagConstraints cons = new GridBagConstraints();
 		
@@ -251,7 +252,8 @@ public class GUserInterface extends BaseGameServerRegister implements ActionList
 		}
 		else if (cmd.equals("about"))
 		{
-			JOptionPane.showMessageDialog(getFrame(), getBundle().getString("credits") + Config.EOL + "http://www.l2jserver.com" + Config.EOL + Config.EOL + getBundle().getString("icons") + Config.EOL + Config.EOL + getBundle().getString("langText") + Config.EOL + getBundle().getString("translation"), getBundle().getString("aboutItem"), JOptionPane.INFORMATION_MESSAGE, ImagesTable.getImage("l2jserverlogo.png"));
+			JOptionPane.showMessageDialog(getFrame(), getBundle().getString("credits") + Config.EOL + "http://www.l2jserver.com" + Config.EOL + Config.EOL + getBundle().getString("icons") + Config.EOL + Config.EOL + getBundle().getString("langText") + Config.EOL
+				+ getBundle().getString("translation"), getBundle().getString("aboutItem"), JOptionPane.INFORMATION_MESSAGE, ImagesTable.getImage("l2jserverlogo.png"));
 		}
 		else if (cmd.equals("removeAll"))
 		{

+ 2 - 2
src/main/java/com/l2jserver/util/Rnd.java

@@ -259,7 +259,7 @@ public final class Rnd
 		
 		public ThreadLocalRandom()
 		{
-			_seedLocal = new ThreadLocal<Seed>()
+			_seedLocal = new ThreadLocal<>()
 			{
 				@Override
 				public final Seed initialValue()
@@ -271,7 +271,7 @@ public final class Rnd
 		
 		public ThreadLocalRandom(final long seed)
 		{
-			_seedLocal = new ThreadLocal<Seed>()
+			_seedLocal = new ThreadLocal<>()
 			{
 				@Override
 				public final Seed initialValue()

+ 53 - 97
src/test/java/com/l2jserver/gameserver/model/stats/FormulasTest.java

@@ -1,20 +1,28 @@
 package com.l2jserver.gameserver.model.stats;
 
+import static com.l2jserver.gameserver.enums.ShotType.BLESSED_SPIRITSHOTS;
+import static com.l2jserver.gameserver.enums.ShotType.SPIRITSHOTS;
+import static java.lang.Double.NaN;
+import static java.lang.Double.POSITIVE_INFINITY;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 
-import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-import com.l2jserver.gameserver.enums.ShotType;
+import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.skills.Skill;
 
-import mockit.Mock;
-import mockit.MockUp;
-
 /**
  * Formulas test.
  * @author Zoey76
@@ -25,112 +33,60 @@ public class FormulasTest
 	
 	private static final String PROVIDE_CHARACTERS = "PROVIDE_CHARACTERS";
 	
-	private static final int HP_REGENERATE_PERIOD_CHARACTER = 3000;
+	private static final Integer HP_REGENERATE_PERIOD_CHARACTER = 3000;
+	
+	private static final Integer HP_REGENERATE_PERIOD_DOOR = 300000;
 	
-	private static final int HP_REGENERATE_PERIOD_DOOR = 300000;
+	@BeforeClass
+	private void init()
+	{
+		Config.DATAPACK_ROOT = new File("src/test/resources");
+	}
 	
 	@Test(dataProvider = PROVIDE_CHARACTERS)
-	public void testGetRegeneratePeriod(L2Character character, int expected)
+	public void testGetRegeneratePeriod(L2Character character, Integer expected)
 	{
-		Assert.assertEquals(Formulas.getRegeneratePeriod(character), expected);
+		assertEquals(Formulas.getRegeneratePeriod(character), expected.intValue());
 	}
 	
 	@Test(dataProvider = PROVIDE_SPEED_SKILL_TIME)
 	public void testCalcAtkSpd(int hitTime, boolean isChanneling, int channelingSkillId, boolean isStatic, boolean isMagic, //
 		int mAtkSpeed, double pAtkSpeed, boolean isChargedSpiritshots, boolean isChargedBlessedSpiritShots, double expected)
 	{
-		final L2Character character = new MockUp<L2Character>()
-		{
-			@Mock
-			int getMAtkSpd()
-			{
-				return mAtkSpeed;
-			}
-			
-			@Mock
-			double getPAtkSpd()
-			{
-				return pAtkSpeed;
-			}
-			
-			@Mock
-			boolean isChargedShot(ShotType type)
-			{
-				switch (type)
-				{
-					case SPIRITSHOTS:
-					{
-						return isChargedSpiritshots;
-					}
-					case BLESSED_SPIRITSHOTS:
-					{
-						return isChargedBlessedSpiritShots;
-					}
-				}
-				return false;
-			}
-		}.getMockInstance();
+		final L2Character character = mock(L2Character.class);
+		when(character.getMAtkSpd()).thenReturn(mAtkSpeed);
+		when(character.getPAtkSpd()).thenReturn(pAtkSpeed);
+		when(character.isChargedShot(SPIRITSHOTS)).thenReturn(isChargedSpiritshots);
+		when(character.isChargedShot(BLESSED_SPIRITSHOTS)).thenReturn(isChargedBlessedSpiritShots);
+		when(character.getMAtkSpd()).thenReturn(mAtkSpeed);
+		when(character.getMAtkSpd()).thenReturn(mAtkSpeed);
+		when(character.getMAtkSpd()).thenReturn(mAtkSpeed);
+		when(character.getMAtkSpd()).thenReturn(mAtkSpeed);
 		
-		final Skill skill = new MockUp<Skill>()
-		{
-			@Mock
-			int getHitTime()
-			{
-				return hitTime;
-			}
-			
-			@Mock
-			boolean isChanneling()
-			{
-				return isChanneling;
-			}
-			
-			@Mock
-			int getChannelingSkillId()
-			{
-				return channelingSkillId;
-			}
-			
-			@Mock
-			boolean isStatic()
-			{
-				return isStatic;
-			}
-			
-			@Mock
-			boolean isMagic()
-			{
-				return isMagic;
-			}
-		}.getMockInstance();
-		
-		Assert.assertEquals(Formulas.calcCastTime(character, skill), expected);
+		final Skill skill = mock(Skill.class);
+		when(skill.getHitTime()).thenReturn(hitTime);
+		when(skill.isChanneling()).thenReturn(isChanneling);
+		when(skill.getChannelingSkillId()).thenReturn(channelingSkillId);
+		when(skill.isStatic()).thenReturn(isStatic);
+		when(skill.isMagic()).thenReturn(isMagic);
+		assertEquals(Formulas.calcCastTime(character, skill), expected);
 	}
 	
 	@DataProvider(name = PROVIDE_CHARACTERS)
 	private Iterator<Object[]> provideCharacters()
 	{
-		final Set<Object[]> result = new HashSet<>();
-		final L2Character c1 = new MockUp<L2Character>()
-		{
-			@Mock
-			boolean isDoor()
-			{
-				return true;
-			}
-		}.getMockInstance();
-		final L2Character c2 = new MockUp<L2Character>()
-		{
-			@Mock
-			boolean isDoor()
-			{
-				return false;
-			}
-		}.getMockInstance();
+		final List<Object[]> result = new LinkedList<>();
+		final L2Character c1 = mock(L2Character.class);
+		when(c1.isDoor()).thenReturn(true);
+		
+		final L2Character c2 = mock(L2Character.class);
+		when(c2.isDoor()).thenReturn(false);
+		
 		// @formatter:off
 		result.add(new Object[]{ c1, HP_REGENERATE_PERIOD_DOOR });
 		result.add(new Object[]{ c2, HP_REGENERATE_PERIOD_CHARACTER });
 		// @formatter:on
+		
 		return result.iterator();
 	}
 	
@@ -141,18 +97,18 @@ public class FormulasTest
 		// @formatter:off
 		// TODO(Zoey76): Take care of the "bad" values.
 		result.add(new Object[]{ 0, true, 1, false, false, 0, 0.0, false, false, 0.0 });
-		result.add(new Object[]{ 0, true, 0, false, false, 0, 0.0, false, false, Double.NaN });
-		result.add(new Object[]{ 0, false, 1, false, false, 0, 0.0, false, false, Double.NaN });
+		result.add(new Object[]{ 0, true, 0, false, false, 0, 0.0, false, false, NaN });
+		result.add(new Object[]{ 0, false, 1, false, false, 0, 0.0, false, false, NaN });
 		result.add(new Object[]{ 0, false, 0, false, true, 500, 0.0, false, false, 0.0 });
 		result.add(new Object[]{ 600, false, 0, false, true, 500, 0.0, false, false, 500.0 });
 		result.add(new Object[]{ 3000, false, 0, false, true, 600, 0.0, false, false, 1665.0 });
 		result.add(new Object[]{ 0, false, 0, false, false, 0, 500.0, false, false, 0.0 });
 		result.add(new Object[]{ 600, false, 0, false, false, 0, 500.0, false, false, 500.0 });
 		result.add(new Object[]{ 3000, false, 0, false, false, 0, 600.0, false, false, 1665.0 });
-		result.add(new Object[]{ 1400, false, 0, false, true, 0, 0.0, true, false, 2.147483647E9 });
-		result.add(new Object[]{ 1400, false, 0, false, true, 0, 0.0, false, true, 2.147483647E9 });	
-		result.add(new Object[]{ 1400, false, 0, true, true, 0, 0.0, true, false, 1000.0 });
-		result.add(new Object[]{ 1400, false, 0, true, true, 0, 0.0, false, true, 1000.0 });
+		result.add(new Object[]{ 1400, false, 0, false, true, 0, 0.0, true, false, POSITIVE_INFINITY });
+		result.add(new Object[]{ 1400, false, 0, false, true, 0, 0.0, false, true, POSITIVE_INFINITY });
+		result.add(new Object[]{ 1400, false, 0, true, true, 0, 0.0, true, false, 840.0 });
+		result.add(new Object[]{ 1400, false, 0, true, true, 0, 0.0, false, true, 840.0 });
 		// @formatter:on
 		return result.iterator();
 	}

+ 621 - 0
src/test/resources/data/stats/statBonus.xml

@@ -0,0 +1,621 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/statBonus.xsd">
+	<STR>
+		<!-- 1.036^(STR-34.845) -->
+		<stat value="0" bonus="0.29" /> <!-- Not Needed -->
+		<stat value="1" bonus="0.3" />
+		<stat value="2" bonus="0.31" />
+		<stat value="3" bonus="0.32" />
+		<stat value="4" bonus="0.34" />
+		<stat value="5" bonus="0.35" />
+		<stat value="6" bonus="0.36" />
+		<stat value="7" bonus="0.37" />
+		<stat value="8" bonus="0.39" />
+		<stat value="9" bonus="0.4" />
+		<stat value="10" bonus="0.42" />
+		<stat value="11" bonus="0.43" />
+		<stat value="12" bonus="0.45" />
+		<stat value="13" bonus="0.46" />
+		<stat value="14" bonus="0.48" />
+		<stat value="15" bonus="0.5" />
+		<stat value="16" bonus="0.51" />
+		<stat value="17" bonus="0.53" />
+		<stat value="18" bonus="0.55" />
+		<stat value="19" bonus="0.57" />
+		<stat value="20" bonus="0.59" />
+		<stat value="21" bonus="0.61" />
+		<stat value="22" bonus="0.63" />
+		<stat value="23" bonus="0.66" />
+		<stat value="24" bonus="0.68" />
+		<stat value="25" bonus="0.71" />
+		<stat value="26" bonus="0.73" />
+		<stat value="27" bonus="0.76" />
+		<stat value="28" bonus="0.78" />
+		<stat value="29" bonus="0.81" />
+		<stat value="30" bonus="0.84" />
+		<stat value="31" bonus="0.87" />
+		<stat value="32" bonus="0.9" />
+		<stat value="33" bonus="0.94" />
+		<stat value="34" bonus="0.97" />
+		<stat value="35" bonus="1.01" />
+		<stat value="36" bonus="1.04" />
+		<stat value="37" bonus="1.08" />
+		<stat value="38" bonus="1.12" />
+		<stat value="39" bonus="1.16" />
+		<stat value="40" bonus="1.2" />
+		<stat value="41" bonus="1.24" />
+		<stat value="42" bonus="1.29" />
+		<stat value="43" bonus="1.33" />
+		<stat value="44" bonus="1.38" />
+		<stat value="45" bonus="1.43" />
+		<stat value="46" bonus="1.48" />
+		<stat value="47" bonus="1.54" />
+		<stat value="48" bonus="1.59" />
+		<stat value="49" bonus="1.65" />
+		<stat value="50" bonus="1.71" />
+		<stat value="51" bonus="1.77" />
+		<stat value="52" bonus="1.83" />
+		<stat value="53" bonus="1.9" />
+		<stat value="54" bonus="1.97" />
+		<stat value="55" bonus="2.04" />
+		<stat value="56" bonus="2.11" />
+		<stat value="57" bonus="2.19" />
+		<stat value="58" bonus="2.27" />
+		<stat value="59" bonus="2.35" />
+		<stat value="60" bonus="2.43" />
+		<stat value="61" bonus="2.52" />
+		<stat value="62" bonus="2.61" />
+		<stat value="63" bonus="2.71" />
+		<stat value="64" bonus="2.8" />
+		<stat value="65" bonus="2.91" />
+		<stat value="66" bonus="3.01" />
+		<stat value="67" bonus="3.12" />
+		<stat value="68" bonus="3.23" />
+		<stat value="69" bonus="3.35" />
+		<stat value="70" bonus="3.47" />
+		<stat value="71" bonus="3.59" />
+		<stat value="72" bonus="3.72" />
+		<stat value="73" bonus="3.86" />
+		<stat value="74" bonus="3.99" />
+		<stat value="75" bonus="4.14" />
+		<stat value="76" bonus="4.29" />
+		<stat value="77" bonus="4.44" />
+		<stat value="78" bonus="4.6" />
+		<stat value="79" bonus="4.77" />
+		<stat value="80" bonus="4.94" />
+		<stat value="81" bonus="5.12" />
+		<stat value="82" bonus="5.3" />
+		<stat value="83" bonus="5.49" />
+		<stat value="84" bonus="5.69" />
+		<stat value="85" bonus="5.89" />
+		<stat value="86" bonus="6.11" />
+		<stat value="87" bonus="6.33" />
+		<stat value="88" bonus="6.55" />
+		<stat value="89" bonus="6.79" />
+		<stat value="90" bonus="7.03" />
+		<stat value="91" bonus="7.29" />
+		<stat value="92" bonus="7.55" />
+		<stat value="93" bonus="7.82" />
+		<stat value="94" bonus="8.1" />
+		<stat value="95" bonus="8.39" />
+		<stat value="96" bonus="8.7" />
+		<stat value="97" bonus="9.01" />
+		<stat value="98" bonus="9.33" />
+		<stat value="99" bonus="9.67" />
+	</STR>
+	<INT>
+		<!-- 1.020^(INT-31.375) -->
+		<stat value="0" bonus="0.54" /> <!-- Not Needed -->
+		<stat value="1" bonus="0.55" />
+		<stat value="2" bonus="0.56" />
+		<stat value="3" bonus="0.57" />
+		<stat value="4" bonus="0.58" />
+		<stat value="5" bonus="0.59" />
+		<stat value="6" bonus="0.61" />
+		<stat value="7" bonus="0.62" />
+		<stat value="8" bonus="0.63" />
+		<stat value="9" bonus="0.64" />
+		<stat value="10" bonus="0.65" />
+		<stat value="11" bonus="0.67" />
+		<stat value="12" bonus="0.68" />
+		<stat value="13" bonus="0.69" />
+		<stat value="14" bonus="0.71" />
+		<stat value="15" bonus="0.72" />
+		<stat value="16" bonus="0.74" />
+		<stat value="17" bonus="0.75" />
+		<stat value="18" bonus="0.77" />
+		<stat value="19" bonus="0.78" />
+		<stat value="20" bonus="0.8" />
+		<stat value="21" bonus="0.81" />
+		<stat value="22" bonus="0.83" />
+		<stat value="23" bonus="0.85" />
+		<stat value="24" bonus="0.86" />
+		<stat value="25" bonus="0.88" />
+		<stat value="26" bonus="0.9" />
+		<stat value="27" bonus="0.92" />
+		<stat value="28" bonus="0.94" />
+		<stat value="29" bonus="0.95" />
+		<stat value="30" bonus="0.97" />
+		<stat value="31" bonus="0.99" />
+		<stat value="32" bonus="1.01" />
+		<stat value="33" bonus="1.03" />
+		<stat value="34" bonus="1.05" />
+		<stat value="35" bonus="1.07" />
+		<stat value="36" bonus="1.1" />
+		<stat value="37" bonus="1.12" />
+		<stat value="38" bonus="1.14" />
+		<stat value="39" bonus="1.16" />
+		<stat value="40" bonus="1.19" />
+		<stat value="41" bonus="1.21" />
+		<stat value="42" bonus="1.23" />
+		<stat value="43" bonus="1.26" />
+		<stat value="44" bonus="1.28" />
+		<stat value="45" bonus="1.31" />
+		<stat value="46" bonus="1.34" />
+		<stat value="47" bonus="1.36" />
+		<stat value="48" bonus="1.39" />
+		<stat value="49" bonus="1.42" />
+		<stat value="50" bonus="1.45" />
+		<stat value="51" bonus="1.47" />
+		<stat value="52" bonus="1.5" />
+		<stat value="53" bonus="1.53" />
+		<stat value="54" bonus="1.57" />
+		<stat value="55" bonus="1.6" />
+		<stat value="56" bonus="1.63" />
+		<stat value="57" bonus="1.66" />
+		<stat value="58" bonus="1.69" />
+		<stat value="59" bonus="1.73" />
+		<stat value="60" bonus="1.76" />
+		<stat value="61" bonus="1.8" />
+		<stat value="62" bonus="1.83" />
+		<stat value="63" bonus="1.87" />
+		<stat value="64" bonus="1.91" />
+		<stat value="65" bonus="1.95" />
+		<stat value="66" bonus="1.99" />
+		<stat value="67" bonus="2.02" />
+		<stat value="68" bonus="2.07" />
+		<stat value="69" bonus="2.11" />
+		<stat value="70" bonus="2.15" />
+		<stat value="71" bonus="2.19" />
+		<stat value="72" bonus="2.24" />
+		<stat value="73" bonus="2.28" />
+		<stat value="74" bonus="2.33" />
+		<stat value="75" bonus="2.37" />
+		<stat value="76" bonus="2.42" />
+		<stat value="77" bonus="2.47" />
+		<stat value="78" bonus="2.52" />
+		<stat value="79" bonus="2.57" />
+		<stat value="80" bonus="2.62" />
+		<stat value="81" bonus="2.67" />
+		<stat value="82" bonus="2.73" />
+		<stat value="83" bonus="2.78" />
+		<stat value="84" bonus="2.84" />
+		<stat value="85" bonus="2.89" />
+		<stat value="86" bonus="2.95" />
+		<stat value="87" bonus="3.01" />
+		<stat value="88" bonus="3.07" />
+		<stat value="89" bonus="3.13" />
+		<stat value="90" bonus="3.19" />
+		<stat value="91" bonus="3.26" />
+		<stat value="92" bonus="3.32" />
+		<stat value="93" bonus="3.39" />
+		<stat value="94" bonus="3.46" />
+		<stat value="95" bonus="3.53" />
+		<stat value="96" bonus="3.6" />
+		<stat value="97" bonus="3.67" />
+		<stat value="98" bonus="3.74" />
+		<stat value="99" bonus="3.82" />
+	</INT>
+	<CON>
+		<!-- 1.030^(CON-27.632) -->
+		<stat value="0" bonus="0.45" /> <!-- Not Needed -->
+		<stat value="1" bonus="0.46" />
+		<stat value="2" bonus="0.47" />
+		<stat value="3" bonus="0.48" />
+		<stat value="4" bonus="0.5" />
+		<stat value="5" bonus="0.51" />
+		<stat value="6" bonus="0.53" />
+		<stat value="7" bonus="0.54" />
+		<stat value="8" bonus="0.56" />
+		<stat value="9" bonus="0.58" />
+		<stat value="10" bonus="0.59" />
+		<stat value="11" bonus="0.61" />
+		<stat value="12" bonus="0.63" />
+		<stat value="13" bonus="0.65" />
+		<stat value="14" bonus="0.67" />
+		<stat value="15" bonus="0.69" />
+		<stat value="16" bonus="0.71" />
+		<stat value="17" bonus="0.73" />
+		<stat value="18" bonus="0.75" />
+		<stat value="19" bonus="0.77" />
+		<stat value="20" bonus="0.8" />
+		<stat value="21" bonus="0.82" />
+		<stat value="22" bonus="0.85" />
+		<stat value="23" bonus="0.87" />
+		<stat value="24" bonus="0.9" />
+		<stat value="25" bonus="0.93" />
+		<stat value="26" bonus="0.95" />
+		<stat value="27" bonus="0.98" />
+		<stat value="28" bonus="1.01" />
+		<stat value="29" bonus="1.04" />
+		<stat value="30" bonus="1.07" />
+		<stat value="31" bonus="1.1" />
+		<stat value="32" bonus="1.14" />
+		<stat value="33" bonus="1.17" />
+		<stat value="34" bonus="1.21" />
+		<stat value="35" bonus="1.24" />
+		<stat value="36" bonus="1.28" />
+		<stat value="37" bonus="1.32" />
+		<stat value="38" bonus="1.36" />
+		<stat value="39" bonus="1.4" />
+		<stat value="40" bonus="1.44" />
+		<stat value="41" bonus="1.48" />
+		<stat value="42" bonus="1.53" />
+		<stat value="43" bonus="1.58" />
+		<stat value="44" bonus="1.62" />
+		<stat value="45" bonus="1.67" />
+		<stat value="46" bonus="1.72" />
+		<stat value="47" bonus="1.77" />
+		<stat value="48" bonus="1.83" />
+		<stat value="49" bonus="1.88" />
+		<stat value="50" bonus="1.94" />
+		<stat value="51" bonus="2" />
+		<stat value="52" bonus="2.06" />
+		<stat value="53" bonus="2.12" />
+		<stat value="54" bonus="2.18" />
+		<stat value="55" bonus="2.25" />
+		<stat value="56" bonus="2.31" />
+		<stat value="57" bonus="2.38" />
+		<stat value="58" bonus="2.45" />
+		<stat value="59" bonus="2.53" />
+		<stat value="60" bonus="2.6" />
+		<stat value="61" bonus="2.68" />
+		<stat value="62" bonus="2.76" />
+		<stat value="63" bonus="2.84" />
+		<stat value="64" bonus="2.93" />
+		<stat value="65" bonus="3.02" />
+		<stat value="66" bonus="3.11" />
+		<stat value="67" bonus="3.2" />
+		<stat value="68" bonus="3.3" />
+		<stat value="69" bonus="3.4" />
+		<stat value="70" bonus="3.5" />
+		<stat value="71" bonus="3.6" />
+		<stat value="72" bonus="3.71" />
+		<stat value="73" bonus="3.82" />
+		<stat value="74" bonus="3.94" />
+		<stat value="75" bonus="4.06" />
+		<stat value="76" bonus="4.18" />
+		<stat value="77" bonus="4.3" />
+		<stat value="78" bonus="4.43" />
+		<stat value="79" bonus="4.56" />
+		<stat value="80" bonus="4.7" />
+		<stat value="81" bonus="4.84" />
+		<stat value="82" bonus="4.99" />
+		<stat value="83" bonus="5.14" />
+		<stat value="84" bonus="5.29" />
+		<stat value="85" bonus="5.45" />
+		<stat value="86" bonus="5.61" />
+		<stat value="87" bonus="5.78" />
+		<stat value="88" bonus="5.96" />
+		<stat value="89" bonus="6.13" />
+		<stat value="90" bonus="6.32" />
+		<stat value="91" bonus="6.51" />
+		<stat value="92" bonus="6.7" />
+		<stat value="93" bonus="6.9" />
+		<stat value="94" bonus="7.11" />
+		<stat value="95" bonus="7.33" />
+		<stat value="96" bonus="7.54" />
+		<stat value="97" bonus="7.77" />
+		<stat value="98" bonus="8" />
+		<stat value="99" bonus="8.24" />
+	</CON>
+	<MEN>
+		<!-- 1.010^(MEN+0.060) -->
+		<stat value="0" bonus="1" /> <!-- Not Needed -->
+		<stat value="1" bonus="1.01" />
+		<stat value="2" bonus="1.02" />
+		<stat value="3" bonus="1.03" />
+		<stat value="4" bonus="1.04" />
+		<stat value="5" bonus="1.05" />
+		<stat value="6" bonus="1.06" />
+		<stat value="7" bonus="1.07" />
+		<stat value="8" bonus="1.08" />
+		<stat value="9" bonus="1.09" />
+		<stat value="10" bonus="1.11" />
+		<stat value="11" bonus="1.12" />
+		<stat value="12" bonus="1.13" />
+		<stat value="13" bonus="1.14" />
+		<stat value="14" bonus="1.15" />
+		<stat value="15" bonus="1.16" />
+		<stat value="16" bonus="1.17" />
+		<stat value="17" bonus="1.19" />
+		<stat value="18" bonus="1.2" />
+		<stat value="19" bonus="1.21" />
+		<stat value="20" bonus="1.22" />
+		<stat value="21" bonus="1.23" />
+		<stat value="22" bonus="1.25" />
+		<stat value="23" bonus="1.26" />
+		<stat value="24" bonus="1.27" />
+		<stat value="25" bonus="1.28" />
+		<stat value="26" bonus="1.3" />
+		<stat value="27" bonus="1.31" />
+		<stat value="28" bonus="1.32" />
+		<stat value="29" bonus="1.34" />
+		<stat value="30" bonus="1.35" />
+		<stat value="31" bonus="1.36" />
+		<stat value="32" bonus="1.38" />
+		<stat value="33" bonus="1.39" />
+		<stat value="34" bonus="1.4" />
+		<stat value="35" bonus="1.42" />
+		<stat value="36" bonus="1.43" />
+		<stat value="37" bonus="1.45" />
+		<stat value="38" bonus="1.46" />
+		<stat value="39" bonus="1.48" />
+		<stat value="40" bonus="1.49" />
+		<stat value="41" bonus="1.5" />
+		<stat value="42" bonus="1.52" />
+		<stat value="43" bonus="1.53" />
+		<stat value="44" bonus="1.55" />
+		<stat value="45" bonus="1.57" />
+		<stat value="46" bonus="1.58" />
+		<stat value="47" bonus="1.6" />
+		<stat value="48" bonus="1.61" />
+		<stat value="49" bonus="1.63" />
+		<stat value="50" bonus="1.65" />
+		<stat value="51" bonus="1.66" />
+		<stat value="52" bonus="1.68" />
+		<stat value="53" bonus="1.7" />
+		<stat value="54" bonus="1.71" />
+		<stat value="55" bonus="1.73" />
+		<stat value="56" bonus="1.75" />
+		<stat value="57" bonus="1.76" />
+		<stat value="58" bonus="1.78" />
+		<stat value="59" bonus="1.8" />
+		<stat value="60" bonus="1.82" />
+		<stat value="61" bonus="1.84" />
+		<stat value="62" bonus="1.85" />
+		<stat value="63" bonus="1.87" />
+		<stat value="64" bonus="1.89" />
+		<stat value="65" bonus="1.91" />
+		<stat value="66" bonus="1.93" />
+		<stat value="67" bonus="1.95" />
+		<stat value="68" bonus="1.97" />
+		<stat value="69" bonus="1.99" />
+		<stat value="70" bonus="2.01" />
+		<stat value="71" bonus="2.03" />
+		<stat value="72" bonus="2.05" />
+		<stat value="73" bonus="2.07" />
+		<stat value="74" bonus="2.09" />
+		<stat value="75" bonus="2.11" />
+		<stat value="76" bonus="2.13" />
+		<stat value="77" bonus="2.15" />
+		<stat value="78" bonus="2.17" />
+		<stat value="79" bonus="2.2" />
+		<stat value="80" bonus="2.22" />
+		<stat value="81" bonus="2.24" />
+		<stat value="82" bonus="2.26" />
+		<stat value="83" bonus="2.29" />
+		<stat value="84" bonus="2.31" />
+		<stat value="85" bonus="2.33" />
+		<stat value="86" bonus="2.35" />
+		<stat value="87" bonus="2.38" />
+		<stat value="88" bonus="2.4" />
+		<stat value="89" bonus="2.43" />
+		<stat value="90" bonus="2.45" />
+		<stat value="91" bonus="2.47" />
+		<stat value="92" bonus="2.5" />
+		<stat value="93" bonus="2.52" />
+		<stat value="94" bonus="2.55" />
+		<stat value="95" bonus="2.58" />
+		<stat value="96" bonus="2.6" />
+		<stat value="97" bonus="2.63" />
+		<stat value="98" bonus="2.65" />
+		<stat value="99" bonus="2.68" />
+	</MEN>
+	<DEX>
+		<!-- 1.009^(DEX-19.360) -->
+		<stat value="0" bonus="0.84" /> <!-- Not Needed -->
+		<stat value="1" bonus="0.85" />
+		<stat value="2" bonus="0.86" />
+		<stat value="3" bonus="0.86" />
+		<stat value="4" bonus="0.87" />
+		<stat value="5" bonus="0.88" />
+		<stat value="6" bonus="0.89" />
+		<stat value="7" bonus="0.9" />
+		<stat value="8" bonus="0.9" />
+		<stat value="9" bonus="0.91" />
+		<stat value="10" bonus="0.92" />
+		<stat value="11" bonus="0.93" />
+		<stat value="12" bonus="0.94" />
+		<stat value="13" bonus="0.94" />
+		<stat value="14" bonus="0.95" />
+		<stat value="15" bonus="0.96" />
+		<stat value="16" bonus="0.97" />
+		<stat value="17" bonus="0.98" />
+		<stat value="18" bonus="0.99" />
+		<stat value="19" bonus="1" />
+		<stat value="20" bonus="1.01" />
+		<stat value="21" bonus="1.01" />
+		<stat value="22" bonus="1.02" />
+		<stat value="23" bonus="1.03" />
+		<stat value="24" bonus="1.04" />
+		<stat value="25" bonus="1.05" />
+		<stat value="26" bonus="1.06" />
+		<stat value="27" bonus="1.07" />
+		<stat value="28" bonus="1.08" />
+		<stat value="29" bonus="1.09" />
+		<stat value="30" bonus="1.1" />
+		<stat value="31" bonus="1.11" />
+		<stat value="32" bonus="1.12" />
+		<stat value="33" bonus="1.13" />
+		<stat value="34" bonus="1.14" />
+		<stat value="35" bonus="1.15" />
+		<stat value="36" bonus="1.16" />
+		<stat value="37" bonus="1.17" />
+		<stat value="38" bonus="1.18" />
+		<stat value="39" bonus="1.19" />
+		<stat value="40" bonus="1.2" />
+		<stat value="41" bonus="1.21" />
+		<stat value="42" bonus="1.22" />
+		<stat value="43" bonus="1.24" />
+		<stat value="44" bonus="1.25" />
+		<stat value="45" bonus="1.26" />
+		<stat value="46" bonus="1.27" />
+		<stat value="47" bonus="1.28" />
+		<stat value="48" bonus="1.29" />
+		<stat value="49" bonus="1.3" />
+		<stat value="50" bonus="1.32" />
+		<stat value="51" bonus="1.33" />
+		<stat value="52" bonus="1.34" />
+		<stat value="53" bonus="1.35" />
+		<stat value="54" bonus="1.36" />
+		<stat value="55" bonus="1.38" />
+		<stat value="56" bonus="1.39" />
+		<stat value="57" bonus="1.4" />
+		<stat value="58" bonus="1.41" />
+		<stat value="59" bonus="1.43" />
+		<stat value="60" bonus="1.44" />
+		<stat value="61" bonus="1.45" />
+		<stat value="62" bonus="1.47" />
+		<stat value="63" bonus="1.48" />
+		<stat value="64" bonus="1.49" />
+		<stat value="65" bonus="1.51" />
+		<stat value="66" bonus="1.52" />
+		<stat value="67" bonus="1.53" />
+		<stat value="68" bonus="1.55" />
+		<stat value="69" bonus="1.56" />
+		<stat value="70" bonus="1.57" />
+		<stat value="71" bonus="1.59" />
+		<stat value="72" bonus="1.6" />
+		<stat value="73" bonus="1.62" />
+		<stat value="74" bonus="1.63" />
+		<stat value="75" bonus="1.65" />
+		<stat value="76" bonus="1.66" />
+		<stat value="77" bonus="1.68" />
+		<stat value="78" bonus="1.69" />
+		<stat value="79" bonus="1.71" />
+		<stat value="80" bonus="1.72" />
+		<stat value="81" bonus="1.74" />
+		<stat value="82" bonus="1.75" />
+		<stat value="83" bonus="1.77" />
+		<stat value="84" bonus="1.78" />
+		<stat value="85" bonus="1.8" />
+		<stat value="86" bonus="1.82" />
+		<stat value="87" bonus="1.83" />
+		<stat value="88" bonus="1.85" />
+		<stat value="89" bonus="1.87" />
+		<stat value="90" bonus="1.88" />
+		<stat value="91" bonus="1.9" />
+		<stat value="92" bonus="1.92" />
+		<stat value="93" bonus="1.93" />
+		<stat value="94" bonus="1.95" />
+		<stat value="95" bonus="1.97" />
+		<stat value="96" bonus="1.99" />
+		<stat value="97" bonus="2" />
+		<stat value="98" bonus="2.02" />
+		<stat value="99" bonus="2.04" />
+	</DEX>
+	<WIT>
+		<!-- 1.050^(WIT-20.000) -->
+		<stat value="0" bonus="0.39" /> <!-- Not Needed -->
+		<stat value="1" bonus="0.4" />
+		<stat value="2" bonus="0.42" />
+		<stat value="3" bonus="0.44" />
+		<stat value="4" bonus="0.46" />
+		<stat value="5" bonus="0.48" />
+		<stat value="6" bonus="0.51" />
+		<stat value="7" bonus="0.53" />
+		<stat value="8" bonus="0.56" />
+		<stat value="9" bonus="0.58" />
+		<stat value="10" bonus="0.61" />
+		<stat value="11" bonus="0.64" />
+		<stat value="12" bonus="0.68" />
+		<stat value="13" bonus="0.71" />
+		<stat value="14" bonus="0.75" />
+		<stat value="15" bonus="0.78" />
+		<stat value="16" bonus="0.82" />
+		<stat value="17" bonus="0.86" />
+		<stat value="18" bonus="0.91" />
+		<stat value="19" bonus="0.95" />
+		<stat value="20" bonus="1" />
+		<stat value="21" bonus="1.05" />
+		<stat value="22" bonus="1.1" />
+		<stat value="23" bonus="1.16" />
+		<stat value="24" bonus="1.22" />
+		<stat value="25" bonus="1.28" />
+		<stat value="26" bonus="1.34" />
+		<stat value="27" bonus="1.41" />
+		<stat value="28" bonus="1.48" />
+		<stat value="29" bonus="1.55" />
+		<stat value="30" bonus="1.63" />
+		<stat value="31" bonus="1.71" />
+		<stat value="32" bonus="1.8" />
+		<stat value="33" bonus="1.89" />
+		<stat value="34" bonus="1.98" />
+		<stat value="35" bonus="2.08" />
+		<stat value="36" bonus="2.18" />
+		<stat value="37" bonus="2.29" />
+		<stat value="38" bonus="2.41" />
+		<stat value="39" bonus="2.53" />
+		<stat value="40" bonus="2.65" />
+		<stat value="41" bonus="2.79" />
+		<stat value="42" bonus="2.93" />
+		<stat value="43" bonus="3.07" />
+		<stat value="44" bonus="3.23" />
+		<stat value="45" bonus="3.39" />
+		<stat value="46" bonus="3.56" />
+		<stat value="47" bonus="3.73" />
+		<stat value="48" bonus="3.92" />
+		<stat value="49" bonus="4.12" />
+		<stat value="50" bonus="4.32" />
+		<stat value="51" bonus="4.54" />
+		<stat value="52" bonus="4.76" />
+		<stat value="53" bonus="5" />
+		<stat value="54" bonus="5.25" />
+		<stat value="55" bonus="5.52" />
+		<stat value="56" bonus="5.79" />
+		<stat value="57" bonus="6.08" />
+		<stat value="58" bonus="6.39" />
+		<stat value="59" bonus="6.7" />
+		<stat value="60" bonus="7.04" />
+		<stat value="61" bonus="7.39" />
+		<stat value="62" bonus="7.76" />
+		<stat value="63" bonus="8.15" />
+		<stat value="64" bonus="8.56" />
+		<stat value="65" bonus="8.99" />
+		<stat value="66" bonus="9.43" />
+		<stat value="67" bonus="9.91" />
+		<stat value="68" bonus="10.4" />
+		<stat value="69" bonus="10.92" />
+		<stat value="70" bonus="11.47" />
+		<stat value="71" bonus="12.04" />
+		<stat value="72" bonus="12.64" />
+		<stat value="73" bonus="13.27" />
+		<stat value="74" bonus="13.94" />
+		<stat value="75" bonus="14.64" />
+		<stat value="76" bonus="15.37" />
+		<stat value="77" bonus="16.14" />
+		<stat value="78" bonus="16.94" />
+		<stat value="79" bonus="17.79" />
+		<stat value="80" bonus="18.68" />
+		<stat value="81" bonus="19.61" />
+		<stat value="82" bonus="20.59" />
+		<stat value="83" bonus="21.62" />
+		<stat value="84" bonus="22.7" />
+		<stat value="85" bonus="23.84" />
+		<stat value="86" bonus="25.03" />
+		<stat value="87" bonus="26.28" />
+		<stat value="88" bonus="27.6" />
+		<stat value="89" bonus="28.98" />
+		<stat value="90" bonus="30.43" />
+		<stat value="91" bonus="31.95" />
+		<stat value="92" bonus="33.55" />
+		<stat value="93" bonus="35.22" />
+		<stat value="94" bonus="36.98" />
+		<stat value="95" bonus="38.83" />
+		<stat value="96" bonus="40.77" />
+		<stat value="97" bonus="42.81" />
+		<stat value="98" bonus="44.95" />
+		<stat value="99" bonus="47.2" />
+	</WIT>
+</list>