/*
* This file is part of MyPet
*
* Copyright © 2011-2016 Keyle
* MyPet is licensed under the GNU Lesser General Public License.
*
* MyPet 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.
*
* MyPet 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 de.Keyle.MyPet.skill.experience;
import de.Keyle.MyPet.MyPetApi;
import de.Keyle.MyPet.api.entity.MyPet;
import de.Keyle.MyPet.api.skill.experience.Experience;
import org.bukkit.ChatColor;
import org.mozilla.javascript.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class JavaScript extends Experience {
private static JavaScriptExperience jsExp = null;
private static boolean isUsable = false;
private double lastExpLevel = Double.NaN;
private double lastExpRequiredExp = Double.NaN;
private double lastExpCurrentExp = Double.NaN;
private int lastLevel = 1;
private double lastCurrentExp = 0.0;
private double lastRequiredExp = 0.0;
private MyPetScriptInfo scriptInfo;
public JavaScript(MyPet myPet) {
super(myPet);
scriptInfo = new MyPetScriptInfo();
initScriptEngine();
}
public boolean isUsable() {
return isUsable;
}
public int getLevel(double exp) {
if (exp == 0) {
return 1;
}
if (lastExpLevel == exp) {
return lastLevel;
}
lastExpLevel = exp;
if (jsExp != null) {
try {
return lastLevel = jsExp.getLevel(exp, scriptInfo);
} catch (Exception e) {
MyPetApi.getLogger().warning(ChatColor.RED + "This error appeared because your Levelscript (exp.js) caused an error:");
MyPetApi.getLogger().warning(" " + e.getLocalizedMessage());
e.printStackTrace();
isUsable = false;
return 0;
}
}
return lastLevel;
}
public double getRequiredExp(double exp) {
if (lastExpRequiredExp == exp) {
return lastRequiredExp;
}
lastExpRequiredExp = exp;
if (jsExp != null) {
try {
return lastRequiredExp = jsExp.getRequiredExp(exp, scriptInfo);
} catch (Exception e) {
MyPetApi.getLogger().warning(ChatColor.RED + "This error appeared because your Levelscript (exp.js) caused an error.");
MyPetApi.getLogger().warning(" " + e.getLocalizedMessage());
e.printStackTrace();
isUsable = false;
return 0;
}
}
return lastRequiredExp;
}
public double getCurrentExp(double exp) {
if (lastExpCurrentExp == exp) {
return lastCurrentExp;
}
lastExpCurrentExp = exp;
if (jsExp != null) {
try {
return lastCurrentExp = jsExp.getCurrentExp(exp, scriptInfo);
} catch (Exception e) {
MyPetApi.getLogger().warning(ChatColor.RED + "This error appeared because your Levelscript (exp.js) caused an error.");
MyPetApi.getLogger().warning(" " + e.getLocalizedMessage());
e.printStackTrace();
isUsable = false;
return 0;
}
}
return lastCurrentExp;
}
@Override
public double getExpByLevel(int level) {
if (level <= 1) {
return 0;
}
if (jsExp != null) {
try {
return jsExp.getExpByLevel(level, scriptInfo);
} catch (Exception e) {
MyPetApi.getLogger().warning(ChatColor.RED + "This error appeared because your Levelscript (exp.js) caused an error.");
MyPetApi.getLogger().warning(" " + e.getLocalizedMessage());
e.printStackTrace();
isUsable = false;
return 0;
}
}
return 0;
}
public static void reset() {
if (isUsable) {
Context.exit();
}
jsExp = null;
isUsable = false;
}
private static void initScriptEngine() {
if (jsExp == null) {
Context cx = Context.enter();
try {
File jsFile = new File(MyPetApi.getPlugin().getDataFolder().getPath(), "exp.js");
ScriptableObject scriptable = new ImporterTopLevel(cx);
Scriptable scope = cx.initStandardObjects(scriptable);
cx.evaluateReader(scope, new FileReader(jsFile), "exp.js", 0, null);
jsExp = new JavaScriptExperience(cx, scope);
isUsable = jsExp.init();
if (!isUsable) {
Context.exit();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class JavaScriptExperience {
Context cx;
Scriptable scope;
private Function getRequiredExp = null;
private Function getLevel = null;
private Function getCurrentExp = null;
private Function getExpByLevel = null;
public JavaScriptExperience(Context cx, Scriptable scope) {
this.cx = cx;
this.scope = scope;
}
public boolean init() {
boolean usable = true;
if (!scope.has("getRequiredExp", scope)) {
MyPetApi.getLogger().warning(ChatColor.RED + "Your levelscript (exp.js) lacks the \"getRequiredExp(exp, mypet)\" function:");
usable = false;
}
if (!scope.has("getLevel", scope)) {
MyPetApi.getLogger().warning(ChatColor.RED + "Your levelscript (exp.js) lacks the \"getLevel(exp, mypet)\" function:");
usable = false;
}
if (!scope.has("getCurrentExp", scope)) {
MyPetApi.getLogger().warning(ChatColor.RED + "Your levelscript (exp.js) lacks the \"getCurrentExp(exp, mypet)\" function:");
usable = false;
}
if (!scope.has("getExpByLevel", scope)) {
MyPetApi.getLogger().warning(ChatColor.RED + "Your levelscript (exp.js) lacks the \"getExpByLevel(level, mypet)\" function:");
usable = false;
}
if (!usable) {
return false;
}
this.getRequiredExp = (Function) scope.get("getRequiredExp", scope);
this.getLevel = (Function) scope.get("getLevel", scope);
this.getCurrentExp = (Function) scope.get("getCurrentExp", scope);
this.getExpByLevel = (Function) scope.get("getExpByLevel", scope);
return true;
}
public int getLevel(double exp, MyPetScriptInfo mypet) {
return ((Number) getLevel.call(cx, scope, scope, new Object[]{exp, mypet})).intValue();
}
public double getRequiredExp(double exp, MyPetScriptInfo mypet) {
return ((Number) getRequiredExp.call(cx, scope, scope, new Object[]{exp, mypet})).doubleValue();
}
public double getCurrentExp(double exp, MyPetScriptInfo mypet) {
return ((Number) getCurrentExp.call(cx, scope, scope, new Object[]{exp, mypet})).doubleValue();
}
public double getExpByLevel(int level, MyPetScriptInfo mypet) {
return ((Number) getExpByLevel.call(cx, scope, scope, new Object[]{level, mypet})).doubleValue();
}
}
class MyPetScriptInfo {
public String getType() {
return getMyPet().getPetType().name();
}
public String getOwnerName() {
return getMyPet().getOwner().getName();
}
public String getSkilltree() {
return getMyPet().getSkilltree() != null ? getMyPet().getSkilltree().getName() : "";
}
public String getUUID() {
return getMyPet().getUUID().toString();
}
public String getWorldGroup() {
return getMyPet().getWorldGroup();
}
}
}