Merge branch 'development' into questing

This commit is contained in:
akatatsu27
2022-07-26 14:17:42 +03:00
committed by GitHub
17 changed files with 244 additions and 60 deletions

View File

@@ -240,7 +240,7 @@ public final class GiveCommand implements CommandHandler {
}
private static Avatar makeAvatar(GiveItemParameters param) {
return makeAvatar(param.avatarData, param.lvl, Avatar.getMinPromoteLevel(param.lvl), 0);
return makeAvatar(param.avatarData, param.lvl, Avatar.getMinPromoteLevel(param.lvl), param.constellation);
}
private static Avatar makeAvatar(AvatarData avatarData, int level, int promoteLevel, int constellation) {

View File

@@ -0,0 +1,85 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.AvatarTalentData;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.World;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.List;
import java.util.Set;
@Command(
label = "setConst",
aliases = {"setconstellation"},
usage = {"<constellation level>"},
permission = "player.setconstellation",
permissionTargeted = "player.setconstellation.others")
public final class SetConstCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
sendUsageMessage(sender);
return;
}
try {
int constLevel = Integer.parseInt(args.get(0));
if (constLevel < 0 || constLevel > 6) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.range_error");
return;
}
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
if (entity == null) return;
Avatar avatar = entity.getAvatar();
this.setConstellation(targetPlayer, avatar, constLevel);
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
} catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.level_error");
}
}
private void setConstellation(Player player, Avatar avatar, int constLevel) {
int currentConstLevel = avatar.getCoreProudSkillLevel();
IntArrayList talentIds = new IntArrayList(avatar.getSkillDepot().getTalents());
Set<Integer> talentIdList = avatar.getTalentIdList();
talentIdList.clear();
avatar.setCoreProudSkillLevel(0);
for(int talent = 0; talent < constLevel; talent++) {
AvatarTalentData talentData = GameData.getAvatarTalentDataMap().get(talentIds.getInt(talent));
int mainCostItemId = talentData.getMainCostItemId();
player.getInventory().addItem(mainCostItemId);
Grasscutter.getGameServer().getInventorySystem().unlockAvatarConstellation(player, avatar.getGuid());
}
// force player to reload scene when necessary
if (constLevel < currentConstLevel) {
World world = player.getWorld();
Scene scene = player.getScene();
Position pos = player.getPosition();
world.transferPlayerToScene(player, 1, pos);
world.transferPlayerToScene(player, scene.getId(), pos);
scene.broadcastPacket(new PacketSceneEntityAppearNotify(player));
}
// ensure that all changes are visible to the player
avatar.recalcConstellations();
avatar.recalcStats(true);
avatar.save();
}
}

View File

@@ -8,6 +8,7 @@ import java.util.Map;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.utils.Utils;
import emu.grasscutter.data.excels.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
@@ -25,6 +26,7 @@ public class GameData {
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<QuestEncryptionKey> questsKeys = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
@@ -169,6 +171,10 @@ public class GameData {
return mainQuestData;
}
public static Int2ObjectMap<QuestEncryptionKey> getMainQuestEncryptionMap() {
return questsKeys;
}
public static Int2ObjectMap<HomeworldDefaultSaveData> getHomeworldDefaultSaveData() {
return homeworldDefaultSaveData;
}

View File

@@ -1,5 +1,25 @@
package emu.grasscutter.data;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
import emu.grasscutter.data.common.PointData;
import emu.grasscutter.data.common.ScenePointConfig;
import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
import emu.grasscutter.scripts.SceneIndexManager;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.file.Files;
@@ -9,27 +29,7 @@ import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.scripts.SceneIndexManager;
import emu.grasscutter.utils.Utils;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
import emu.grasscutter.data.common.PointData;
import emu.grasscutter.data.common.ScenePointConfig;
import emu.grasscutter.game.world.SpawnDataEntry.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.config.Configuration.RESOURCE;
import static emu.grasscutter.utils.Language.translate;
public class ResourceLoader {
@@ -418,6 +418,18 @@ public class ResourceLoader {
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
}
try (Reader reader = DataLoader.loadReader("QuestEncryptionKeys.json")) {
List<QuestEncryptionKey> keys = Grasscutter.getGsonFactory().fromJson(
reader,
TypeToken.getParameterized(List.class, QuestEncryptionKey.class).getType());
Int2ObjectMap<QuestEncryptionKey> questEncryptionMap = GameData.getMainQuestEncryptionMap();
keys.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
Grasscutter.getLogger().info("loaded {} quest keys.", questEncryptionMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load quest keys.", e);
}
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
}

View File

@@ -219,6 +219,7 @@ public class EntityGadget extends EntityBaseGadget {
.setConfigId(this.getConfigId())
.setGadgetState(this.getState())
.setIsEnableInteract(true)
.setDraftId(this.metaGadget.draft_id)
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
if (this.getContent() != null) {

View File

@@ -342,13 +342,10 @@ public class GameMainQuest {
ParentQuest.Builder proto = ParentQuest.newBuilder()
.setParentQuestId(getParentQuestId())
.setIsFinished(isFinished());
/**
if ParentQuestState is NONE, official server does not send ParentQuestState nor childQuestList!!!
might need more sniffing...
sending childQuestList without ParentQuestState set causes the game to hang on login
*/
if (getState() != ParentQuestState.PARENT_QUEST_STATE_NONE) {
proto.setParentQuestState(getState().getValue());
.setCutsceneEncryptionKey(QuestManager.getQuestKey(parentQuestId));
for (GameQuest quest : this.getChildQuests().values()) {
if (quest.getState() != QuestState.QUEST_STATE_UNSTARTED) {
ChildQuest childQuest = ChildQuest.newBuilder()
@@ -359,11 +356,12 @@ public class GameMainQuest {
proto.addChildQuestList(childQuest);
}
}
}
for (int i : getQuestVars()) {
proto.addQuestVar(i);
}
return proto.build();
}

View File

@@ -0,0 +1,12 @@
package emu.grasscutter.game.quest;
import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class QuestEncryptionKey {
int mainQuestId;
long encryptionKey;
}

View File

@@ -3,8 +3,6 @@ package emu.grasscutter.game.quest;
import java.beans.Transient;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData;
@@ -25,6 +23,7 @@ import jdk.jshell.spi.ExecutionControl;
import lombok.Getter;
public class QuestManager extends BasePlayerManager {
@Getter private final Player player;
@Getter private Map<Integer,Integer> questGlobalVariables;
@@ -64,7 +63,13 @@ public class QuestManager extends BasePlayerManager {
);
*/
public static long getQuestKey(int mainQuestId){
QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId);
return questEncryptionKey != null ? questEncryptionKey.getEncryptionKey() : 0L;
}
public QuestManager(Player player) {
super(player);
this.player = player;
this.questGlobalVariables = player.getQuestGlobalVariables();

View File

@@ -12,6 +12,7 @@ public class SceneGadget extends SceneObject{
public SceneBossChest boss_chest;
public int interact_id;
public boolean isOneoff;
public int draft_id;
public void setIsOneoff(boolean isOneoff){
this.isOneoff = isOneoff;