mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-17 09:25:06 +01:00
Fix whitespace [skip actions]
This commit is contained in:
@@ -24,196 +24,196 @@ import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SceneScriptManager {
|
||||
private final Scene scene;
|
||||
private final Map<String, Integer> variables;
|
||||
private SceneMeta meta;
|
||||
private boolean isInit;
|
||||
/**
|
||||
* current triggers controlled by RefreshGroup
|
||||
*/
|
||||
private final Map<Integer, Set<SceneTrigger>> currentTriggers;
|
||||
private final Scene scene;
|
||||
private final Map<String, Integer> variables;
|
||||
private SceneMeta meta;
|
||||
private boolean isInit;
|
||||
/**
|
||||
* current triggers controlled by RefreshGroup
|
||||
*/
|
||||
private final Map<Integer, Set<SceneTrigger>> currentTriggers;
|
||||
private final Map<Integer, EntityRegion> regions; // <EntityId-Region>
|
||||
private final Map<Integer,SceneGroup> sceneGroups;
|
||||
private ScriptMonsterTideService scriptMonsterTideService;
|
||||
private ScriptMonsterSpawnService scriptMonsterSpawnService;
|
||||
/**
|
||||
* blockid - loaded groupSet
|
||||
*/
|
||||
private final Map<Integer, Set<SceneGroup>> loadedGroupSetPerBlock;
|
||||
public static final ExecutorService eventExecutor;
|
||||
static {
|
||||
eventExecutor = new ThreadPoolExecutor(4, 4,
|
||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
|
||||
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
public SceneScriptManager(Scene scene) {
|
||||
this.scene = scene;
|
||||
this.currentTriggers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer,SceneGroup> sceneGroups;
|
||||
private ScriptMonsterTideService scriptMonsterTideService;
|
||||
private ScriptMonsterSpawnService scriptMonsterSpawnService;
|
||||
/**
|
||||
* blockid - loaded groupSet
|
||||
*/
|
||||
private final Map<Integer, Set<SceneGroup>> loadedGroupSetPerBlock;
|
||||
public static final ExecutorService eventExecutor;
|
||||
static {
|
||||
eventExecutor = new ThreadPoolExecutor(4, 4,
|
||||
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
|
||||
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
public SceneScriptManager(Scene scene) {
|
||||
this.scene = scene;
|
||||
this.currentTriggers = new ConcurrentHashMap<>();
|
||||
|
||||
this.regions = new ConcurrentHashMap<>();
|
||||
this.variables = new ConcurrentHashMap<>();
|
||||
this.sceneGroups = new ConcurrentHashMap<>();
|
||||
this.scriptMonsterSpawnService = new ScriptMonsterSpawnService(this);
|
||||
this.loadedGroupSetPerBlock = new ConcurrentHashMap<>();
|
||||
this.regions = new ConcurrentHashMap<>();
|
||||
this.variables = new ConcurrentHashMap<>();
|
||||
this.sceneGroups = new ConcurrentHashMap<>();
|
||||
this.scriptMonsterSpawnService = new ScriptMonsterSpawnService(this);
|
||||
this.loadedGroupSetPerBlock = new ConcurrentHashMap<>();
|
||||
|
||||
// TEMPORARY
|
||||
if (this.getScene().getId() < 10 && !Grasscutter.getConfig().server.game.enableScriptInBigWorld) {
|
||||
return;
|
||||
}
|
||||
// TEMPORARY
|
||||
if (this.getScene().getId() < 10 && !Grasscutter.getConfig().server.game.enableScriptInBigWorld) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create
|
||||
this.init();
|
||||
}
|
||||
// Create
|
||||
this.init();
|
||||
}
|
||||
|
||||
public Scene getScene() {
|
||||
return scene;
|
||||
}
|
||||
public Scene getScene() {
|
||||
return scene;
|
||||
}
|
||||
|
||||
public SceneConfig getConfig() {
|
||||
if(!isInit){
|
||||
return null;
|
||||
}
|
||||
return meta.config;
|
||||
}
|
||||
public SceneConfig getConfig() {
|
||||
if (!isInit) {
|
||||
return null;
|
||||
}
|
||||
return meta.config;
|
||||
}
|
||||
|
||||
public Map<Integer, SceneBlock> getBlocks() {
|
||||
return meta.blocks;
|
||||
}
|
||||
public Map<Integer, SceneBlock> getBlocks() {
|
||||
return meta.blocks;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
public Map<String, Integer> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public Set<SceneTrigger> getTriggersByEvent(int eventId) {
|
||||
return currentTriggers.computeIfAbsent(eventId, e -> new HashSet<>());
|
||||
}
|
||||
public void registerTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::registerTrigger);
|
||||
}
|
||||
public void registerTrigger(SceneTrigger trigger) {
|
||||
getTriggersByEvent(trigger.event).add(trigger);
|
||||
public Set<SceneTrigger> getTriggersByEvent(int eventId) {
|
||||
return currentTriggers.computeIfAbsent(eventId, e -> new HashSet<>());
|
||||
}
|
||||
public void registerTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::registerTrigger);
|
||||
}
|
||||
public void registerTrigger(SceneTrigger trigger) {
|
||||
getTriggersByEvent(trigger.event).add(trigger);
|
||||
Grasscutter.getLogger().debug("Registered trigger {}", trigger.name);
|
||||
}
|
||||
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::deregisterTrigger);
|
||||
}
|
||||
public void deregisterTrigger(SceneTrigger trigger) {
|
||||
getTriggersByEvent(trigger.event).remove(trigger);
|
||||
}
|
||||
public void resetTriggers(int eventId) {
|
||||
currentTriggers.put(eventId, new HashSet<>());
|
||||
}
|
||||
public void refreshGroup(SceneGroup group, int suiteIndex){
|
||||
var suite = group.getSuiteByIndex(suiteIndex);
|
||||
if(suite == null){
|
||||
return;
|
||||
}
|
||||
if(suite.sceneTriggers.size() > 0){
|
||||
for(var trigger : suite.sceneTriggers){
|
||||
resetTriggers(trigger.event);
|
||||
this.currentTriggers.get(trigger.event).add(trigger);
|
||||
}
|
||||
}
|
||||
spawnMonstersInGroup(group, suite);
|
||||
spawnGadgetsInGroup(group, suite);
|
||||
}
|
||||
public EntityRegion getRegionById(int id) {
|
||||
return regions.get(id);
|
||||
}
|
||||
}
|
||||
public void deregisterTrigger(List<SceneTrigger> triggers) {
|
||||
triggers.forEach(this::deregisterTrigger);
|
||||
}
|
||||
public void deregisterTrigger(SceneTrigger trigger) {
|
||||
getTriggersByEvent(trigger.event).remove(trigger);
|
||||
}
|
||||
public void resetTriggers(int eventId) {
|
||||
currentTriggers.put(eventId, new HashSet<>());
|
||||
}
|
||||
public void refreshGroup(SceneGroup group, int suiteIndex) {
|
||||
var suite = group.getSuiteByIndex(suiteIndex);
|
||||
if (suite == null) {
|
||||
return;
|
||||
}
|
||||
if (suite.sceneTriggers.size() > 0) {
|
||||
for (var trigger : suite.sceneTriggers) {
|
||||
resetTriggers(trigger.event);
|
||||
this.currentTriggers.get(trigger.event).add(trigger);
|
||||
}
|
||||
}
|
||||
spawnMonstersInGroup(group, suite);
|
||||
spawnGadgetsInGroup(group, suite);
|
||||
}
|
||||
public EntityRegion getRegionById(int id) {
|
||||
return regions.get(id);
|
||||
}
|
||||
|
||||
public void registerRegion(EntityRegion region) {
|
||||
regions.put(region.getId(), region);
|
||||
public void registerRegion(EntityRegion region) {
|
||||
regions.put(region.getId(), region);
|
||||
Grasscutter.getLogger().debug("Registered region {} from group {}", region.getMetaRegion().config_id, region.getGroupId());
|
||||
}
|
||||
public void registerRegionInGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
}
|
||||
public void registerRegionInGroupSuite(SceneGroup group, SceneSuite suite) {
|
||||
suite.sceneRegions.stream().map(region -> new EntityRegion(this.getScene(), region))
|
||||
.forEach(this::registerRegion);
|
||||
}
|
||||
public synchronized void deregisterRegion(SceneRegion region) {
|
||||
var instance = regions.values().stream()
|
||||
public synchronized void deregisterRegion(SceneRegion region) {
|
||||
var instance = regions.values().stream()
|
||||
.filter(r -> r.getConfigId() == region.config_id)
|
||||
.findFirst();
|
||||
instance.ifPresent(entityRegion -> regions.remove(entityRegion.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Set<SceneGroup>> getLoadedGroupSetPerBlock() {
|
||||
return loadedGroupSetPerBlock;
|
||||
}
|
||||
public Map<Integer, Set<SceneGroup>> getLoadedGroupSetPerBlock() {
|
||||
return loadedGroupSetPerBlock;
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
public SceneGroup getGroupById(int groupId) {
|
||||
for (SceneBlock block : this.getScene().getLoadedBlocks()) {
|
||||
var group = block.groups.get(groupId);
|
||||
if(group == null){
|
||||
continue;
|
||||
}
|
||||
// TODO optimize
|
||||
public SceneGroup getGroupById(int groupId) {
|
||||
for (SceneBlock block : this.getScene().getLoadedBlocks()) {
|
||||
var group = block.groups.get(groupId);
|
||||
if (group == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!group.isLoaded()){
|
||||
getScene().onLoadGroup(List.of(group));
|
||||
}
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!group.isLoaded()) {
|
||||
getScene().onLoadGroup(List.of(group));
|
||||
}
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
var meta = ScriptLoader.getSceneMeta(getScene().getId());
|
||||
if (meta == null){
|
||||
return;
|
||||
}
|
||||
this.meta = meta;
|
||||
private void init() {
|
||||
var meta = ScriptLoader.getSceneMeta(getScene().getId());
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
this.meta = meta;
|
||||
|
||||
// TEMP
|
||||
this.isInit = true;
|
||||
}
|
||||
// TEMP
|
||||
this.isInit = true;
|
||||
}
|
||||
|
||||
public boolean isInit() {
|
||||
return isInit;
|
||||
}
|
||||
public boolean isInit() {
|
||||
return isInit;
|
||||
}
|
||||
|
||||
public void loadBlockFromScript(SceneBlock block) {
|
||||
block.load(scene.getId(), meta.context);
|
||||
}
|
||||
public void loadBlockFromScript(SceneBlock block) {
|
||||
block.load(scene.getId(), meta.context);
|
||||
}
|
||||
|
||||
public void loadGroupFromScript(SceneGroup group) {
|
||||
group.load(getScene().getId());
|
||||
public void loadGroupFromScript(SceneGroup group) {
|
||||
group.load(getScene().getId());
|
||||
|
||||
if (group.variables != null) {
|
||||
group.variables.forEach(var -> this.getVariables().put(var.name, var.value));
|
||||
}
|
||||
if (group.variables != null) {
|
||||
group.variables.forEach(var -> this.getVariables().put(var.name, var.value));
|
||||
}
|
||||
|
||||
this.sceneGroups.put(group.id, group);
|
||||
}
|
||||
this.sceneGroups.put(group.id, group);
|
||||
}
|
||||
|
||||
public void checkRegions() {
|
||||
if (this.regions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
public void checkRegions() {
|
||||
if (this.regions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var region : this.regions.values()) {
|
||||
for (var region : this.regions.values()) {
|
||||
// currently all condition_ENTER_REGION Events check for avatar, so we have no necessary to add other types of entity
|
||||
getScene().getEntities().values()
|
||||
.stream()
|
||||
.filter(e -> e.getEntityType() == EntityType.Avatar.getValue() && region.getMetaRegion().contains(e.getPosition()))
|
||||
.forEach(region::addEntity);
|
||||
getScene().getEntities().values()
|
||||
.stream()
|
||||
.filter(e -> e.getEntityType() == EntityType.Avatar.getValue() && region.getMetaRegion().contains(e.getPosition()))
|
||||
.forEach(region::addEntity);
|
||||
|
||||
var players = region.getScene().getPlayers();
|
||||
int targetID = 0;
|
||||
if(players.size() > 0)
|
||||
if (players.size() > 0)
|
||||
targetID = players.get(0).getUid();
|
||||
|
||||
if (region.hasNewEntities()) {
|
||||
if (region.hasNewEntities()) {
|
||||
Grasscutter.getLogger().trace("Call EVENT_ENTER_REGION_{}",region.getMetaRegion().config_id);
|
||||
callEvent(EventType.EVENT_ENTER_REGION, new ScriptArgs(region.getConfigId())
|
||||
callEvent(EventType.EVENT_ENTER_REGION, new ScriptArgs(region.getConfigId())
|
||||
.setSourceEntityId(region.getId())
|
||||
.setTargetEntityId(targetID)
|
||||
);
|
||||
|
||||
region.resetNewEntities();
|
||||
}
|
||||
region.resetNewEntities();
|
||||
}
|
||||
|
||||
for(int entityId : region.getEntities()) {
|
||||
if(getScene().getEntityById(entityId) == null || !region.getMetaRegion().contains(getScene().getEntityById(entityId).getPosition())) {
|
||||
for (int entityId : region.getEntities()) {
|
||||
if (getScene().getEntityById(entityId) == null || !region.getMetaRegion().contains(getScene().getEntityById(entityId).getPosition())) {
|
||||
region.removeEntity(entityId);
|
||||
|
||||
}
|
||||
@@ -224,24 +224,24 @@ public class SceneScriptManager {
|
||||
.setTargetEntityId(region.getFirstEntityId())
|
||||
);
|
||||
|
||||
region.resetNewEntities();
|
||||
}
|
||||
}
|
||||
}
|
||||
region.resetNewEntities();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<EntityGadget> getGadgetsInGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
public List<EntityGadget> getGadgetsInGroupSuite(SceneGroup group, SceneSuite suite) {
|
||||
return suite.sceneGadgets.stream()
|
||||
.map(g -> createGadget(group.id, group.block_id, g))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
public List<EntityMonster> getMonstersInGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
public List<EntityMonster> getMonstersInGroupSuite(SceneGroup group, SceneSuite suite) {
|
||||
return suite.sceneMonsters.stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
public void addGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
public void addGroupSuite(SceneGroup group, SceneSuite suite) {
|
||||
// we added trigger first
|
||||
registerTrigger(suite.sceneTriggers);
|
||||
|
||||
@@ -251,67 +251,67 @@ public class SceneScriptManager {
|
||||
addEntities(toCreate);
|
||||
|
||||
registerRegionInGroupSuite(group, suite);
|
||||
}
|
||||
public void removeGroupSuite(SceneGroup group, SceneSuite suite){
|
||||
}
|
||||
public void removeGroupSuite(SceneGroup group, SceneSuite suite) {
|
||||
deregisterTrigger(suite.sceneTriggers);
|
||||
removeMonstersInGroup(group, suite);
|
||||
removeGadgetsInGroup(group, suite);
|
||||
removeMonstersInGroup(group, suite);
|
||||
removeGadgetsInGroup(group, suite);
|
||||
|
||||
suite.sceneRegions.forEach(this::deregisterRegion);
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnGadgetsInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var gadgets = group.gadgets.values();
|
||||
public void spawnGadgetsInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var gadgets = group.gadgets.values();
|
||||
|
||||
if (suite != null) {
|
||||
gadgets = suite.sceneGadgets;
|
||||
}
|
||||
if (suite != null) {
|
||||
gadgets = suite.sceneGadgets;
|
||||
}
|
||||
|
||||
var toCreate = gadgets.stream()
|
||||
.map(g -> createGadget(g.group.id, group.block_id, g))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
this.addEntities(toCreate);
|
||||
}
|
||||
var toCreate = gadgets.stream()
|
||||
.map(g -> createGadget(g.group.id, group.block_id, g))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
this.addEntities(toCreate);
|
||||
}
|
||||
|
||||
public void spawnMonstersInGroup(SceneGroup group, SceneSuite suite) {
|
||||
if(suite == null || suite.sceneMonsters.size() <= 0){
|
||||
return;
|
||||
}
|
||||
this.addEntities(suite.sceneMonsters.stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||
}
|
||||
public void spawnMonstersInGroup(SceneGroup group, SceneSuite suite) {
|
||||
if (suite == null || suite.sceneMonsters.size() <= 0) {
|
||||
return;
|
||||
}
|
||||
this.addEntities(suite.sceneMonsters.stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||
}
|
||||
|
||||
public void startMonsterTideInGroup(SceneGroup group, Integer[] ordersConfigId, int tideCount, int sceneLimit) {
|
||||
this.scriptMonsterTideService =
|
||||
new ScriptMonsterTideService(this, group, tideCount, sceneLimit, ordersConfigId);
|
||||
public void startMonsterTideInGroup(SceneGroup group, Integer[] ordersConfigId, int tideCount, int sceneLimit) {
|
||||
this.scriptMonsterTideService =
|
||||
new ScriptMonsterTideService(this, group, tideCount, sceneLimit, ordersConfigId);
|
||||
|
||||
}
|
||||
public void unloadCurrentMonsterTide(){
|
||||
if(this.getScriptMonsterTideService() == null){
|
||||
return;
|
||||
}
|
||||
this.getScriptMonsterTideService().unload();
|
||||
}
|
||||
public void spawnMonstersByConfigId(SceneGroup group, int configId, int delayTime) {
|
||||
// TODO delay
|
||||
getScene().addEntity(createMonster(group.id, group.block_id, group.monsters.get(configId)));
|
||||
}
|
||||
// Events
|
||||
public void callEvent(int eventType, ScriptArgs params){
|
||||
/**
|
||||
* We use ThreadLocal to trans SceneScriptManager context to ScriptLib, to avoid eval script for every groups' trigger in every scene instances.
|
||||
* But when callEvent is called in a ScriptLib func, it may cause NPE because the inner call cleans the ThreadLocal so that outer call could not get it.
|
||||
* e.g. CallEvent -> set -> ScriptLib.xxx -> CallEvent -> set -> remove -> NPE -> (remove)
|
||||
* So we use thread pool to clean the stack to avoid this new issue.
|
||||
*/
|
||||
eventExecutor.submit(() -> this.realCallEvent(eventType, params));
|
||||
}
|
||||
}
|
||||
public void unloadCurrentMonsterTide() {
|
||||
if (this.getScriptMonsterTideService() == null) {
|
||||
return;
|
||||
}
|
||||
this.getScriptMonsterTideService().unload();
|
||||
}
|
||||
public void spawnMonstersByConfigId(SceneGroup group, int configId, int delayTime) {
|
||||
// TODO delay
|
||||
getScene().addEntity(createMonster(group.id, group.block_id, group.monsters.get(configId)));
|
||||
}
|
||||
// Events
|
||||
public void callEvent(int eventType, ScriptArgs params) {
|
||||
/**
|
||||
* We use ThreadLocal to trans SceneScriptManager context to ScriptLib, to avoid eval script for every groups' trigger in every scene instances.
|
||||
* But when callEvent is called in a ScriptLib func, it may cause NPE because the inner call cleans the ThreadLocal so that outer call could not get it.
|
||||
* e.g. CallEvent -> set -> ScriptLib.xxx -> CallEvent -> set -> remove -> NPE -> (remove)
|
||||
* So we use thread pool to clean the stack to avoid this new issue.
|
||||
*/
|
||||
eventExecutor.submit(() -> this.realCallEvent(eventType, params));
|
||||
}
|
||||
|
||||
private void realCallEvent(int eventType, ScriptArgs params) {
|
||||
private void realCallEvent(int eventType, ScriptArgs params) {
|
||||
try {
|
||||
Set<SceneTrigger> relevantTriggers = new HashSet<>();
|
||||
if(eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
||||
if (eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
||||
List<SceneTrigger> relevantTriggersList = this.getTriggersByEvent(eventType).stream()
|
||||
.filter(p -> p.condition.contains(String.valueOf(params.param1))).toList();
|
||||
relevantTriggers = new HashSet<>(relevantTriggersList);
|
||||
@@ -344,154 +344,154 @@ public class SceneScriptManager {
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
// make sure it is removed
|
||||
ScriptLoader.getScriptLib().removeSceneScriptManager();
|
||||
}
|
||||
}
|
||||
// make sure it is removed
|
||||
ScriptLoader.getScriptLib().removeSceneScriptManager();
|
||||
}
|
||||
}
|
||||
|
||||
private LuaValue callScriptFunc(String funcName, SceneGroup group, ScriptArgs params){
|
||||
LuaValue funcLua = null;
|
||||
if (funcName != null && !funcName.isEmpty()) {
|
||||
funcLua = (LuaValue) group.getBindings().get(funcName);
|
||||
}
|
||||
private LuaValue callScriptFunc(String funcName, SceneGroup group, ScriptArgs params) {
|
||||
LuaValue funcLua = null;
|
||||
if (funcName != null && !funcName.isEmpty()) {
|
||||
funcLua = (LuaValue) group.getBindings().get(funcName);
|
||||
}
|
||||
|
||||
LuaValue ret = LuaValue.TRUE;
|
||||
LuaValue ret = LuaValue.TRUE;
|
||||
|
||||
if (funcLua != null) {
|
||||
LuaValue args = LuaValue.NIL;
|
||||
if (funcLua != null) {
|
||||
LuaValue args = LuaValue.NIL;
|
||||
|
||||
if (params != null) {
|
||||
args = CoerceJavaToLua.coerce(params);
|
||||
}
|
||||
if (params != null) {
|
||||
args = CoerceJavaToLua.coerce(params);
|
||||
}
|
||||
|
||||
ret = safetyCall(funcName, funcLua, args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
ret = safetyCall(funcName, funcLua, args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public LuaValue safetyCall(String name, LuaValue func, LuaValue args){
|
||||
try{
|
||||
return func.call(ScriptLoader.getScriptLibLua(), args);
|
||||
}catch (LuaError error){
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{}",name,args,error);
|
||||
return LuaValue.valueOf(-1);
|
||||
}
|
||||
}
|
||||
public LuaValue safetyCall(String name, LuaValue func, LuaValue args) {
|
||||
try {
|
||||
return func.call(ScriptLoader.getScriptLibLua(), args);
|
||||
}catch (LuaError error) {
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{}",name,args,error);
|
||||
return LuaValue.valueOf(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptMonsterTideService getScriptMonsterTideService() {
|
||||
return scriptMonsterTideService;
|
||||
}
|
||||
public ScriptMonsterTideService getScriptMonsterTideService() {
|
||||
return scriptMonsterTideService;
|
||||
}
|
||||
|
||||
public ScriptMonsterSpawnService getScriptMonsterSpawnService() {
|
||||
return scriptMonsterSpawnService;
|
||||
}
|
||||
public ScriptMonsterSpawnService getScriptMonsterSpawnService() {
|
||||
return scriptMonsterSpawnService;
|
||||
}
|
||||
|
||||
public EntityGadget createGadget(int groupId, int blockId, SceneGadget g) {
|
||||
if(g.isOneoff){
|
||||
public EntityGadget createGadget(int groupId, int blockId, SceneGadget g) {
|
||||
if (g.isOneoff) {
|
||||
var hasEntity = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityGadget)
|
||||
.filter(e -> e.getGroupId() == g.group.id)
|
||||
.filter(e -> e.getConfigId() == g.config_id)
|
||||
.findFirst();
|
||||
if(hasEntity.isPresent()){
|
||||
if (hasEntity.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
EntityGadget entity = new EntityGadget(getScene(), g.gadget_id, g.pos);
|
||||
EntityGadget entity = new EntityGadget(getScene(), g.gadget_id, g.pos);
|
||||
|
||||
if (entity.getGadgetData() == null){
|
||||
return null;
|
||||
}
|
||||
if (entity.getGadgetData() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
entity.setBlockId(blockId);
|
||||
entity.setConfigId(g.config_id);
|
||||
entity.setGroupId(groupId);
|
||||
entity.getRotation().set(g.rot);
|
||||
entity.setState(g.state);
|
||||
entity.setPointType(g.point_type);
|
||||
entity.setMetaGadget(g);
|
||||
entity.buildContent();
|
||||
entity.setBlockId(blockId);
|
||||
entity.setConfigId(g.config_id);
|
||||
entity.setGroupId(groupId);
|
||||
entity.getRotation().set(g.rot);
|
||||
entity.setState(g.state);
|
||||
entity.setPointType(g.point_type);
|
||||
entity.setMetaGadget(g);
|
||||
entity.buildContent();
|
||||
|
||||
return entity;
|
||||
}
|
||||
public EntityNPC createNPC(SceneNPC npc, int blockId, int suiteId) {
|
||||
return new EntityNPC(getScene(), npc, blockId, suiteId);
|
||||
}
|
||||
public EntityMonster createMonster(int groupId, int blockId, SceneMonster monster) {
|
||||
if(monster == null){
|
||||
return null;
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
public EntityNPC createNPC(SceneNPC npc, int blockId, int suiteId) {
|
||||
return new EntityNPC(getScene(), npc, blockId, suiteId);
|
||||
}
|
||||
public EntityMonster createMonster(int groupId, int blockId, SceneMonster monster) {
|
||||
if (monster == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MonsterData data = GameData.getMonsterDataMap().get(monster.monster_id);
|
||||
MonsterData data = GameData.getMonsterDataMap().get(monster.monster_id);
|
||||
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate level
|
||||
int level = monster.level;
|
||||
// Calculate level
|
||||
int level = monster.level;
|
||||
|
||||
if (getScene().getDungeonData() != null) {
|
||||
level = getScene().getDungeonData().getShowLevel();
|
||||
} else if (getScene().getWorld().getWorldLevel() > 0) {
|
||||
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(getScene().getWorld().getWorldLevel());
|
||||
if (getScene().getDungeonData() != null) {
|
||||
level = getScene().getDungeonData().getShowLevel();
|
||||
} else if (getScene().getWorld().getWorldLevel() > 0) {
|
||||
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(getScene().getWorld().getWorldLevel());
|
||||
|
||||
if (worldLevelData != null) {
|
||||
level = worldLevelData.getMonsterLevel();
|
||||
}
|
||||
}
|
||||
if (worldLevelData != null) {
|
||||
level = worldLevelData.getMonsterLevel();
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn mob
|
||||
EntityMonster entity = new EntityMonster(getScene(), data, monster.pos, level);
|
||||
entity.getRotation().set(monster.rot);
|
||||
entity.setGroupId(groupId);
|
||||
entity.setBlockId(blockId);
|
||||
entity.setConfigId(monster.config_id);
|
||||
entity.setPoseId(monster.pose_id);
|
||||
// Spawn mob
|
||||
EntityMonster entity = new EntityMonster(getScene(), data, monster.pos, level);
|
||||
entity.getRotation().set(monster.rot);
|
||||
entity.setGroupId(groupId);
|
||||
entity.setBlockId(blockId);
|
||||
entity.setConfigId(monster.config_id);
|
||||
entity.setPoseId(monster.pose_id);
|
||||
|
||||
this.getScriptMonsterSpawnService()
|
||||
.onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
|
||||
this.getScriptMonsterSpawnService()
|
||||
.onMonsterCreatedListener.forEach(action -> action.onNotify(entity));
|
||||
|
||||
return entity;
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void addEntity(GameEntity gameEntity){
|
||||
getScene().addEntity(gameEntity);
|
||||
}
|
||||
public void addEntity(GameEntity gameEntity) {
|
||||
getScene().addEntity(gameEntity);
|
||||
}
|
||||
|
||||
public void meetEntities(List<? extends GameEntity> gameEntity){
|
||||
getScene().addEntities(gameEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_MEET);
|
||||
}
|
||||
public void meetEntities(List<? extends GameEntity> gameEntity) {
|
||||
getScene().addEntities(gameEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_MEET);
|
||||
}
|
||||
|
||||
public void addEntities(List<? extends GameEntity> gameEntity){
|
||||
getScene().addEntities(gameEntity);
|
||||
}
|
||||
public void addEntities(List<? extends GameEntity> gameEntity) {
|
||||
getScene().addEntities(gameEntity);
|
||||
}
|
||||
|
||||
public RTree<SceneBlock, Geometry> getBlocksIndex() {
|
||||
return meta.sceneBlockIndex;
|
||||
}
|
||||
public void removeMonstersInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneMonsters.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityMonster)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
public RTree<SceneBlock, Geometry> getBlocksIndex() {
|
||||
return meta.sceneBlockIndex;
|
||||
}
|
||||
public void removeMonstersInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneMonsters.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityMonster)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_TYPE_MISS);
|
||||
}
|
||||
public void removeGadgetsInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneGadgets.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityGadget)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_TYPE_MISS);
|
||||
}
|
||||
public void removeGadgetsInGroup(SceneGroup group, SceneSuite suite) {
|
||||
var configSet = suite.sceneGadgets.stream()
|
||||
.map(m -> m.config_id)
|
||||
.collect(Collectors.toSet());
|
||||
var toRemove = getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityGadget)
|
||||
.filter(e -> e.getGroupId() == group.id)
|
||||
.filter(e -> configSet.contains(e.getConfigId()))
|
||||
.toList();
|
||||
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_TYPE_MISS);
|
||||
}
|
||||
getScene().removeEntities(toRemove, VisionTypeOuterClass.VisionType.VISION_TYPE_MISS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import lombok.ToString;
|
||||
@ToString
|
||||
@Setter
|
||||
public class SceneGadget extends SceneObject{
|
||||
public int gadget_id;
|
||||
public int state;
|
||||
public int point_type;
|
||||
public SceneBossChest boss_chest;
|
||||
public int interact_id;
|
||||
public int gadget_id;
|
||||
public int state;
|
||||
public int point_type;
|
||||
public SceneBossChest boss_chest;
|
||||
public int interact_id;
|
||||
public boolean isOneoff;
|
||||
public int draft_id;
|
||||
|
||||
public void setIsOneoff(boolean isOneoff){
|
||||
public void setIsOneoff(boolean isOneoff) {
|
||||
this.isOneoff = isOneoff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,29 +7,29 @@ import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
public class SceneRegion {
|
||||
public int config_id;
|
||||
public int shape;
|
||||
public Position pos;
|
||||
public int config_id;
|
||||
public int shape;
|
||||
public Position pos;
|
||||
// for CUBIC
|
||||
public Position size;
|
||||
public Position size;
|
||||
// for SPHERE
|
||||
public int radius;
|
||||
|
||||
public transient SceneGroup group;
|
||||
public boolean contains(Position position) {
|
||||
switch (shape) {
|
||||
case ScriptRegionShape.CUBIC:
|
||||
return (Math.abs(pos.getX() - position.getX()) <= size.getX()) &&
|
||||
(Math.abs(pos.getY() - position.getY()) <= size.getY()) &&
|
||||
(Math.abs(pos.getZ() - position.getZ()) <= size.getZ());
|
||||
case ScriptRegionShape.SPHERE:
|
||||
public boolean contains(Position position) {
|
||||
switch (shape) {
|
||||
case ScriptRegionShape.CUBIC:
|
||||
return (Math.abs(pos.getX() - position.getX()) <= size.getX()) &&
|
||||
(Math.abs(pos.getY() - position.getY()) <= size.getY()) &&
|
||||
(Math.abs(pos.getZ() - position.getZ()) <= size.getZ());
|
||||
case ScriptRegionShape.SPHERE:
|
||||
var x = Math.pow(pos.getX() - position.getX(), 2);
|
||||
var y = Math.pow(pos.getY() - position.getY(), 2);
|
||||
var z = Math.pow(pos.getZ() - position.getZ(), 2);
|
||||
// ^ means XOR in java!
|
||||
return x + y + z <= (radius*radius);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return x + y + z <= (radius*radius);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LuaSerializer implements Serializer {
|
||||
|
||||
private final static Map<Class<?>, MethodAccess> methodAccessCache = new ConcurrentHashMap<>();
|
||||
private final static Map<Class<?>, ConstructorAccess<?>> constructorCache = new ConcurrentHashMap<>();
|
||||
private final static Map<Class<?>, Map<String, FieldMeta>> fieldMetaCache = new ConcurrentHashMap<>();
|
||||
private final static Map<Class<?>, MethodAccess> methodAccessCache = new ConcurrentHashMap<>();
|
||||
private final static Map<Class<?>, ConstructorAccess<?>> constructorCache = new ConcurrentHashMap<>();
|
||||
private final static Map<Class<?>, Map<String, FieldMeta>> fieldMetaCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public <T> List<T> toList(Class<T> type, Object obj) {
|
||||
return serializeList(type, (LuaTable) obj);
|
||||
}
|
||||
@Override
|
||||
public <T> List<T> toList(Class<T> type, Object obj) {
|
||||
return serializeList(type, (LuaTable) obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toObject(Class<T> type, Object obj) {
|
||||
return serialize(type, (LuaTable) obj);
|
||||
}
|
||||
@Override
|
||||
public <T> T toObject(Class<T> type, Object obj) {
|
||||
return serialize(type, (LuaTable) obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Map<String, T> toMap(Class<T> type, Object obj) {
|
||||
@@ -79,161 +79,161 @@ public class LuaSerializer implements Serializer {
|
||||
}
|
||||
|
||||
public <T> List<T> serializeList(Class<T> type, LuaTable table) {
|
||||
List<T> list = new ArrayList<>();
|
||||
List<T> list = new ArrayList<>();
|
||||
|
||||
if (table == null) {
|
||||
return list;
|
||||
}
|
||||
if (table == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
try {
|
||||
LuaValue[] keys = table.keys();
|
||||
for (LuaValue k : keys) {
|
||||
try {
|
||||
LuaValue keyValue = table.get(k);
|
||||
try {
|
||||
LuaValue[] keys = table.keys();
|
||||
for (LuaValue k : keys) {
|
||||
try {
|
||||
LuaValue keyValue = table.get(k);
|
||||
|
||||
T object = null;
|
||||
T object = null;
|
||||
|
||||
if (keyValue.istable()) {
|
||||
object = serialize(type, keyValue.checktable());
|
||||
} else if (keyValue.isint()) {
|
||||
object = (T) (Integer) keyValue.toint();
|
||||
} else if (keyValue.isnumber()) {
|
||||
object = (T) (Float) keyValue.tofloat(); // terrible...
|
||||
} else if (keyValue.isstring()) {
|
||||
object = (T) keyValue.tojstring();
|
||||
if (keyValue.istable()) {
|
||||
object = serialize(type, keyValue.checktable());
|
||||
} else if (keyValue.isint()) {
|
||||
object = (T) (Integer) keyValue.toint();
|
||||
} else if (keyValue.isnumber()) {
|
||||
object = (T) (Float) keyValue.tofloat(); // terrible...
|
||||
} else if (keyValue.isstring()) {
|
||||
object = (T) keyValue.tojstring();
|
||||
} else if (keyValue.isboolean()) {
|
||||
object = (T) (Boolean) keyValue.toboolean();
|
||||
} else {
|
||||
object = (T) keyValue;
|
||||
}
|
||||
object = (T) keyValue;
|
||||
}
|
||||
|
||||
if (object != null) {
|
||||
list.add(object);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (object != null) {
|
||||
list.add(object);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public <T> T serialize(Class<T> type, LuaTable table) {
|
||||
T object = null;
|
||||
public <T> T serialize(Class<T> type, LuaTable table) {
|
||||
T object = null;
|
||||
|
||||
if (type == List.class) {
|
||||
try {
|
||||
Class<T> listType = (Class<T>) type.getTypeParameters()[0].getClass();
|
||||
return (T) serializeList(listType, table);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (type == List.class) {
|
||||
try {
|
||||
Class<T> listType = (Class<T>) type.getTypeParameters()[0].getClass();
|
||||
return (T) serializeList(listType, table);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!methodAccessCache.containsKey(type)) {
|
||||
cacheType(type);
|
||||
}
|
||||
var methodAccess = methodAccessCache.get(type);
|
||||
var fieldMetaMap = fieldMetaCache.get(type);
|
||||
try {
|
||||
if (!methodAccessCache.containsKey(type)) {
|
||||
cacheType(type);
|
||||
}
|
||||
var methodAccess = methodAccessCache.get(type);
|
||||
var fieldMetaMap = fieldMetaCache.get(type);
|
||||
|
||||
object = (T) constructorCache.get(type).newInstance();
|
||||
object = (T) constructorCache.get(type).newInstance();
|
||||
|
||||
if (table == null) {
|
||||
return object;
|
||||
}
|
||||
if (table == null) {
|
||||
return object;
|
||||
}
|
||||
|
||||
LuaValue[] keys = table.keys();
|
||||
for (LuaValue k : keys) {
|
||||
try {
|
||||
var keyName = k.checkjstring();
|
||||
if(!fieldMetaMap.containsKey(keyName)){
|
||||
continue;
|
||||
}
|
||||
var fieldMeta = fieldMetaMap.get(keyName);
|
||||
LuaValue keyValue = table.get(k);
|
||||
LuaValue[] keys = table.keys();
|
||||
for (LuaValue k : keys) {
|
||||
try {
|
||||
var keyName = k.checkjstring();
|
||||
if (!fieldMetaMap.containsKey(keyName)) {
|
||||
continue;
|
||||
}
|
||||
var fieldMeta = fieldMetaMap.get(keyName);
|
||||
LuaValue keyValue = table.get(k);
|
||||
|
||||
if (keyValue.istable()) {
|
||||
methodAccess.invoke(object, fieldMeta.index, serialize(fieldMeta.getType(), keyValue.checktable()));
|
||||
} else if (fieldMeta.getType().equals(float.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tofloat());
|
||||
} else if (fieldMeta.getType().equals(int.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.toint());
|
||||
} else if (fieldMeta.getType().equals(String.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tojstring());
|
||||
if (keyValue.istable()) {
|
||||
methodAccess.invoke(object, fieldMeta.index, serialize(fieldMeta.getType(), keyValue.checktable()));
|
||||
} else if (fieldMeta.getType().equals(float.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tofloat());
|
||||
} else if (fieldMeta.getType().equals(int.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.toint());
|
||||
} else if (fieldMeta.getType().equals(String.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tojstring());
|
||||
} else if (fieldMeta.getType().equals(boolean.class)) {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.toboolean());
|
||||
} else {
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tojstring());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().info(ScriptUtils.toMap(table).toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
methodAccess.invoke(object, fieldMeta.index, keyValue.tojstring());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().info(ScriptUtils.toMap(table).toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public <T> Map<String, FieldMeta> cacheType(Class<T> type){
|
||||
if(fieldMetaCache.containsKey(type)) {
|
||||
return fieldMetaCache.get(type);
|
||||
}
|
||||
if(!constructorCache.containsKey(type)){
|
||||
constructorCache.putIfAbsent(type, ConstructorAccess.get(type));
|
||||
}
|
||||
var methodAccess = Optional.ofNullable(methodAccessCache.get(type)).orElse(MethodAccess.get(type));
|
||||
methodAccessCache.putIfAbsent(type, methodAccess);
|
||||
public <T> Map<String, FieldMeta> cacheType(Class<T> type) {
|
||||
if (fieldMetaCache.containsKey(type)) {
|
||||
return fieldMetaCache.get(type);
|
||||
}
|
||||
if (!constructorCache.containsKey(type)) {
|
||||
constructorCache.putIfAbsent(type, ConstructorAccess.get(type));
|
||||
}
|
||||
var methodAccess = Optional.ofNullable(methodAccessCache.get(type)).orElse(MethodAccess.get(type));
|
||||
methodAccessCache.putIfAbsent(type, methodAccess);
|
||||
|
||||
var fieldMetaMap = new HashMap<String, FieldMeta>();
|
||||
var methodNameSet = new HashSet<>(Arrays.stream(methodAccess.getMethodNames()).toList());
|
||||
var fieldMetaMap = new HashMap<String, FieldMeta>();
|
||||
var methodNameSet = new HashSet<>(Arrays.stream(methodAccess.getMethodNames()).toList());
|
||||
|
||||
Arrays.stream(type.getDeclaredFields())
|
||||
.filter(field -> methodNameSet.contains(getSetterName(field.getName())))
|
||||
.forEach(field -> {
|
||||
var setter = getSetterName(field.getName());
|
||||
var index = methodAccess.getIndex(setter);
|
||||
fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
||||
});
|
||||
Arrays.stream(type.getDeclaredFields())
|
||||
.filter(field -> methodNameSet.contains(getSetterName(field.getName())))
|
||||
.forEach(field -> {
|
||||
var setter = getSetterName(field.getName());
|
||||
var index = methodAccess.getIndex(setter);
|
||||
fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
||||
});
|
||||
|
||||
Arrays.stream(type.getFields())
|
||||
.filter(field -> !fieldMetaMap.containsKey(field.getName()))
|
||||
.filter(field -> methodNameSet.contains(getSetterName(field.getName())))
|
||||
.forEach(field -> {
|
||||
var setter = getSetterName(field.getName());
|
||||
var index = methodAccess.getIndex(setter);
|
||||
fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
||||
});
|
||||
Arrays.stream(type.getFields())
|
||||
.filter(field -> !fieldMetaMap.containsKey(field.getName()))
|
||||
.filter(field -> methodNameSet.contains(getSetterName(field.getName())))
|
||||
.forEach(field -> {
|
||||
var setter = getSetterName(field.getName());
|
||||
var index = methodAccess.getIndex(setter);
|
||||
fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType()));
|
||||
});
|
||||
|
||||
fieldMetaCache.put(type, fieldMetaMap);
|
||||
return fieldMetaMap;
|
||||
}
|
||||
fieldMetaCache.put(type, fieldMetaMap);
|
||||
return fieldMetaMap;
|
||||
}
|
||||
|
||||
public String getSetterName(String fieldName){
|
||||
if(fieldName == null || fieldName.length() == 0){
|
||||
return null;
|
||||
}
|
||||
if(fieldName.length() == 1){
|
||||
return "set" + fieldName.toUpperCase();
|
||||
}
|
||||
return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
|
||||
}
|
||||
public String getSetterName(String fieldName) {
|
||||
if (fieldName == null || fieldName.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (fieldName.length() == 1) {
|
||||
return "set" + fieldName.toUpperCase();
|
||||
}
|
||||
return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
static class FieldMeta{
|
||||
String name;
|
||||
String setter;
|
||||
int index;
|
||||
Class<?> type;
|
||||
}
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
static class FieldMeta{
|
||||
String name;
|
||||
String setter;
|
||||
int index;
|
||||
Class<?> type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import java.util.Map;
|
||||
|
||||
public interface Serializer {
|
||||
|
||||
public <T> List<T> toList(Class<T> type, Object obj);
|
||||
public <T> List<T> toList(Class<T> type, Object obj);
|
||||
|
||||
public <T> T toObject(Class<T> type, Object obj);
|
||||
public <T> T toObject(Class<T> type, Object obj);
|
||||
|
||||
public <T> Map<String,T> toMap(Class<T> type, Object obj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user