Commit 86b8f454 authored by KingRainbow44's avatar KingRainbow44
Browse files

Merge remote-tracking branch 'origin/api' into api

parents b5c27723 63d41fd7
......@@ -27,6 +27,7 @@ import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.scripts.data.SceneConfig;
import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
......@@ -44,6 +45,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class World implements Iterable<Player> {
private final GameServer server;
private final Player owner;
private final List<Player> players;
private final Int2ObjectMap<Scene> scenes;
......@@ -61,6 +63,7 @@ public class World implements Iterable<Player> {
public World(Player player, boolean isMultiplayer) {
this.owner = player;
this.server = player.getServer();
this.players = Collections.synchronizedList(new ArrayList<>());
this.scenes = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
......@@ -75,6 +78,10 @@ public class World implements Iterable<Player> {
return owner;
}
public GameServer getServer() {
return server;
}
public int getLevelEntityId() {
return levelEntityId;
}
......
package emu.grasscutter.scripts;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
......@@ -23,6 +24,7 @@ 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;
......@@ -33,6 +35,7 @@ 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;
......@@ -49,14 +52,17 @@ public class SceneScriptManager {
private Bindings bindings;
private SceneConfig config;
private List<SceneBlock> blocks;
private Int2ObjectOpenHashMap<Set<SceneTrigger>> triggers;
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
......@@ -108,6 +114,18 @@ public class SceneScriptManager {
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()) {
......@@ -134,9 +152,6 @@ public class SceneScriptManager {
bindings = ScriptLoader.getEngine().createBindings();
// Set variables
bindings.put("EventType", new EventType()); // TODO - make static class to avoid instantiating a new class every scene
bindings.put("GadgetState", new ScriptGadgetState());
bindings.put("RegionShape", new ScriptRegionShape());
bindings.put("ScriptLib", getScriptLib());
// Eval script
......@@ -211,6 +226,7 @@ public class SceneScriptManager {
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
......@@ -235,11 +251,27 @@ public class SceneScriptManager {
}
public void onTick() {
checkTriggers();
checkRegions();
}
public void checkTriggers() {
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) {
......
......@@ -17,6 +17,7 @@ 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;
......@@ -184,6 +185,19 @@ public class ScriptLib {
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);
}
......
......@@ -4,6 +4,7 @@ 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;
......@@ -13,7 +14,17 @@ 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;
......@@ -31,11 +42,31 @@ public class ScriptLoader {
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() {
......
......@@ -14,6 +14,7 @@ public class SceneGroup {
public List<SceneMonster> monsters;
public List<SceneGadget> gadgets;
public List<SceneTrigger> triggers;
public List<SceneRegion> regions;
public List<SceneSuite> suites;
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 {
public int param1;
public int param2;
public int param3;
public int source_eid; // Source entity
public ScriptArgs() {
......@@ -44,4 +45,13 @@ public class ScriptArgs {
this.param3 = param3;
return this;
}
public int getSourceEntityId() {
return source_eid;
}
public ScriptArgs setSourceEntityId(int source_eid) {
this.source_eid = source_eid;
return this;
}
}
......@@ -490,8 +490,8 @@ public final class DispatchServer {
// Captcha
server.createContext( // api-account-os.hoyoverse.com
"/account/risky/api/check",
new DispatchHttpJsonHandler(
"{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"c8820f246a5241ab9973f71df3ddd791\",\"action\":\"\",\"geetest\":{\"challenge\":\"\",\"gt\":\"\",\"new_captcha\":0,\"success\":1}}}"));
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"none\",\"action\":\"ACTION_NONE\",\"geetest\":null}}")
);
// Config
server.createContext( // sdk-os-static.hoyoverse.com
"/combo/box/api/config/sdk/combo",
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetFriendShowAvatarInfoReqOuterClass.GetFriendShowAvatarInfoReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetFriendShowAvatarInfoRsp;
@Opcodes(PacketOpcodes.GetFriendShowAvatarInfoReq)
public class HandlerGetFriendShowAvatarInfoReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
GetFriendShowAvatarInfoReq req = GetFriendShowAvatarInfoReq.parseFrom(payload);
int targetUid = req.getUid();
Player targetPlayer = session.getServer().getPlayerByUid(targetUid, true);
if (targetPlayer.isShowAvatars()) {
session.send(new PacketGetFriendShowAvatarInfoRsp(targetUid, targetPlayer.getShowAvatarInfoList()));
}
}
}
......@@ -17,6 +17,8 @@ import emu.grasscutter.server.event.game.PlayerCreationEvent;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.game.GameSession.SessionState;
import java.util.Arrays;
@Opcodes(PacketOpcodes.SetPlayerBornDataReq)
public class HandlerSetPlayerBornDataReq extends PacketHandler {
......@@ -85,9 +87,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
mailBuilder.mail.mailContent.title = String.format("W%sl%som%s to %s%s%s%s%s%s%s%s%s%s%s!", DatabaseHelper.AWJVN, u, DatabaseHelper.AWJVN, d, e, z, GameData.EJWOA, GameData.EJWOA, u, PacketOpcodes.ONLWE, s, s, DatabaseHelper.AWJVN, e);
mailBuilder.mail.mailContent.sender = String.format("L%swnmow%s%s @ Gi%sH%sb", z, DatabaseHelper.AWJVN, e, s, PacketOpcodes.ONLWE);
mailBuilder.mail.mailContent.content = Grasscutter.getConfig().GameServer.WelcomeMailContent;
for (int itemId : Grasscutter.getConfig().GameServer.WelcomeMailItems) {
mailBuilder.mail.itemList.add(new Mail.MailItem(itemId, 1, 1));
}
mailBuilder.mail.itemList.addAll(Arrays.asList(Grasscutter.getConfig().GameServer.WelcomeMailItems));
mailBuilder.mail.importance = 1;
player.sendMail(mailBuilder.mail);
} catch (Exception e) {
......
......@@ -17,10 +17,12 @@ public class PacketDungeonEntryInfoRsp extends BasePacket {
DungeonEntryInfoRsp.Builder proto = DungeonEntryInfoRsp.newBuilder()
.setPointId(pointData.getId());
if (pointData.getDungeonIds() != null) {
for (int dungeonId : pointData.getDungeonIds()) {
DungeonEntryInfo info = DungeonEntryInfo.newBuilder().setDungeonId(dungeonId).build();
proto.addDungeonEntryList(info);
}
}
this.setData(proto);
}
......
package emu.grasscutter.server.packet.send;
import java.util.List;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetFriendShowAvatarInfoRspOuterClass.GetFriendShowAvatarInfoRsp;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo;
@Opcodes(PacketOpcodes.GetFriendShowAvatarInfoRsp)
public class PacketGetFriendShowAvatarInfoRsp extends BasePacket {
public PacketGetFriendShowAvatarInfoRsp(int uid, List<ShowAvatarInfo> showAvatarInfoList) {
super(PacketOpcodes.GetFriendShowAvatarInfoRsp);
GetFriendShowAvatarInfoRsp.Builder p = GetFriendShowAvatarInfoRsp.newBuilder()
.setUid(uid)
.addAllShowAvatarInfoList(showAvatarInfoList);
this.setData(p.build());
}
}
......@@ -18,36 +18,19 @@ import java.util.Objects;
public class PacketGetOnlinePlayerListRsp extends BasePacket {
public PacketGetOnlinePlayerListRsp(Player session){
super(PacketOpcodes.GetOnlinePlayerListRsp);
Map<Integer, Player> playersMap = Grasscutter.getGameServer().getPlayers();
List<Player> players = Grasscutter.getGameServer().getPlayers().values().stream().limit(50).toList();
GetOnlinePlayerListRsp.Builder proto = GetOnlinePlayerListRsp.newBuilder();
if(playersMap.size() != 0){
List<OnlinePlayerInfo> playerInfoList = new ArrayList<>();
for(Player player:playersMap.values()){
ProfilePicture.Builder picture = ProfilePicture.newBuilder();
OnlinePlayerInfo.Builder playerInfo = OnlinePlayerInfo.newBuilder();
if(player.getUid() == session.getUid())continue;
picture.setAvatarId(player.getProfile().getAvatarId())
.build();
System.out.println(player.getHeadImage());
playerInfo.setUid(player.getUid())
.setNickname(player.getNickname())
.setPlayerLevel(player.getLevel())
.setMpSettingType(MpSettingTypeOuterClass.MpSettingType.MP_SETTING_ENTER_AFTER_APPLY)
.setCurPlayerNumInWorld(player.getWorld().getPlayerCount())
.setWorldLevel(player.getWorldLevel())
.setNameCardId(player.getNameCardId())
.setProfilePicture(picture);
if(!Objects.equals(player.getSignature(), "")){
playerInfo.setSignature(player.getSignature());
}
playerInfoList.add(playerInfo.build());
}
for (OnlinePlayerInfo onlinePlayerInfo : playerInfoList) {
proto.addPlayerInfoList(onlinePlayerInfo).build();
if (players.size() != 0) {
for(Player player : players) {
if (player.getUid() == session.getUid()) continue;
proto.addPlayerInfoList(player.getOnlinePlayerInfo());
}
}
this.setData(proto);
}
}
......@@ -18,9 +18,9 @@ public class PacketGetPlayerFriendListRsp extends BasePacket {
FriendBrief serverFriend = FriendBrief.newBuilder()
.setUid(GameConstants.SERVER_CONSOLE_UID)
.setNickname("Server")
.setNickname(GameConstants.SERVER_AVATAR_NAME)
.setLevel(1)
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(GameConstants.MAIN_CHARACTER_FEMALE))
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(GameConstants.SERVER_AVATAR_ID))
.setWorldLevel(0)
.setSignature("")
.setLastActiveTime((int) (System.currentTimeMillis() / 1000f))
......
package emu.grasscutter.server.packet.send;
import emu.grasscutter.data.GameData;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetScenePointRspOuterClass.GetScenePointRsp;
......@@ -12,9 +13,13 @@ public class PacketGetScenePointRsp extends BasePacket {
GetScenePointRsp.Builder p = GetScenePointRsp.newBuilder()
.setSceneId(sceneId);
if (GameData.getScenePointIdList().size() == 0) {
for (int i = 1; i < 1000; i++) {
p.addUnlockedPointList(i);
}
} else {
p.addAllUnlockedPointList(GameData.getScenePointIdList());
}
for (int i = 1; i < 9; i++) {
p.addUnlockAreaList(i);
......
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