Run spotlessApply

also set line endings to native, no more line conflict errors!
This commit is contained in:
KingRainbow44
2023-05-02 14:00:00 +01:00
parent 4f1136ce2d
commit d32f6982be
1426 changed files with 1307544 additions and 1212706 deletions

View File

@@ -6,7 +6,6 @@ import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameQuest;
import java.util.List;
@Command(
@@ -64,15 +63,22 @@ public final class QuestCommand implements CommandHandler {
return;
}
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.running",
questId, translate(sender, switch(quest.state) {
case QUEST_STATE_NONE, NONE -> "commands.quest.state.none";
case QUEST_STATE_UNSTARTED, UNSTARTED -> "commands.quest.state.unstarted";
case QUEST_STATE_UNFINISHED, UNFINISHED -> "commands.quest.state.unfinished";
case QUEST_STATE_FINISHED, FINISHED -> "commands.quest.state.finished";
case QUEST_STATE_FAILED, FAILED -> "commands.quest.state.failed";
}), quest.getState().getValue())
);
CommandHandler.sendMessage(
sender,
translate(
sender,
"commands.quest.running",
questId,
translate(
sender,
switch (quest.state) {
case QUEST_STATE_NONE, NONE -> "commands.quest.state.none";
case QUEST_STATE_UNSTARTED, UNSTARTED -> "commands.quest.state.unstarted";
case QUEST_STATE_UNFINISHED, UNFINISHED -> "commands.quest.state.unfinished";
case QUEST_STATE_FINISHED, FINISHED -> "commands.quest.state.finished";
case QUEST_STATE_FAILED, FAILED -> "commands.quest.state.failed";
}),
quest.getState().getValue()));
}
case "talking" -> {
var mainQuest = targetPlayer.getQuestManager().getMainQuestByTalkId(questId);
@@ -82,17 +88,24 @@ public final class QuestCommand implements CommandHandler {
}
var talk = mainQuest.getTalks().get(questId);
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.talking",
questId, talk == null ?
translate(sender, "commands.quest.state.not_exists") :
translate(sender, "commands.quest.state.exists"),
mainQuest.getParentQuestId(), mainQuest.getState().getValue()));
CommandHandler.sendMessage(
sender,
translate(
sender,
"commands.quest.talking",
questId,
talk == null
? translate(sender, "commands.quest.state.not_exists")
: translate(sender, "commands.quest.state.exists"),
mainQuest.getParentQuestId(),
mainQuest.getState().getValue()));
}
case "dungeons" -> {
var dungeons = targetPlayer.getPlayerProgress().getCompletedDungeons();
CommandHandler.sendMessage(sender, "Dungeons completed: " +
String.join(", ", dungeons.intStream()
.mapToObj(String::valueOf).toList()));
CommandHandler.sendMessage(
sender,
"Dungeons completed: "
+ String.join(", ", dungeons.intStream().mapToObj(String::valueOf).toList()));
}
case "debug" -> {
var loggedQuests = targetPlayer.getQuestManager().getLoggedQuests();
@@ -101,8 +114,10 @@ public final class QuestCommand implements CommandHandler {
if (shouldAdd) loggedQuests.add(questId);
else loggedQuests.remove(questId);
CommandHandler.sendMessage(sender, "Quest %s will %s."
.formatted(questId, shouldAdd ? "now be logged" : "no longer be logged"));
CommandHandler.sendMessage(
sender,
"Quest %s will %s."
.formatted(questId, shouldAdd ? "now be logged" : "no longer be logged"));
}
case "triggers" -> {
var quest = targetPlayer.getQuestManager().getQuestById(questId);
@@ -111,8 +126,10 @@ public final class QuestCommand implements CommandHandler {
return;
}
CommandHandler.sendMessage(sender, "Triggers registered for %s: %s."
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
CommandHandler.sendMessage(
sender,
"Triggers registered for %s: %s."
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
}
default -> this.sendUsageMessage(sender);
}

View File

@@ -1,10 +1,5 @@
package emu.grasscutter.command.commands;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
@@ -14,6 +9,10 @@ import emu.grasscutter.game.tower.TowerLevelRecord;
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
@Command(
label = "setProp",

View File

@@ -297,12 +297,11 @@ public final class GameData {
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<QuestData> questDataMap =
new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<QuestData> questDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<QuestGlobalVarData> questGlobalVarDataMap =
new Int2ObjectOpenHashMap<>();
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<ReliquaryAffixData> reliquaryAffixDataMap =
@@ -324,12 +323,11 @@ public final class GameData {
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<SceneData> sceneDataMap =
new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
@Getter
private static final Int2ObjectMap<TalkConfigData> talkConfigDataMap =
new Int2ObjectOpenHashMap<>();
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap =

View File

@@ -490,14 +490,16 @@ public final class ResourceLoader {
private static void loadQuests() {
try (var files = Files.list(getResourcePath("BinOutput/Quest/"))) {
files.forEach(path -> {
try {
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
files.forEach(
path -> {
try {
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
mainQuest.onLoad(); // Load the quest data.
} catch (IOException ignored) { }
});
mainQuest.onLoad(); // Load the quest data.
} catch (IOException ignored) {
}
});
} catch (IOException e) {
Grasscutter.getLogger().error("Quest data missing");
return;

View File

@@ -3,12 +3,10 @@ package emu.grasscutter.data.binout;
import dev.morphia.annotations.Entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.game.quest.enums.QuestType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import lombok.Data;
public class MainQuestData {
@@ -61,19 +59,20 @@ public class MainQuestData {
if (this.talks == null) this.talks = new ArrayList<>();
if (this.subQuests == null) this.subQuests = new SubQuestData[0];
this.talks = this.talks.stream()
.filter(Objects::nonNull).toList();
this.talks = this.talks.stream().filter(Objects::nonNull).toList();
// Apply talk data to the quest talk map.
this.talks.forEach(talkData -> GameData.getQuestTalkMap().put(
talkData.getId(), this.getId()));
this.talks.forEach(talkData -> GameData.getQuestTalkMap().put(talkData.getId(), this.getId()));
// Apply additional sub-quest data to sub-quests.
Arrays.stream(this.subQuests).forEach(quest -> {
var questData = GameData.getQuestDataMap().get(quest.getSubId());
if (questData != null) questData.applyFrom(quest);
});
Arrays.stream(this.subQuests)
.forEach(
quest -> {
var questData = GameData.getQuestDataMap().get(quest.getSubId());
if (questData != null) questData.applyFrom(quest);
});
}
@Data public static class SubQuestData {
@Data
public static class SubQuestData {
private int subId;
private int order;
private boolean isMpBlock;

View File

@@ -2,9 +2,11 @@ package emu.grasscutter.data.binout.config;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldDefaults;
@Data
@EqualsAndHashCode(callSuper = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigEntityGadget extends ConfigEntityBase {
// There are more values that can be added that might be useful in the json

View File

@@ -1,6 +1,8 @@
package emu.grasscutter.data.binout.config;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class ConfigEntityMonster extends ConfigEntityBase {}

View File

@@ -9,13 +9,12 @@ import lombok.Getter;
@Getter
@ResourceType(name = "ChapterExcelConfigData.json")
public class ChapterData extends GameResource {
@Getter private static final Map<Integer, ChapterData> beginQuestChapterMap
= new HashMap<>();
@Getter private static final Map<Integer, ChapterData> endQuestChapterMap
= new HashMap<>();
@Getter private static final Map<Integer, ChapterData> beginQuestChapterMap = new HashMap<>();
@Getter private static final Map<Integer, ChapterData> endQuestChapterMap = new HashMap<>();
@Getter(onMethod_ = @Override)
private int id;
private int beginQuestId;
private int endQuestId;
private int needPlayerLevel;

View File

@@ -1,37 +1,49 @@
package emu.grasscutter.data.excels;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.talk.TalkExec;
import lombok.*;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import lombok.*;
@ResourceType(name = "TalkExcelConfigData.json")
@EqualsAndHashCode(callSuper=false)
@EqualsAndHashCode(callSuper = false)
@Data
public final class TalkConfigData extends GameResource {
@SerializedName(value="id", alternate={"_id"})
@SerializedName(
value = "id",
alternate = {"_id"})
private int id;
@SerializedName(value="finishExec", alternate={"_finishExec"})
@SerializedName(
value = "finishExec",
alternate = {"_finishExec"})
private List<TalkExecParam> finishExec;
@SerializedName(value="questId", alternate={"_questId"})
@SerializedName(
value = "questId",
alternate = {"_questId"})
private int questId;
@Override
public void onLoad() {
this.finishExec = this.finishExec == null ? List.of() :
this.finishExec.stream()
.filter(x -> x.getType() != null)
.toList();
this.finishExec =
this.finishExec == null
? List.of()
: this.finishExec.stream().filter(x -> x.getType() != null).toList();
}
@Data
public static class TalkExecParam {
@SerializedName(value="type", alternate={"_type"})
@SerializedName(
value = "type",
alternate = {"_type"})
private TalkExec type;
@SerializedName(value="param", alternate={"_param"})
@SerializedName(
value = "param",
alternate = {"_param"})
private String[] param;
}
}

View File

@@ -110,13 +110,19 @@ public class QuestData extends GameResource {
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public static class QuestExecParam {
@SerializedName(value = "_type", alternate = {"type"})
@SerializedName(
value = "_type",
alternate = {"type"})
QuestExec type;
@SerializedName(value = "_param", alternate = {"param"})
@SerializedName(
value = "_param",
alternate = {"param"})
String[] param;
@SerializedName(value = "_count", alternate = {"count"})
@SerializedName(
value = "_count",
alternate = {"count"})
String count;
}
@@ -126,16 +132,24 @@ public class QuestData extends GameResource {
@Data
public static class QuestCondition<TYPE extends Enum<?> & QuestTrigger> {
@SerializedName(value = "_type", alternate = {"type"})
@SerializedName(
value = "_type",
alternate = {"type"})
private TYPE type;
@SerializedName(value = "_param", alternate = {"param"})
@SerializedName(
value = "_param",
alternate = {"param"})
private int[] param;
@SerializedName(value = "_param_str", alternate = {"param_str"})
@SerializedName(
value = "_param_str",
alternate = {"param_str"})
private String paramStr = "";
@SerializedName(value = "_count", alternate = {"count"})
@SerializedName(
value = "_count",
alternate = {"count"})
private int count;
public String asKey() {

View File

@@ -6,7 +6,7 @@ import lombok.*;
import lombok.experimental.FieldDefaults;
@ResourceType(name = "QuestGlobalVarConfigData.json")
@EqualsAndHashCode(callSuper=false)
@EqualsAndHashCode(callSuper = false)
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public final class QuestGlobalVarData extends GameResource {

View File

@@ -273,8 +273,9 @@ public final class DungeonManager {
public void finishDungeon() {
// Mark the dungeon has completed for the players.
var dungeonId = this.getDungeonData().getId();
this.getScene().getPlayers().forEach(player -> player
.getPlayerProgress().markDungeonAsComplete(dungeonId));
this.getScene()
.getPlayers()
.forEach(player -> player.getPlayerProgress().markDungeonAsComplete(dungeonId));
notifyEndDungeon(true);
endDungeon(BaseDungeonResult.DungeonEndReason.COMPLETED);
@@ -287,8 +288,8 @@ public final class DungeonManager {
p -> {
// Trigger the fail event if needed.
if (!successfully) {
p.getQuestManager().queueEvent(
QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
p.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_FAIL_DUNGEON, dungeonData.getId());
}
// Battle pass trigger

View File

@@ -16,7 +16,6 @@ import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import lombok.Getter;
import lombok.Setter;
@@ -37,6 +36,16 @@ public class WorldChallenge {
private long startedAt;
private int finishedTime;
/**
* @param scene The scene the challenge is in.
* @param group The group the challenge is in.
* @param challengeId The challenge's id.
* @param challengeIndex The challenge's index.
* @param paramList The challenge's parameters.
* @param timeLimit The challenge's time limit.
* @param goal The challenge's goal.
* @param challengeTriggers The challenge's triggers.
*/
public WorldChallenge(
Scene scene,
SceneGroup group,
@@ -109,14 +118,18 @@ public class WorldChallenge {
var eventSource = new AtomicReference<>("");
// TODO: This is a hack to get the event source.
// This should be properly implemented.
scriptManager.getTriggersByEvent(EventType.EVENT_CHALLENGE_SUCCESS)
.forEach(trigger -> {
if (trigger.currentGroup.id == this.getGroup().id) {
eventSource.set(trigger.getSource());
}
});
scriptManager.callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS)
.setParam2(finishedTime).setEventSource(eventSource.get()));
scriptManager
.getTriggersByEvent(EventType.EVENT_CHALLENGE_SUCCESS)
.forEach(
trigger -> {
if (trigger.currentGroup.id == this.getGroup().id) {
eventSource.set(trigger.getSource());
}
});
scriptManager.callEvent(
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS)
.setParam2(finishedTime)
.setEventSource(eventSource.get()));
this.getScene()
.triggerDungeonEvent(
@@ -137,15 +150,18 @@ public class WorldChallenge {
// TODO: This is a hack to get the event source.
// This should be properly implemented.
var scriptManager = this.getScene().getScriptManager();
scriptManager.getTriggersByEvent(EventType.EVENT_CHALLENGE_FAIL)
.forEach(trigger -> {
if (trigger.currentGroup.id == this.getGroup().id) {
eventSource.set(trigger.getSource());
}
});
scriptManager
.getTriggersByEvent(EventType.EVENT_CHALLENGE_FAIL)
.forEach(
trigger -> {
if (trigger.currentGroup.id == this.getGroup().id) {
eventSource.set(trigger.getSource());
}
});
scriptManager.callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL)
.setEventSource(eventSource.get()));
scriptManager.callEvent(
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL)
.setEventSource(eventSource.get()));
challengeTriggers.forEach(t -> t.onFinish(this));
}

View File

@@ -66,7 +66,8 @@ public class EntityAvatar extends GameEntity {
weapon.setWeaponEntityId(world.getNextEntityId(EntityIdType.WEAPON));
}
} else {
Grasscutter.getLogger().error("Unable to create EntityAvatar instance; provided scene is null.");
Grasscutter.getLogger()
.error("Unable to create EntityAvatar instance; provided scene is null.");
}
}

View File

@@ -53,13 +53,12 @@ public final class GadgetWorktop extends GadgetContent {
if (options == null) return;
try {
var worktop = WorktopInfo.newBuilder()
.addAllOptionList(options).build();
var worktop = WorktopInfo.newBuilder().addAllOptionList(options).build();
gadgetInfo.setWorktop(worktop);
} catch (NullPointerException ignored) {
// "this.wrapped" is null.
gadgetInfo.setWorktop(WorktopInfo.newBuilder()
.addAllOptionList(Collections.emptyList()).build());
gadgetInfo.setWorktop(
WorktopInfo.newBuilder().addAllOptionList(Collections.emptyList()).build());
Grasscutter.getLogger().warn("GadgetWorktop.onBuildProto: this.wrapped is null");
}
}
@@ -69,7 +68,6 @@ public final class GadgetWorktop extends GadgetContent {
}
public boolean onSelectWorktopOption(SelectWorktopOptionReq req) {
return this.handler != null && this.handler
.onSelectWorktopOption(this, req.getOptionId());
return this.handler != null && this.handler.onSelectWorktopOption(this, req.getOptionId());
}
}

View File

@@ -9,6 +9,7 @@ import emu.grasscutter.game.world.Scene;
import emu.grasscutter.utils.Position;
public class EntitySolarIsotomaElevatorPlatform extends EntityGadget {
@SuppressWarnings("removal")
public EntitySolarIsotomaElevatorPlatform(
EntitySolarIsotomaClientGadget isotoma,
Scene scene,

View File

@@ -923,46 +923,6 @@ public class Player {
this.getServer().getChatSystem().sendPrivateMessageFromServer(getUid(), message.toString());
}
public void setAvatarsAbilityForScene(Scene scene) {
try {
var levelEntityConfig = scene.getSceneData().getLevelEntityConfig();
var config = GameData.getConfigLevelEntityDataMap().get(levelEntityConfig);
if (config == null){
return;
}
List<Integer> avatarIds = scene.getSceneData().getSpecifiedAvatarList();
List<EntityAvatar> specifiedAvatarList = getTeamManager().getActiveTeam();
if (avatarIds != null && avatarIds.size() > 0){
// certain scene could limit a specific avatar's entry
specifiedAvatarList.clear();
for (int id : avatarIds){
var avatar = getAvatars().getAvatarById(id);
if (avatar == null){
continue;
}
specifiedAvatarList.add(new EntityAvatar(scene, avatar));
}
}
for (EntityAvatar entityAvatar : specifiedAvatarList){
var avatarData = entityAvatar.getAvatar().getAvatarData();
if (avatarData == null){
continue;
}
avatarData.buildEmbryo();
if (config.getAvatarAbilities() == null){
continue; // continue and not break because has to rebuild ability for the next avatar if any
}
for (var abilities : config.getAvatarAbilities()){
avatarData.getAbilities().add(Utils.abilityHash(abilities.getAbilityName()));
}
}
} catch (Exception e){
Grasscutter.getLogger().error("Error applying level entity config for scene {}", scene.getSceneData().getId(), e);
}
}
/**
* Sends a message to another player.
*

View File

@@ -6,9 +6,8 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.quest.enums.QuestContent;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.Map;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -39,28 +38,27 @@ public class PlayerProgress {
}
/**
* Marks a dungeon as completed.
* Triggers the quest event.
* Marks a dungeon as completed. Triggers the quest event.
*
* @param dungeonId The dungeon which was completed.
*/
public void markDungeonAsComplete(int dungeonId) {
if (this.getCompletedDungeons().contains(dungeonId))
return;
if (this.getCompletedDungeons().contains(dungeonId)) return;
// Mark the dungeon as completed.
this.getCompletedDungeons().add(dungeonId);
// Trigger the completion event.
if (this.getPlayer() != null) {
this.getPlayer().getQuestManager().queueEvent(
QuestContent.QUEST_CONTENT_FINISH_DUNGEON, dungeonId
);
this.getPlayer()
.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_FINISH_DUNGEON, dungeonId);
} else {
Grasscutter.getLogger().warn("Unable to execute 'QUEST_CONTENT_FINISH_DUNGEON'. The player is null.");
Grasscutter.getLogger()
.warn("Unable to execute 'QUEST_CONTENT_FINISH_DUNGEON'. The player is null.");
}
Grasscutter.getLogger().debug("Dungeon {} has been marked complete for {}.",
dungeonId, this.getPlayer().getUid());
Grasscutter.getLogger()
.debug("Dungeon {} has been marked complete for {}.", dungeonId, this.getPlayer().getUid());
}
public boolean hasPlayerObtainedItemHistorically(int itemId) {

View File

@@ -132,8 +132,7 @@ public final class TeamManager extends BasePlayerDataManager {
}
/**
* Returns the active team.
* If there are errors with the team, they can be fixed.
* Returns the active team. If there are errors with the team, they can be fixed.
*
* @param fix If true, the team will be fixed.
* @return The active team.
@@ -558,27 +557,32 @@ public final class TeamManager extends BasePlayerDataManager {
this.trialAvatarTeam = new TeamInfo();
// Remove the avatars from the team.
this.getActiveTeam().forEach(avatarEntity -> scene
.removeEntity(avatarEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE));
this.getActiveTeam()
.forEach(
avatarEntity ->
scene.removeEntity(
avatarEntity, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE));
if (isTeam) {
this.getActiveTeam().clear();
this.getTrialAvatars().clear();
} else {
trialAvatarIds.forEach(
trialAvatarId -> {
this.getActiveTeam().removeIf(x -> x.getAvatar().getTrialAvatarId() == trialAvatarId);
this.getTrialAvatars().values().removeIf(x -> x.getTrialAvatarId() == trialAvatarId);
});
trialAvatarId -> {
this.getActiveTeam().removeIf(x -> x.getAvatar().getTrialAvatarId() == trialAvatarId);
this.getTrialAvatars().values().removeIf(x -> x.getTrialAvatarId() == trialAvatarId);
});
}
// Re-add the avatars to the team.
if (isTeam) {
// Restores all avatars from the player's avatar storage.
this.getCurrentTeamInfo().getAvatars().forEach(avatarId ->
this.getActiveTeam().add(new EntityAvatar(
scene, player.getAvatars().getAvatarById(avatarId)
)));
this.getCurrentTeamInfo()
.getAvatars()
.forEach(
avatarId ->
this.getActiveTeam()
.add(new EntityAvatar(scene, player.getAvatars().getAvatarById(avatarId))));
} else {
// Restores all avatars from the player's avatar storage.
// If the avatar is already in the team, it will not be added.
@@ -586,9 +590,9 @@ public final class TeamManager extends BasePlayerDataManager {
for (var index = 0; index < avatars.size() - 1; index++) {
var avatar = avatars.get(index);
if (this.getActiveTeam().stream()
.map(entity -> entity.getAvatar().getAvatarId())
.toList()
.contains(avatar)) continue;
.map(entity -> entity.getAvatar().getAvatarId())
.toList()
.contains(avatar)) continue;
// Check if the player owns the avatar.
var avatarData = player.getAvatars().getAvatarById(avatar);
@@ -1123,9 +1127,9 @@ public final class TeamManager extends BasePlayerDataManager {
throw new IllegalStateException("Player is not using trial team.");
this.getPlayer()
.sendPacket(
new PacketAvatarDelNotify(
trialAvatarIds.stream().map(this::getTrialAvatarGuid).toList()));
.sendPacket(
new PacketAvatarDelNotify(
trialAvatarIds.stream().map(this::getTrialAvatarGuid).toList()));
this.removeTrialAvatarTeam(trialAvatarIds);
// Update the team.

View File

@@ -10,8 +10,8 @@ import emu.grasscutter.data.binout.MainQuestData;
import emu.grasscutter.data.binout.MainQuestData.SubQuestData;
import emu.grasscutter.data.binout.MainQuestData.TalkData;
import emu.grasscutter.data.binout.ScriptSceneData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.data.excels.RewardData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
@@ -26,7 +26,6 @@ import emu.grasscutter.utils.ConversionUtils;
import emu.grasscutter.utils.Position;
import java.util.*;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.val;
import org.bson.types.ObjectId;
@@ -139,7 +138,8 @@ public class GameMainQuest {
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_VAR_GREATER, index, value);
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_VAR_LESS, index, value);
this.getOwner().sendPacket(new PacketQuestUpdateQuestVarNotify(this.getParentQuestId(), this.questVars));
this.getOwner()
.sendPacket(new PacketQuestUpdateQuestVarNotify(this.getParentQuestId(), this.questVars));
}
public GameQuest getChildQuestById(int id) {
@@ -158,7 +158,10 @@ public class GameMainQuest {
// when auto finishing all child quests with QUEST_STATE_UNFINISHED (below)
synchronized (this) {
if (this.isFinished || this.state == ParentQuestState.PARENT_QUEST_STATE_FINISHED) {
Grasscutter.getLogger().debug("Skip main quest {} finishing because it's already finished",this.getParentQuestId());
Grasscutter.getLogger()
.debug(
"Skip main quest {} finishing because it's already finished",
this.getParentQuestId());
return;
}
@@ -178,7 +181,7 @@ public class GameMainQuest {
* new MainQuest 355 but if 35312 is not completed after the completion
* of the main quest 353 - the character will not be able to leave place
* (return again and again)
*/
*/
this.getChildQuests().values().stream()
.filter(p -> p.state != QuestState.QUEST_STATE_FINISHED)
.forEach(GameQuest::finish);
@@ -500,9 +503,16 @@ public class GameMainQuest {
subQuestWithCond.getFinishProgressList());
if (this.getQuestManager().getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) {
Grasscutter.getLogger().debug(">>> Quest {} will be {} as a result of content trigger {} ({}, {}).",
subQuestWithCond.getSubQuestId(), shouldFinish ? "finished" : "not finished", condType.name(), paramStr,
Arrays.stream(params).mapToObj(String::valueOf).collect(Collectors.joining(", ")));
Grasscutter.getLogger()
.debug(
">>> Quest {} will be {} as a result of content trigger {} ({}, {}).",
subQuestWithCond.getSubQuestId(),
shouldFinish ? "finished" : "not finished",
condType.name(),
paramStr,
Arrays.stream(params)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ")));
}
if (shouldFinish) subQuestWithCond.finish();

View File

@@ -5,8 +5,8 @@ import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.ChapterData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.data.excels.TriggerExcelConfigData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
@@ -76,8 +76,7 @@ public class GameQuest {
.toList();
if (triggerCond.size() > 0) {
for (val cond : triggerCond) {
var newTrigger = GameData.getTriggerExcelConfigDataMap()
.get(cond.getParam()[0]);
var newTrigger = GameData.getTriggerExcelConfigDataMap().get(cond.getParam()[0]);
if (newTrigger != null) {
if (this.triggerData == null) {
this.triggerData = new HashMap<>();
@@ -85,8 +84,7 @@ public class GameQuest {
triggerData.put(newTrigger.getTriggerName(), newTrigger);
triggers.put(newTrigger.getTriggerName(), false);
var group = SceneGroup.of(newTrigger.getGroupId())
.load(newTrigger.getSceneId());
var group = SceneGroup.of(newTrigger.getGroupId()).load(newTrigger.getSceneId());
this.getOwner()
.getWorld()
.getSceneById(newTrigger.getSceneId())
@@ -111,8 +109,7 @@ public class GameQuest {
this.getQuestData()
.getBeginExec()
.forEach(e -> getOwner().getServer().getQuestSystem()
.triggerExec(this, e, e.getParam()));
.forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam()));
this.getOwner().getQuestManager().checkQuestAlreadyFullfilled(this);
Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
@@ -120,11 +117,8 @@ public class GameQuest {
}
/**
* Triggers events:
* 'QUEST_COND_STATE_EQUAL',
* 'QUEST_COND_STATE_NOT_EQUAL',
* 'QUEST_CONTENT_QUEST_STATE_EQUAL',
* 'QUEST_CONTENT_QUEST_STATE_NOT_EQUAL'
* Triggers events: 'QUEST_COND_STATE_EQUAL', 'QUEST_COND_STATE_NOT_EQUAL',
* 'QUEST_CONTENT_QUEST_STATE_EQUAL', 'QUEST_CONTENT_QUEST_STATE_NOT_EQUAL'
*/
public void triggerStateEvents() {
var questManager = this.getOwner().getQuestManager();
@@ -134,7 +128,8 @@ public class GameQuest {
questManager.queueEvent(QuestCond.QUEST_COND_STATE_EQUAL, questId, state, 0, 0, 0);
questManager.queueEvent(QuestCond.QUEST_COND_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_STATE_EQUAL, questId, state, 0, 0, 0);
questManager.queueEvent(QuestContent.QUEST_CONTENT_QUEST_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
questManager.queueEvent(
QuestContent.QUEST_CONTENT_QUEST_STATE_NOT_EQUAL, questId, state, 0, 0, 0);
}
public String getTriggerNameById(int id) {

View File

@@ -20,7 +20,6 @@ public class ConditionStateNotEqual extends BaseCondition {
var questStateValue = condition.getParam()[1];
var checkQuest = owner.getQuestManager().getQuestById(questId);
return checkQuest != null &&
checkQuest.getState().getValue() != questStateValue;
return checkQuest != null && checkQuest.getState().getValue() != questStateValue;
}
}

View File

@@ -15,8 +15,9 @@ public class ContentCompleteAnyTalk extends BaseContent {
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return Stream.of(condition.getParamStr().split(","))
.mapToInt(Integer::parseInt)
.anyMatch(talkId -> GameData.getTalkConfigDataMap()
.get(params[0]) != null && talkId == params[0]);
.mapToInt(Integer::parseInt)
.anyMatch(
talkId ->
GameData.getTalkConfigDataMap().get(params[0]) != null && talkId == params[0]);
}
}

View File

@@ -2,7 +2,6 @@ package emu.grasscutter.game.quest.content;
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValueContent;

View File

@@ -14,7 +14,6 @@ public class ContentFinishDungeon extends BaseContent {
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
var dungeonId = condition.getParam()[0];
return quest.getOwner().getPlayerProgress()
.getCompletedDungeons().contains(dungeonId);
return quest.getOwner().getPlayerProgress().getCompletedDungeons().contains(dungeonId);
}
}

View File

@@ -17,8 +17,7 @@ public class ContentTriggerFire extends BaseContent {
return quest.getTriggers().get(quest.getTriggerNameById(params[0]));
} else {
Grasscutter.getLogger()
.debug("Quest {} doesn't have trigger {} registered.",
quest.getSubQuestId(), params[0]);
.debug("Quest {} doesn't have trigger {} registered.", quest.getSubQuestId(), params[0]);
return false;
}
}

View File

@@ -72,7 +72,7 @@ public enum QuestCond implements QuestTrigger {
QUEST_COND_NEW_HOMEWORLD_LEVEL_REWARD(62), // missing, only Gadget groups
QUEST_COND_NEW_HOMEWORLD_MAKE_FINISH(63), // missing, only Gadget groups
QUEST_COND_HOMEWORLD_NPC_EVENT(64), // missing, only NPC groups
QUEST_COND_TIME_VAR_GT_EQ(65), // currently unused
QUEST_COND_TIME_VAR_GT_EQ(65),
QUEST_COND_TIME_VAR_PASS_DAY(66),
QUEST_COND_HOMEWORLD_NPC_NEW_TALK(67), // missing, only NPC groups
QUEST_COND_PLAYER_CHOOSE_MALE(68), // missing, only talks

View File

@@ -18,7 +18,8 @@ public class ExecRemoveTrialAvatar extends QuestExecHandler {
return true;
} catch (IllegalStateException ignored) {
// The player does not have any trial avatars equipped.
Grasscutter.getLogger().warn("Attempted to remove trial avatars from player with none equipped.");
Grasscutter.getLogger()
.warn("Attempted to remove trial avatars from player with none equipped.");
return true;
} catch (RuntimeException exception) {
exception.printStackTrace();

View File

@@ -2,12 +2,11 @@ package emu.grasscutter.game.talk;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
public enum TalkExec {
@@ -32,11 +31,12 @@ public enum TalkExec {
static {
Stream.of(TalkExec.values())
.filter(e -> e.name().startsWith("TALK_EXEC_"))
.forEach(entry -> {
execMap.put(entry.getValue(), entry);
execStringMap.put(entry.name(), entry);
});
.filter(e -> e.name().startsWith("TALK_EXEC_"))
.forEach(
entry -> {
execMap.put(entry.getValue(), entry);
execStringMap.put(entry.name(), entry);
});
}
/**

View File

@@ -1,16 +1,15 @@
package emu.grasscutter.game.talk;
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData.TalkData;
import emu.grasscutter.game.player.BasePlayerManager;
import emu.grasscutter.game.player.Player;
import lombok.NonNull;
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
public final class TalkManager extends BasePlayerManager {
public TalkManager(@NonNull Player player) {
super(player);
@@ -27,8 +26,11 @@ public final class TalkManager extends BasePlayerManager {
var player = this.getPlayer();
// Execute the talk action on associated handlers.
talkData.getFinishExec().forEach(e -> this.getPlayer().getServer()
.getTalkSystem().triggerExec(getPlayer(), talkData, e));
talkData
.getFinishExec()
.forEach(
e ->
this.getPlayer().getServer().getTalkSystem().triggerExec(getPlayer(), talkData, e));
// Invoke the talking events for quests.
var questManager = player.getQuestManager();
@@ -43,8 +45,7 @@ public final class TalkManager extends BasePlayerManager {
public void saveTalkToQuest(int talkId, int mainQuestId) {
// TODO, problem with this is that some talks for activity also have
// quest id, which isn't present in QuestExcels
var mainQuest = this.getPlayer().getQuestManager()
.getMainQuestById(mainQuestId);
var mainQuest = this.getPlayer().getQuestManager().getMainQuestById(mainQuestId);
if (mainQuest == null) return;
mainQuest.getTalks().put(talkId, new TalkData(talkId, ""));

View File

@@ -11,15 +11,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.reflections.Reflections;
public final class TalkSystem extends BaseGameSystem {
private final Int2ObjectMap<TalkExecHandler> execHandlers
= new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<TalkExecHandler> execHandlers = new Int2ObjectOpenHashMap<>();
public TalkSystem(GameServer server) {
super(server);
this.registerHandlers(this.execHandlers,
"emu.grasscutter.game.talk.exec",
TalkExecHandler.class);
this.registerHandlers(
this.execHandlers, "emu.grasscutter.game.talk.exec", TalkExecHandler.class);
}
/**
@@ -46,7 +44,8 @@ public final class TalkSystem extends BaseGameSystem {
*/
public <T> void registerTalkHandler(Int2ObjectMap<T> map, Class<? extends T> handlerClass) {
try {
var value = 0; if (handlerClass.isAnnotationPresent(TalkValueExec.class)) {
var value = 0;
if (handlerClass.isAnnotationPresent(TalkValueExec.class)) {
TalkValueExec opcode = handlerClass.getAnnotation(TalkValueExec.class);
value = opcode.value().getValue();
} else {
@@ -70,8 +69,11 @@ public final class TalkSystem extends BaseGameSystem {
public void triggerExec(Player player, TalkConfigData talkData, TalkExecParam execParam) {
var handler = this.execHandlers.get(execParam.getType().getValue());
if (handler == null) {
Grasscutter.getLogger().debug("Could not execute talk handlers for {} ({}).",
talkData.getId(), execParam.getType().getValue());
Grasscutter.getLogger()
.debug(
"Could not execute talk handlers for {} ({}).",
talkData.getId(),
execParam.getType().getValue());
return;
}

View File

@@ -13,9 +13,9 @@ public final class ExecDecQuestGlobalVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 2) return;
player.getQuestManager().decQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
player
.getQuestManager()
.decQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -14,14 +14,11 @@ public final class ExecDecQuestVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 3) return;
GameMainQuest mainQuest = player.getQuestManager().getMainQuestById(
Integer.parseInt(execParam.getParam()[2])
);
GameMainQuest mainQuest =
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
if (mainQuest == null) return;
mainQuest.decQuestVar(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -13,9 +13,9 @@ public final class ExecIncQuestGlobalVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 2) return;
player.getQuestManager().incQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
player
.getQuestManager()
.incQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -14,14 +14,11 @@ public final class ExecIncQuestVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 3) return;
GameMainQuest mainQuest = player.getQuestManager().getMainQuestById(
Integer.parseInt(execParam.getParam()[2])
);
GameMainQuest mainQuest =
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
if (mainQuest == null) return;
mainQuest.incQuestVar(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -13,9 +13,9 @@ public final class ExecSetQuestGlobalVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 2) return;
player.getQuestManager().setQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
player
.getQuestManager()
.setQuestGlobalVarValue(
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -3,7 +3,6 @@ package emu.grasscutter.game.talk.exec;
import emu.grasscutter.data.excels.TalkConfigData;
import emu.grasscutter.data.excels.TalkConfigData.TalkExecParam;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.talk.TalkExec;
import emu.grasscutter.game.talk.TalkExecHandler;
import emu.grasscutter.game.talk.TalkValueExec;
@@ -14,14 +13,11 @@ public final class ExecSetQuestVar extends TalkExecHandler {
public void execute(Player player, TalkConfigData talkData, TalkExecParam execParam) {
if (execParam.getParam().length < 3) return;
var mainQuest = player.getQuestManager().getMainQuestById(
Integer.parseInt(execParam.getParam()[2])
);
var mainQuest =
player.getQuestManager().getMainQuestById(Integer.parseInt(execParam.getParam()[2]));
if (mainQuest == null) return;
mainQuest.setQuestVar(
Integer.parseInt(execParam.getParam()[0]),
Integer.parseInt(execParam.getParam()[1])
);
Integer.parseInt(execParam.getParam()[0]), Integer.parseInt(execParam.getParam()[1]));
}
}

View File

@@ -1,7 +1,6 @@
package emu.grasscutter.game.talk.exec;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.ScriptSceneData;
import emu.grasscutter.data.excels.TalkConfigData;
import emu.grasscutter.data.excels.TalkConfigData.TalkExecParam;
import emu.grasscutter.game.player.Player;
@@ -17,23 +16,30 @@ public final class ExecTransSceneDummyPoint extends TalkExecHandler {
// param[0] == sceneid, param[1] == position
if (execParam.getParam().length < 2) return;
var fullGlobals = GameData.getScriptSceneDataMap().get("flat.luas.scenes.full_globals.lua.json");
var fullGlobals =
GameData.getScriptSceneDataMap().get("flat.luas.scenes.full_globals.lua.json");
if (fullGlobals == null) return;
var dummyPointScript = fullGlobals.getScriptObjectList()
.get(execParam.getParam()[0] + "/scene" + execParam.getParam()[0] + "_dummy_points.lua");
var dummyPointScript =
fullGlobals
.getScriptObjectList()
.get(
execParam.getParam()[0] + "/scene" + execParam.getParam()[0] + "_dummy_points.lua");
if (dummyPointScript == null) return;
var dummyPointMap = dummyPointScript.getDummyPoints();
if (dummyPointMap == null) return;
var transmitPosPos = dummyPointMap.get(execParam.getParam()[1] + ".pos");
// List<Float> transmitPosRot = dummyPointMap.get(e.getParam()[1] + ".rot"); would be useful when transportation consider rotation
// List<Float> transmitPosRot = dummyPointMap.get(e.getParam()[1] + ".rot"); would be useful
// when transportation consider rotation
if (transmitPosPos == null || transmitPosPos.isEmpty()) return;
player.getWorld().transferPlayerToScene(
player,
Integer.parseInt(execParam.getParam()[0]),
new Position(transmitPosPos.get(0), transmitPosPos.get(1), transmitPosPos.get(2)));
player
.getWorld()
.transferPlayerToScene(
player,
Integer.parseInt(execParam.getParam()[0]),
new Position(transmitPosPos.get(0), transmitPosPos.get(1), transmitPosPos.get(2)));
}
}

View File

@@ -795,7 +795,7 @@ public final class Scene {
return true;
}
public void checkGroups() {
public synchronized void checkGroups() {
Set<Integer> visible =
this.players.stream()
.map(player -> this.getPlayerActiveGroups(player))
@@ -833,7 +833,7 @@ public final class Scene {
this.getScriptManager().loadBlockFromScript(block);
scriptManager.getLoadedGroupSetPerBlock().put(block.id, new HashSet<>());
Grasscutter.getLogger().trace("Scene {} Block {} loaded.", this.getId(), block.id);
Grasscutter.getLogger().debug("Scene {} Block {} loaded.", this.getId(), block.id);
}
public int loadDynamicGroup(int group_id) {
@@ -963,7 +963,7 @@ public final class Scene {
groupInstance = cachedInstance;
}
/* Don't load garbages
// Load garbages
var garbageGadgets = group.getGarbageGadgets();
if (garbageGadgets != null) {
@@ -973,7 +973,7 @@ public final class Scene {
.filter(Objects::nonNull)
.toList());
}
*/
// Load suites
// int suite = group.findInitSuiteIndex(0);
this.getScriptManager()
@@ -1014,7 +1014,7 @@ public final class Scene {
if (this.scriptManager.getLoadedGroupSetPerBlock().get(block.id).isEmpty()) {
this.scriptManager.getLoadedGroupSetPerBlock().remove(block.id);
Grasscutter.getLogger().trace("Scene {} Block {} is unloaded.", this.getId(), block.id);
Grasscutter.getLogger().debug("Scene {} Block {} is unloaded.", this.getId(), block.id);
}
this.broadcastPacket(new PacketGroupUnloadNotify(List.of(group_id)));

View File

@@ -282,9 +282,7 @@ public class World implements Iterable<Player> {
teleportProps
.teleportTo(dungeonData.getStartPosition())
.teleportRot(dungeonData.getStartRotation());
teleportProps
.enterType(EnterType.ENTER_TYPE_DUNGEON)
.enterReason(EnterReason.DungeonEnter);
teleportProps.enterType(EnterType.ENTER_TYPE_DUNGEON).enterReason(EnterReason.DungeonEnter);
teleportProps.dungeonId(dungeonData.getId());
} else if (player.getSceneId() == sceneId) {
teleportProps.enterType(EnterType.ENTER_TYPE_GOTO);
@@ -504,10 +502,7 @@ public class World implements Iterable<Player> {
// Trigger script events.
this.players.forEach(
player ->
player
.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
player -> player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
}
/**
@@ -528,10 +523,7 @@ public class World implements Iterable<Player> {
// Update all players.
this.host.updatePlayerGameTime(currentWorldTime);
this.players.forEach(
player ->
player
.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
player -> player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
}
@Override

View File

@@ -53,14 +53,15 @@ public class PacketOpcodesUtils {
public static void dumpPacketIds() {
try (var writer = new FileWriter("./PacketIds_" + GameConstants.VERSION + ".json")) {
// Create sorted tree map
var packetIds = opcodeMap.int2ObjectEntrySet().stream()
.filter(e -> e.getIntKey() > 0)
.collect(
Collectors.toMap(
Int2ObjectMap.Entry::getIntKey,
Int2ObjectMap.Entry::getValue,
(k, v) -> v,
TreeMap::new));
var packetIds =
opcodeMap.int2ObjectEntrySet().stream()
.filter(e -> e.getIntKey() > 0)
.collect(
Collectors.toMap(
Int2ObjectMap.Entry::getIntKey,
Int2ObjectMap.Entry::getValue,
(k, v) -> v,
TreeMap::new));
// Write to file
writer.write(JsonUtils.encode(packetIds));
Grasscutter.getLogger().info("Dumped packet IDs.");

View File

@@ -661,8 +661,7 @@ public class SceneScriptManager {
for (var entityId : region.getEntities()) {
var entity = this.getScene().getEntityById(entityId);
if (entity == null || !region.getMetaRegion()
.contains(entity.getPosition())) {
if (entity == null || !region.getMetaRegion().contains(entity.getPosition())) {
region.removeEntity(entityId);
}
}

View File

@@ -39,8 +39,7 @@ public class ScriptLoader {
private static Map<String, SoftReference<CompiledScript>> scriptsCache =
new ConcurrentHashMap<>();
/** sceneId - SceneMeta */
private static Map<Integer, SoftReference<SceneMeta>> sceneMetaCache =
new ConcurrentHashMap<>();
private static Map<Integer, SoftReference<SceneMeta>> sceneMetaCache = new ConcurrentHashMap<>();
public static synchronized void init() throws Exception {
if (sm != null) {

View File

@@ -93,9 +93,8 @@ public final class SceneGroup {
this.bindings = ScriptLoader.getEngine().createBindings();
CompiledScript cs =
ScriptLoader.getScript(
"Scene/" + sceneId + "/scene" + sceneId + "_group" + this.id + ".lua");
var cs =
ScriptLoader.getScript("Scene/%s/scene%s_group%s.lua".formatted(sceneId, sceneId, this.id));
if (cs == null) {
return this;
@@ -171,8 +170,10 @@ public final class SceneGroup {
.error(
"An error occurred while loading group " + this.id + " in scene " + sceneId + ".", e);
} catch (LuaError luaError) {
Grasscutter.getLogger().error("An error occurred while loading group %s in scene %s."
.formatted(this.id, sceneId), luaError);
Grasscutter.getLogger()
.error(
"An error occurred while loading group %s in scene %s.".formatted(this.id, sceneId),
luaError);
}
Grasscutter.getLogger().trace("Successfully loaded group {} in scene {}.", this.id, sceneId);

View File

@@ -114,8 +114,7 @@ public final class RegionHandler implements Router {
customConfig.addProperty("sdkenv", "2");
customConfig.addProperty("checkdevice", "false");
customConfig.addProperty("loadPatch", "false");
customConfig.addProperty("showexception",
String.valueOf(showExceptions));
customConfig.addProperty("showexception", String.valueOf(showExceptions));
customConfig.addProperty("regionConfig", "pm|fk|add");
customConfig.addProperty("downloadMode", "0");
customConfig.add("coverSwitch", hiddenIcons);

View File

@@ -1,10 +1,5 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData;
import emu.grasscutter.data.binout.MainQuestData.TalkData;
import emu.grasscutter.game.quest.enums.QuestCond;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;

View File

@@ -3,7 +3,6 @@ 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.net.proto.PacketHeadOuterClass.PacketHead;
import emu.grasscutter.net.proto.PlayerSetPauseReqOuterClass.PlayerSetPauseReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketPlayerSetPauseRsp;

View File

@@ -5,11 +5,9 @@ import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestUpdateQuestVarReqOuterClass.QuestUpdateQuestVarReq;
import emu.grasscutter.net.proto.QuestVarOpOuterClass.QuestVarOp;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarRsp;
import java.util.List;
@Opcodes(PacketOpcodes.QuestUpdateQuestVarReq)
public class HandlerQuestUpdateQuestVarReq extends PacketHandler {

View File

@@ -3,7 +3,6 @@ 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.net.proto.SkipPlayerGameTimeReqOuterClass;
import emu.grasscutter.net.proto.SkipPlayerGameTimeReqOuterClass.SkipPlayerGameTimeReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify;
@@ -16,7 +15,10 @@ public class HandlerSkipPlayerGameTimeReq extends PacketHandler {
var req = SkipPlayerGameTimeReq.parseFrom(payload);
var player = session.getPlayer();
var newTime = req.getGameTime() * 1000L + player.getPlayerGameTime() - (player.getPlayerGameTime() % 1440000);
var newTime =
req.getGameTime() * 1000L
+ player.getPlayerGameTime()
- (player.getPlayerGameTime() % 1440000);
player.updatePlayerGameTime(newTime);
player.getScene().broadcastPacket(new PacketPlayerGameTimeNotify(player));
player.sendPacket(new PacketSkipPlayerGameTimeRsp(req));

View File

@@ -10,7 +10,6 @@ public class PacketPlayerSetPauseRsp extends BasePacket {
public PacketPlayerSetPauseRsp() {
super(PacketOpcodes.PlayerSetPauseRsp);
this.setData(PlayerSetPauseRsp.newBuilder()
.setRetcode(Retcode.RET_SUCC_VALUE));
this.setData(PlayerSetPauseRsp.newBuilder().setRetcode(Retcode.RET_SUCC_VALUE));
}
}

View File

@@ -6,18 +6,21 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestGlobalVarNotifyOuterClass.QuestGlobalVarNotify;
import emu.grasscutter.net.proto.QuestGlobalVarOuterClass.QuestGlobalVar;
public final class PacketQuestGlobalVarNotify extends BasePacket {
public PacketQuestGlobalVarNotify(Player player) {
super(PacketOpcodes.QuestGlobalVarNotify);
this.setData(QuestGlobalVarNotify.newBuilder()
.addAllVarList(player.getQuestGlobalVariables().entrySet().stream()
.map(entry -> QuestGlobalVar.newBuilder()
.setKey(entry.getKey())
.setValue(entry.getValue())
.build())
.toList())
.build());
this.setData(
QuestGlobalVarNotify.newBuilder()
.addAllVarList(
player.getQuestGlobalVariables().entrySet().stream()
.map(
entry ->
QuestGlobalVar.newBuilder()
.setKey(entry.getKey())
.setValue(entry.getValue())
.build())
.toList())
.build());
}
}

View File

@@ -3,17 +3,16 @@ package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuestUpdateQuestVarNotifyOuterClass.QuestUpdateQuestVarNotify;
import java.util.stream.IntStream;
public class PacketQuestUpdateQuestVarNotify extends BasePacket {
public PacketQuestUpdateQuestVarNotify(int mainQuestId, int... questVars) {
super(PacketOpcodes.QuestUpdateQuestVarNotify);
this.setData(QuestUpdateQuestVarNotify.newBuilder()
.setParentQuestId(mainQuestId)
.addAllQuestVar(IntStream.of(questVars)
.boxed().toList())
.build());
this.setData(
QuestUpdateQuestVarNotify.newBuilder()
.setParentQuestId(mainQuestId)
.addAllQuestVar(IntStream.of(questVars).boxed().toList())
.build());
}
}

View File

@@ -11,25 +11,24 @@ public class PacketSceneTeamUpdateNotify extends BasePacket {
public PacketSceneTeamUpdateNotify(Player player) {
super(PacketOpcodes.SceneTeamUpdateNotify);
var proto = SceneTeamUpdateNotify.newBuilder()
.setIsInMp(player.getWorld().isMultiplayer());
var proto = SceneTeamUpdateNotify.newBuilder().setIsInMp(player.getWorld().isMultiplayer());
for (var p : player.getWorld().getPlayers()) {
for (var entityAvatar : p.getTeamManager().getActiveTeam(true)) {
var avatarProto =
SceneTeamAvatar.newBuilder()
.setPlayerUid(p.getUid())
.setAvatarGuid(entityAvatar.getAvatar().getGuid())
.setSceneId(p.getSceneId())
.setEntityId(entityAvatar.getId())
.setSceneEntityInfo(entityAvatar.toProto())
.setWeaponGuid(entityAvatar.getAvatar().getWeapon().getGuid())
.setWeaponEntityId(entityAvatar.getWeaponEntityId())
.setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
.setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
.setAvatarAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setWeaponAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setAbilityControlBlock(entityAvatar.getAbilityControlBlock());
SceneTeamAvatar.newBuilder()
.setPlayerUid(p.getUid())
.setAvatarGuid(entityAvatar.getAvatar().getGuid())
.setSceneId(p.getSceneId())
.setEntityId(entityAvatar.getId())
.setSceneEntityInfo(entityAvatar.toProto())
.setWeaponGuid(entityAvatar.getAvatar().getWeapon().getGuid())
.setWeaponEntityId(entityAvatar.getWeaponEntityId())
.setIsPlayerCurAvatar(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
.setIsOnScene(p.getTeamManager().getCurrentAvatarEntity() == entityAvatar)
.setAvatarAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setWeaponAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setAbilityControlBlock(entityAvatar.getAbilityControlBlock());
if (player.getWorld().isMultiplayer()) {
avatarProto.setAvatarInfo(entityAvatar.getAvatar().toProto());

View File

@@ -85,13 +85,14 @@ public final class Tools {
void newTranslatedLine(String template, TextStrings... textstrings) {
for (int i = 0; i < TextStrings.NUM_LANGUAGES; i++) {
String s = template;
for (int j = 0; j < textstrings.length; j++) try {
s = s.replace("{" + j + "}", textstrings[j].strings[i]);
} catch (NullPointerException ignored) {
// TextMap cache is outdated.
j--; // Retry the action.
Language.loadTextMaps(true);
}
for (int j = 0; j < textstrings.length; j++)
try {
s = s.replace("{" + j + "}", textstrings[j].strings[i]);
} catch (NullPointerException ignored) {
// TextMap cache is outdated.
j--; // Retry the action.
Language.loadTextMaps(true);
}
handbookBuilders.get(i).append(s + "\n");
}
}

View File

@@ -41,11 +41,7 @@ public final class GridPosition implements Serializable {
@SneakyThrows
public GridPosition(String str) {
var listOfParams = str
.replace(" ", "")
.replace("(", "")
.replace(")", "")
.split(",");
var listOfParams = str.replace(" ", "").replace("(", "").replace(")", "").split(",");
if (listOfParams.length != 3)
throw new IOException("invalid size on GridPosition definition - ");
try {

View File

@@ -90,20 +90,14 @@ public class JsonAdapters {
// GridPosition follows the format of: (x, y, z).
// Flatten to (x,y,z) for easier parsing.
var str = in.nextString()
.replace("(", "")
.replace(")", "")
.replace(" ", "");
var str = in.nextString().replace("(", "").replace(")", "").replace(" ", "");
var split = str.split(",");
if (split.length != 3)
throw new IOException("Invalid GridPosition definition - " + in.peek().name());
return new GridPosition(
Integer.parseInt(split[0]),
Integer.parseInt(split[1]),
Integer.parseInt(split[2])
);
Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
}
}

View File

@@ -22,13 +22,13 @@ import java.util.Map;
public final class JsonUtils {
static final Gson gson =
new GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter())
.registerTypeAdapter(IntList.class, new IntListAdapter())
.registerTypeAdapter(Position.class, new PositionAdapter())
.registerTypeAdapter(GridPosition.class, new GridPositionAdapter())
.registerTypeAdapterFactory(new EnumTypeAdapterFactory())
.create();
.setPrettyPrinting()
.registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter())
.registerTypeAdapter(IntList.class, new IntListAdapter())
.registerTypeAdapter(Position.class, new PositionAdapter())
.registerTypeAdapter(GridPosition.class, new GridPositionAdapter())
.registerTypeAdapterFactory(new EnumTypeAdapterFactory())
.create();
/*
* Encode an object to a JSON string

View File

@@ -314,9 +314,7 @@ public final class Language {
return getTextMapKey((int) hash);
}
/**
* Loads game text maps with caching.
*/
/** Loads game text maps with caching. */
public static void loadTextMaps() {
Language.loadTextMaps(false);
}
@@ -328,36 +326,38 @@ public final class Language {
*/
public static void loadTextMaps(boolean bypassCache) {
// Check system timestamps on cache and resources
if (!bypassCache) try {
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
long textmapsModified =
Files.list(getResourcePath("TextMap"))
.filter(path -> path.toString().endsWith(".json"))
.map(
path -> {
try {
return Files.getLastModifiedTime(path).toMillis();
} catch (Exception ignored) {
Grasscutter.getLogger()
.debug("Exception while checking modified time: ", path);
return Long.MAX_VALUE; // Don't use cache, something has gone wrong
}
})
.max(Long::compare)
.get();
if (!bypassCache)
try {
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
long textmapsModified =
Files.list(getResourcePath("TextMap"))
.filter(path -> path.toString().endsWith(".json"))
.map(
path -> {
try {
return Files.getLastModifiedTime(path).toMillis();
} catch (Exception ignored) {
Grasscutter.getLogger()
.debug("Exception while checking modified time: ", path);
return Long.MAX_VALUE; // Don't use cache, something has gone wrong
}
})
.max(Long::compare)
.get();
Grasscutter.getLogger()
.debug(
"Cache modified %d, textmap modified %d".formatted(cacheModified, textmapsModified));
if (textmapsModified < cacheModified) {
// Try loading from cache
Grasscutter.getLogger().debug("Loading cached 'TextMaps'...");
textMapStrings = loadTextMapsCache();
return;
Grasscutter.getLogger()
.debug(
"Cache modified %d, textmap modified %d"
.formatted(cacheModified, textmapsModified));
if (textmapsModified < cacheModified) {
// Try loading from cache
Grasscutter.getLogger().debug("Loading cached 'TextMaps'...");
textMapStrings = loadTextMapsCache();
return;
}
} catch (Exception exception) {
Grasscutter.getLogger().error("Error loading textmaps cache: " + exception.toString());
}
} catch (Exception exception) {
Grasscutter.getLogger().error("Error loading textmaps cache: " + exception.toString());
}
// Regenerate cache
Grasscutter.getLogger().debug("Generating TextMaps cache");

View File

@@ -57,7 +57,7 @@ public class TsvUtils {
private static final Function<String, Object> parseLong =
value -> (long) Double.parseDouble(value); // Long::parseLong;
private static final Map<Class<?>, Function<String, Object>> enumTypeParsers = new HashMap<>();
private final static Map<Type, Function<String, Object>> primitiveTypeParsers =
private static final Map<Type, Function<String, Object>> primitiveTypeParsers =
Map.ofEntries(
Map.entry(String.class, parseString),
Map.entry(Integer.class, parseInt),
@@ -72,7 +72,7 @@ public class TsvUtils {
Map.entry(boolean.class, Boolean::parseBoolean));
private static final Map<Type, Function<String, Object>> typeParsers =
new HashMap<>(primitiveTypeParsers);
private final static Map<Class<?>, Map<String, FieldParser>> cachedClassFieldMaps =
private static final Map<Class<?>, Map<String, FieldParser>> cachedClassFieldMaps =
new HashMap<>();
@SuppressWarnings("unchecked")