Commit 23800745 authored by omg-xtao's avatar omg-xtao Committed by GitHub
Browse files

Merge branch 'development' into tp

parents 7fdf7498 eef216ae
...@@ -17,6 +17,7 @@ import emu.grasscutter.game.entity.GameEntity; ...@@ -17,6 +17,7 @@ import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup; import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster; import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.SceneRegion;
import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.scripts.data.ScriptArgs;
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;
...@@ -184,6 +185,19 @@ public class ScriptLib { ...@@ -184,6 +185,19 @@ public class ScriptLib {
return 0; 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) { public void PrintContextLog(String msg) {
Grasscutter.getLogger().info("[LUA] " + msg); Grasscutter.getLogger().info("[LUA] " + msg);
} }
......
...@@ -4,6 +4,7 @@ import java.io.File; ...@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -13,7 +14,17 @@ import javax.script.ScriptEngine; ...@@ -13,7 +14,17 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager; 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.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.LuaSerializer;
import emu.grasscutter.scripts.serializer.Serializer; import emu.grasscutter.scripts.serializer.Serializer;
...@@ -31,11 +42,31 @@ public class ScriptLoader { ...@@ -31,11 +42,31 @@ public class ScriptLoader {
throw new Exception("Script loader already initialized"); throw new Exception("Script loader already initialized");
} }
// Create script engine
sm = new ScriptEngineManager(); sm = new ScriptEngineManager();
engine = sm.getEngineByName("luaj"); engine = sm.getEngineByName("luaj");
factory = getEngine().getFactory(); factory = getEngine().getFactory();
// Lua stuff
fileType = "lua"; fileType = "lua";
serializer = new LuaSerializer(); 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() { public static ScriptEngine getEngine() {
......
...@@ -14,6 +14,7 @@ public class SceneGroup { ...@@ -14,6 +14,7 @@ public class SceneGroup {
public List<SceneMonster> monsters; public List<SceneMonster> monsters;
public List<SceneGadget> gadgets; public List<SceneGadget> gadgets;
public List<SceneTrigger> triggers; public List<SceneTrigger> triggers;
public List<SceneRegion> regions;
public List<SceneSuite> suites; public List<SceneSuite> suites;
public SceneInitConfig init_config; public SceneInitConfig init_config;
......
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;
}
}
...@@ -4,6 +4,7 @@ public class ScriptArgs { ...@@ -4,6 +4,7 @@ public class ScriptArgs {
public int param1; public int param1;
public int param2; public int param2;
public int param3; public int param3;
public int source_eid; // Source entity
public ScriptArgs() { public ScriptArgs() {
...@@ -44,4 +45,13 @@ public class ScriptArgs { ...@@ -44,4 +45,13 @@ public class ScriptArgs {
this.param3 = param3; this.param3 = param3;
return this; return this;
} }
public int getSourceEntityId() {
return source_eid;
}
public ScriptArgs setSourceEntityId(int source_eid) {
this.source_eid = source_eid;
return this;
}
} }
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetOnlinePlayerListRsp;
@Opcodes(PacketOpcodes.GetOnlinePlayerListReq)
public class HandlerGetOnlinePlayerListReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
session.send(new PacketGetOnlinePlayerListRsp(session.getPlayer()));
}
}
...@@ -17,10 +17,12 @@ public class PacketDungeonEntryInfoRsp extends BasePacket { ...@@ -17,10 +17,12 @@ public class PacketDungeonEntryInfoRsp extends BasePacket {
DungeonEntryInfoRsp.Builder proto = DungeonEntryInfoRsp.newBuilder() DungeonEntryInfoRsp.Builder proto = DungeonEntryInfoRsp.newBuilder()
.setPointId(pointData.getId()); .setPointId(pointData.getId());
if (pointData.getDungeonIds() != null) {
for (int dungeonId : pointData.getDungeonIds()) { for (int dungeonId : pointData.getDungeonIds()) {
DungeonEntryInfo info = DungeonEntryInfo.newBuilder().setDungeonId(dungeonId).build(); DungeonEntryInfo info = DungeonEntryInfo.newBuilder().setDungeonId(dungeonId).build();
proto.addDungeonEntryList(info); proto.addDungeonEntryList(info);
} }
}
this.setData(proto); this.setData(proto);
} }
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetOnlinePlayerListReqOuterClass;
import emu.grasscutter.net.proto.GetOnlinePlayerListRspOuterClass.*;
import emu.grasscutter.net.proto.MpSettingTypeOuterClass;
import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class PacketGetOnlinePlayerListRsp extends BasePacket {
public PacketGetOnlinePlayerListRsp(Player session){
super(PacketOpcodes.GetOnlinePlayerListRsp);
List<Player> players = Grasscutter.getGameServer().getPlayers().values().stream().limit(50).toList();
GetOnlinePlayerListRsp.Builder proto = GetOnlinePlayerListRsp.newBuilder();
if (players.size() != 0) {
for(Player player : players) {
if (player.getUid() == session.getUid()) continue;
proto.addPlayerInfoList(player.getOnlinePlayerInfo());
}
}
this.setData(proto);
}
}
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.data.GameData;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetScenePointRspOuterClass.GetScenePointRsp; import emu.grasscutter.net.proto.GetScenePointRspOuterClass.GetScenePointRsp;
...@@ -12,9 +13,13 @@ public class PacketGetScenePointRsp extends BasePacket { ...@@ -12,9 +13,13 @@ public class PacketGetScenePointRsp extends BasePacket {
GetScenePointRsp.Builder p = GetScenePointRsp.newBuilder() GetScenePointRsp.Builder p = GetScenePointRsp.newBuilder()
.setSceneId(sceneId); .setSceneId(sceneId);
if (GameData.getScenePointIdList().size() == 0) {
for (int i = 1; i < 1000; i++) { for (int i = 1; i < 1000; i++) {
p.addUnlockedPointList(i); p.addUnlockedPointList(i);
} }
} else {
p.addAllUnlockedPointList(GameData.getScenePointIdList());
}
for (int i = 1; i < 9; i++) { for (int i = 1; i < 9; i++) {
p.addUnlockAreaList(i); p.addUnlockAreaList(i);
......
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.entity.EntityVehicle;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.entity.GameEntity; import emu.grasscutter.game.entity.GameEntity;
...@@ -17,16 +18,49 @@ public class PacketVehicleInteractRsp extends BasePacket { ...@@ -17,16 +18,49 @@ public class PacketVehicleInteractRsp extends BasePacket {
VehicleInteractRsp.Builder proto = VehicleInteractRsp.newBuilder(); VehicleInteractRsp.Builder proto = VehicleInteractRsp.newBuilder();
GameEntity vehicle = player.getScene().getEntityById(entityId); GameEntity vehicle = player.getScene().getEntityById(entityId);
if(vehicle != null) {
if(vehicle instanceof EntityVehicle) {
proto.setEntityId(vehicle.getId()); proto.setEntityId(vehicle.getId());
proto.setInteractType(interactType);
VehicleMember vehicleMember = VehicleMember.newBuilder() VehicleMember vehicleMember = VehicleMember.newBuilder()
.setUid(player.getUid()) .setUid(player.getUid())
.setAvatarGuid(player.getTeamManager().getCurrentCharacterGuid()) .setAvatarGuid(player.getTeamManager().getCurrentCharacterGuid())
.build(); .build();
proto.setInteractType(interactType);
proto.setMember(vehicleMember); proto.setMember(vehicleMember);
switch(interactType){
case VEHICLE_INTERACT_IN -> {
((EntityVehicle) vehicle).getVehicleMembers().add(vehicleMember);
}
case VEHICLE_INTERACT_OUT -> {
((EntityVehicle) vehicle).getVehicleMembers().remove(vehicleMember);
}
default -> {}
}
}
this.setData(proto.build());
}
public PacketVehicleInteractRsp(EntityVehicle vehicle, VehicleMember vehicleMember, VehicleInteractType interactType) {
super(PacketOpcodes.VehicleInteractRsp);
VehicleInteractRsp.Builder proto = VehicleInteractRsp.newBuilder();
if(vehicle != null) {
proto.setEntityId(vehicle.getId());
proto.setInteractType(interactType);
proto.setMember(vehicleMember);
switch(interactType){
case VEHICLE_INTERACT_IN -> {
vehicle.getVehicleMembers().add(vehicleMember);
}
case VEHICLE_INTERACT_OUT -> {
vehicle.getVehicleMembers().remove(vehicleMember);
}
default -> {}
}
} }
this.setData(proto.build()); this.setData(proto.build());
} }
......
...@@ -8,10 +8,16 @@ import emu.grasscutter.game.entity.GameEntity; ...@@ -8,10 +8,16 @@ import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.VehicleMemberOuterClass.VehicleMember;
import emu.grasscutter.net.proto.VehicleSpawnRspOuterClass.VehicleSpawnRsp; import emu.grasscutter.net.proto.VehicleSpawnRspOuterClass.VehicleSpawnRsp;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.List;
import static emu.grasscutter.net.proto.VehicleInteractTypeOuterClass.VehicleInteractType.VEHICLE_INTERACT_OUT;
public class PacketVehicleSpawnRsp extends BasePacket { public class PacketVehicleSpawnRsp extends BasePacket {
...@@ -19,6 +25,23 @@ public class PacketVehicleSpawnRsp extends BasePacket { ...@@ -19,6 +25,23 @@ public class PacketVehicleSpawnRsp extends BasePacket {
super(PacketOpcodes.VehicleSpawnRsp); super(PacketOpcodes.VehicleSpawnRsp);
VehicleSpawnRsp.Builder proto = VehicleSpawnRsp.newBuilder(); VehicleSpawnRsp.Builder proto = VehicleSpawnRsp.newBuilder();
// Eject vehicle members and Kill previous vehicles if there are any
List<GameEntity> previousVehicles = player.getScene().getEntities().values().stream()
.filter(entity -> entity instanceof EntityVehicle
&& ((EntityVehicle) entity).getGadgetId() == vehicleId
&& ((EntityVehicle) entity).getOwner().equals(player))
.toList();
previousVehicles.stream().forEach(entity -> {
List<VehicleMember> vehicleMembers = ((EntityVehicle) entity).getVehicleMembers().stream().toList();
vehicleMembers.stream().forEach(vehicleMember -> {
player.getScene().broadcastPacket(new PacketVehicleInteractRsp(((EntityVehicle) entity), vehicleMember, VEHICLE_INTERACT_OUT));
});
player.getScene().killEntity(entity, 0);
});
EntityVehicle vehicle = new EntityVehicle(player.getScene(), player, vehicleId, pointId, pos, rot); EntityVehicle vehicle = new EntityVehicle(player.getScene(), player, vehicleId, pointId, pos, rot);
switch (vehicleId) { switch (vehicleId) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment