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
bad85357
Commit
bad85357
authored
May 19, 2022
by
Akka
Committed by
Melledy
May 18, 2022
Browse files
optimized the Lua func binding so that the script will not eval again
parent
a8f38ad9
Changes
7
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/dungeons/DungeonChallenge.java
View file @
bad85357
...
@@ -138,7 +138,9 @@ public class DungeonChallenge {
...
@@ -138,7 +138,9 @@ public class DungeonChallenge {
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
getScene
().
getDungeonSettleObservers
().
forEach
(
o
->
o
.
onDungeonSettle
(
getScene
()));
if
(!
stage
){
if
(!
stage
){
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_DUNGEON_SETTLE
,
new
ScriptArgs
(
this
.
isSuccess
()
?
1
:
0
));
getScene
().
getScriptManager
().
callEvent
(
EventType
.
EVENT_DUNGEON_SETTLE
,
// TODO record the time in PARAM2 and used in action
new
ScriptArgs
(
this
.
isSuccess
()
?
1
:
0
,
100
));
}
}
}
}
...
...
src/main/java/emu/grasscutter/game/world/WorldDataManager.java
View file @
bad85357
...
@@ -26,7 +26,7 @@ public class WorldDataManager {
...
@@ -26,7 +26,7 @@ public class WorldDataManager {
}
}
public
synchronized
void
load
(){
public
synchronized
void
load
(){
try
(
InputStream
is
=
DataLoader
.
load
(
"ChestReward.json"
,
false
);
InputStreamReader
isr
=
new
InputStreamReader
(
is
))
{
try
(
InputStream
is
=
DataLoader
.
load
(
"ChestReward.json"
);
InputStreamReader
isr
=
new
InputStreamReader
(
is
))
{
List
<
ChestReward
>
chestReward
=
Grasscutter
.
getGsonFactory
().
fromJson
(
List
<
ChestReward
>
chestReward
=
Grasscutter
.
getGsonFactory
().
fromJson
(
isr
,
isr
,
TypeToken
.
getParameterized
(
List
.
class
,
ChestReward
.
class
).
getType
());
TypeToken
.
getParameterized
(
List
.
class
,
ChestReward
.
class
).
getType
());
...
...
src/main/java/emu/grasscutter/scripts/SceneScriptManager.java
View file @
bad85357
...
@@ -20,16 +20,11 @@ import org.luaj.vm2.LuaError;
...
@@ -20,16 +20,11 @@ import org.luaj.vm2.LuaError;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
org.luaj.vm2.lib.jse.CoerceJavaToLua
;
import
javax.script.Bindings
;
import
javax.script.ScriptException
;
import
java.util.*
;
import
java.util.*
;
public
class
SceneScriptManager
{
public
class
SceneScriptManager
{
private
final
Scene
scene
;
private
final
Scene
scene
;
private
final
ScriptLib
scriptLib
;
private
final
LuaValue
scriptLibLua
;
private
final
Map
<
String
,
Integer
>
variables
;
private
final
Map
<
String
,
Integer
>
variables
;
private
Bindings
bindings
;
private
SceneMeta
meta
;
private
SceneMeta
meta
;
private
boolean
isInit
;
private
boolean
isInit
;
/**
/**
...
@@ -50,8 +45,6 @@ public class SceneScriptManager {
...
@@ -50,8 +45,6 @@ public class SceneScriptManager {
private
Int2ObjectMap
<
Set
<
SceneGroup
>>
loadedGroupSetPerBlock
;
private
Int2ObjectMap
<
Set
<
SceneGroup
>>
loadedGroupSetPerBlock
;
public
SceneScriptManager
(
Scene
scene
)
{
public
SceneScriptManager
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
scene
=
scene
;
this
.
scriptLib
=
new
ScriptLib
(
this
);
this
.
scriptLibLua
=
CoerceJavaToLua
.
coerce
(
this
.
scriptLib
);
this
.
triggers
=
new
HashMap
<>();
this
.
triggers
=
new
HashMap
<>();
this
.
currentTriggers
=
new
Int2ObjectOpenHashMap
<>();
this
.
currentTriggers
=
new
Int2ObjectOpenHashMap
<>();
...
@@ -74,18 +67,6 @@ public class SceneScriptManager {
...
@@ -74,18 +67,6 @@ public class SceneScriptManager {
return
scene
;
return
scene
;
}
}
public
ScriptLib
getScriptLib
()
{
return
scriptLib
;
}
public
LuaValue
getScriptLibLua
()
{
return
scriptLibLua
;
}
public
Bindings
getBindings
()
{
return
bindings
;
}
public
SceneConfig
getConfig
()
{
public
SceneConfig
getConfig
()
{
if
(!
isInit
){
if
(!
isInit
){
return
null
;
return
null
;
...
@@ -162,11 +143,6 @@ public class SceneScriptManager {
...
@@ -162,11 +143,6 @@ public class SceneScriptManager {
}
}
private
void
init
()
{
private
void
init
()
{
// Create bindings
bindings
=
ScriptLoader
.
getEngine
().
createBindings
();
// Set variables
bindings
.
put
(
"ScriptLib"
,
getScriptLib
());
var
meta
=
ScriptLoader
.
getSceneMeta
(
getScene
().
getId
());
var
meta
=
ScriptLoader
.
getSceneMeta
(
getScene
().
getId
());
if
(
meta
==
null
){
if
(
meta
==
null
){
return
;
return
;
...
@@ -186,14 +162,7 @@ public class SceneScriptManager {
...
@@ -186,14 +162,7 @@ public class SceneScriptManager {
}
}
public
void
loadGroupFromScript
(
SceneGroup
group
)
{
public
void
loadGroupFromScript
(
SceneGroup
group
)
{
group
.
load
(
getScene
().
getId
(),
meta
.
context
);
group
.
load
(
getScene
().
getId
());
try
{
// build the trigger for this scene
group
.
getScript
().
eval
(
getBindings
());
}
catch
(
ScriptException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Could not build the trigger for this scene"
,
e
);
}
group
.
variables
.
forEach
(
var
->
this
.
getVariables
().
put
(
var
.
name
,
var
.
value
));
group
.
variables
.
forEach
(
var
->
this
.
getVariables
().
put
(
var
.
name
,
var
.
value
));
this
.
sceneGroups
.
put
(
group
.
id
,
group
);
this
.
sceneGroups
.
put
(
group
.
id
,
group
);
...
@@ -284,47 +253,55 @@ public class SceneScriptManager {
...
@@ -284,47 +253,55 @@ public class SceneScriptManager {
// Events
// Events
public
void
callEvent
(
int
eventType
,
ScriptArgs
params
)
{
public
void
callEvent
(
int
eventType
,
ScriptArgs
params
)
{
try
{
ScriptLoader
.
getScriptLib
().
setSceneScriptManager
(
this
);
for
(
SceneTrigger
trigger
:
this
.
getTriggersByEvent
(
eventType
))
{
for
(
SceneTrigger
trigger
:
this
.
getTriggersByEvent
(
eventType
))
{
scriptLib
.
setCurrentGroup
(
trigger
.
currentGroup
);
try
{
LuaValue
condition
=
null
;
ScriptLoader
.
getScriptLib
().
setCurrentGroup
(
trigger
.
currentGroup
);
LuaValue
ret
=
callScriptFunc
(
trigger
.
condition
,
trigger
.
currentGroup
,
params
);
Grasscutter
.
getLogger
().
trace
(
"Call Condition Trigger {}"
,
trigger
.
condition
);
if
(
ret
.
isboolean
()
&&
ret
.
checkboolean
())
{
// the SetGroupVariableValueByGroup in tower need the param to record the first stage time
callScriptFunc
(
trigger
.
action
,
trigger
.
currentGroup
,
params
);
Grasscutter
.
getLogger
().
trace
(
"Call Action Trigger {}"
,
trigger
.
action
);
}
//TODO some ret may not bool
}
finally
{
ScriptLoader
.
getScriptLib
().
removeCurrentGroup
();
}
}
}
finally
{
// make sure it is removed
ScriptLoader
.
getScriptLib
().
removeSceneScriptManager
();
}
}
if
(
trigger
.
condition
!=
null
&&
!
trigger
.
condition
.
isEmpty
())
{
public
LuaValue
callScriptFunc
(
String
funcName
,
SceneGroup
group
,
ScriptArgs
params
){
condition
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
condition
);
LuaValue
funcLua
=
null
;
if
(
funcName
!=
null
&&
!
funcName
.
isEmpty
())
{
funcLua
=
(
LuaValue
)
group
.
getBindings
().
get
(
funcName
);
}
}
LuaValue
ret
=
LuaValue
.
TRUE
;
LuaValue
ret
=
LuaValue
.
TRUE
;
if
(
condition
!=
null
)
{
if
(
funcLua
!=
null
)
{
LuaValue
args
=
LuaValue
.
NIL
;
LuaValue
args
=
LuaValue
.
NIL
;
if
(
params
!=
null
)
{
if
(
params
!=
null
)
{
args
=
CoerceJavaToLua
.
coerce
(
params
);
args
=
CoerceJavaToLua
.
coerce
(
params
);
}
}
ScriptLib
.
logger
.
trace
(
"Call Condition Trigger {}"
,
trigger
);
ret
=
safetyCall
(
funcName
,
funcLua
,
args
);
ret
=
safetyCall
(
trigger
.
condition
,
condition
,
args
);
}
if
(
ret
.
isboolean
()
&&
ret
.
checkboolean
())
{
if
(
trigger
.
action
==
null
||
trigger
.
action
.
isEmpty
()){
return
;
}
ScriptLib
.
logger
.
trace
(
"Call Action Trigger {}"
,
trigger
);
LuaValue
action
=
(
LuaValue
)
this
.
getBindings
().
get
(
trigger
.
action
);
// TODO impl the param of SetGroupVariableValueByGroup
var
arg
=
new
ScriptArgs
();
arg
.
param2
=
100
;
var
args
=
CoerceJavaToLua
.
coerce
(
arg
);
safetyCall
(
trigger
.
action
,
action
,
args
);
}
//TODO some ret may not bool
scriptLib
.
removeCurrentGroup
();
}
}
return
ret
;
}
}
public
LuaValue
safetyCall
(
String
name
,
LuaValue
func
,
LuaValue
args
){
public
LuaValue
safetyCall
(
String
name
,
LuaValue
func
,
LuaValue
args
){
try
{
try
{
return
func
.
call
(
this
.
getScriptLibLua
(),
args
);
return
func
.
call
(
ScriptLoader
.
getScriptLibLua
(),
args
);
}
catch
(
LuaError
error
){
}
catch
(
LuaError
error
){
ScriptLib
.
logger
.
error
(
"[LUA] call trigger failed {},{},{}"
,
name
,
args
,
error
.
getMessage
());
ScriptLib
.
logger
.
error
(
"[LUA] call trigger failed {},{},{}"
,
name
,
args
,
error
.
getMessage
());
return
LuaValue
.
valueOf
(-
1
);
return
LuaValue
.
valueOf
(-
1
);
...
...
src/main/java/emu/grasscutter/scripts/ScriptLib.java
View file @
bad85357
...
@@ -10,6 +10,7 @@ import emu.grasscutter.scripts.data.SceneRegion;
...
@@ -10,6 +10,7 @@ import emu.grasscutter.scripts.data.SceneRegion;
import
emu.grasscutter.server.packet.send.PacketCanUseSkillNotify
;
import
emu.grasscutter.server.packet.send.PacketCanUseSkillNotify
;
import
emu.grasscutter.server.packet.send.PacketGadgetStateNotify
;
import
emu.grasscutter.server.packet.send.PacketGadgetStateNotify
;
import
emu.grasscutter.server.packet.send.PacketWorktopOptionNotify
;
import
emu.grasscutter.server.packet.send.PacketWorktopOptionNotify
;
import
io.netty.util.concurrent.FastThreadLocal
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaTable
;
import
org.luaj.vm2.LuaValue
;
import
org.luaj.vm2.LuaValue
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -20,15 +21,24 @@ import java.util.Optional;
...
@@ -20,15 +21,24 @@ import java.util.Optional;
public
class
ScriptLib
{
public
class
ScriptLib
{
public
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ScriptLib
.
class
);
public
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ScriptLib
.
class
);
private
final
SceneScriptManager
sceneScriptManager
;
private
final
FastThreadLocal
<
SceneScriptManager
>
sceneScriptManager
;
private
final
FastThreadLocal
<
SceneGroup
>
currentGroup
;
public
ScriptLib
()
{
this
.
sceneScriptManager
=
new
FastThreadLocal
<>();
this
.
currentGroup
=
new
FastThreadLocal
<>();
}
public
void
setSceneScriptManager
(
SceneScriptManager
sceneScriptManager
){
this
.
sceneScriptManager
.
set
(
sceneScriptManager
);
}
public
ScriptLib
(
SceneScriptManager
sceneScriptManager
)
{
public
void
removeSceneScriptManager
(){
this
.
sceneScriptManager
=
sceneScriptManager
;
this
.
sceneScriptManager
.
remove
();
this
.
currentGroup
=
new
ThreadLocal
<>();
}
}
public
SceneScriptManager
getSceneScriptManager
()
{
public
SceneScriptManager
getSceneScriptManager
()
{
return
sceneScriptManager
;
// normally not null
return
Optional
.
of
(
sceneScriptManager
.
get
()).
get
();
}
}
private
String
printTable
(
LuaTable
table
){
private
String
printTable
(
LuaTable
table
){
...
@@ -40,13 +50,11 @@ public class ScriptLib {
...
@@ -40,13 +50,11 @@ public class ScriptLib {
sb
.
append
(
"}"
);
sb
.
append
(
"}"
);
return
sb
.
toString
();
return
sb
.
toString
();
}
}
private
final
ThreadLocal
<
SceneGroup
>
currentGroup
;
public
void
setCurrentGroup
(
SceneGroup
currentGroup
){
public
void
setCurrentGroup
(
SceneGroup
currentGroup
){
logger
.
debug
(
"current {}"
,
currentGroup
);
this
.
currentGroup
.
set
(
currentGroup
);
this
.
currentGroup
.
set
(
currentGroup
);
}
}
public
Optional
<
SceneGroup
>
getCurrentGroup
(){
public
Optional
<
SceneGroup
>
getCurrentGroup
(){
return
Optional
.
of
Nullable
(
this
.
currentGroup
.
get
());
return
Optional
.
of
(
this
.
currentGroup
.
get
());
}
}
public
void
removeCurrentGroup
(){
public
void
removeCurrentGroup
(){
this
.
currentGroup
.
remove
();
this
.
currentGroup
.
remove
();
...
...
src/main/java/emu/grasscutter/scripts/ScriptLoader.java
View file @
bad85357
...
@@ -29,6 +29,8 @@ public class ScriptLoader {
...
@@ -29,6 +29,8 @@ public class ScriptLoader {
private
static
ScriptEngineFactory
factory
;
private
static
ScriptEngineFactory
factory
;
private
static
String
fileType
;
private
static
String
fileType
;
private
static
Serializer
serializer
;
private
static
Serializer
serializer
;
private
static
ScriptLib
scriptLib
;
private
static
LuaValue
scriptLibLua
;
/**
/**
* suggest GC to remove it if the memory is less
* suggest GC to remove it if the memory is less
*/
*/
...
@@ -68,6 +70,10 @@ public class ScriptLoader {
...
@@ -68,6 +70,10 @@ public class ScriptLoader {
ctx
.
globals
.
set
(
"EventType"
,
CoerceJavaToLua
.
coerce
(
new
EventType
()));
// TODO - make static class to avoid instantiating a new class every scene
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
(
"GadgetState"
,
CoerceJavaToLua
.
coerce
(
new
ScriptGadgetState
()));
ctx
.
globals
.
set
(
"RegionShape"
,
CoerceJavaToLua
.
coerce
(
new
ScriptRegionShape
()));
ctx
.
globals
.
set
(
"RegionShape"
,
CoerceJavaToLua
.
coerce
(
new
ScriptRegionShape
()));
scriptLib
=
new
ScriptLib
();
scriptLibLua
=
CoerceJavaToLua
.
coerce
(
scriptLib
);
ctx
.
globals
.
set
(
"ScriptLib"
,
scriptLibLua
);
}
}
public
static
ScriptEngine
getEngine
()
{
public
static
ScriptEngine
getEngine
()
{
...
@@ -82,6 +88,14 @@ public class ScriptLoader {
...
@@ -82,6 +88,14 @@ public class ScriptLoader {
return
serializer
;
return
serializer
;
}
}
public
static
ScriptLib
getScriptLib
()
{
return
scriptLib
;
}
public
static
LuaValue
getScriptLibLua
()
{
return
scriptLibLua
;
}
public
static
<
T
>
Optional
<
T
>
tryGet
(
SoftReference
<
T
>
softReference
){
public
static
<
T
>
Optional
<
T
>
tryGet
(
SoftReference
<
T
>
softReference
){
try
{
try
{
return
Optional
.
ofNullable
(
softReference
.
get
());
return
Optional
.
ofNullable
(
softReference
.
get
());
...
...
src/main/java/emu/grasscutter/scripts/data/SceneGroup.java
View file @
bad85357
...
@@ -10,12 +10,11 @@ import javax.script.Bindings;
...
@@ -10,12 +10,11 @@ import javax.script.Bindings;
import
javax.script.CompiledScript
;
import
javax.script.CompiledScript
;
import
javax.script.ScriptException
;
import
javax.script.ScriptException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
import
static
emu
.
grasscutter
.
Configuration
.
*
;
import
static
emu
.
grasscutter
.
Configuration
.
SCRIPT
;
@ToString
@ToString
@Setter
@Setter
...
@@ -40,6 +39,7 @@ public class SceneGroup {
...
@@ -40,6 +39,7 @@ public class SceneGroup {
private
transient
boolean
loaded
;
// Not an actual variable in the scripts either
private
transient
boolean
loaded
;
// Not an actual variable in the scripts either
private
transient
CompiledScript
script
;
private
transient
CompiledScript
script
;
private
transient
Bindings
bindings
;
public
boolean
isLoaded
()
{
public
boolean
isLoaded
()
{
return
loaded
;
return
loaded
;
...
@@ -65,13 +65,19 @@ public class SceneGroup {
...
@@ -65,13 +65,19 @@ public class SceneGroup {
return
suites
.
get
(
index
-
1
);
return
suites
.
get
(
index
-
1
);
}
}
public
SceneGroup
load
(
int
sceneId
,
Bindings
bindings
){
public
Bindings
getBindings
()
{
return
bindings
;
}
public
SceneGroup
load
(
int
sceneId
){
if
(
loaded
){
if
(
loaded
){
return
this
;
return
this
;
}
}
// Set flag here so if there is no script, we dont call this function over and over again.
// Set flag here so if there is no script, we dont call this function over and over again.
setLoaded
(
true
);
setLoaded
(
true
);
this
.
bindings
=
ScriptLoader
.
getEngine
().
createBindings
();
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
CompiledScript
cs
=
ScriptLoader
.
getScriptByPath
(
SCRIPT
(
"Scene/"
+
sceneId
+
"/scene"
+
sceneId
+
"_group"
+
id
+
"."
+
ScriptLoader
.
getScriptType
()));
SCRIPT
(
"Scene/"
+
sceneId
+
"/scene"
+
sceneId
+
"_group"
+
id
+
"."
+
ScriptLoader
.
getScriptType
()));
...
...
src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java
View file @
bad85357
...
@@ -87,6 +87,9 @@ public class LuaSerializer implements Serializer {
...
@@ -87,6 +87,9 @@ public class LuaSerializer implements Serializer {
object
=
(
T
)
constructorCache
.
get
(
type
).
newInstance
();
object
=
(
T
)
constructorCache
.
get
(
type
).
newInstance
();
if
(
table
==
null
){
return
object
;
}
LuaValue
[]
keys
=
table
.
keys
();
LuaValue
[]
keys
=
table
.
keys
();
for
(
LuaValue
k
:
keys
)
{
for
(
LuaValue
k
:
keys
)
{
try
{
try
{
...
...
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