Commit 9a0a15a4 authored by HotaruYS's avatar HotaruYS Committed by GitHub
Browse files

Merge branch 'development' into patch-3

parents beea95fd 5d1f4957
...@@ -9,10 +9,12 @@ import emu.grasscutter.game.dungeons.TowerDungeonSettleListener; ...@@ -9,10 +9,12 @@ import emu.grasscutter.game.dungeons.TowerDungeonSettleListener;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify; import emu.grasscutter.server.packet.send.PacketCanUseSkillNotify;
import emu.grasscutter.server.packet.send.PacketTowerCurLevelRecordChangeNotify; import emu.grasscutter.server.packet.send.PacketTowerCurLevelRecordChangeNotify;
import emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp; import emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp;
import emu.grasscutter.server.packet.send.PacketTowerLevelStarCondNotify;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Entity @Entity
public class TowerManager { public class TowerManager {
...@@ -26,11 +28,19 @@ public class TowerManager { ...@@ -26,11 +28,19 @@ public class TowerManager {
this.player = player; this.player = player;
} }
/**
* the floor players chose
*/
private int currentFloorId; private int currentFloorId;
private int currentLevel; private int currentLevel;
@Transient @Transient
private int currentLevelId; private int currentLevelId;
/**
* floorId - Record
*/
private Map<Integer, TowerLevelRecord> recordMap;
@Transient @Transient
private int entryScene; private int entryScene;
...@@ -38,7 +48,26 @@ public class TowerManager { ...@@ -38,7 +48,26 @@ public class TowerManager {
return currentFloorId; return currentFloorId;
} }
public int getCurrentLevelId(){
return this.currentLevelId + currentLevel;
}
/**
* form 1-3
*/
public int getCurrentLevel(){
return currentLevel + 1;
}
private static final List<DungeonSettleListener> towerDungeonSettleListener = List.of(new TowerDungeonSettleListener()); private static final List<DungeonSettleListener> towerDungeonSettleListener = List.of(new TowerDungeonSettleListener());
public Map<Integer, TowerLevelRecord> getRecordMap() {
if(recordMap == null){
recordMap = new HashMap<>();
recordMap.put(1001, new TowerLevelRecord(1001));
}
return recordMap;
}
public void teamSelect(int floor, List<List<Long>> towerTeams) { public void teamSelect(int floor, List<List<Long>> towerTeams) {
var floorData = GameData.getTowerFloorDataMap().get(floor); var floorData = GameData.getTowerFloorDataMap().get(floor);
...@@ -54,51 +83,73 @@ public class TowerManager { ...@@ -54,51 +83,73 @@ public class TowerManager {
entryScene = player.getSceneId(); entryScene = player.getSceneId();
} }
player.getTeamManager().setupTemporaryTeam(towerTeams); player.getTeamManager().setupTemporaryTeam(towerTeams);
} }
public void enterLevel(int enterPointId) { public void enterLevel(int enterPointId) {
var levelData = GameData.getTowerLevelDataMap().get(currentLevelId + currentLevel); var levelData = GameData.getTowerLevelDataMap().get(getCurrentLevelId());
this.currentLevel++; var dungeonId = levelData.getDungeonId();
var id = levelData.getDungeonId();
notifyCurLevelRecordChange(); notifyCurLevelRecordChange();
// use team user choose // use team user choose
player.getTeamManager().useTemporaryTeam(0); player.getTeamManager().useTemporaryTeam(0);
player.getServer().getDungeonManager().handoffDungeon(player, id, player.getServer().getDungeonManager().handoffDungeon(player, dungeonId,
towerDungeonSettleListener); towerDungeonSettleListener);
// make sure user can exit dungeon correctly // make sure user can exit dungeon correctly
player.getScene().setPrevScene(entryScene); player.getScene().setPrevScene(entryScene);
player.getScene().setPrevScenePoint(enterPointId); player.getScene().setPrevScenePoint(enterPointId);
player.getSession().send(new PacketTowerEnterLevelRsp(currentFloorId, currentLevel)); player.getSession().send(new PacketTowerEnterLevelRsp(currentFloorId, getCurrentLevel()));
// stop using skill // stop using skill
player.getSession().send(new PacketCanUseSkillNotify(false)); player.getSession().send(new PacketCanUseSkillNotify(false));
// notify the cond of stars
player.getSession().send(new PacketTowerLevelStarCondNotify(currentFloorId, getCurrentLevel()));
} }
public void notifyCurLevelRecordChange(){ public void notifyCurLevelRecordChange(){
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, currentLevel)); player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, getCurrentLevel()));
}
public void notifyCurLevelRecordChangeWhenDone(int stars){
if(!recordMap.containsKey(currentFloorId)){
recordMap.put(currentFloorId,
new TowerLevelRecord(currentFloorId).setLevelStars(getCurrentLevelId(),stars));
}else{
recordMap.put(currentFloorId,
recordMap.get(currentFloorId).setLevelStars(getCurrentLevelId(),stars));
}
this.currentLevel++;
if(!hasNextLevel()){
// set up the next floor
recordMap.put(getNextFloorId(), new TowerLevelRecord(getNextFloorId()));
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(getNextFloorId(), 1));
}else{
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, getCurrentLevel()));
} }
public void notifyCurLevelRecordChangeWhenDone(){
player.getSession().send(new PacketTowerCurLevelRecordChangeNotify(currentFloorId, currentLevel + 1));
} }
public boolean hasNextLevel(){ public boolean hasNextLevel(){
return this.currentLevel < 3; return this.currentLevel < 3;
} }
public int getNextFloorId() { public int getNextFloorId() {
if(hasNextLevel()){ return player.getServer().getTowerScheduleManager().getNextFloorId(this.currentFloorId);
return 0;
} }
this.currentFloorId++; public boolean hasNextFloor(){
return this.currentFloorId; return player.getServer().getTowerScheduleManager().getNextFloorId(this.currentFloorId) > 0;
} }
public void clearEntry() { public void clearEntry() {
this.entryScene = 0; this.entryScene = 0;
} }
public boolean canEnterScheduleFloor(){
if(!recordMap.containsKey(player.getServer().getTowerScheduleManager().getLastEntranceFloor())){
return false;
}
return recordMap.get(player.getServer().getTowerScheduleManager().getLastEntranceFloor())
.getStarCount() >= 6;
}
} }
package emu.grasscutter.game.tower;
import java.util.Date;
public class TowerScheduleConfig {
private int scheduleId;
private Date scheduleStartTime;
private Date nextScheduleChangeTime;
public int getScheduleId() {
return scheduleId;
}
public void setScheduleId(int scheduleId) {
this.scheduleId = scheduleId;
}
public Date getScheduleStartTime() {
return scheduleStartTime;
}
public void setScheduleStartTime(Date scheduleStartTime) {
this.scheduleStartTime = scheduleStartTime;
}
public Date getNextScheduleChangeTime() {
return nextScheduleChangeTime;
}
public void setNextScheduleChangeTime(Date nextScheduleChangeTime) {
this.nextScheduleChangeTime = nextScheduleChangeTime;
}
}
package emu.grasscutter.game.tower;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.TowerScheduleData;
import emu.grasscutter.server.game.GameServer;
import java.io.FileReader;
import java.util.List;
public class TowerScheduleManager {
private final GameServer gameServer;
public GameServer getGameServer() {
return gameServer;
}
public TowerScheduleManager(GameServer gameServer) {
this.gameServer = gameServer;
this.load();
}
private TowerScheduleConfig towerScheduleConfig;
public synchronized void load(){
try (FileReader fileReader = new FileReader(Grasscutter.getConfig().DATA_FOLDER + "TowerSchedule.json")) {
towerScheduleConfig = Grasscutter.getGsonFactory().fromJson(fileReader, TowerScheduleConfig.class);
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load tower schedule config.", e);
}
}
public TowerScheduleConfig getTowerScheduleConfig() {
return towerScheduleConfig;
}
public TowerScheduleData getCurrentTowerScheduleData(){
var data = GameData.getTowerScheduleDataMap().get(towerScheduleConfig.getScheduleId());
if(data == null){
Grasscutter.getLogger().error("Could not get current tower schedule data by config:{}", towerScheduleConfig);
}
return data;
}
public List<Integer> getScheduleFloors() {
return getCurrentTowerScheduleData().getSchedules().get(0).getFloorList();
}
public int getNextFloorId(int floorId){
var entranceFloors = getCurrentTowerScheduleData().getEntranceFloorId();
var nextId = 0;
// find in entrance floors first
for(int i=0;i<entranceFloors.size()-1;i++){
if(floorId == entranceFloors.get(i)){
nextId = entranceFloors.get(i+1);
}
}
if(nextId != 0){
return nextId;
}
var scheduleFloors = getScheduleFloors();
// find in schedule floors
for(int i=0;i<scheduleFloors.size()-1;i++){
if(floorId == scheduleFloors.get(i)){
nextId = scheduleFloors.get(i+1);
}
}
return nextId;
}
public Integer getLastEntranceFloor() {
return getCurrentTowerScheduleData().getEntranceFloorId().get(getCurrentTowerScheduleData().getEntranceFloorId().size()-1);
}
}
...@@ -385,27 +385,7 @@ public class Scene { ...@@ -385,27 +385,7 @@ public class Scene {
} }
// Sanity check // Sanity check
if (target.getFightProperties() == null) { target.damage(result.getDamage(), result.getAttackerId());
return;
}
// Lose hp
target.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -result.getDamage());
// Check if dead
boolean isDead = false;
if (target.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
target.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
isDead = true;
}
// Packets
this.broadcastPacket(new PacketEntityFightPropUpdateNotify(target, FightProperty.FIGHT_PROP_CUR_HP));
// Check if dead
if (isDead) {
this.killEntity(target, result.getAttackerId());
}
} }
public void killEntity(GameEntity target, int attackerId) { public void killEntity(GameEntity target, int attackerId) {
......
...@@ -90,6 +90,10 @@ public class SceneScriptManager { ...@@ -90,6 +90,10 @@ public class SceneScriptManager {
return config; return config;
} }
public SceneGroup getCurrentGroup() {
return currentGroup;
}
public List<SceneBlock> getBlocks() { public List<SceneBlock> getBlocks() {
return blocks; return blocks;
} }
...@@ -237,16 +241,16 @@ public class SceneScriptManager { ...@@ -237,16 +241,16 @@ public class SceneScriptManager {
for (SceneSuite suite : group.suites) { for (SceneSuite suite : group.suites) {
suite.sceneMonsters = new ArrayList<>(suite.monsters.size()); suite.sceneMonsters = new ArrayList<>(suite.monsters.size());
for (int id : suite.monsters) { suite.monsters.forEach(id -> {
try { Object objEntry = map.get(id.intValue());
SceneMonster monster = (SceneMonster) map.get(id); if (objEntry instanceof Map.Entry<?,?> monsterEntry) {
if (monster != null) { Object monster = monsterEntry.getValue();
suite.sceneMonsters.add(monster); if(monster instanceof SceneMonster sceneMonster){
} suite.sceneMonsters.add(sceneMonster);
} catch (Exception e) {
continue;
} }
} }
});
suite.sceneGadgets = new ArrayList<>(suite.gadgets.size()); suite.sceneGadgets = new ArrayList<>(suite.gadgets.size());
for (int id : suite.gadgets) { for (int id : suite.gadgets) {
try { try {
...@@ -320,14 +324,16 @@ public class SceneScriptManager { ...@@ -320,14 +324,16 @@ public class SceneScriptManager {
} }
public void spawnMonstersInGroup(SceneGroup group, int suiteIndex) { public void spawnMonstersInGroup(SceneGroup group, int suiteIndex) {
this.currentGroup = group;
this.monsterSceneLimit = 0;
var suite = group.getSuiteByIndex(suiteIndex); var suite = group.getSuiteByIndex(suiteIndex);
if(suite == null){ if(suite == null){
return; return;
} }
if(suite.sceneMonsters.size() > 0){
this.currentGroup = group;
this.monsterSceneLimit = 0;
suite.sceneMonsters.forEach(mob -> spawnMonstersInGroup(group, mob)); suite.sceneMonsters.forEach(mob -> spawnMonstersInGroup(group, mob));
} }
}
public void spawnMonstersInGroup(SceneGroup group) { public void spawnMonstersInGroup(SceneGroup group) {
this.currentGroup = group; this.currentGroup = group;
...@@ -401,6 +407,7 @@ public class SceneScriptManager { ...@@ -401,6 +407,7 @@ public class SceneScriptManager {
spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll())); spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll()));
}else if(this.monsterAlive.get() == 0){ }else if(this.monsterAlive.get() == 0){
// spawn the last turn of monsters // spawn the last turn of monsters
//callEvent(EventType.EVENT_MONSTER_TIDE_DIE, new ScriptArgs());
while(!this.monsterOrders.isEmpty()){ while(!this.monsterOrders.isEmpty()){
spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll())); spawnMonstersInGroup(this.currentGroup, this.currentGroup.monsters.get(this.monsterOrders.poll()));
} }
......
...@@ -137,7 +137,6 @@ public class ScriptLib { ...@@ -137,7 +137,6 @@ public class ScriptLib {
return 1; return 1;
} }
// TODO just spawn all from group for now
this.getSceneScriptManager().spawnMonstersInGroup(group, suite); this.getSceneScriptManager().spawnMonstersInGroup(group, suite);
return 0; return 0;
...@@ -160,6 +159,12 @@ public class ScriptLib { ...@@ -160,6 +159,12 @@ public class ScriptLib {
return 1; return 1;
} }
if(getSceneScriptManager().getScene().getChallenge() != null &&
getSceneScriptManager().getScene().getChallenge().inProgress())
{
return 0;
}
DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group); DungeonChallenge challenge = new DungeonChallenge(getSceneScriptManager().getScene(), group);
challenge.setChallengeId(challengeId); challenge.setChallengeId(challengeId);
challenge.setChallengeIndex(challengeIndex); challenge.setChallengeIndex(challengeIndex);
...@@ -249,7 +254,7 @@ public class ScriptLib { ...@@ -249,7 +254,7 @@ public class ScriptLib {
var1); var1);
return (int) getSceneScriptManager().getScene().getEntities().values().stream() return (int) getSceneScriptManager().getScene().getEntities().values().stream()
.filter(e -> e instanceof EntityMonster) .filter(e -> e instanceof EntityMonster && e.getGroupId() == getSceneScriptManager().getCurrentGroup().id)
.count(); .count();
} }
public int SetMonsterBattleByGroup(int var1, int var2, int var3){ public int SetMonsterBattleByGroup(int var1, int var2, int var3){
...@@ -266,13 +271,11 @@ public class ScriptLib { ...@@ -266,13 +271,11 @@ public class ScriptLib {
return 0; return 0;
} }
// 8-1 // 8-1
public int GetGroupVariableValueByGroup(int var1, String var2, int var3){ public int GetGroupVariableValueByGroup(String name, int groupId){
logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{},{}", logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{}",
var1,var2,var3); name,groupId);
//TODO
return getSceneScriptManager().getVariables().getOrDefault(var2, 0); return getSceneScriptManager().getVariables().getOrDefault(name, 0);
} }
public int SetIsAllowUseSkill(int canUse, int var2){ public int SetIsAllowUseSkill(int canUse, int var2){
...@@ -299,4 +302,11 @@ public class ScriptLib { ...@@ -299,4 +302,11 @@ public class ScriptLib {
return 0; return 0;
} }
public int SetGroupVariableValueByGroup(String key, int value, int groupId){
logger.debug("[LUA] Call SetGroupVariableValueByGroup with {},{},{}",
key,value,groupId);
return 0;
}
} }
...@@ -15,6 +15,7 @@ import emu.grasscutter.game.managers.InventoryManager; ...@@ -15,6 +15,7 @@ import emu.grasscutter.game.managers.InventoryManager;
import emu.grasscutter.game.managers.MultiplayerManager; import emu.grasscutter.game.managers.MultiplayerManager;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.shop.ShopManager; import emu.grasscutter.game.shop.ShopManager;
import emu.grasscutter.game.tower.TowerScheduleManager;
import emu.grasscutter.game.world.World; import emu.grasscutter.game.world.World;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
...@@ -54,6 +55,7 @@ public final class GameServer extends KcpServer { ...@@ -54,6 +55,7 @@ public final class GameServer extends KcpServer {
private final DropManager dropManager; private final DropManager dropManager;
private final CombineManger combineManger; private final CombineManger combineManger;
private final TowerScheduleManager towerScheduleManager;
public GameServer() { public GameServer() {
this(new InetSocketAddress( this(new InetSocketAddress(
...@@ -82,7 +84,7 @@ public final class GameServer extends KcpServer { ...@@ -82,7 +84,7 @@ public final class GameServer extends KcpServer {
this.dropManager = new DropManager(this); this.dropManager = new DropManager(this);
this.expeditionManager = new ExpeditionManager(this); this.expeditionManager = new ExpeditionManager(this);
this.combineManger = new CombineManger(this); this.combineManger = new CombineManger(this);
this.towerScheduleManager = new TowerScheduleManager(this);
// Hook into shutdown event. // Hook into shutdown event.
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown)); Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
} }
...@@ -139,6 +141,10 @@ public final class GameServer extends KcpServer { ...@@ -139,6 +141,10 @@ public final class GameServer extends KcpServer {
return this.combineManger; return this.combineManger;
} }
public TowerScheduleManager getTowerScheduleManager() {
return towerScheduleManager;
}
public TaskMap getTaskMap() { public TaskMap getTaskMap() {
return this.taskMap; return this.taskMap;
} }
......
...@@ -6,6 +6,7 @@ import emu.grasscutter.net.proto.AbilityInvocationsNotifyOuterClass.AbilityInvoc ...@@ -6,6 +6,7 @@ import emu.grasscutter.net.proto.AbilityInvocationsNotifyOuterClass.AbilityInvoc
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry; import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.utils.Utils;
@Opcodes(PacketOpcodes.AbilityInvocationsNotify) @Opcodes(PacketOpcodes.AbilityInvocationsNotify)
public class HandlerAbilityInvocationsNotify extends PacketHandler { public class HandlerAbilityInvocationsNotify extends PacketHandler {
...@@ -15,13 +16,9 @@ public class HandlerAbilityInvocationsNotify extends PacketHandler { ...@@ -15,13 +16,9 @@ public class HandlerAbilityInvocationsNotify extends PacketHandler {
AbilityInvocationsNotify notif = AbilityInvocationsNotify.parseFrom(payload); AbilityInvocationsNotify notif = AbilityInvocationsNotify.parseFrom(payload);
for (AbilityInvokeEntry entry : notif.getInvokesList()) { for (AbilityInvokeEntry entry : notif.getInvokesList()) {
//System.out.println(entry.getArgumentType() + ": " + Utils.bytesToHex(entry.getAbilityData().toByteArray())); session.getPlayer().getAbilityManager().onAbilityInvoke(entry);
session.getPlayer().getAbilityInvokeHandler().addEntry(entry.getForwardType(), entry); session.getPlayer().getAbilityInvokeHandler().addEntry(entry.getForwardType(), entry);
} }
if (notif.getInvokesList().size() > 0) {
session.getPlayer().getAbilityInvokeHandler().update(session.getPlayer());
}
} }
} }
...@@ -6,6 +6,7 @@ import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry ...@@ -6,6 +6,7 @@ import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry
import emu.grasscutter.net.proto.ClientAbilityInitFinishNotifyOuterClass.ClientAbilityInitFinishNotify; import emu.grasscutter.net.proto.ClientAbilityInitFinishNotifyOuterClass.ClientAbilityInitFinishNotify;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.utils.Utils;
@Opcodes(PacketOpcodes.ClientAbilityInitFinishNotify) @Opcodes(PacketOpcodes.ClientAbilityInitFinishNotify)
public class HandlerClientAbilityInitFinishNotify extends PacketHandler { public class HandlerClientAbilityInitFinishNotify extends PacketHandler {
...@@ -15,6 +16,7 @@ public class HandlerClientAbilityInitFinishNotify extends PacketHandler { ...@@ -15,6 +16,7 @@ public class HandlerClientAbilityInitFinishNotify extends PacketHandler {
ClientAbilityInitFinishNotify notif = ClientAbilityInitFinishNotify.parseFrom(payload); ClientAbilityInitFinishNotify notif = ClientAbilityInitFinishNotify.parseFrom(payload);
for (AbilityInvokeEntry entry : notif.getInvokesList()) { for (AbilityInvokeEntry entry : notif.getInvokesList()) {
session.getPlayer().getAbilityManager().onAbilityInvoke(entry);
session.getPlayer().getClientAbilityInitFinishHandler().addEntry(entry.getForwardType(), entry); session.getPlayer().getClientAbilityInitFinishHandler().addEntry(entry.getForwardType(), entry);
} }
......
...@@ -74,14 +74,6 @@ public class HandlerCombatInvocationsNotify extends PacketHandler { ...@@ -74,14 +74,6 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry); session.getPlayer().getCombatInvokeHandler().addEntry(entry.getForwardType(), entry);
} }
if (notif.getInvokeListList().size() > 0) {
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
}
// Handle attack results last
while (!session.getPlayer().getAttackResults().isEmpty()) {
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
}
} }
private void handleFallOnGround(GameSession session, GameEntity entity, MotionState motionState) { private void handleFallOnGround(GameSession session, GameEntity entity, MotionState motionState) {
......
...@@ -14,11 +14,6 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler { ...@@ -14,11 +14,6 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
EvtCreateGadgetNotify notify = EvtCreateGadgetNotify.parseFrom(payload); EvtCreateGadgetNotify notify = EvtCreateGadgetNotify.parseFrom(payload);
// Dont handle in singleplayer
if (!session.getPlayer().getWorld().isMultiplayer()) {
return;
}
// Sanity check - dont add duplicate entities // Sanity check - dont add duplicate entities
if (session.getPlayer().getScene().getEntityById(notify.getEntityId()) != null) { if (session.getPlayer().getScene().getEntityById(notify.getEntityId()) != null) {
return; return;
......
...@@ -13,11 +13,6 @@ public class HandlerEvtDestroyGadgetNotify extends PacketHandler { ...@@ -13,11 +13,6 @@ public class HandlerEvtDestroyGadgetNotify extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
EvtDestroyGadgetNotify notify = EvtDestroyGadgetNotify.parseFrom(payload); EvtDestroyGadgetNotify notify = EvtDestroyGadgetNotify.parseFrom(payload);
// Dont handle in singleplayer
if (!session.getPlayer().getWorld().isMultiplayer()) {
return;
}
session.getPlayer().getScene().onPlayerDestroyGadget(notify.getEntityId()); session.getPlayer().getScene().onPlayerDestroyGadget(notify.getEntityId());
} }
......
...@@ -23,7 +23,7 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler { ...@@ -23,7 +23,7 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler {
BasePacket packet = new BasePacket(PacketOpcodes.SetEntityClientDataNotify, true); BasePacket packet = new BasePacket(PacketOpcodes.SetEntityClientDataNotify, true);
packet.setData(notif); packet.setData(notif);
session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), packet); session.getPlayer().getScene().broadcastPacket(packet);
} }
} }
...@@ -62,7 +62,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler { ...@@ -62,7 +62,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
// Create avatar // Create avatar
if (player.getAvatars().getAvatarCount() == 0) { if (player.getAvatars().getAvatarCount() == 0) {
Avatar mainCharacter = new Avatar(avatarId); Avatar mainCharacter = new Avatar(avatarId);
mainCharacter.setSkillDepot(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot)); mainCharacter.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
player.addAvatar(mainCharacter); player.addAvatar(mainCharacter);
player.setMainCharacterId(avatarId); player.setMainCharacterId(avatarId);
player.setHeadImage(avatarId); player.setHeadImage(avatarId);
......
...@@ -11,7 +11,10 @@ public class HandlerTowerAllDataReq extends PacketHandler { ...@@ -11,7 +11,10 @@ public class HandlerTowerAllDataReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
session.send(new PacketTowerAllDataRsp()); session.send(new PacketTowerAllDataRsp(
session.getServer().getTowerScheduleManager(),
session.getPlayer().getTowerManager()
));
} }
} }
...@@ -15,5 +15,14 @@ public class HandlerUnionCmdNotify extends PacketHandler { ...@@ -15,5 +15,14 @@ public class HandlerUnionCmdNotify extends PacketHandler {
for (UnionCmd cmd : req.getCmdListList()) { for (UnionCmd cmd : req.getCmdListList()) {
session.getServer().getPacketHandler().handle(session, cmd.getMessageId(), EMPTY_BYTE_ARRAY, cmd.getBody().toByteArray()); session.getServer().getPacketHandler().handle(session, cmd.getMessageId(), EMPTY_BYTE_ARRAY, cmd.getBody().toByteArray());
} }
// Update
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
session.getPlayer().getAbilityInvokeHandler().update(session.getPlayer());
// Handle attack results last
while (!session.getPlayer().getAttackResults().isEmpty()) {
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
}
} }
} }
...@@ -46,7 +46,7 @@ public class PacketDungeonSettleNotify extends BasePacket { ...@@ -46,7 +46,7 @@ public class PacketDungeonSettleNotify extends BasePacket {
.setCount(1000) .setCount(1000)
.build()) .build())
; ;
if(nextFloorId > 0){ if(nextFloorId > 0 && canJump){
towerLevelEndNotify.setNextFloorId(nextFloorId); towerLevelEndNotify.setNextFloorId(nextFloorId);
} }
......
...@@ -11,21 +11,27 @@ import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason; ...@@ -11,21 +11,27 @@ import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
import java.util.List; import java.util.List;
public class PacketEntityFightPropChangeReasonNotify extends BasePacket { public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, List<Integer> param, PropChangeReason reason, ChangeHpReason changeHpReason) { public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, List<Integer> param, PropChangeReason reason, ChangeHpReason changeHpReason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify); super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify.Builder proto = EntityFightPropChangeReasonNotify.newBuilder() EntityFightPropChangeReasonNotify.Builder proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId()) .setEntityId(entity.getId())
.setPropType(prop.getId()) .setPropType(prop.getId())
.setPropDelta(value) .setPropDelta(value)
.setReason(reason) .setReason(reason)
.setChangeHpReason(changeHpReason); .setChangeHpReason(changeHpReason);
for(int p: param){
for(int p : param){
proto.addParamList(p); proto.addParamList(p);
} }
this.setData(proto); this.setData(proto);
} }
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason, ChangeHpReason changeHpReason) { public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason, ChangeHpReason changeHpReason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify); super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder() EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId()) .setEntityId(entity.getId())
.setPropType(prop.getId()) .setPropType(prop.getId())
...@@ -33,6 +39,20 @@ public class PacketEntityFightPropChangeReasonNotify extends BasePacket { ...@@ -33,6 +39,20 @@ public class PacketEntityFightPropChangeReasonNotify extends BasePacket {
.setReason(reason) .setReason(reason)
.setChangeHpReason(changeHpReason) .setChangeHpReason(changeHpReason)
.build(); .build();
this.setData(proto);
}
public PacketEntityFightPropChangeReasonNotify(GameEntity entity, FightProperty prop, Float value, PropChangeReason reason) {
super(PacketOpcodes.EntityFightPropChangeReasonNotify);
EntityFightPropChangeReasonNotify proto = EntityFightPropChangeReasonNotify.newBuilder()
.setEntityId(entity.getId())
.setPropType(prop.getId())
.setPropDelta(value)
.setReason(reason)
.build();
this.setData(proto); this.setData(proto);
} }
} }
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.data.GameData; import emu.grasscutter.game.tower.TowerManager;
import emu.grasscutter.data.def.TowerFloorData; import emu.grasscutter.game.tower.TowerScheduleManager;
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.TowerAllDataRspOuterClass.TowerAllDataRsp; import emu.grasscutter.net.proto.TowerAllDataRspOuterClass.TowerAllDataRsp;
import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord; import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord;
import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord; import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord;
import emu.grasscutter.net.proto.TowerLevelRecordOuterClass;
import emu.grasscutter.utils.DateHelper;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PacketTowerAllDataRsp extends BasePacket { public class PacketTowerAllDataRsp extends BasePacket {
public PacketTowerAllDataRsp() { public PacketTowerAllDataRsp(TowerScheduleManager towerScheduleManager, TowerManager towerManager) {
super(PacketOpcodes.TowerAllDataRsp); super(PacketOpcodes.TowerAllDataRsp);
var list = GameData.getTowerFloorDataMap().values().stream() var recordList = towerManager.getRecordMap().values().stream()
.map(TowerFloorData::getFloorId) .map(rec -> TowerFloorRecord.newBuilder()
.map(id -> TowerFloorRecord.newBuilder().setFloorId(id).build()) .setFloorId(rec.getFloorId())
.collect(Collectors.toList()); .setFloorStarRewardProgress(rec.getFloorStarRewardProgress())
.putAllPassedLevelMap(rec.getPassedLevelMap())
.addAllPassedLevelRecordList(buildFromPassedLevelMap(rec.getPassedLevelMap()))
.build()
)
.toList();
var openTimeMap = towerScheduleManager.getScheduleFloors().stream()
.collect(Collectors.toMap(x -> x,
y -> DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.getScheduleStartTime()))
);
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder() TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
.setTowerScheduleId(29) .setTowerScheduleId(towerScheduleManager.getCurrentTowerScheduleData().getScheduleId())
.addAllTowerFloorRecordList(list) .addAllTowerFloorRecordList(recordList)
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true)) .setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
.setNextScheduleChangeTime(Integer.MAX_VALUE) .setScheduleStartTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.putFloorOpenTimeMap(1024, 1630486800) .getScheduleStartTime()))
.putFloorOpenTimeMap(1025, 1630486800) .setNextScheduleChangeTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
.putFloorOpenTimeMap(1026, 1630486800) .getNextScheduleChangeTime()))
.putFloorOpenTimeMap(1027, 1630486800) .putAllFloorOpenTimeMap(openTimeMap)
.setScheduleStartTime(1630486800) .setIsFinishedEntranceFloor(towerManager.canEnterScheduleFloor())
.build(); .build();
this.setData(proto); this.setData(proto);
} }
private List<TowerLevelRecordOuterClass.TowerLevelRecord> buildFromPassedLevelMap(Map<Integer, Integer> map){
return map.entrySet().stream()
.map(item -> TowerLevelRecordOuterClass.TowerLevelRecord.newBuilder()
.setLevelId(item.getKey())
.addAllSatisfiedCondList(IntStream.range(1, item.getValue() + 1).boxed().toList())
.build())
.toList();
}
} }
...@@ -8,13 +8,13 @@ import emu.grasscutter.net.proto.TowerLevelRecordOuterClass.TowerLevelRecord; ...@@ -8,13 +8,13 @@ import emu.grasscutter.net.proto.TowerLevelRecordOuterClass.TowerLevelRecord;
public class PacketTowerFloorRecordChangeNotify extends BasePacket { public class PacketTowerFloorRecordChangeNotify extends BasePacket {
public PacketTowerFloorRecordChangeNotify(int floorId) { public PacketTowerFloorRecordChangeNotify(int floorId, int stars, boolean canEnterScheduleFloor) {
super(PacketOpcodes.TowerFloorRecordChangeNotify); super(PacketOpcodes.TowerFloorRecordChangeNotify);
TowerFloorRecordChangeNotify proto = TowerFloorRecordChangeNotify.newBuilder() TowerFloorRecordChangeNotify proto = TowerFloorRecordChangeNotify.newBuilder()
.addTowerFloorRecordList(TowerFloorRecord.newBuilder() .addTowerFloorRecordList(TowerFloorRecord.newBuilder()
.setFloorId(floorId) .setFloorId(floorId)
.setFloorStarRewardProgress(3) .setFloorStarRewardProgress(stars)
.addPassedLevelRecordList(TowerLevelRecord.newBuilder() .addPassedLevelRecordList(TowerLevelRecord.newBuilder()
.setLevelId(1) .setLevelId(1)
.addSatisfiedCondList(1) .addSatisfiedCondList(1)
...@@ -22,7 +22,7 @@ public class PacketTowerFloorRecordChangeNotify extends BasePacket { ...@@ -22,7 +22,7 @@ public class PacketTowerFloorRecordChangeNotify extends BasePacket {
.addSatisfiedCondList(3) .addSatisfiedCondList(3)
.build()) .build())
.build()) .build())
.setIsFinishedEntranceFloor(true) .setIsFinishedEntranceFloor(canEnterScheduleFloor)
.build(); .build();
this.setData(proto); this.setData(proto);
......
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