Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
01b190bc
Commit
01b190bc
authored
May 07, 2022
by
Magix
Committed by
GitHub
May 07, 2022
Browse files
UPGRADE TO 1.1.0 POG
Merge `development` into `stable`
parents
6b81b888
1beddf16
Changes
497
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
javax.script.Bindings
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptException
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.data.def.WorldLevelData
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.constants.ScriptGadgetState
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.scripts.data.SceneBlock
;
import
emu.grasscutter.scripts.data.SceneConfig
;
import
emu.grasscutter.scripts.data.SceneGadget
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.SceneInitConfig
;
import
emu.grasscutter.scripts.data.SceneMonster
;
import
emu.grasscutter.scripts.data.SceneRegion
;
import
emu.grasscutter.scripts.data.SceneSuite
;
import
emu.grasscutter.scripts.data.SceneTrigger
;
import
emu.grasscutter.scripts.data.SceneVar
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
SceneScriptManager
{
private
final
Scene
scene
;
private
final
ScriptLib
scriptLib
;
private
final
LuaValue
scriptLibLua
;
private
final
Map
<
String
,
Integer
>
variables
;
private
Bindings
bindings
;
private
SceneConfig
config
;
private
List
<
SceneBlock
>
blocks
;
private
boolean
isInit
;
private
final
Int2ObjectOpenHashMap
<
Set
<
SceneTrigger
>>
triggers
;
private
final
Int2ObjectOpenHashMap
<
SceneRegion
>
regions
;
public
SceneScriptManager
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
scriptLib
=
new
ScriptLib
(
this
);
this
.
scriptLibLua
=
CoerceJavaToLua
.
coerce
(
this
.
scriptLib
);
this
.
triggers
=
new
Int2ObjectOpenHashMap
<>();
this
.
regions
=
new
Int2ObjectOpenHashMap
<>();
this
.
variables
=
new
HashMap
<>();
// TEMPORARY
if
(
this
.
getScene
().
getId
()
<
10
)
{
return
;
}
// Create
this
.
init
();
}
public
Scene
getScene
()
{
return
scene
;
}
public
ScriptLib
getScriptLib
()
{
return
scriptLib
;
}
public
LuaValue
getScriptLibLua
()
{
return
scriptLibLua
;
}
public
Bindings
getBindings
()
{
return
bindings
;
}
public
SceneConfig
getConfig
()
{
return
config
;
}
public
List
<
SceneBlock
>
getBlocks
()
{
return
blocks
;
}
public
Map
<
String
,
Integer
>
getVariables
()
{
return
variables
;
}
public
Set
<
SceneTrigger
>
getTriggersByEvent
(
int
eventId
)
{
return
triggers
.
computeIfAbsent
(
eventId
,
e
->
new
HashSet
<>());
}
public
void
registerTrigger
(
SceneTrigger
trigger
)
{
getTriggersByEvent
(
trigger
.
event
).
add
(
trigger
);
}
public
void
deregisterTrigger
(
SceneTrigger
trigger
)
{
getTriggersByEvent
(
trigger
.
event
).
remove
(
trigger
);
}
public
SceneRegion
getRegionById
(
int
id
)
{
return
regions
.
get
(
id
);
}
public
void
registerRegion
(
SceneRegion
region
)
{
regions
.
put
(
region
.
config_id
,
region
);
}
public
void
deregisterRegion
(
SceneRegion
region
)
{
regions
.
remove
(
region
.
config_id
);
}
// TODO optimize
public
SceneGroup
getGroupById
(
int
groupId
)
{
for
(
SceneBlock
block
:
this
.
getScene
().
getLoadedBlocks
())
{
for
(
SceneGroup
group
:
block
.
groups
)
{
if
(
group
.
id
==
groupId
)
{
return
group
;
}
}
}
return
null
;
}
private
void
init
()
{
// Get compiled script if cached
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
Grasscutter
.
getLogger
().
warn
(
"No script found for scene "
+
getScene
().
getId
());
return
;
}
// Create bindings
bindings
=
ScriptLoader
.
getEngine
().
createBindings
();
// Set variables
bindings
.
put
(
"ScriptLib"
,
getScriptLib
());
// Eval script
try
{
cs
.
eval
(
getBindings
());
this
.
config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneConfig
.
class
,
bindings
.
get
(
"scene_config"
));
// TODO optimize later
// Create blocks
List
<
Integer
>
blockIds
=
ScriptLoader
.
getSerializer
().
toList
(
Integer
.
class
,
bindings
.
get
(
"blocks"
));
List
<
SceneBlock
>
blocks
=
ScriptLoader
.
getSerializer
().
toList
(
SceneBlock
.
class
,
bindings
.
get
(
"block_rects"
));
for
(
int
i
=
0
;
i
<
blocks
.
size
();
i
++)
{
SceneBlock
block
=
blocks
.
get
(
i
);
block
.
id
=
blockIds
.
get
(
i
);
loadBlockFromScript
(
block
);
}
this
.
blocks
=
blocks
;
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error running script"
,
e
);
return
;
}
// TEMP
this
.
isInit
=
true
;
}
public
boolean
isInit
()
{
return
isInit
;
}
private
void
loadBlockFromScript
(
SceneBlock
block
)
{
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"_block"
+
block
.
id
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
return
;
}
// Eval script
try
{
cs
.
eval
(
getBindings
());
// Set groups
block
.
groups
=
ScriptLoader
.
getSerializer
().
toList
(
SceneGroup
.
class
,
bindings
.
get
(
"groups"
));
block
.
groups
.
forEach
(
g
->
g
.
block_id
=
block
.
id
);
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading block "
+
block
.
id
+
" in scene "
+
getScene
().
getId
(),
e
);
}
}
public
void
loadGroupFromScript
(
SceneGroup
group
)
{
// Set flag here so if there is no script, we dont call this function over and over again.
group
.
setLoaded
(
true
);
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
Grasscutter
.
getConfig
().
SCRIPTS_FOLDER
+
"Scene/"
+
getScene
().
getId
()
+
"/scene"
+
getScene
().
getId
()
+
"_group"
+
group
.
id
+
"."
+
ScriptLoader
.
getScriptType
());
if
(
cs
==
null
)
{
return
;
}
// Eval script
try
{
cs
.
eval
(
getBindings
());
// Set
group
.
monsters
=
ScriptLoader
.
getSerializer
().
toList
(
SceneMonster
.
class
,
bindings
.
get
(
"monsters"
));
group
.
gadgets
=
ScriptLoader
.
getSerializer
().
toList
(
SceneGadget
.
class
,
bindings
.
get
(
"gadgets"
));
group
.
triggers
=
ScriptLoader
.
getSerializer
().
toList
(
SceneTrigger
.
class
,
bindings
.
get
(
"triggers"
));
group
.
suites
=
ScriptLoader
.
getSerializer
().
toList
(
SceneSuite
.
class
,
bindings
.
get
(
"suites"
));
group
.
regions
=
ScriptLoader
.
getSerializer
().
toList
(
SceneRegion
.
class
,
bindings
.
get
(
"regions"
));
group
.
init_config
=
ScriptLoader
.
getSerializer
().
toObject
(
SceneInitConfig
.
class
,
bindings
.
get
(
"init_config"
));
// Add variables to suite
List
<
SceneVar
>
variables
=
ScriptLoader
.
getSerializer
().
toList
(
SceneVar
.
class
,
bindings
.
get
(
"variables"
));
variables
.
forEach
(
var
->
this
.
getVariables
().
put
(
var
.
name
,
var
.
value
));
// Add monsters to suite TODO optimize
Int2ObjectMap
<
Object
>
map
=
new
Int2ObjectOpenHashMap
<>();
group
.
monsters
.
forEach
(
m
->
map
.
put
(
m
.
config_id
,
m
));
group
.
gadgets
.
forEach
(
m
->
map
.
put
(
m
.
config_id
,
m
));
for
(
SceneSuite
suite
:
group
.
suites
)
{
suite
.
sceneMonsters
=
new
ArrayList
<>(
suite
.
monsters
.
size
());
for
(
int
id
:
suite
.
monsters
)
{
try
{
SceneMonster
monster
=
(
SceneMonster
)
map
.
get
(
id
);
if
(
monster
!=
null
)
{
suite
.
sceneMonsters
.
add
(
monster
);
}
}
catch
(
Exception
e
)
{
continue
;
}
}
suite
.
sceneGadgets
=
new
ArrayList
<>(
suite
.
gadgets
.
size
());
for
(
int
id
:
suite
.
gadgets
)
{
try
{
SceneGadget
gadget
=
(
SceneGadget
)
map
.
get
(
id
);
if
(
gadget
!=
null
)
{
suite
.
sceneGadgets
.
add
(
gadget
);
}
}
catch
(
Exception
e
)
{
continue
;
}
}
}
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading group "
+
group
.
id
+
" in scene "
+
getScene
().
getId
(),
e
);
}
}
public
void
onTick
()
{
checkRegions
();
}
public
void
checkRegions
()
{
if
(
this
.
regions
.
size
()
==
0
)
{
return
;
}
for
(
SceneRegion
region
:
this
.
regions
.
values
())
{
getScene
().
getEntities
().
values
()
.
stream
()
.
filter
(
e
->
e
.
getEntityType
()
<=
2
&&
region
.
contains
(
e
.
getPosition
()))
.
forEach
(
region:
:
addEntity
);
if
(
region
.
hasNewEntities
())
{
// This is not how it works, source_eid should be region entity id, but we dont have an entity for regions yet
callEvent
(
EventType
.
EVENT_ENTER_REGION
,
new
ScriptArgs
(
region
.
config_id
).
setSourceEntityId
(
region
.
config_id
));
region
.
resetNewEntities
();
}
}
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
spawnGadgetsInGroup
(
group
,
group
.
getSuiteByIndex
(
suiteIndex
));
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
)
{
spawnGadgetsInGroup
(
group
,
null
);
}
public
void
spawnGadgetsInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
List
<
SceneGadget
>
gadgets
=
group
.
gadgets
;
if
(
suite
!=
null
)
{
gadgets
=
suite
.
sceneGadgets
;
}
for
(
SceneGadget
g
:
gadgets
)
{
EntityGadget
entity
=
new
EntityGadget
(
getScene
(),
g
.
gadget_id
,
g
.
pos
);
if
(
entity
.
getGadgetData
()
==
null
)
continue
;
entity
.
setBlockId
(
group
.
block_id
);
entity
.
setConfigId
(
g
.
config_id
);
entity
.
setGroupId
(
group
.
id
);
entity
.
getRotation
().
set
(
g
.
rot
);
entity
.
setState
(
g
.
state
);
getScene
().
addEntity
(
entity
);
this
.
callEvent
(
EventType
.
EVENT_GADGET_CREATE
,
new
ScriptArgs
(
entity
.
getConfigId
()));
}
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
int
suiteIndex
)
{
spawnMonstersInGroup
(
group
,
group
.
getSuiteByIndex
(
suiteIndex
));
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
)
{
spawnMonstersInGroup
(
group
,
null
);
}
public
void
spawnMonstersInGroup
(
SceneGroup
group
,
SceneSuite
suite
)
{
List
<
SceneMonster
>
monsters
=
group
.
monsters
;
if
(
suite
!=
null
)
{
monsters
=
suite
.
sceneMonsters
;
}
List
<
GameEntity
>
toAdd
=
new
ArrayList
<>();
for
(
SceneMonster
monster
:
monsters
)
{
MonsterData
data
=
GameData
.
getMonsterDataMap
().
get
(
monster
.
monster_id
);
if
(
data
==
null
)
{
continue
;
}
// 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
(
worldLevelData
!=
null
)
{
level
=
worldLevelData
.
getMonsterLevel
();
}
}
// Spawn mob
EntityMonster
entity
=
new
EntityMonster
(
getScene
(),
data
,
monster
.
pos
,
level
);
entity
.
getRotation
().
set
(
monster
.
rot
);
entity
.
setGroupId
(
group
.
id
);
entity
.
setConfigId
(
monster
.
config_id
);
toAdd
.
add
(
entity
);
}
if
(
toAdd
.
size
()
>
0
)
{
getScene
().
addEntities
(
toAdd
);
for
(
GameEntity
entity
:
toAdd
)
{
callEvent
(
EventType
.
EVENT_ANY_MONSTER_LIVE
,
new
ScriptArgs
(
entity
.
getConfigId
()));
}
}
}
// Events
public
void
callEvent
(
int
eventType
,
ScriptArgs
params
)
{
for
(
SceneTrigger
trigger
:
this
.
getTriggersByEvent
(
eventType
))
{
LuaValue
condition
=
null
;
if
(
trigger
.
condition
!=
null
&&
!
trigger
.
condition
.
isEmpty
())
{
condition
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
condition
);
}
LuaValue
ret
=
LuaValue
.
TRUE
;
if
(
condition
!=
null
)
{
LuaValue
args
=
LuaValue
.
NIL
;
if
(
params
!=
null
)
{
args
=
CoerceJavaToLua
.
coerce
(
params
);
}
ret
=
condition
.
call
(
this
.
getScriptLibLua
(),
args
);
}
if
(
ret
.
checkboolean
()
==
true
)
{
LuaValue
action
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
action
);
action
.
call
(
this
.
getScriptLibLua
(),
LuaValue
.
NIL
);
}
}
}
}
src/main/java/emu/grasscutter/scripts/ScriptLib.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.MonsterData
;
import
emu.grasscutter.game.dungeons.DungeonChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.SceneMonster
;
import
emu.grasscutter.scripts.data.SceneRegion
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketGadgetStateNotify
;
import
emu.grasscutter.server.packet.send.PacketWorktopOptionNotify
;
public
class
ScriptLib
{
private
final
SceneScriptManager
sceneScriptManager
;
public
ScriptLib
(
SceneScriptManager
sceneScriptManager
)
{
this
.
sceneScriptManager
=
sceneScriptManager
;
}
public
SceneScriptManager
getSceneScriptManager
()
{
return
sceneScriptManager
;
}
public
int
SetGadgetStateByConfigId
(
int
configId
,
int
gadgetState
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
setState
(
gadgetState
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketGadgetStateNotify
(
gadget
,
gadgetState
));
return
0
;
}
public
int
SetGroupGadgetStateByConfigId
(
int
groupId
,
int
configId
,
int
gadgetState
)
{
List
<
GameEntity
>
list
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getGroupId
()
==
groupId
).
toList
();
for
(
GameEntity
entity
:
list
)
{
if
(!(
entity
instanceof
EntityGadget
))
{
continue
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
;
gadget
.
setState
(
gadgetState
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketGadgetStateNotify
(
gadget
,
gadgetState
));
}
return
0
;
}
public
int
SetWorktopOptionsByGroupId
(
int
groupId
,
int
configId
,
int
[]
options
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
&&
e
.
getGroupId
()
==
groupId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
addWorktopOptions
(
options
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketWorktopOptionNotify
(
gadget
));
return
0
;
}
public
int
DelWorktopOptionByGroupId
(
int
groupId
,
int
configId
,
int
option
)
{
Optional
<
GameEntity
>
entity
=
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
.
getConfigId
()
==
configId
&&
e
.
getGroupId
()
==
groupId
).
findFirst
();
if
(
entity
.
isEmpty
())
{
return
1
;
}
if
(!(
entity
.
get
()
instanceof
EntityGadget
))
{
return
1
;
}
EntityGadget
gadget
=
(
EntityGadget
)
entity
.
get
();
gadget
.
removeWorktopOption
(
option
);
getSceneScriptManager
().
getScene
().
broadcastPacket
(
new
PacketWorktopOptionNotify
(
gadget
));
return
0
;
}
// Some fields are guessed
public
int
AutoMonsterTide
(
int
challengeIndex
,
int
groupId
,
int
[]
config_ids
,
int
param4
,
int
param5
,
int
param6
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
// TODO just spawn all from group for now
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
);
return
0
;
}
public
int
AddExtraGroupSuite
(
int
groupId
,
int
suite
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
// TODO just spawn all from group for now
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
,
suite
);
return
0
;
}
// param3 (probably time limit for timed dungeons)
public
int
ActiveChallenge
(
int
challengeId
,
int
challengeIndex
,
int
param3
,
int
groupId
,
int
objectiveKills
,
int
param5
)
{
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
DungeonChallenge
challenge
=
new
DungeonChallenge
(
getSceneScriptManager
().
getScene
(),
group
);
challenge
.
setChallengeId
(
challengeId
);
challenge
.
setChallengeIndex
(
challengeIndex
);
challenge
.
setObjective
(
objectiveKills
);
getSceneScriptManager
().
getScene
().
setChallenge
(
challenge
);
challenge
.
start
();
return
0
;
}
public
int
GetGroupMonsterCountByGroupId
(
int
groupId
)
{
return
(
int
)
getSceneScriptManager
().
getScene
().
getEntities
().
values
().
stream
()
.
filter
(
e
->
e
instanceof
EntityMonster
&&
e
.
getGroupId
()
==
groupId
)
.
count
();
}
public
int
GetGroupVariableValue
(
String
var
)
{
return
getSceneScriptManager
().
getVariables
().
getOrDefault
(
var
,
0
);
}
public
int
SetGroupVariableValue
(
String
var
,
int
value
)
{
getSceneScriptManager
().
getVariables
().
put
(
var
,
value
);
return
0
;
}
public
LuaValue
ChangeGroupVariableValue
(
String
var
,
int
value
)
{
getSceneScriptManager
().
getVariables
().
put
(
var
,
getSceneScriptManager
().
getVariables
().
get
(
var
)
+
value
);
return
LuaValue
.
ZERO
;
}
public
int
RefreshGroup
(
LuaTable
table
)
{
// Kill and Respawn?
int
groupId
=
table
.
get
(
"group_id"
).
toint
();
int
suite
=
table
.
get
(
"suite"
).
toint
();
SceneGroup
group
=
getSceneScriptManager
().
getGroupById
(
groupId
);
if
(
group
==
null
||
group
.
monsters
==
null
)
{
return
1
;
}
this
.
getSceneScriptManager
().
spawnMonstersInGroup
(
group
,
suite
);
this
.
getSceneScriptManager
().
spawnGadgetsInGroup
(
group
,
suite
);
return
0
;
}
public
int
GetRegionEntityCount
(
LuaTable
table
)
{
int
regionId
=
table
.
get
(
"region_eid"
).
toint
();
int
entityType
=
table
.
get
(
"entity_type"
).
toint
();
SceneRegion
region
=
this
.
getSceneScriptManager
().
getRegionById
(
regionId
);
if
(
region
==
null
)
{
return
0
;
}
return
(
int
)
region
.
getEntities
().
intStream
().
filter
(
e
->
e
>>
24
==
entityType
).
count
();
}
public
void
PrintContextLog
(
String
msg
)
{
Grasscutter
.
getLogger
().
info
(
"[LUA] "
+
msg
);
}
public
int
TowerCountTimeStatus
(
int
var1
,
int
var2
){
return
0
;
}
public
int
GetGroupMonsterCount
(
int
var1
){
// Maybe...
return
GetGroupMonsterCountByGroupId
(
var1
);
}
public
int
SetMonsterBattleByGroup
(
int
var1
,
int
var2
,
int
var3
){
return
0
;
}
public
int
CauseDungeonFail
(
int
var1
){
return
0
;
}
}
src/main/java/emu/grasscutter/scripts/ScriptLoader.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.script.Compilable
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptEngine
;
import
javax.script.ScriptEngineFactory
;
import
javax.script.ScriptEngineManager
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.lib.OneArgFunction
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
org.luaj.vm2.script.LuajContext
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.props.EntityType
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.constants.ScriptGadgetState
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.scripts.serializer.LuaSerializer
;
import
emu.grasscutter.scripts.serializer.Serializer
;
public
class
ScriptLoader
{
private
static
ScriptEngineManager
sm
;
private
static
ScriptEngine
engine
;
private
static
ScriptEngineFactory
factory
;
private
static
String
fileType
;
private
static
Serializer
serializer
;
private
static
Map
<
String
,
CompiledScript
>
scripts
=
new
HashMap
<>();
public
synchronized
static
void
init
()
throws
Exception
{
if
(
sm
!=
null
)
{
throw
new
Exception
(
"Script loader already initialized"
);
}
// Create script engine
sm
=
new
ScriptEngineManager
();
engine
=
sm
.
getEngineByName
(
"luaj"
);
factory
=
getEngine
().
getFactory
();
// Lua stuff
fileType
=
"lua"
;
serializer
=
new
LuaSerializer
();
// Set engine to replace require as a temporary fix to missing scripts
LuajContext
ctx
=
(
LuajContext
)
engine
.
getContext
();
ctx
.
globals
.
set
(
"require"
,
new
OneArgFunction
()
{
@Override
public
LuaValue
call
(
LuaValue
arg0
)
{
return
LuaValue
.
ZERO
;
}
});
LuaTable
table
=
new
LuaTable
();
Arrays
.
stream
(
EntityType
.
values
()).
forEach
(
e
->
table
.
set
(
e
.
name
().
toUpperCase
(),
e
.
getValue
()));
ctx
.
globals
.
set
(
"EntityType"
,
table
);
ctx
.
globals
.
set
(
"EventType"
,
CoerceJavaToLua
.
coerce
(
new
EventType
()));
// TODO - make static class to avoid instantiating a new class every scene
ctx
.
globals
.
set
(
"GadgetState"
,
CoerceJavaToLua
.
coerce
(
new
ScriptGadgetState
()));
ctx
.
globals
.
set
(
"RegionShape"
,
CoerceJavaToLua
.
coerce
(
new
ScriptRegionShape
()));
}
public
static
ScriptEngine
getEngine
()
{
return
engine
;
}
public
static
String
getScriptType
()
{
return
fileType
;
}
public
static
Serializer
getSerializer
()
{
return
serializer
;
}
public
static
CompiledScript
getScriptByPath
(
String
path
)
{
CompiledScript
sc
=
scripts
.
get
(
path
);
Grasscutter
.
getLogger
().
info
(
"Loaded "
+
path
);
if
(
sc
==
null
)
{
File
file
=
new
File
(
path
);
if
(!
file
.
exists
())
return
null
;
try
(
FileReader
fr
=
new
FileReader
(
file
))
{
sc
=
((
Compilable
)
getEngine
()).
compile
(
fr
);
scripts
.
put
(
path
,
sc
);
}
catch
(
Exception
e
)
{
//e.printStackTrace();
return
null
;
}
}
return
sc
;
}
}
src/main/java/emu/grasscutter/scripts/constants/EventType.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.constants
;
public
class
EventType
{
public
static
final
int
EVENT_NONE
=
0
;
public
static
final
int
EVENT_ANY_MONSTER_DIE
=
1
;
public
static
final
int
EVENT_ANY_GADGET_DIE
=
2
;
public
static
final
int
EVENT_VARIABLE_CHANGE
=
3
;
public
static
final
int
EVENT_ENTER_REGION
=
4
;
public
static
final
int
EVENT_LEAVE_REGION
=
5
;
public
static
final
int
EVENT_GADGET_CREATE
=
6
;
public
static
final
int
EVENT_GADGET_STATE_CHANGE
=
7
;
public
static
final
int
EVENT_DUNGEON_SETTLE
=
8
;
public
static
final
int
EVENT_SELECT_OPTION
=
9
;
public
static
final
int
EVENT_CLIENT_EXECUTE
=
10
;
public
static
final
int
EVENT_ANY_MONSTER_LIVE
=
11
;
public
static
final
int
EVENT_SPECIFIC_MONSTER_HP_CHANGE
=
12
;
public
static
final
int
EVENT_CITY_LEVELUP_UNLOCK_DUNGEON_ENTRY
=
13
;
public
static
final
int
EVENT_DUNGEON_BROADCAST_ONTIMER
=
14
;
public
static
final
int
EVENT_TIMER_EVENT
=
15
;
public
static
final
int
EVENT_CHALLENGE_SUCCESS
=
16
;
public
static
final
int
EVENT_CHALLENGE_FAIL
=
17
;
public
static
final
int
EVENT_SEAL_BATTLE_BEGIN
=
18
;
public
static
final
int
EVENT_SEAL_BATTLE_END
=
19
;
public
static
final
int
EVENT_GATHER
=
20
;
public
static
final
int
EVENT_QUEST_FINISH
=
21
;
public
static
final
int
EVENT_MONSTER_BATTLE
=
22
;
public
static
final
int
EVENT_CITY_LEVELUP
=
23
;
public
static
final
int
EVENT_CUTSCENE_END
=
24
;
public
static
final
int
EVENT_AVATAR_NEAR_PLATFORM
=
25
;
public
static
final
int
EVENT_PLATFORM_REACH_POINT
=
26
;
public
static
final
int
EVENT_UNLOCK_TRANS_POINT
=
27
;
public
static
final
int
EVENT_QUEST_START
=
28
;
public
static
final
int
EVENT_GROUP_LOAD
=
29
;
public
static
final
int
EVENT_GROUP_WILL_UNLOAD
=
30
;
public
static
final
int
EVENT_GROUP_WILL_REFRESH
=
31
;
public
static
final
int
EVENT_GROUP_REFRESH
=
32
;
public
static
final
int
EVENT_DUNGEON_REWARD_GET
=
33
;
public
static
final
int
EVENT_SPECIFIC_GADGET_HP_CHANGE
=
34
;
public
static
final
int
EVENT_MONSTER_TIDE_OVER
=
35
;
public
static
final
int
EVENT_MONSTER_TIDE_CREATE
=
36
;
public
static
final
int
EVENT_MONSTER_TIDE_DIE
=
37
;
public
static
final
int
EVENT_SEALAMP_PHASE_CHANGE
=
38
;
public
static
final
int
EVENT_BLOSSOM_PROGRESS_FINISH
=
39
;
public
static
final
int
EVENT_BLOSSOM_CHEST_DIE
=
40
;
public
static
final
int
EVENT_GADGET_PLAY_START
=
41
;
public
static
final
int
EVENT_GADGET_PLAY_START_CD
=
42
;
public
static
final
int
EVENT_GADGET_PLAY_STOP
=
43
;
public
static
final
int
EVENT_GADGET_LUA_NOTIFY
=
44
;
public
static
final
int
EVENT_MP_PLAY_PREPARE
=
45
;
public
static
final
int
EVENT_MP_PLAY_BATTLE
=
46
;
public
static
final
int
EVENT_MP_PLAY_PREPARE_INTERRUPT
=
47
;
public
static
final
int
EVENT_SELECT_DIFFICULTY
=
48
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_STATE
=
49
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_STAGE_CHANGE
=
50
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_RESULT
=
51
;
public
static
final
int
EVENT_SEAL_BATTLE_PROGRESS_DECREASE
=
52
;
public
static
final
int
EVENT_GENERAL_REWARD_DIE
=
53
;
public
static
final
int
EVENT_SCENE_MP_PLAY_BATTLE_INTERRUPT
=
54
;
public
static
final
int
EVENT_MONSTER_DIE_BEFORE_LEAVE_SCENE
=
55
;
public
static
final
int
EVENT_SCENE_MP_PLAY_OPEN
=
56
;
public
static
final
int
EVENT_OFFERING_LEVELUP
=
57
;
public
static
final
int
EVENT_DUNGEON_REVIVE
=
58
;
public
static
final
int
EVENT_SCENE_MP_PLAY_ALL_AVATAR_DIE
=
59
;
public
static
final
int
EVENT_DUNGEON_ALL_AVATAR_DIE
=
60
;
public
static
final
int
EVENT_GENERAL_REWARD_TAKEN
=
61
;
public
static
final
int
EVENT_PLATFORM_REACH_ARRAYPOINT
=
62
;
public
static
final
int
EVENT_SCENE_MULTISTAGE_PLAY_STAGE_END
=
63
;
public
static
final
int
EVENT_SCENE_MULTISTAGE_PLAY_END_STAGE_REQ
=
64
;
public
static
final
int
EVENT_MECHANICUS_PICKED_CARD
=
65
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_OVER
=
66
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_CREATE
=
67
;
public
static
final
int
EVENT_POOL_MONSTER_TIDE_DIE
=
68
;
public
static
final
int
EVENT_DUNGEON_AVATAR_SLIP_DIE
=
69
;
public
static
final
int
EVENT_GALLERY_START
=
70
;
public
static
final
int
EVENT_GALLERY_STOP
=
71
;
public
static
final
int
EVENT_TIME_AXIS_PASS
=
72
;
public
static
final
int
EVENT_FLEUR_FAIR_DUNGEON_ALL_PLAYER_ENTER
=
73
;
public
static
final
int
EVENT_GADGETTALK_DONE
=
74
;
public
static
final
int
EVENT_SET_GAME_TIME
=
75
;
public
static
final
int
EVENT_HIDE_AND_SEEK_PLAYER_QUIT
=
76
;
public
static
final
int
EVENT_AVATAR_DIE
=
77
;
}
src/main/java/emu/grasscutter/scripts/constants/ScriptGadgetState.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.constants
;
public
class
ScriptGadgetState
{
public
static
final
int
Default
=
0
;
public
static
final
int
GatherDrop
=
1
;
public
static
final
int
ChestLocked
=
101
;
public
static
final
int
ChestOpened
=
102
;
public
static
final
int
ChestTrap
=
103
;
public
static
final
int
ChestBramble
=
104
;
public
static
final
int
ChestFrozen
=
105
;
public
static
final
int
ChestRock
=
106
;
public
static
final
int
GearStart
=
201
;
public
static
final
int
GearStop
=
202
;
public
static
final
int
GearAction1
=
203
;
public
static
final
int
GearAction2
=
204
;
public
static
final
int
CrystalResonate1
=
301
;
public
static
final
int
CrystalResonate2
=
302
;
public
static
final
int
CrystalExplode
=
303
;
public
static
final
int
CrystalDrain
=
304
;
public
static
final
int
StatueActive
=
401
;
public
static
final
int
Action01
=
901
;
public
static
final
int
Action02
=
902
;
public
static
final
int
Action03
=
903
;
}
src/main/java/emu/grasscutter/scripts/constants/ScriptRegionShape.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.constants
;
public
class
ScriptRegionShape
{
public
static
final
int
NONE
=
0
;
public
static
final
int
SPHERE
=
1
;
public
static
final
int
CUBIC
=
2
;
}
src/main/java/emu/grasscutter/scripts/data/SceneBlock.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneBlock
{
public
int
id
;
public
Position
max
;
public
Position
min
;
public
List
<
SceneGroup
>
groups
;
public
boolean
contains
(
Position
pos
)
{
return
pos
.
getX
()
<=
max
.
getX
()
&&
pos
.
getX
()
>=
min
.
getX
()
&&
pos
.
getZ
()
<=
max
.
getZ
()
&&
pos
.
getZ
()
>=
min
.
getZ
();
}
}
src/main/java/emu/grasscutter/scripts/data/SceneConfig.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneConfig
{
public
Position
vision_anchor
;
public
Position
born_pos
;
public
Position
born_rot
;
public
Position
begin_pos
;
public
Position
size
;
}
src/main/java/emu/grasscutter/scripts/data/SceneGadget.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneGadget
{
public
int
level
;
public
int
config_id
;
public
int
gadget_id
;
public
int
state
;
public
Position
pos
;
public
Position
rot
;
}
src/main/java/emu/grasscutter/scripts/data/SceneGroup.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneGroup
{
public
transient
int
block_id
;
// Not an actual variable in the scripts but we will keep it here for reference
public
int
id
;
public
int
refresh_id
;
public
Position
pos
;
public
List
<
SceneMonster
>
monsters
;
public
List
<
SceneGadget
>
gadgets
;
public
List
<
SceneTrigger
>
triggers
;
public
List
<
SceneRegion
>
regions
;
public
List
<
SceneSuite
>
suites
;
public
SceneInitConfig
init_config
;
private
transient
boolean
isLoaded
;
// Not an actual variable in the scripts either
public
boolean
isLoaded
()
{
return
isLoaded
;
}
public
boolean
setLoaded
(
boolean
loaded
)
{
return
loaded
;
}
public
SceneSuite
getSuiteByIndex
(
int
index
)
{
return
suites
.
get
(
index
-
1
);
}
}
src/main/java/emu/grasscutter/scripts/data/SceneInitConfig.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneInitConfig
{
public
int
suite
;
public
int
end_suite
;
public
int
rand_suite
;
}
src/main/java/emu/grasscutter/scripts/data/SceneMonster.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.utils.Position
;
public
class
SceneMonster
{
public
int
level
;
public
int
config_id
;
public
int
monster_id
;
public
Position
pos
;
public
Position
rot
;
}
src/main/java/emu/grasscutter/scripts/data/SceneRegion.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.scripts.constants.ScriptRegionShape
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
public
class
SceneRegion
{
public
int
config_id
;
public
int
shape
;
public
Position
pos
;
public
Position
size
;
private
boolean
hasNewEntities
;
private
final
IntSet
entities
;
// Ids of entities inside this region
public
SceneRegion
()
{
this
.
entities
=
new
IntOpenHashSet
();
}
public
IntSet
getEntities
()
{
return
entities
;
}
public
void
addEntity
(
GameEntity
entity
)
{
if
(
this
.
getEntities
().
contains
(
entity
.
getId
()))
{
return
;
}
this
.
getEntities
().
add
(
entity
.
getId
());
this
.
hasNewEntities
=
true
;
}
public
void
removeEntity
(
GameEntity
entity
)
{
this
.
getEntities
().
remove
(
entity
.
getId
());
}
public
boolean
contains
(
Position
p
)
{
switch
(
shape
)
{
case
ScriptRegionShape
.
CUBIC
:
return
(
Math
.
abs
(
pos
.
getX
()
-
p
.
getX
())
<=
size
.
getX
())
&&
(
Math
.
abs
(
pos
.
getZ
()
-
p
.
getZ
())
<=
size
.
getZ
());
case
ScriptRegionShape
.
SPHERE
:
return
false
;
}
return
false
;
}
public
boolean
hasNewEntities
()
{
return
hasNewEntities
;
}
public
void
resetNewEntities
()
{
hasNewEntities
=
false
;
}
}
src/main/java/emu/grasscutter/scripts/data/SceneSuite.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
import
java.util.List
;
import
emu.grasscutter.utils.Position
;
public
class
SceneSuite
{
public
List
<
Integer
>
monsters
;
public
List
<
Integer
>
gadgets
;
public
List
<
String
>
triggers
;
public
int
rand_weight
;
public
transient
List
<
SceneMonster
>
sceneMonsters
;
public
transient
List
<
SceneGadget
>
sceneGadgets
;
}
src/main/java/emu/grasscutter/scripts/data/SceneTrigger.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
public
class
SceneTrigger
{
public
String
name
;
public
int
config_id
;
public
int
event
;
public
String
source
;
public
String
condition
;
public
String
action
;
}
src/main/java/emu/grasscutter/scripts/data/SceneVar.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
public
class
SceneVar
{
public
String
name
;
public
int
value
;
public
boolean
no_refresh
;
}
src/main/java/emu/grasscutter/scripts/data/ScriptArgs.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.data
;
public
class
ScriptArgs
{
public
int
param1
;
public
int
param2
;
public
int
param3
;
public
int
source_eid
;
// Source entity
public
ScriptArgs
()
{
}
public
ScriptArgs
(
int
param1
)
{
this
.
param1
=
param1
;
}
public
ScriptArgs
(
int
param1
,
int
param2
)
{
this
.
param1
=
param1
;
this
.
param2
=
param2
;
}
public
int
getParam1
()
{
return
param1
;
}
public
ScriptArgs
setParam1
(
int
param1
)
{
this
.
param1
=
param1
;
return
this
;
}
public
int
getParam2
()
{
return
param2
;
}
public
ScriptArgs
setParam2
(
int
param2
)
{
this
.
param2
=
param2
;
return
this
;
}
public
int
getParam3
()
{
return
param3
;
}
public
ScriptArgs
setParam3
(
int
param3
)
{
this
.
param3
=
param3
;
return
this
;
}
public
int
getSourceEntityId
()
{
return
source_eid
;
}
public
ScriptArgs
setSourceEntityId
(
int
source_eid
)
{
this
.
source_eid
=
source_eid
;
return
this
;
}
}
src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.serializer
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
public
class
LuaSerializer
implements
Serializer
{
@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
);
}
public
<
T
>
List
<
T
>
serializeList
(
Class
<
T
>
type
,
LuaTable
table
)
{
List
<
T
>
list
=
new
ArrayList
();
try
{
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
try
{
LuaValue
keyValue
=
table
.
get
(
k
);
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
();
}
else
{
object
=
(
T
)
keyValue
;
}
if
(
object
!=
null
)
{
list
.
add
(
object
);
}
}
catch
(
Exception
ex
)
{
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
list
;
}
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
;
}
}
try
{
object
=
type
.
getDeclaredConstructor
().
newInstance
(
null
);
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
try
{
Field
field
=
object
.
getClass
().
getDeclaredField
(
k
.
checkjstring
());
if
(
field
==
null
)
{
continue
;
}
field
.
setAccessible
(
true
);
LuaValue
keyValue
=
table
.
get
(
k
);
if
(
keyValue
.
istable
())
{
field
.
set
(
object
,
serialize
(
field
.
getType
(),
keyValue
.
checktable
()));
}
else
if
(
field
.
getType
().
equals
(
float
.
class
))
{
field
.
setFloat
(
object
,
keyValue
.
tofloat
());
}
else
if
(
field
.
getType
().
equals
(
int
.
class
))
{
field
.
setInt
(
object
,
keyValue
.
toint
());
}
else
if
(
field
.
getType
().
equals
(
String
.
class
))
{
field
.
set
(
object
,
keyValue
.
tojstring
());
}
else
{
field
.
set
(
object
,
keyValue
);
}
}
catch
(
Exception
ex
)
{
//ex.printStackTrace();
continue
;
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
object
;
}
}
src/main/java/emu/grasscutter/scripts/serializer/Serializer.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.scripts.serializer
;
import
java.util.List
;
import
org.luaj.vm2.LuaTable
;
public
interface
Serializer
{
public
<
T
>
List
<
T
>
toList
(
Class
<
T
>
type
,
Object
obj
);
public
<
T
>
T
toObject
(
Class
<
T
>
type
,
Object
obj
);
}
src/main/java/emu/grasscutter/server/dispatch/AnnouncementHandler.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.dispatch
;
import
emu.grasscutter.Grasscutter
;
import
express.http.HttpContextHandler
;
import
express.http.Request
;
import
express.http.Response
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.util.Objects
;
public
final
class
AnnouncementHandler
implements
HttpContextHandler
{
@Override
public
void
handle
(
Request
request
,
Response
response
)
throws
IOException
{
//event
if
(
Objects
.
equals
(
request
.
baseUrl
(),
"/common/hk4e_global/announcement/api/getAnnContent"
))
{
response
.
send
(
"{\"retcode\":0,\"message\":\"OK\",\"data\":"
+
readToString
(
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"GameAnnouncement.json"
))
+
"}"
);
}
else
if
(
Objects
.
equals
(
request
.
baseUrl
(),
"/common/hk4e_global/announcement/api/getAnnList"
))
{
String
data
=
readToString
(
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"GameAnnouncementList.json"
)).
replace
(
"System.currentTimeMillis()"
,
String
.
valueOf
(
System
.
currentTimeMillis
()));
response
.
send
(
"{\"retcode\":0,\"message\":\"OK\",\"data\": "
+
data
+
"}"
);
}
}
private
static
String
readToString
(
File
file
)
{
Long
filelength
=
file
.
length
();
byte
[]
filecontent
=
new
byte
[
filelength
.
intValue
()];
try
{
FileInputStream
in
=
new
FileInputStream
(
file
);
in
.
read
(
filecontent
);
in
.
close
();
}
catch
(
IOException
fileNotFoundException
)
{
fileNotFoundException
.
printStackTrace
();
}
return
new
String
(
filecontent
);
}
}
\ No newline at end of file
Prev
1
…
7
8
9
10
11
12
13
14
15
…
25
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment