Run the formatter & Generate protocol definitions

This commit is contained in:
KingRainbow44
2023-08-26 19:51:45 -04:00
parent edb00adf61
commit f656143038
101 changed files with 15615 additions and 6636 deletions

View File

@@ -27,11 +27,10 @@ import emu.grasscutter.game.quest.enums.QuestCond;
import emu.grasscutter.game.world.GroupReplacementData;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.*;
import javax.annotation.Nullable;
import lombok.*;
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
public final class GameData {
@@ -142,8 +141,7 @@ public final class GameData {
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<BargainData> bargainDataMap
= new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<BargainData> bargainDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap =
@@ -250,7 +248,8 @@ public final class GameData {
private static final Int2ObjectMap<GivingData> givingDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<GivingGroupData> givingGroupDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<GivingGroupData> givingGroupDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
@Deprecated // This is to prevent people from using this map. This is for the resource loader
@@ -270,17 +269,18 @@ public final class GameData {
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<ItemData> itemDataMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<ItemData> itemDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MapLayerData> mapLayerDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MapLayerFloorData> mapLayerFloorDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<MapLayerFloorData> mapLayerFloorDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MapLayerGroupData> mapLayerGroupDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<MapLayerGroupData> mapLayerGroupDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MonsterCurveData> monsterCurveDataMap =
@@ -347,16 +347,18 @@ public final class GameData {
@Getter
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
@Getter
private static final Int2ObjectMap<SceneTagData> sceneTagDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<SceneTagData> sceneTagDataMap =
new Int2ObjectLinkedOpenHashMap<>();
@Getter
private static final Int2ObjectMap<TalkConfigData> talkConfigDataMap =
new Int2ObjectOpenHashMap<>();
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap =
new Int2ObjectOpenHashMap<>();
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap =

View File

@@ -1,9 +1,8 @@
package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import lombok.Getter;
import java.util.List;
import lombok.Getter;
@Getter
@ResourceType(name = "BargainExcelConfigData.json")
@@ -14,11 +13,11 @@ public final class BargainData extends GameResource {
private List<Integer> dialogId;
/**
* This is a list of 2 integers.
* The first integer is the minimum value of the bargain.
* The second integer is the maximum value of the bargain.
* This is a list of 2 integers. The first integer is the minimum value of the bargain. The second
* integer is the maximum value of the bargain.
*/
private List<Integer> expectedValue;
private int space;
private List<Integer> successTalkId;
@@ -26,11 +25,11 @@ public final class BargainData extends GameResource {
private int moodNpcId;
/**
* This is a list of 2 integers.
* The first integer is the minimum value of the mood.
* The second integer is the maximum value of the mood.
* This is a list of 2 integers. The first integer is the minimum value of the mood. The second
* integer is the maximum value of the mood.
*/
private List<Integer> randomMood;
private int moodAlertLimit;
private int moodLowLimit;
private int singleFailMoodDeduction;

View File

@@ -4,9 +4,8 @@ import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.inventory.BagTab;
import lombok.*;
import java.util.List;
import lombok.*;
@Data
@EqualsAndHashCode(callSuper = false)
@@ -14,6 +13,7 @@ import java.util.List;
public final class GivingData extends GameResource {
@SerializedName(value = "id", alternate = "Id")
private int id;
private int talkId;
private int mistakeTalkId;
@@ -40,7 +40,9 @@ public final class GivingData extends GameResource {
}
public enum GiveType {
@SerializedName("GIVING_TYPE_QUEST") QUEST,
@SerializedName("GIVING_TYPE_GROUP") GROUP
@SerializedName("GIVING_TYPE_QUEST")
QUEST,
@SerializedName("GIVING_TYPE_GROUP")
GROUP
}
}

View File

@@ -2,9 +2,8 @@ package emu.grasscutter.data.excels.giving;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.*;
import lombok.*;
import java.util.List;
import lombok.*;
@Data
@EqualsAndHashCode(callSuper = false)

View File

@@ -13,7 +13,7 @@ public final class MapLayerData extends GameResource {
@SerializedName("NLPFIGAEBFP")
private int idk1;
@SerializedName("GCBPOOPNLLD")
private float level; //how deep thoronium is in me
@SerializedName("GCBPOOPNLLD")
private float level; // how deep thoronium is in me
}

View File

@@ -3,22 +3,26 @@ package emu.grasscutter.data.excels.scene;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import java.util.List;
@ResourceType(name = "MapLayerFloorExcelConfigData.json")
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)
public final class MapLayerFloorData extends GameResource {
@Getter(onMethod_ = @Override)
int id;
int PJDGAAAGOPO;
int LCGNJBLMDHA;
@SerializedName(value = "floorNameTextMapHash", alternate = {"NDAGFKELEAP"})
@SerializedName(
value = "floorNameTextMapHash",
alternate = {"NDAGFKELEAP"})
long floorNameTextMapHash;
CKNDNKLCAHC CKNDNKLCAHC;
long BHEMLJCFHPI;

View File

@@ -3,9 +3,8 @@ package emu.grasscutter.data.excels.scene;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.Getter;
import java.util.List;
import lombok.Getter;
@ResourceType(name = "MapLayerGroupExcelConfigData.json")
@Getter
@@ -15,7 +14,7 @@ public final class MapLayerGroupData extends GameResource {
@SerializedName("FIIAHPKBCDE")
private List<Integer> areaIds;
@SerializedName("ODEFCAMHKNK")
private float mapFloorId; //MapLayerFloorExcel (first level of the maplayer)
@SerializedName("ODEFCAMHKNK")
private float mapFloorId; // MapLayerFloorExcel (first level of the maplayer)
}

View File

@@ -3,9 +3,8 @@ package emu.grasscutter.data.excels.scene;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.*;
import emu.grasscutter.game.props.SceneType;
import lombok.Getter;
import java.util.List;
import lombok.Getter;
@ResourceType(name = "SceneExcelConfigData.json")
@Getter

View File

@@ -3,9 +3,8 @@ package emu.grasscutter.data.excels.scene;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import lombok.Getter;
import java.util.List;
import lombok.Getter;
@ResourceType(name = "SceneTagConfigData.json")
@Getter
@@ -15,6 +14,7 @@ public final class SceneTagData extends GameResource {
@SerializedName("DJCOAOBDIHP")
private boolean idk1;
@SerializedName("LOLNNMPKHIB")
private boolean idk2;

View File

@@ -21,10 +21,10 @@ import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.world.SceneGroupInstance;
import emu.grasscutter.utils.objects.Returnable;
import io.netty.util.concurrent.FastThreadLocalThread;
import javax.annotation.Nullable;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import lombok.Getter;
public final class DatabaseHelper {
@@ -542,18 +542,16 @@ public final class DatabaseHelper {
DatabaseHelper.saveGameAsync(musicGameBeatmap);
}
@Nullable
public static Achievements getAchievementData(int uid) {
@Nullable public static Achievements getAchievementData(int uid) {
try {
return DatabaseManager.getGameDatastore()
.find(Achievements.class)
.filter(Filters.and(Filters.eq("uid", uid)))
.first();
.find(Achievements.class)
.filter(Filters.and(Filters.eq("uid", uid)))
.first();
} catch (IllegalArgumentException e) {
Grasscutter.getLogger().debug("Error occurred while getting uid " + uid + "'s achievement data", e);
DatabaseManager.getGameDatabase()
.getCollection("achievements")
.deleteMany(eq("uid", uid));
Grasscutter.getLogger()
.debug("Error occurred while getting uid " + uid + "'s achievement data", e);
DatabaseManager.getGameDatabase().getCollection("achievements").deleteMany(eq("uid", uid));
return null;
}
}

View File

@@ -19,11 +19,10 @@ import emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType;
import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry;
import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction;
import io.netty.util.concurrent.FastThreadLocalThread;
import lombok.Getter;
import org.reflections.Reflections;
import java.util.HashMap;
import java.util.concurrent.*;
import lombok.Getter;
import org.reflections.Reflections;
public final class AbilityManager extends BasePlayerManager {
private static final HashMap<AbilityModifierAction.Type, AbilityActionHandler> actionHandlers =
@@ -93,7 +92,7 @@ public final class AbilityManager extends BasePlayerManager {
if (handler == null || ability == null) {
if (DebugConstants.LOG_ABILITIES) {
Grasscutter.getLogger()
.debug("Could not execute ability action {} at {}", action.type, ability);
.debug("Could not execute ability action {} at {}", action.type, ability);
}
return;

View File

@@ -1,22 +1,21 @@
package emu.grasscutter.game.achievement;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.AchievementOuterClass;
import emu.grasscutter.net.proto.StatusOuterClass;
import lombok.Getter;
import lombok.Setter;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.AchievementOuterClass.Achievement.Status;
import lombok.*;
@Entity
@Getter
public class Achievement {
@Setter private StatusOuterClass.Status status;
@Setter private Status status;
private int id;
private int totalProgress;
@Setter private int curProgress;
@Setter private int finishTimestampSec;
public Achievement(
StatusOuterClass.Status status,
Status status,
int id,
int totalProgress,
int curProgress,

View File

@@ -1,9 +1,7 @@
package emu.grasscutter.game.achievement;
import com.github.davidmoten.guavamini.Lists;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Transient;
import dev.morphia.annotations.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.achievement.AchievementData;
@@ -11,22 +9,15 @@ import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.proto.StatusOuterClass;
import emu.grasscutter.server.packet.send.PacketAchievementAllDataNotify;
import emu.grasscutter.server.packet.send.PacketAchievementUpdateNotify;
import emu.grasscutter.server.packet.send.PacketTakeAchievementGoalRewardRsp;
import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardRsp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import emu.grasscutter.net.proto.AchievementOuterClass.Achievement.Status;
import emu.grasscutter.server.packet.send.*;
import lombok.*;
import org.bson.types.ObjectId;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntSupplier;
import javax.annotation.Nullable;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import org.bson.types.ObjectId;
@Entity("achievements")
@Data
@@ -35,7 +26,7 @@ public class Achievements {
private static final IntSupplier currentTimeSecs =
() -> (int) (System.currentTimeMillis() / 1000L);
private static final Achievement INVALID =
new Achievement(StatusOuterClass.Status.STATUS_INVALID, -1, 0, 0, 0);
new Achievement(Status.STATUS_INVALID, -1, 0, 0, 0);
@Id private ObjectId id;
private int uid;
@Transient private Player player;
@@ -75,7 +66,7 @@ public class Achievements {
map.put(
a.getId(),
new Achievement(
StatusOuterClass.Status.STATUS_UNFINISHED, a.getId(), a.getProgress(), 0, 0));
Status.STATUS_UNFINISHED, a.getId(), a.getProgress(), 0, 0));
});
return map;
}
@@ -135,13 +126,13 @@ public class Achievements {
}
private boolean update(Achievement a) {
if (a.getStatus() == StatusOuterClass.Status.STATUS_UNFINISHED
if (a.getStatus() == Status.STATUS_UNFINISHED
&& a.getCurProgress() >= a.getTotalProgress()) {
a.setStatus(StatusOuterClass.Status.STATUS_FINISHED);
a.setStatus(Status.STATUS_FINISHED);
a.setFinishTimestampSec(currentTimeSecs.getAsInt());
return true;
} else if (this.isFinished(a.getId()) && a.getCurProgress() < a.getTotalProgress()) {
a.setStatus(StatusOuterClass.Status.STATUS_UNFINISHED);
a.setStatus(Status.STATUS_UNFINISHED);
a.setFinishTimestampSec(0);
return true;
}
@@ -187,7 +178,7 @@ public class Achievements {
achievementId,
id -> {
return new Achievement(
StatusOuterClass.Status.STATUS_UNFINISHED,
Status.STATUS_UNFINISHED,
id,
GameData.getAchievementDataMap().get(id.intValue()).getProgress(),
0,
@@ -200,14 +191,14 @@ public class Achievements {
return data == null || data.isDisuse();
}
public StatusOuterClass.Status getStatus(int achievementId) {
public Status getStatus(int achievementId) {
return this.getAchievementList().getOrDefault(achievementId, INVALID).getStatus();
}
public boolean isFinished(int achievementId) {
var status = this.getStatus(achievementId);
return status == StatusOuterClass.Status.STATUS_FINISHED
|| status == StatusOuterClass.Status.STATUS_REWARD_TAKEN;
return status == Status.STATUS_FINISHED
|| status == Status.STATUS_REWARD_TAKEN;
}
public void takeReward(List<Integer> ids) {
@@ -244,7 +235,7 @@ public class Achievements {
});
var a = this.getAchievement(i);
a.setStatus(StatusOuterClass.Status.STATUS_REWARD_TAKEN);
a.setStatus(Status.STATUS_REWARD_TAKEN);
this.save();
this.sendUpdatePacket(a);
}
@@ -298,11 +289,11 @@ public class Achievements {
}
public boolean isRewardTaken(int achievementId) {
return this.getStatus(achievementId) == StatusOuterClass.Status.STATUS_REWARD_TAKEN;
return this.getStatus(achievementId) == Status.STATUS_REWARD_TAKEN;
}
public boolean isRewardLeft(int achievementId) {
return this.getStatus(achievementId) == StatusOuterClass.Status.STATUS_FINISHED;
return this.getStatus(achievementId) == Status.STATUS_FINISHED;
}
private boolean isPacketSendable() {
@@ -324,12 +315,15 @@ public class Achievements {
private void registerNewAchievementsIfExist() {
GameData.getAchievementDataMap().values().stream()
.filter(AchievementData::isUsed)
.filter(a -> !this.achievementList.containsKey(a.getId()))
.forEach(a -> {
Grasscutter.getLogger().info("Registering a new achievement (id: {})", a.getId());
this.achievementList.put(a.getId(), new Achievement(AchievementStatus.UNFINISHED, a.getId(), a.getProgress(), 0, 0));
});
.filter(AchievementData::isUsed)
.filter(a -> !this.achievementList.containsKey(a.getId()))
.forEach(
a -> {
Grasscutter.getLogger().trace("Registering a new achievement (id: {})", a.getId());
this.achievementList.put(
a.getId(),
new Achievement(Status.STATUS_UNFINISHED, a.getId(), a.getProgress(), 0, 0));
});
this.save();
}
}

View File

@@ -828,11 +828,11 @@ public class Avatar {
switch (entry.getExtraTalentIndex()) {
case 9 -> this.skillDepot.getEnergySkill(); // Ult skill
case 2 -> (this.skillDepot.getSkills().size() >= 2)
? this.skillDepot.getSkills().get(1)
: 0; // E skill
? this.skillDepot.getSkills().get(1)
: 0; // E skill
case 1 -> (this.skillDepot.getSkills().size() >= 1)
? this.skillDepot.getSkills().get(0)
: 0; // Normal Attack (Liney)
? this.skillDepot.getSkills().get(0)
: 0; // Normal Attack (Liney)
default -> 0;
};
// Sanity check

View File

@@ -3,20 +3,16 @@ package emu.grasscutter.game.dungeons.challenge;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger;
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneTrigger;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
import emu.grasscutter.scripts.data.*;
import emu.grasscutter.server.packet.send.*;
import lombok.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@@ -81,7 +77,7 @@ public class WorldChallenge {
public void start() {
if (inProgress()) {
Grasscutter.getLogger().info("Could not start a in progress challenge.");
Grasscutter.getLogger().debug("Could not start a in progress challenge.");
return;
}
this.progress = true;

View File

@@ -1,10 +1,9 @@
package emu.grasscutter.game.inventory;
import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import java.util.*;
import java.util.stream.Stream;
import lombok.*;
@RequiredArgsConstructor
public enum BagTab {
@@ -24,11 +23,11 @@ public enum BagTab {
static {
Stream.of(BagTab.values())
.forEach(
entry -> {
map.put(entry.getValue(), entry);
stringMap.put(entry.name(), entry);
});
.forEach(
entry -> {
map.put(entry.getValue(), entry);
stringMap.put(entry.name(), entry);
});
}
@Getter private final int value;

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.game.inventory;
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData;
@@ -15,13 +17,10 @@ import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.longs.*;
import java.util.*;
import javax.annotation.Nullable;
import lombok.val;
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
private final Long2ObjectMap<GameItem> store;
private final Int2ObjectMap<InventoryTab> inventoryTypes;
@@ -185,8 +184,8 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
}
/**
* Checks to see if the player has the item in their inventory.
* This will succeed if the player has at least the minimum count of the item.
* Checks to see if the player has the item in their inventory. This will succeed if the player
* has at least the minimum count of the item.
*
* @param itemId The item id to check for.
* @param minCount The minimum count of the item to check for.
@@ -201,30 +200,26 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
*
* @param itemId The item id to check for.
* @param count The count of the item to check for.
* @param enforce If true, the player must have the exact amount.
* If false, the player must have at least the amount.
* @param enforce If true, the player must have the exact amount. If false, the player must have
* at least the amount.
* @return True if the player has the item, false otherwise.
*/
public boolean hasItem(int itemId, int count, boolean enforce) {
var item = this.getFirstItem(itemId);
if (item == null) return false;
return enforce ?
item.getCount() == count :
item.getCount() >= count;
return enforce ? item.getCount() == count : item.getCount() >= count;
}
/**
* Checks to see if the player has the item in their inventory.
* This is exact.
* Checks to see if the player has the item in their inventory. This is exact.
*
* @param items A map of item game IDs to their count.
* @return True if the player has the items, false otherwise.
*/
public boolean hasAllItems(Collection<ItemParam> items) {
for (var item : items) {
if (!this.hasItem(item.getItemId(), item.getCount(), true))
return false;
if (!this.hasItem(item.getItemId(), item.getCount(), true)) return false;
}
return true;
@@ -530,22 +525,18 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
}
/**
* Removes an item from the player's inventory.
* This uses the item ID to find the first stack of the item's type.
* Removes an item from the player's inventory. This uses the item ID to find the first stack of
* the item's type.
*
* @param itemId The ID of the item to remove.
* @param count The amount of items to remove.
* @return True if the item was removed, false otherwise.
*/
public synchronized boolean removeItem(int itemId, int count) {
var item = this.getItems().values().stream()
.filter(i -> i.getItemId() == itemId)
.findFirst();
var item = this.getItems().values().stream().filter(i -> i.getItemId() == itemId).findFirst();
// Check if the item is in the player's inventory.
return item
.filter(gameItem -> this.removeItem(gameItem, count))
.isPresent();
return item.filter(gameItem -> this.removeItem(gameItem, count)).isPresent();
}
public synchronized boolean removeItem(long guid, int count) {
@@ -566,14 +557,10 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
* @return True if the item was removed, false otherwise.
*/
public synchronized boolean removeItemById(int itemId, int count) {
var item = this.getItems().values().stream()
.filter(i -> i.getItemId() == itemId)
.findFirst();
var item = this.getItems().values().stream().filter(i -> i.getItemId() == itemId).findFirst();
// Check if the item is in the player's inventory.
return item
.filter(gameItem -> this.removeItem(gameItem, count))
.isPresent();
return item.filter(gameItem -> this.removeItem(gameItem, count)).isPresent();
}
public synchronized boolean removeItem(GameItem item) {

View File

@@ -5,10 +5,9 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.quest.*;
import emu.grasscutter.game.quest.enums.QuestContent;
import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import lombok.*;
/** Tracks progress the player made in the world, like obtained items, seen characters and more */
@Getter

View File

@@ -2,7 +2,6 @@ package emu.grasscutter.game.props;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
@@ -22,10 +21,10 @@ public enum ClimateType {
static {
Stream.of(values())
.forEach(
e -> {
map.put(e.getValue(), e);
stringMap.put(e.name(), e);
.forEach(
e -> {
map.put(e.getValue(), e);
stringMap.put(e.name(), e);
});
}

View File

@@ -13,20 +13,17 @@ import lombok.*;
@Builder
public final class BargainRecord {
/**
* Provides an instance of a bargain record.
* Uses information from game resources.
* Provides an instance of a bargain record. Uses information from game resources.
*
* @param bargainId The ID of the bargain.
* @return An instance of a bargain record.
*/
public static BargainRecord resolve(int bargainId) {
var bargainData = GameData.getBargainDataMap().get(bargainId);
if (bargainData == null) throw new RuntimeException("No bargain data found for " + bargainId + ".");
if (bargainData == null)
throw new RuntimeException("No bargain data found for " + bargainId + ".");
return BargainRecord.builder()
.bargainId(bargainId)
.build()
.determineBase(bargainData);
return BargainRecord.builder().bargainId(bargainId).build().determineBase(bargainData);
}
private int bargainId;
@@ -38,21 +35,17 @@ public final class BargainRecord {
private boolean finished;
private BargainResultType result;
/**
* Determines the price of the bargain.
*/
/** Determines the price of the bargain. */
public BargainRecord determineBase(BargainData data) {
// Set the expected price.
var price = data.getExpectedValue();
this.setExpectedPrice(Utils.randomRange(
price.get(0), price.get(1)));
this.setExpectedPrice(Utils.randomRange(price.get(0), price.get(1)));
// Set the lowest price.
this.setLowestPrice(price.get(0));
// Set the base mood.
var mood = data.getRandomMood();
this.setCurrentMood(Utils.randomRange(
mood.get(0), mood.get(1)));
this.setCurrentMood(Utils.randomRange(mood.get(0), mood.get(1)));
return this;
}
@@ -100,10 +93,10 @@ public final class BargainRecord {
*/
public BargainSnapshot toSnapshot() {
return BargainSnapshot.newBuilder()
.setBargainId(this.getBargainId())
.setCurMood(this.getCurrentMood())
.setBALOPACHCDB(this.getExpectedPrice())
.setIOCNPJJNHLD(this.getLowestPrice())
.build();
.setBargainId(this.getBargainId())
.setCurMood(this.getCurrentMood())
.setBALOPACHCDB(this.getExpectedPrice())
.setIOCNPJJNHLD(this.getLowestPrice())
.build();
}
}

View File

@@ -15,10 +15,9 @@ import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.IntIntImmutablePair;
import lombok.*;
import javax.script.Bindings;
import java.util.*;
import javax.script.Bindings;
import lombok.*;
@Entity
public class GameQuest {

View File

@@ -4,49 +4,45 @@ import dev.morphia.annotations.Entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.giving.GivingData.GiveMethod;
import emu.grasscutter.net.proto.GivingRecordOuterClass.GivingRecord;
import lombok.*;
import java.util.*;
import lombok.*;
@Data
@Entity
@Builder
public final class ItemGiveRecord {
/**
* Provides a builder for an item give record.
* Uses information from game resources.
* Provides a builder for an item give record. Uses information from game resources.
*
* @param givingId The ID of the giving action.
* @return A builder for an item give record.
*/
public static ItemGiveRecord resolve(int givingId) {
var givingData = GameData.getGivingDataMap().get(givingId);
if (givingData == null) throw new RuntimeException("No giving data found for " + givingId + ".");
if (givingData == null)
throw new RuntimeException("No giving data found for " + givingId + ".");
var builder = ItemGiveRecord.builder()
.givingId(givingId)
.finished(false);
var builder = ItemGiveRecord.builder().givingId(givingId).finished(false);
// Create a map.
var givenItems = new HashMap<Integer, Integer>();
if (givingData.getGivingMethod() == GiveMethod.GIVING_METHOD_EXACT) {
givingData.getExactItems().forEach(item ->
givenItems.put(item.getItemId(), 0));
givingData.getExactItems().forEach(item -> givenItems.put(item.getItemId(), 0));
} else {
givingData.getGivingGroupIds().forEach(groupId -> {
var groupData = GameData.getGivingGroupDataMap().get((int) groupId);
if (groupData == null) return;
givingData
.getGivingGroupIds()
.forEach(
groupId -> {
var groupData = GameData.getGivingGroupDataMap().get((int) groupId);
if (groupData == null) return;
// Add all items in the group.
groupData.getItemIds().forEach(itemId ->
givenItems.put(itemId, 0));
builder.groupId(groupId);
});
// Add all items in the group.
groupData.getItemIds().forEach(itemId -> givenItems.put(itemId, 0));
builder.groupId(groupId);
});
}
return builder
.givenItems(givenItems)
.build();
return builder.givenItems(givenItems).build();
}
private int givingId;
@@ -63,13 +59,13 @@ public final class ItemGiveRecord {
*/
public GivingRecord toProto() {
return GivingRecord.newBuilder()
.setGivingId(this.getGivingId())
.setConfigId(this.getConfigId())
.setGroupId(this.getGroupId())
.setLastGroupId(this.getLastGroupId())
.setIsFinished(this.isFinished())
.setIsGadgetGiving(false)
.putAllMaterialCntMap(this.getGivenItems())
.build();
.setGivingId(this.getGivingId())
.setConfigId(this.getConfigId())
.setGroupId(this.getGroupId())
.setLastGroupId(this.getLastGroupId())
.setIsFinished(this.isFinished())
.setIsGadgetGiving(false)
.putAllMaterialCntMap(this.getGivenItems())
.build();
}
}

View File

@@ -1,5 +1,8 @@
package emu.grasscutter.game.quest;
import static emu.grasscutter.GameConstants.DEBUG;
import static emu.grasscutter.config.Configuration.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.*;
@@ -12,16 +15,12 @@ import emu.grasscutter.net.proto.GivingRecordOuterClass.GivingRecord;
import emu.grasscutter.server.packet.send.*;
import io.netty.util.concurrent.FastThreadLocalThread;
import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static emu.grasscutter.GameConstants.DEBUG;
import static emu.grasscutter.config.Configuration.*;
import javax.annotation.Nonnull;
import lombok.*;
public final class QuestManager extends BasePlayerManager {
@Getter private final Player player;
@@ -32,10 +31,15 @@ public final class QuestManager extends BasePlayerManager {
private long lastHourCheck = 0;
private long lastDayCheck = 0;
public static final ExecutorService eventExecutor
= new ThreadPoolExecutor(4, 4,
60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000),
FastThreadLocalThread::new, new ThreadPoolExecutor.AbortPolicy());
public static final ExecutorService eventExecutor =
new ThreadPoolExecutor(
4,
4,
60,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(1000),
FastThreadLocalThread::new,
new ThreadPoolExecutor.AbortPolicy());
public static long getQuestKey(int mainQuestId) {
QuestEncryptionKey questEncryptionKey = GameData.getMainQuestEncryptionMap().get(mainQuestId);
@@ -50,37 +54,37 @@ public final class QuestManager extends BasePlayerManager {
this.loggedQuests = new ArrayList<>();
if (DEBUG) {
this.loggedQuests.addAll(List.of(
31101, // Quest which holds talks 30902 and 30904.
35001, // Quest which unlocks world border & starts act 2.
30901, // Quest which is completed upon finishing all 3 initial dungeons.
30903, // Quest which is finished when re-entering scene 3. (home world)
30904, // Quest which unlocks the Adventurers' Guild
this.loggedQuests.addAll(
List.of(
31101, // Quest which holds talks 30902 and 30904.
35001, // Quest which unlocks world border & starts act 2.
30901, // Quest which is completed upon finishing all 3 initial dungeons.
30903, // Quest which is finished when re-entering scene 3. (home world)
30904, // Quest which unlocks the Adventurers' Guild
46904, // Quest which is required to be started, but not completed for 31101's talks
// to begin.
// This quest is related to obtaining your first Anemoculus.
46904, // Quest which is required to be started, but not completed for 31101's talks to begin.
// This quest is related to obtaining your first Anemoculus.
35104, // Quest which is required to be finished for 46904 to begin.
// This quest requires 31101 not be finished.
// This quest should be accepted when the account is created.
35104, // Quest which is required to be finished for 46904 to begin.
// This quest requires 31101 not be finished.
// This quest should be accepted when the account is created.
// These quests currently have bugged triggers.
30700, // Quest which is responsible for unlocking Crash Course.
30800, // Quest which is responsible for unlocking Sparks Amongst the Pages.
47001, 47002, 47003, 47004,
2010103, 2010144, // Prologue Act 2: Chasing Shadows,
2012 // This is the main quest ID for Chapter 2 Act 1.
// Used for debugging giving items.
));
// These quests currently have bugged triggers.
30700, // Quest which is responsible for unlocking Crash Course.
30800, // Quest which is responsible for unlocking Sparks Amongst the Pages.
47001,
47002,
47003,
47004,
2010103,
2010144, // Prologue Act 2: Chasing Shadows,
2012 // This is the main quest ID for Chapter 2 Act 1.
// Used for debugging giving items.
));
}
}
/**
* Checks if questing can be enabled.
*/
/** Checks if questing can be enabled. */
public boolean isQuestingEnabled() {
// Check if scripts are enabled.
if (!SERVER.game.enableScriptInBigWorld) {
@@ -97,8 +101,7 @@ public final class QuestManager extends BasePlayerManager {
* @param givingId The giving action ID.
* @throws IllegalStateException If the giving action is already active.
*/
public void addGiveItemAction(int givingId)
throws IllegalStateException {
public void addGiveItemAction(int givingId) throws IllegalStateException {
var progress = this.player.getPlayerProgress();
var givings = progress.getItemGivings();
@@ -163,10 +166,9 @@ public final class QuestManager extends BasePlayerManager {
* @return Serialized giving records to be used in a packet.
*/
public Collection<GivingRecord> getGivingRecords() {
return this.getPlayer().getPlayerProgress()
.getItemGivings().values().stream()
.map(ItemGiveRecord::toProto)
.toList();
return this.getPlayer().getPlayerProgress().getItemGivings().values().stream()
.map(ItemGiveRecord::toProto)
.toList();
}
/**
@@ -199,7 +201,7 @@ public final class QuestManager extends BasePlayerManager {
* @param bargainId The bargain ID.
*/
public void stopBargain(int bargainId) {
var progress = this.player.getPlayerProgress();
var progress = this.player.getPlayerProgress();
var bargains = progress.getBargains();
// Check if the bargain is already present.
@@ -216,14 +218,10 @@ public final class QuestManager extends BasePlayerManager {
this.player.sendPacket(new PacketBargainTerminateNotify(bargainId));
}
/**
* Sends the giving records to the player.
*/
/** Sends the giving records to the player. */
public void sendGivingRecords() {
// Send the record to the player.
this.player.sendPacket(
new PacketGivingRecordNotify(
this.getGivingRecords()));
this.player.sendPacket(new PacketGivingRecordNotify(this.getGivingRecords()));
}
public void onPlayerBorn() {
@@ -244,9 +242,9 @@ public final class QuestManager extends BasePlayerManager {
getPlayer().getPosition().set(rewindPos.get(0));
getPlayer().getRotation().set(rewindPos.get(1));
}
if(activeQuest!=null && rewindPos!=null){
//activeSubs.add(activeQuest);
//player.sendPacket(new PacketQuestProgressUpdateNotify(activeQuest));
if (activeQuest != null && rewindPos != null) {
// activeSubs.add(activeQuest);
// player.sendPacket(new PacketQuestProgressUpdateNotify(activeQuest));
}
quest.checkProgress();
}
@@ -270,29 +268,32 @@ public final class QuestManager extends BasePlayerManager {
boolean checkDays = currentDays != lastDayCheck;
boolean checkHours = currentHours != lastHourCheck;
if(!checkDays && !checkHours){
if (!checkDays && !checkHours) {
return;
}
this.lastDayCheck = currentDays;
this.lastHourCheck = currentHours;
player.getActiveQuestTimers().forEach(mainQuestId -> {
if (checkHours) {
this.queueEvent(QuestCond.QUEST_COND_TIME_VAR_GT_EQ, mainQuestId);
this.queueEvent(QuestContent.QUEST_CONTENT_TIME_VAR_GT_EQ, mainQuestId);
}
if (checkDays) {
this.queueEvent(QuestCond.QUEST_COND_TIME_VAR_PASS_DAY, mainQuestId);
this.queueEvent(QuestContent.QUEST_CONTENT_TIME_VAR_PASS_DAY, mainQuestId);
}
});
player
.getActiveQuestTimers()
.forEach(
mainQuestId -> {
if (checkHours) {
this.queueEvent(QuestCond.QUEST_COND_TIME_VAR_GT_EQ, mainQuestId);
this.queueEvent(QuestContent.QUEST_CONTENT_TIME_VAR_GT_EQ, mainQuestId);
}
if (checkDays) {
this.queueEvent(QuestCond.QUEST_COND_TIME_VAR_PASS_DAY, mainQuestId);
this.queueEvent(QuestContent.QUEST_CONTENT_TIME_VAR_PASS_DAY, mainQuestId);
}
});
}
private List<GameMainQuest> addMultMainQuests(Set<Integer> mainQuestIds) {
List<GameMainQuest> newQuests = new ArrayList<>();
for (Integer id : mainQuestIds) {
getMainQuests().put(id.intValue(),new GameMainQuest(this.player, id));
getMainQuests().put(id.intValue(), new GameMainQuest(this.player, id));
getMainQuestById(id).save();
newQuests.add(getMainQuestById(id));
}
@@ -319,27 +320,29 @@ public final class QuestManager extends BasePlayerManager {
* Looking through mainQuests 72201-72208 and 72174, we can infer that a questGlobalVar's default value is 0
*/
public Integer getQuestGlobalVarValue(Integer variable) {
return getPlayer().getQuestGlobalVariables()
.computeIfAbsent(variable, k -> this.getGlobalVarDefault(variable));
return getPlayer()
.getQuestGlobalVariables()
.computeIfAbsent(variable, k -> this.getGlobalVarDefault(variable));
}
public void setQuestGlobalVarValue(int variable, int setVal) {
var prevVal = this.getPlayer().getQuestGlobalVariables().put(variable, setVal);
if (prevVal == null){
if (prevVal == null) {
prevVal = this.getGlobalVarDefault(variable);
}
var newVal = this.getQuestGlobalVarValue(variable);
Grasscutter.getLogger().debug("Changed questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
Grasscutter.getLogger()
.debug("Changed questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
this.triggerQuestGlobalVarAction(variable, setVal);
}
public void incQuestGlobalVarValue(int variable, int inc) {
var prevVal = getQuestGlobalVarValue(variable);
var newVal = getPlayer().getQuestGlobalVariables()
.compute(variable, (k, v) -> prevVal + inc);
var newVal = getPlayer().getQuestGlobalVariables().compute(variable, (k, v) -> prevVal + inc);
Grasscutter.getLogger().debug("Incremented questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
Grasscutter.getLogger()
.debug("Incremented questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
this.triggerQuestGlobalVarAction(variable, newVal);
}
@@ -349,7 +352,8 @@ public final class QuestManager extends BasePlayerManager {
this.getPlayer().getQuestGlobalVariables().put(variable, prevVal - dec);
var newVal = getQuestGlobalVarValue(variable);
Grasscutter.getLogger().debug("Decremented questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
Grasscutter.getLogger()
.debug("Decremented questGlobalVar {} value from {} to {}", variable, prevVal, newVal);
this.triggerQuestGlobalVarAction(variable, newVal);
}
@@ -422,7 +426,7 @@ public final class QuestManager extends BasePlayerManager {
return null;
}
return this.addQuest(questConfig);
return this.addQuest(questConfig);
}
public GameQuest addQuest(@Nonnull QuestData questConfig) {
@@ -452,10 +456,10 @@ public final class QuestManager extends BasePlayerManager {
}
Arrays.stream(mainQuestData.getSubQuests())
.min(Comparator.comparingInt(MainQuestData.SubQuestData::getOrder))
.map(MainQuestData.SubQuestData::getSubId)
.ifPresent(this::addQuest);
//TODO find a better way then hardcoding to detect needed required quests
.min(Comparator.comparingInt(MainQuestData.SubQuestData::getOrder))
.map(MainQuestData.SubQuestData::getSubId)
.ifPresent(this::addQuest);
// TODO find a better way then hardcoding to detect needed required quests
// if (mainQuestId == 355){
// startMainQuest(361);
// startMainQuest(418);
@@ -463,9 +467,11 @@ public final class QuestManager extends BasePlayerManager {
// startMainQuest(20509);
// }
}
public void queueEvent(QuestCond condType, int... params) {
queueEvent(condType, "", params);
}
public void queueEvent(QuestContent condType, int... params) {
queueEvent(condType, "", params);
}
@@ -478,57 +484,69 @@ public final class QuestManager extends BasePlayerManager {
eventExecutor.submit(() -> triggerEvent(condType, paramStr, params));
}
//QUEST_EXEC are handled directly by each subQuest
// QUEST_EXEC are handled directly by each subQuest
public void triggerEvent(QuestCond condType, String paramStr, int... params) {
Grasscutter.getLogger().trace("Trigger Event {}, {}, {}", condType, paramStr, params);
var potentialQuests = GameData.getQuestDataByConditions(condType, params[0], paramStr);
if(potentialQuests == null){
if (potentialQuests == null) {
return;
}
var questSystem = getPlayer().getServer().getQuestSystem();
var owner = getPlayer();
potentialQuests.forEach(questData -> {
if(this.wasSubQuestStarted(questData)){
return;
}
val acceptCond = questData.getAcceptCond();
int[] accept = new int[acceptCond.size()];
for (int i = 0; i < acceptCond.size(); i++) {
val condition = acceptCond.get(i);
boolean result = questSystem.triggerCondition(owner, questData, condition, paramStr, params);
accept[i] = result ? 1 : 0;
}
potentialQuests.forEach(
questData -> {
if (this.wasSubQuestStarted(questData)) {
return;
}
val acceptCond = questData.getAcceptCond();
int[] accept = new int[acceptCond.size()];
for (int i = 0; i < acceptCond.size(); i++) {
val condition = acceptCond.get(i);
boolean result =
questSystem.triggerCondition(owner, questData, condition, paramStr, params);
accept[i] = result ? 1 : 0;
}
boolean shouldAccept = LogicType.calculate(questData.getAcceptCondComb(), accept);
if (this.loggedQuests.contains(questData.getId())) {
Grasscutter.getLogger().debug(">>> Quest {} will be {} as a result of event trigger {} ({}, {}).",
questData.getId(), shouldAccept ? "accepted" : "not accepted", condType.name(), paramStr,
Arrays.stream(params).mapToObj(String::valueOf).collect(Collectors.joining(", ")));
for (var i = 0; i < accept.length; i++) {
var condition = acceptCond.get(i);
Grasscutter.getLogger().debug("^ Condition {} has params {} with result {}.",
condition.getType().name(),
Arrays.stream(condition.getParam())
.filter(value -> value > 0)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ")),
accept[i] == 1 ? "success" : "failure");
}
}
boolean shouldAccept = LogicType.calculate(questData.getAcceptCondComb(), accept);
if (this.loggedQuests.contains(questData.getId())) {
Grasscutter.getLogger()
.debug(
">>> Quest {} will be {} as a result of event trigger {} ({}, {}).",
questData.getId(),
shouldAccept ? "accepted" : "not accepted",
condType.name(),
paramStr,
Arrays.stream(params)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ")));
for (var i = 0; i < accept.length; i++) {
var condition = acceptCond.get(i);
Grasscutter.getLogger()
.debug(
"^ Condition {} has params {} with result {}.",
condition.getType().name(),
Arrays.stream(condition.getParam())
.filter(value -> value > 0)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ")),
accept[i] == 1 ? "success" : "failure");
}
}
if (shouldAccept) {
GameQuest quest = owner.getQuestManager().addQuest(questData);
Grasscutter.getLogger().debug("Added quest {} result {}", questData.getSubId(), quest != null);
}
});
if (shouldAccept) {
GameQuest quest = owner.getQuestManager().addQuest(questData);
Grasscutter.getLogger()
.debug("Added quest {} result {}", questData.getSubId(), quest != null);
}
});
}
public boolean wasSubQuestStarted(QuestData questData) {
var quest = getQuestById(questData.getId());
if(quest == null) return false;
if (quest == null) return false;
return quest.state != QuestState.QUEST_STATE_UNSTARTED;
}
@@ -536,9 +554,10 @@ public final class QuestManager extends BasePlayerManager {
public void triggerEvent(QuestContent condType, String paramStr, int... params) {
Grasscutter.getLogger().trace("Trigger Event {}, {}, {}", condType, paramStr, params);
List<GameMainQuest> checkMainQuests = this.getMainQuests().values().stream()
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
.toList();
List<GameMainQuest> checkMainQuests =
this.getMainQuests().values().stream()
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
.toList();
for (GameMainQuest mainQuest : checkMainQuests) {
mainQuest.tryFailSubQuests(condType, paramStr, params);
mainQuest.tryFinishSubQuests(condType, paramStr, params);
@@ -546,46 +565,58 @@ public final class QuestManager extends BasePlayerManager {
}
/**
* TODO maybe trigger them delayed to allow basic communication finish first
* TODO move content checks to use static informations where possible to allow direct already fulfilled checking
* TODO maybe trigger them delayed to allow basic communication finish first TODO move content
* checks to use static informations where possible to allow direct already fulfilled checking
*
* @param quest The ID of the quest.
*/
public void checkQuestAlreadyFulfilled(GameQuest quest){
Grasscutter.getThreadPool().submit(() -> {
for (var condition : quest.getQuestData().getFinishCond()){
switch (condition.getType()) {
case QUEST_CONTENT_OBTAIN_ITEM, QUEST_CONTENT_ITEM_LESS_THAN -> {
//check if we already own enough of the item
var item = getPlayer().getInventory().getItemByGuid(condition.getParam()[0]);
queueEvent(condition.getType(), condition.getParam()[0], item != null ? item.getCount() : 0);
}
case QUEST_CONTENT_UNLOCK_TRANS_POINT -> {
var scenePoints = getPlayer().getUnlockedScenePoints().get(condition.getParam()[0]);
if (scenePoints != null && scenePoints.contains(condition.getParam()[1])) {
queueEvent(condition.getType(), condition.getParam()[0], condition.getParam()[1]);
}
}
case QUEST_CONTENT_UNLOCK_AREA -> {
var sceneAreas = getPlayer().getUnlockedSceneAreas().get(condition.getParam()[0]);
if (sceneAreas != null && sceneAreas.contains(condition.getParam()[1])) {
queueEvent(condition.getType(), condition.getParam()[0], condition.getParam()[1]);
}
}
case QUEST_CONTENT_PLAYER_LEVEL_UP -> queueEvent(condition.getType(), player.getLevel());
}
}
});
public void checkQuestAlreadyFulfilled(GameQuest quest) {
Grasscutter.getThreadPool()
.submit(
() -> {
for (var condition : quest.getQuestData().getFinishCond()) {
switch (condition.getType()) {
case QUEST_CONTENT_OBTAIN_ITEM, QUEST_CONTENT_ITEM_LESS_THAN -> {
// check if we already own enough of the item
var item = getPlayer().getInventory().getItemByGuid(condition.getParam()[0]);
queueEvent(
condition.getType(),
condition.getParam()[0],
item != null ? item.getCount() : 0);
}
case QUEST_CONTENT_UNLOCK_TRANS_POINT -> {
var scenePoints =
getPlayer().getUnlockedScenePoints().get(condition.getParam()[0]);
if (scenePoints != null && scenePoints.contains(condition.getParam()[1])) {
queueEvent(
condition.getType(), condition.getParam()[0], condition.getParam()[1]);
}
}
case QUEST_CONTENT_UNLOCK_AREA -> {
var sceneAreas =
getPlayer().getUnlockedSceneAreas().get(condition.getParam()[0]);
if (sceneAreas != null && sceneAreas.contains(condition.getParam()[1])) {
queueEvent(
condition.getType(), condition.getParam()[0], condition.getParam()[1]);
}
}
case QUEST_CONTENT_PLAYER_LEVEL_UP -> queueEvent(
condition.getType(), player.getLevel());
}
}
});
}
public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) {
return getMainQuests().values().stream()
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
.map(GameMainQuest::getQuestGroupSuites)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.filter(i -> i.getScene() == sceneId)
.toList();
.filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
.map(GameMainQuest::getQuestGroupSuites)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.filter(i -> i.getScene() == sceneId)
.toList();
}
public void loadFromDatabase() {
List<GameMainQuest> quests = DatabaseHelper.getAllQuests(getPlayer());
@@ -626,24 +657,30 @@ public final class QuestManager extends BasePlayerManager {
var pointId = point.getPointData().getId();
// Get the active quests.
return this.getActiveMainQuests().stream()
// Get the sub-quests of the main quest.
.map(GameMainQuest::getChildQuests)
// Get the values of the sub-quests map.
.map(Map::values)
.map(quests -> quests.stream()
// Get the dungeon IDs of each quest.
.map(GameQuest::getDungeonIds)
.map(ids -> ids.stream()
// Find entry points which match this dungeon.
.filter(id -> id.rightInt() == pointId)
.toList())
.map(ids -> ids.stream()
// Of the remaining dungeons, find the ID of the quest dungeon.
.map(IntIntImmutablePair::leftInt)
.toList())
// Get the sub-quests of the main quest.
.map(GameMainQuest::getChildQuests)
// Get the values of the sub-quests map.
.map(Map::values)
.map(
quests ->
quests.stream()
// Get the dungeon IDs of each quest.
.map(GameQuest::getDungeonIds)
.map(
ids ->
ids.stream()
// Find entry points which match this dungeon.
.filter(id -> id.rightInt() == pointId)
.toList())
.map(
ids ->
ids.stream()
// Of the remaining dungeons, find the ID of the quest dungeon.
.map(IntIntImmutablePair::leftInt)
.toList())
.flatMap(Collection::stream)
.toList())
.flatMap(Collection::stream)
.toList())
.flatMap(Collection::stream)
.toList();
.toList();
}
}

View File

@@ -3,13 +3,12 @@ package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.game.quest.*;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType;
@QuestValueContent(QuestContent.QUEST_CONTENT_BARGAIN_FAIL)
public final class ContentBargainFail extends BaseContent {
@Override
public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] &&
condition.getParam()[1] == params[1];
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1];
}
}

View File

@@ -3,13 +3,12 @@ package emu.grasscutter.game.quest.content;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.game.quest.*;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.net.proto.BargainResultTypeOuterClass.BargainResultType;
@QuestValueContent(QuestContent.QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN)
public final class ContentBargainLessThan extends BaseContent {
@Override
public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] &&
condition.getParam()[1] == params[1];
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1];
}
}

View File

@@ -7,8 +7,8 @@ import emu.grasscutter.game.quest.enums.QuestContent;
@QuestValueContent(QuestContent.QUEST_CONTENT_BARGAIN_SUCC)
public final class ContentBargainSuccess extends BaseContent {
@Override
public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] &&
condition.getParam()[1] == params[1];
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1];
}
}

View File

@@ -7,8 +7,8 @@ import emu.grasscutter.game.quest.enums.QuestContent;
@QuestValueContent(QuestContent.QUEST_CONTENT_FINISH_ITEM_GIVING)
public final class ContentFinishGivingItem extends BaseContent {
@Override
public boolean execute(GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] &&
condition.getParam()[1] == params[1];
public boolean execute(
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
return condition.getParam()[0] == params[0] && condition.getParam()[1] == params[1];
}
}

View File

@@ -17,12 +17,12 @@ public final class ExecActiveItemGiving extends QuestExecHandler {
try {
questManager.addGiveItemAction(givingId);
Grasscutter.getLogger().debug("Quest {} added give action {}.",
quest.getSubQuestId(), givingId);
Grasscutter.getLogger()
.debug("Quest {} added give action {}.", quest.getSubQuestId(), givingId);
return true;
} catch (IllegalStateException ignored) {
Grasscutter.getLogger().warn("Quest {} attempted to add give action {} twice.",
quest.getSubQuestId(), givingId);
Grasscutter.getLogger()
.warn("Quest {} attempted to add give action {} twice.", quest.getSubQuestId(), givingId);
return false;
}
}

View File

@@ -17,8 +17,11 @@ public final class ExecDeactivateItemGiving extends QuestExecHandler {
questManager.removeGivingItemAction(givingId);
return true;
} catch (IllegalStateException ignored) {
Grasscutter.getLogger().warn("Quest {} attempted to remove give action {} twice.",
quest.getSubQuestId(), givingId);
Grasscutter.getLogger()
.warn(
"Quest {} attempted to remove give action {} twice.",
quest.getSubQuestId(),
givingId);
return false;
}
}

View File

@@ -15,8 +15,7 @@ public final class ExecStartBargain extends QuestExecHandler {
try {
// Start the bargain.
quest.getOwner().getQuestManager()
.startBargain(bargainId);
quest.getOwner().getQuestManager().startBargain(bargainId);
Grasscutter.getLogger().debug("Bargain {} started.", bargainId);
return true;
} catch (RuntimeException ignored) {

View File

@@ -15,8 +15,7 @@ public final class ExecStopBargain extends QuestExecHandler {
try {
// Start the bargain.
quest.getOwner().getQuestManager()
.stopBargain(bargainId);
quest.getOwner().getQuestManager().stopBargain(bargainId);
Grasscutter.getLogger().debug("Bargain {} stopped.", bargainId);
return true;
} catch (RuntimeException ignored) {

View File

@@ -23,8 +23,8 @@ import emu.grasscutter.game.props.*;
import emu.grasscutter.game.quest.QuestGroupSuite;
import emu.grasscutter.game.world.data.TeleportProperties;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.scripts.*;
import emu.grasscutter.scripts.constants.EventType;
@@ -35,12 +35,11 @@ import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.scheduler.ServerTaskScheduler;
import emu.grasscutter.utils.objects.KahnsSort;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.*;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import lombok.*;
public final class Scene {
@Getter private final World world;

View File

@@ -6,7 +6,7 @@ public final class PacketOpcodes {
// Opcodes
public static final int ACCKLIOPBHN = 205;
public static final int ACDCLDJFDFK = 26672;
public static final int PlayerEnterMapLayerNotify = 26672;
public static final int ACOPFPFIJHN = 6465;
public static final int AEHOGBMFIDK = 21196;
public static final int AGBOEIBCIHC = 1992;
@@ -185,7 +185,7 @@ public final class PacketOpcodes {
public static final int BKNAMDDEIKH = 1557;
public static final int BKOHLDCHKBL = 20475;
public static final int BLDHOHDIBHB = 27514;
public static final int BMODMHEPOFF = 2225;
public static final int PlayerEnterChildMapLayerNotify = 2225;
public static final int BMODNHIFDPI = 7195;
public static final int BMPHGPCILIK = 22933;
public static final int BOFOFKKOBNO = 273;

View File

@@ -4,9 +4,8 @@ import emu.grasscutter.*;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.scripts.*;
import org.luaj.vm2.*;
import javax.script.*;
import org.luaj.vm2.*;
public class EntityController {
private transient CompiledScript entityController;
@@ -38,8 +37,11 @@ public class EntityController {
public int onClientExecuteRequest(GameEntity entity, int param1, int param2, int param3) {
if (DebugConstants.LOG_LUA_SCRIPTS) {
Grasscutter.getLogger()
.debug(
"Request on {}, {}: {}", entity.getGroupId(), param1, entity.getPosition().toString());
.debug(
"Request on {}, {}: {}",
entity.getGroupId(),
param1,
entity.getPosition().toString());
}
LuaValue value =
callControllerScriptFunc(

View File

@@ -1,16 +1,15 @@
package emu.grasscutter.server.game;
import static emu.grasscutter.config.Configuration.GAME_INFO;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerDebugMode;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.server.event.game.ReceivePacketEvent;
import emu.grasscutter.server.game.GameSession.SessionState;
import it.unimi.dsi.fastutil.ints.*;
import org.reflections.Reflections;
import java.util.Set;
import static emu.grasscutter.config.Configuration.GAME_INFO;
import org.reflections.Reflections;
@SuppressWarnings("unchecked")
public class GameServerPacketHandler {

View File

@@ -1,5 +1,8 @@
package emu.grasscutter.server.game;
import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerDebugMode;
import emu.grasscutter.game.Account;
@@ -8,14 +11,10 @@ import emu.grasscutter.net.packet.*;
import emu.grasscutter.server.event.game.SendPacketEvent;
import emu.grasscutter.utils.*;
import io.netty.buffer.*;
import lombok.*;
import java.io.File;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.utils.lang.Language.translate;
import lombok.*;
public class GameSession implements GameSessionManager.KcpChannel {
private final GameServer server;

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.server.http.dispatch;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.auth.AuthenticationSystem;
import emu.grasscutter.auth.OAuthAuthenticator.ClientType;
@@ -10,8 +12,6 @@ import emu.grasscutter.utils.*;
import io.javalin.Javalin;
import io.javalin.http.Context;
import static emu.grasscutter.utils.lang.Language.translate;
/** Handles requests related to authentication. */
public final class AuthenticationHandler implements Router {
/**

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.server.http.dispatch;
import static emu.grasscutter.config.Configuration.*;
import com.google.gson.*;
import com.google.protobuf.ByteString;
import emu.grasscutter.*;
@@ -16,14 +18,11 @@ import emu.grasscutter.server.http.objects.QueryCurRegionRspJson;
import emu.grasscutter.utils.*;
import io.javalin.Javalin;
import io.javalin.http.Context;
import org.slf4j.Logger;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import static emu.grasscutter.config.Configuration.*;
import org.slf4j.Logger;
/** Handles requests related to region queries. */
public final class RegionHandler implements Router {
@@ -114,8 +113,7 @@ public final class RegionHandler implements Router {
customConfig.addProperty("sdkenv", "2");
customConfig.addProperty("checkdevice", "false");
customConfig.addProperty("loadPatch", "false");
customConfig.addProperty("showexception",
String.valueOf(GameConstants.DEBUG));
customConfig.addProperty("showexception", String.valueOf(GameConstants.DEBUG));
customConfig.addProperty("regionConfig", "pm|fk|add");
customConfig.addProperty("downloadMode", "0");
customConfig.add("codeSwitch", codeSwitch);
@@ -254,11 +252,10 @@ public final class RegionHandler implements Router {
String key_id = ctx.queryParam("key_id");
if (
versionMajor != GameConstants.VERSION_PARTS[0] ||
versionMinor != GameConstants.VERSION_PARTS[1]
// The 'fix' or 'patch' version is not checked because it is only used
// when miHoYo is desperate and fucks up big time.
if (versionMajor != GameConstants.VERSION_PARTS[0]
|| versionMinor != GameConstants.VERSION_PARTS[1]
// The 'fix' or 'patch' version is not checked because it is only used
// when miHoYo is desperate and fucks up big time.
) { // Reject clients when there is a version mismatch
boolean updateClient = GameConstants.VERSION.compareTo(clientVersion) > 0;

View File

@@ -4,9 +4,9 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.scene.SceneData;
import emu.grasscutter.data.excels.avatar.AvatarData;
import emu.grasscutter.data.excels.monster.MonsterData;
import emu.grasscutter.data.excels.scene.SceneData;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.lang.Language;
import io.javalin.http.ContentType;

View File

@@ -9,8 +9,7 @@ import emu.grasscutter.server.packet.send.PacketBargainOfferPriceRsp;
@Opcodes(PacketOpcodes.BargainOfferPriceReq)
public final class HandlerBargainOfferPriceReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload)
throws Exception {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var packet = BargainOfferPriceReq.parseFrom(payload);
var player = session.getPlayer();
@@ -27,14 +26,11 @@ public final class HandlerBargainOfferPriceReq extends PacketHandler {
var questManager = player.getQuestManager();
switch (result) {
case BARGAIN_COMPLETE_SUCC -> questManager.queueEvent(
QuestContent.QUEST_CONTENT_BARGAIN_SUCC,
bargainId, 0);
QuestContent.QUEST_CONTENT_BARGAIN_SUCC, bargainId, 0);
case BARGAIN_SINGLE_FAIL -> questManager.queueEvent(
QuestContent.QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN,
bargainId, 0);
QuestContent.QUEST_CONTENT_ITEM_LESS_THAN_BARGAIN, bargainId, 0);
case BARGAIN_COMPLETE_FAIL -> questManager.queueEvent(
QuestContent.QUEST_CONTENT_BARGAIN_FAIL,
bargainId, 0);
QuestContent.QUEST_CONTENT_BARGAIN_FAIL, bargainId, 0);
}
// Return the resulting packet.

View File

@@ -8,10 +8,8 @@ import emu.grasscutter.server.packet.send.PacketGetAllActivatedBargainDataRsp;
public final class HandlerGetAllActivatedBargainDataReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) {
session.send(new PacketGetAllActivatedBargainDataRsp(
session.getPlayer()
.getPlayerProgress()
.getBargains()
.values()));
session.send(
new PacketGetAllActivatedBargainDataRsp(
session.getPlayer().getPlayerProgress().getBargains().values()));
}
}

View File

@@ -9,18 +9,13 @@ import emu.grasscutter.server.packet.send.PacketGetBargainDataRsp;
@Opcodes(PacketOpcodes.GetBargainDataReq)
public final class HandlerGetBargainDataReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload)
throws Exception {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var packet = GetBargainDataReq.parseFrom(payload);
var bargainId = packet.getBargainId();
var bargain = session.getPlayer()
.getPlayerProgress()
.getBargains()
.get(bargainId);
var bargain = session.getPlayer().getPlayerProgress().getBargains().get(bargainId);
if (bargain == null) {
session.send(new PacketGetBargainDataRsp(
Retcode.RET_BARGAIN_NOT_ACTIVATED));
session.send(new PacketGetBargainDataRsp(Retcode.RET_BARGAIN_NOT_ACTIVATED));
return;
}

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.server.packet.recv;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
@@ -11,12 +13,9 @@ import emu.grasscutter.server.game.GameSession.SessionState;
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
import emu.grasscutter.utils.*;
import emu.grasscutter.utils.helpers.ByteHelper;
import javax.crypto.Cipher;
import java.nio.ByteBuffer;
import java.security.Signature;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import javax.crypto.Cipher;
@Opcodes(PacketOpcodes.GetPlayerTokenReq)
public class HandlerGetPlayerTokenReq extends PacketHandler {

View File

@@ -8,7 +8,6 @@ import emu.grasscutter.net.proto.ItemGivingReqOuterClass.ItemGivingReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketItemGivingRsp;
import emu.grasscutter.server.packet.send.PacketItemGivingRsp.Mode;
import java.util.*;
@Opcodes(PacketOpcodes.ItemGivingReq)
@@ -31,7 +30,8 @@ public final class HandlerItemGivingReq extends PacketHandler {
// Check the items against the resources.
var data = GameData.getGivingDataMap().get(giveId);
if (data == null) throw new IllegalArgumentException("No giving data found for " + giveId + ".");
if (data == null)
throw new IllegalArgumentException("No giving data found for " + giveId + ".");
switch (data.getGivingMethod()) {
case GIVING_METHOD_EXACT -> {
@@ -60,26 +60,28 @@ public final class HandlerItemGivingReq extends PacketHandler {
// Resolve potential item IDs.
var groupData = GameData.getGivingGroupDataMap();
data.getGivingGroupIds().stream()
.map(groupId -> groupData.get((int) groupId))
.filter(Objects::nonNull)
.forEach(group -> {
var itemIds = group.getItemIds();
.map(groupId -> groupData.get((int) groupId))
.filter(Objects::nonNull)
.forEach(
group -> {
var itemIds = group.getItemIds();
// Match item stacks to the group items.
items.forEach(param -> {
// Get the item instance.
var itemInstance = inventory.getFirstItem(param.getItemId());
if (itemInstance == null) return;
// Match item stacks to the group items.
items.forEach(
param -> {
// Get the item instance.
var itemInstance = inventory.getFirstItem(param.getItemId());
if (itemInstance == null) return;
// Get the item ID.
var itemId = itemInstance.getItemId();
if (!itemIds.contains(itemId)) return;
// Get the item ID.
var itemId = itemInstance.getItemId();
if (!itemIds.contains(itemId)) return;
// Add the item to the given items.
givenItems.put(itemId, param.getCount());
matchedGroups.add(group.getId());
});
});
// Add the item to the given items.
givenItems.put(itemId, param.getCount());
matchedGroups.add(group.getId());
});
});
// Check if the player has any items.
if (givenItems.isEmpty() && matchedGroups.isEmpty()) {

View File

@@ -1,18 +1,15 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BMODMHEPOFFOuterClass;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.BMODMHEPOFF)
public class HandlerPlayerEnterChildMapLayerNotify extends PacketHandler {
@Opcodes(PacketOpcodes.PlayerEnterChildMapLayerNotify)
public final class HandlerPlayerEnterChildMapLayerNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var fromClient = BMODMHEPOFFOuterClass.BMODMHEPOFF.parseFrom(payload);
// var packet = PlayerEnterChildMapLayerNotify.parseFrom(payload);
// probably
Grasscutter.getLogger().info("player entered child map layer: id {}", fromClient.getHJMMAOMEHOL());
// Grasscutter.getLogger()
// .info("player entered child map layer: id {}", packet.getLayerId());
}
}

View File

@@ -1,18 +1,14 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ACDCLDJFDFKOuterClass;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.server.game.GameSession;
@Opcodes(PacketOpcodes.ACDCLDJFDFK)
public class HandlerPlayerEnterMapLayerNotify extends PacketHandler {
@Opcodes(PacketOpcodes.PlayerEnterMapLayerNotify)
public final class HandlerPlayerEnterMapLayerNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
var fromClient = ACDCLDJFDFKOuterClass.ACDCLDJFDFK.parseFrom(payload);
Grasscutter.getLogger().info("[DEBUG] Player found new map layer: id {}", fromClient.getPPLHKCKDHEC());
// var packet = ACDCLDJFDFKOuterClass.ACDCLDJFDFK.parseFrom(payload);
// Grasscutter.getLogger()
// .info("[DEBUG] Player found new map layer: id {}", packet.getLayerId());
}
}

View File

@@ -10,12 +10,14 @@ public final class PacketBargainOfferPriceRsp extends BasePacket {
public PacketBargainOfferPriceRsp(BargainResultType result, BargainRecord record) {
super(PacketOpcodes.BargainOfferPriceRsp);
this.setData(BargainOfferPriceRsp.newBuilder()
.setRetcode(record.isFinished() ?
Retcode.RET_BARGAIN_FINISHED.getNumber() :
Retcode.RET_BARGAIN_NOT_ACTIVATED.getNumber())
.setCurMood(record.getCurrentMood())
.setBargainResult(result)
.setResultParam(0));
this.setData(
BargainOfferPriceRsp.newBuilder()
.setRetcode(
record.isFinished()
? Retcode.RET_BARGAIN_FINISHED.getNumber()
: Retcode.RET_BARGAIN_NOT_ACTIVATED.getNumber())
.setCurMood(record.getCurrentMood())
.setBargainResult(result)
.setResultParam(0));
}
}

View File

@@ -8,8 +8,9 @@ public final class PacketBargainStartNotify extends BasePacket {
public PacketBargainStartNotify(BargainRecord record) {
super(PacketOpcodes.BargainStartNotify);
this.setData(BargainStartNotify.newBuilder()
.setBargainId(record.getBargainId())
.setSnapshot(record.toSnapshot()));
this.setData(
BargainStartNotify.newBuilder()
.setBargainId(record.getBargainId())
.setSnapshot(record.toSnapshot()));
}
}

View File

@@ -7,7 +7,6 @@ public final class PacketBargainTerminateNotify extends BasePacket {
public PacketBargainTerminateNotify(int bargainId) {
super(PacketOpcodes.BargainTerminateNotify);
this.setData(BargainTerminateNotify.newBuilder()
.setBargainId(bargainId));
this.setData(BargainTerminateNotify.newBuilder().setBargainId(bargainId));
}
}

View File

@@ -4,17 +4,15 @@ import emu.grasscutter.game.quest.BargainRecord;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.proto.GetAllActivatedBargainDataRspOuterClass.GetAllActivatedBargainDataRsp;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import java.util.Collection;
public final class PacketGetAllActivatedBargainDataRsp extends BasePacket {
public PacketGetAllActivatedBargainDataRsp(Collection<BargainRecord> records) {
super(PacketOpcodes.GetAllActivatedBargainDataRsp);
this.setData(GetAllActivatedBargainDataRsp.newBuilder()
.setRetcode(Retcode.RET_SUCC.getNumber())
.addAllSnapshotList(records.stream()
.map(BargainRecord::toSnapshot)
.toList()));
this.setData(
GetAllActivatedBargainDataRsp.newBuilder()
.setRetcode(Retcode.RET_SUCC.getNumber())
.addAllSnapshotList(records.stream().map(BargainRecord::toSnapshot).toList()));
}
}

View File

@@ -9,16 +9,16 @@ public final class PacketGetBargainDataRsp extends BasePacket {
public PacketGetBargainDataRsp(Retcode retcode) {
super(PacketOpcodes.GetBargainDataRsp);
this.setData(GetBargainDataRsp.newBuilder()
.setRetcode(retcode.getNumber()));
this.setData(GetBargainDataRsp.newBuilder().setRetcode(retcode.getNumber()));
}
public PacketGetBargainDataRsp(BargainRecord record) {
super(PacketOpcodes.GetBargainDataRsp);
this.setData(GetBargainDataRsp.newBuilder()
.setRetcode(Retcode.RET_SUCC.getNumber())
.setBargainId(record.getBargainId())
.setSnapshot(record.toSnapshot()));
this.setData(
GetBargainDataRsp.newBuilder()
.setRetcode(Retcode.RET_SUCC.getNumber())
.setBargainId(record.getBargainId())
.setSnapshot(record.toSnapshot()));
}
}

View File

@@ -27,7 +27,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
.setChannelId(1)
.setCountryCode("US")
.setClientVersionRandomKey("c25-314dd05b0b5f")
.setEMFDHANIAHH(3) // setRegPlatform
.setRegPlatform(3)
.setClientIpStr(session.getAddress().getAddress().getHostAddress())
.build();
@@ -46,7 +46,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
.setRetcode(retcode)
.setMsg(msg)
.setBlackUidEndTime(blackEndTime)
.setEMFDHANIAHH(3) // setRegPlatform
.setRegPlatform(3)
.setCountryCode("US")
.setClientIpStr(session.getAddress().getAddress().getHostAddress())
.build();
@@ -73,7 +73,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
.setChannelId(1)
.setCountryCode("US")
.setClientVersionRandomKey("c25-314dd05b0b5f")
.setEMFDHANIAHH(3) // setRegPlatform
.setRegPlatform(3)
.setClientIpStr(session.getAddress().getAddress().getHostAddress())
.setServerRandKey(encryptedSeed)
.setSign(encryptedSeedSign)

View File

@@ -14,13 +14,13 @@ public class PacketGetSceneAreaRsp extends BasePacket {
GetSceneAreaRsp p =
GetSceneAreaRsp.newBuilder()
.setSceneId(sceneId)
.addAllAreaIdList(player.getUnlockedSceneAreas(sceneId))
.addCityInfoList(player.getSotsManager().getCityInfo(1).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(2).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(3).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(4).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(5).toProto())
.setSceneId(sceneId)
.addAllAreaIdList(player.getUnlockedSceneAreas(sceneId))
.addCityInfoList(player.getSotsManager().getCityInfo(1).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(2).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(3).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(4).toProto())
.addCityInfoList(player.getSotsManager().getCityInfo(5).toProto())
.build();
this.setData(p);

View File

@@ -3,15 +3,12 @@ package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.*;
import emu.grasscutter.net.proto.GivingRecordNotifyOuterClass.GivingRecordNotify;
import emu.grasscutter.net.proto.GivingRecordOuterClass.GivingRecord;
import java.util.Collection;
public final class PacketGivingRecordNotify extends BasePacket {
public PacketGivingRecordNotify(Collection<GivingRecord> records) {
super(PacketOpcodes.GivingRecordNotify);
this.setData(GivingRecordNotify.newBuilder()
.addAllGivingRecordList(records)
.build());
this.setData(GivingRecordNotify.newBuilder().addAllGivingRecordList(records).build());
}
}

View File

@@ -11,8 +11,7 @@ public final class PacketItemGivingRsp extends BasePacket {
public PacketItemGivingRsp(int value, Mode mode) {
super(PacketOpcodes.ItemGivingRsp);
var packet = ItemGivingRsp.newBuilder()
.setRetcode(mode == Mode.FAILURE ? 1 : 0);
var packet = ItemGivingRsp.newBuilder().setRetcode(mode == Mode.FAILURE ? 1 : 0);
if (mode == Mode.EXACT_SUCCESS) {
packet.setGivingId(value);
} else if (mode == Mode.GROUP_SUCCESS) {

View File

@@ -7,7 +7,6 @@ import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.MapLayerInfoOuterClass;
import emu.grasscutter.net.proto.PlayerWorldSceneInfoListNotifyOuterClass.PlayerWorldSceneInfoListNotify;
import emu.grasscutter.net.proto.PlayerWorldSceneInfoOuterClass.PlayerWorldSceneInfo;
import java.util.stream.IntStream;
public class PacketPlayerWorldSceneInfoListNotify extends BasePacket {
@@ -16,49 +15,66 @@ public class PacketPlayerWorldSceneInfoListNotify extends BasePacket {
super(PacketOpcodes.PlayerWorldSceneInfoListNotify); // Rename opcode later
PlayerWorldSceneInfoListNotify.Builder proto =
PlayerWorldSceneInfoListNotify.newBuilder()
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(1).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder()
.setSceneId(3)
.setIsLocked(false)
.addAllSceneTagIdList(GameData.getSceneTagDataMap().values().stream()
.filter(sceneTag -> sceneTag.getSceneId() == 3)
.filter(sceneTag -> sceneTag.isDefaultValid() || sceneTag.getCond().get(0).getCondType() != null)
.map(SceneTagData::getId)
.toList())
//.addSceneTagIdList(102) // Jade chamber (alr added)
//.addSceneTagIdList(113)
//.addSceneTagIdList(117)
//.addSceneTagIdList(1093) // 3.0 Vana_real
.addSceneTagIdList(1094) // 3.0 Vana_dream
//.addSceneTagIdList(1095) // 3.0 Vana_first
//.addSceneTagIdList(1096) // 3.0 Vana_festival
.addSceneTagIdList(152) // 3.1 event
.addSceneTagIdList(153) // 3.1 event
.addSceneTagIdList(1164) // Desert Arena (XMSM_CWLTop)
.addSceneTagIdList(1166) // Desert Pyramid (CWL_Trans_02)
.setMapLayerInfo(MapLayerInfoOuterClass.MapLayerInfo.newBuilder()
.addAllUnlockedMapLayerIdList(GameData.getMapLayerDataMap().keySet()) // MapLayer Ids
.addAllUnlockedMapLayerFloorIdList(GameData.getMapLayerFloorDataMap().keySet())
.addAllUnlockedMapLayerGroupIdList(GameData.getMapLayerGroupDataMap().keySet()) // will show MapLayer options when hovered over
.build()) //map layer test
.build())
.addInfoList(PlayerWorldSceneInfo.newBuilder()
.setSceneId(4)
.setIsLocked(false)
.addSceneTagIdList(106)
.addSceneTagIdList(109)
.addSceneTagIdList(117)
.build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(5).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(6).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(7).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(9).setIsLocked(false)
.addAllSceneTagIdList(IntStream.range(0, 3000).boxed().toList())
.build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(10).setIsLocked(false)
.addAllSceneTagIdList(IntStream.range(0, 3000).boxed().toList())
.build()); //3.8
PlayerWorldSceneInfoListNotify.newBuilder()
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(1).setIsLocked(false).build())
.addInfoList(
PlayerWorldSceneInfo.newBuilder()
.setSceneId(3)
.setIsLocked(false)
.addAllSceneTagIdList(
GameData.getSceneTagDataMap().values().stream()
.filter(sceneTag -> sceneTag.getSceneId() == 3)
.filter(
sceneTag ->
sceneTag.isDefaultValid()
|| sceneTag.getCond().get(0).getCondType() != null)
.map(SceneTagData::getId)
.toList())
// .addSceneTagIdList(102) // Jade chamber (alr added)
// .addSceneTagIdList(113)
// .addSceneTagIdList(117)
// .addSceneTagIdList(1093) // 3.0 Vana_real
.addSceneTagIdList(1094) // 3.0 Vana_dream
// .addSceneTagIdList(1095) // 3.0 Vana_first
// .addSceneTagIdList(1096) // 3.0 Vana_festival
.addSceneTagIdList(152) // 3.1 event
.addSceneTagIdList(153) // 3.1 event
.addSceneTagIdList(1164) // Desert Arena (XMSM_CWLTop)
.addSceneTagIdList(1166) // Desert Pyramid (CWL_Trans_02)
.setMapLayerInfo(
MapLayerInfoOuterClass.MapLayerInfo.newBuilder()
.addAllUnlockedMapLayerIdList(
GameData.getMapLayerDataMap().keySet()) // MapLayer Ids
.addAllUnlockedMapLayerFloorIdList(
GameData.getMapLayerFloorDataMap().keySet())
.addAllUnlockedMapLayerGroupIdList(
GameData.getMapLayerGroupDataMap()
.keySet()) // will show MapLayer options when hovered over
.build()) // map layer test
.build())
.addInfoList(
PlayerWorldSceneInfo.newBuilder()
.setSceneId(4)
.setIsLocked(false)
.addSceneTagIdList(106)
.addSceneTagIdList(109)
.addSceneTagIdList(117)
.build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(5).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(6).setIsLocked(false).build())
.addInfoList(PlayerWorldSceneInfo.newBuilder().setSceneId(7).setIsLocked(false).build())
.addInfoList(
PlayerWorldSceneInfo.newBuilder()
.setSceneId(9)
.setIsLocked(false)
.addAllSceneTagIdList(IntStream.range(0, 3000).boxed().toList())
.build())
.addInfoList(
PlayerWorldSceneInfo.newBuilder()
.setSceneId(10)
.setIsLocked(false)
.addAllSceneTagIdList(IntStream.range(0, 3000).boxed().toList())
.build()); // 3.8
this.setData(proto);
}