package com.ljsd.fight; import manager.STableManager; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; public class CheckFight { private static final Logger LOGGER = LoggerFactory.getLogger(CheckFight.class); private ThreadLocal localTransCoderObj = new ThreadLocal(); private ThreadLocal localVersion = new ThreadLocal<>(); // private String luaFileName = null; private CheckFight(){} public static class Instance { public final static CheckFight instance = new CheckFight(); } public static CheckFight getInstance() { return CheckFight.Instance.instance; } private AtomicInteger hotFixVersion = new AtomicInteger(); static class LuaHotFixBean{ private int version; public int getVersion() { return version; } } public void luaHotFix(){ LuaHotFixBean luaHotFixBean = STableManager.getJsonFilePathInJsonConf("lua-hotfix.json", LuaHotFixBean.class); if(luaHotFixBean!=null && hotFixVersion.get() < luaHotFixBean.getVersion()){ LOGGER.info("the curhotFixVersion={},the new hotFixVersion={} will hotfix ",hotFixVersion.get(),luaHotFixBean.getVersion()); //init(); LOGGER.info("the luahotfix done"); hotFixVersion.set(luaHotFixBean.getVersion()); } } // public void init(){ // LuaHotFixBean luaHotFixBean = STableManager.getJsonFilePathInJsonConf("lua-hotfix.json", LuaHotFixBean.class); // if(luaHotFixBean!=null) { // hotFixVersion = luaHotFixBean.getVersion(); // } // } public static String getPath(String prefixDir, String... filePath) throws IOException { StringBuilder path = new StringBuilder(); path.append(getRootPath()).append(prefixDir); for (String p : filePath) { path.append(File.separator).append(p); } return path.toString(); } public static String getRootPath() throws IOException { StringBuilder path = new StringBuilder(); if (isWindows()) {// Window 系统 path.append(new File(".").getCanonicalPath()).append(File.separator); }else { path.append("../"); } return path.toString(); } public static boolean isWindows() { String osName = System.getProperty("os.name"); return osName.matches("^(?i)Windows.*$"); } /** * 单线程执行每次用时50ms,目前支持并发100以内,再大用线程池异步处理 * @return {战斗结果, 战斗伤害/战斗时间,单位1剩余血量,单位2剩余血量,单位3剩余血量,单位4剩余血量,单位5剩余血量} */ /** * 执行战斗检查并返回结果。 * @param seed 随机数种子 * @param maxTime 最大时间或轮数 * @param fightData 战斗数据 * @param optionData 选项数据 * @param fightType 战斗类型 * @return 返回一个长整型数组,包含:战斗结果,战斗时间,以及各单位剩余血量等信息。 */ public long[] checkFight(int seed, int maxTime, LuaValue fightData, LuaValue optionData, FightType fightType) { LuaValue transCoderObj = this.getTransCoderObj(); LuaValue result = callLuaValue(seed, maxTime, fightData, optionData, fightType, transCoderObj); long[] resultCache = new long[9]; // 假定最多有8个单位的剩余血量信息 resultCache[0] = result.get("result").tolong(); resultCache[1] = result.get("duration").tolong(); LOGGER.info("Lua check test fight result: {} Length: {}", resultCache[0], result.length()); for (int i = 1; i <= result.length() && i < 8; i++) { long remainingHealth = result.rawget(i).tolong(); resultCache[i + 1] = remainingHealth; LOGGER.info("{} --> 单位剩余血量: {}", i, remainingHealth); } resultCache[8] = result.get("curRound").tolong(); return resultCache; } public long[][] checkHardStageFight(int seed, int maxTime, LuaValue fightData, LuaValue optionData, FightType fightType) { LuaValue transCoderObj = this.getTransCoderObj(); long[][] resultX = new long[2][]; LuaValue result = callLuaValue(seed, maxTime, fightData, optionData, fightType, transCoderObj); int status = 0; int duration = 0; LuaValue resultVal = result.get("result"); if (!resultVal.isnil()) status = resultVal.toint(); resultVal = result.get("duration"); if (!resultVal.isnil()) duration = resultVal.toint(); long[] starRecord = new long[6]; LuaValue starRecordVal = result.get("starRecord"); if (!starRecordVal.isnil()) { for (int x = 1; x <= starRecordVal.length() && x <= starRecord.length; x++) { LuaValue val = starRecordVal.rawget(x); if (!val.isnil()) { starRecord[x - 1] = val.tolong(); } } } long[] resultCache = new long[8]; resultCache[0] = status; resultCache[1] = duration; for (int i = 2; i < resultCache.length && i <= result.length(); i++) { LuaValue val = result.rawget(i); if (!val.isnil()) { resultCache[i] = val.toint(); } LOGGER.info("{} --> 单位剩余血量 : {}", i, resultCache[i]); } resultX[0] = resultCache; resultX[1] = starRecord; return resultX; } public LuaValue callLuaValue(int seed, int maxTime, LuaValue fightData, LuaValue optionData, FightType fightType, LuaValue transCoderObj) { LuaValue func = transCoderObj.get(LuaValue.valueOf("Execute")); LuaValue args = new LuaTable(); args.set("seed", seed); args.set("type", fightType.getType()); args.set("maxRound", maxTime); return func.call(args, fightData, optionData); } public LuaValue getTransCoderObj(){ LuaValue transCoderObj = localTransCoderObj.get(); if(transCoderObj == null||localVersion.get()!=hotFixVersion.get()){ String luaFileName = null; try { luaFileName = getPath("luafight/BattleMain.lua"); } catch (IOException e) { e.printStackTrace(); } localVersion.set( hotFixVersion.get()); Globals globals = JsePlatform.debugGlobals(); transCoderObj = globals.loadfile(luaFileName).call(); localTransCoderObj.set(transCoderObj); return transCoderObj; } return transCoderObj; } }